@Override
  public void rewriteServerbound(ByteBuf packet, int oldId, int newId) {
    super.rewriteServerbound(packet, oldId, newId);
    // Special cases
    int readerIndex = packet.readerIndex();
    int packetId = DefinedPacket.readVarInt(packet);
    int packetIdLength = packet.readerIndex() - readerIndex;

    if (packetId == 0x18 /* Spectate */) {
      UUID uuid = DefinedPacket.readUUID(packet);
      ProxiedPlayer player;
      if ((player = BungeeCord.getInstance().getPlayer(uuid)) != null) {
        int previous = packet.writerIndex();
        packet.readerIndex(readerIndex);
        packet.writerIndex(readerIndex + packetIdLength);
        DefinedPacket.writeUUID(
            ((UserConnection) player).getPendingConnection().getOfflineId(), packet);
        packet.writerIndex(previous);
      }
    }
    packet.readerIndex(readerIndex);
  }
  @Override
  protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
    int size = DefinedPacket.readVarInt(in);
    if (size == 0) {
      out.add(in.slice().retain());
      in.skipBytes(in.readableBytes());
    } else {
      ByteBuf decompressed = ctx.alloc().directBuffer();

      try {
        zlib.process(in, decompressed);
        Preconditions.checkState(
            decompressed.readableBytes() == size, "Decompressed packet size mismatch");

        out.add(decompressed);
        decompressed = null;
      } finally {
        if (decompressed != null) {
          decompressed.release();
        }
      }
    }
  }
  @Override
  @SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
  public void rewriteClientbound(ByteBuf packet, int oldId, int newId) {
    super.rewriteClientbound(packet, oldId, newId);

    // Special cases
    int readerIndex = packet.readerIndex();
    int packetId = DefinedPacket.readVarInt(packet);
    int packetIdLength = packet.readerIndex() - readerIndex;
    if (packetId == 0x0D /* Collect Item */) {
      DefinedPacket.readVarInt(packet);
      rewriteVarInt(packet, oldId, newId, packet.readerIndex());
    } else if (packetId == 0x1B /* Attach Entity */) {
      rewriteInt(packet, oldId, newId, readerIndex + packetIdLength + 4);
    } else if (packetId == 0x13 /* Destroy Entities */) {
      int count = DefinedPacket.readVarInt(packet);
      int[] ids = new int[count];
      for (int i = 0; i < count; i++) {
        ids[i] = DefinedPacket.readVarInt(packet);
      }
      packet.readerIndex(readerIndex + packetIdLength);
      packet.writerIndex(readerIndex + packetIdLength);
      DefinedPacket.writeVarInt(count, packet);
      for (int id : ids) {
        if (id == oldId) {
          id = newId;
        } else if (id == newId) {
          id = oldId;
        }
        DefinedPacket.writeVarInt(id, packet);
      }
    } else if (packetId == 0x0E /* Spawn Object */) {

      DefinedPacket.readVarInt(packet);
      int type = packet.readUnsignedByte();

      if (type == 60 || type == 90) {
        packet.skipBytes(14);
        int position = packet.readerIndex();
        int readId = packet.readInt();
        int changedId = -1;
        if (readId == oldId) {
          packet.setInt(position, newId);
          changedId = newId;
        } else if (readId == newId) {
          packet.setInt(position, oldId);
          changedId = oldId;
        }
        if (changedId != -1) {
          if (changedId == 0 && readId != 0) { // Trim off the extra data
            packet.readerIndex(readerIndex);
            packet.writerIndex(packet.readableBytes() - 6);
          } else if (changedId != 0 && readId == 0) { // Add on the extra data
            packet.readerIndex(readerIndex);
            packet.capacity(packet.readableBytes() + 6);
            packet.writerIndex(packet.readableBytes() + 6);
          }
        }
      }
    } else if (packetId == 0x0C /* Spawn Player */) {
      DefinedPacket.readVarInt(packet); // Entity ID
      int idLength = packet.readerIndex() - readerIndex - packetIdLength;
      UUID uuid = DefinedPacket.readUUID(packet);
      ProxiedPlayer player;
      if ((player = BungeeCord.getInstance().getPlayerByOfflineUUID(uuid)) != null) {
        int previous = packet.writerIndex();
        packet.readerIndex(readerIndex);
        packet.writerIndex(readerIndex + packetIdLength + idLength);
        DefinedPacket.writeUUID(player.getUniqueId(), packet);
        packet.writerIndex(previous);
      }
    } else if (packetId == 0x42 /* Combat Event */) {
      int event = packet.readUnsignedByte();
      if (event == 1 /* End Combat*/) {
        DefinedPacket.readVarInt(packet);
        rewriteInt(packet, oldId, newId, packet.readerIndex());
      } else if (event == 2 /* Entity Dead */) {
        int position = packet.readerIndex();
        rewriteVarInt(packet, oldId, newId, packet.readerIndex());
        packet.readerIndex(position);
        DefinedPacket.readVarInt(packet);
        rewriteInt(packet, oldId, newId, packet.readerIndex());
      }
    }
    packet.readerIndex(readerIndex);
  }
Example #4
0
 @Override
 public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
   if (protocolVersion < ProtocolConstants.MINECRAFT_SNAPSHOT) {
     Item item = items[0]; // Only one at a time
     writeString(item.displayName, buf); // TODO: Server unique only!
     buf.writeBoolean(action != Action.REMOVE_PLAYER);
     buf.writeShort(item.ping);
   } else {
     DefinedPacket.writeVarInt(action.ordinal(), buf);
     DefinedPacket.writeVarInt(items.length, buf);
     for (Item item : items) {
       DefinedPacket.writeUUID(item.uuid, buf);
       switch (action) {
         case ADD_PLAYER:
           DefinedPacket.writeString(item.username, buf);
           DefinedPacket.writeVarInt(item.properties.length, buf);
           for (String[] prop : item.properties) {
             DefinedPacket.writeString(prop[0], buf);
             DefinedPacket.writeString(prop[1], buf);
             if (prop.length >= 3) {
               buf.writeBoolean(true);
               DefinedPacket.writeString(prop[2], buf);
             } else {
               buf.writeBoolean(false);
             }
           }
           DefinedPacket.writeVarInt(item.gamemode, buf);
           DefinedPacket.writeVarInt(item.ping, buf);
           buf.writeBoolean(item.displayName != null);
           if (item.displayName != null) {
             DefinedPacket.writeString(item.displayName, buf);
           }
           break;
         case UPDATE_GAMEMODE:
           DefinedPacket.writeVarInt(item.gamemode, buf);
           break;
         case UPDATE_LATENCY:
           DefinedPacket.writeVarInt(item.ping, buf);
           break;
         case UPDATE_DISPLAY_NAME:
           buf.writeBoolean(item.displayName != null);
           if (item.displayName != null) {
             DefinedPacket.writeString(item.displayName, buf);
           }
           break;
       }
     }
   }
 }
Example #5
0
 @Override
 public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
   if (protocolVersion < ProtocolConstants.MINECRAFT_SNAPSHOT) {
     items = new Item[1];
     Item item = items[0] = new Item();
     item.displayName = item.username = readString(buf);
     action = !buf.readBoolean() ? Action.REMOVE_PLAYER : Action.ADD_PLAYER;
     item.ping = buf.readShort();
   } else {
     action = Action.values()[DefinedPacket.readVarInt(buf)];
     items = new Item[DefinedPacket.readVarInt(buf)];
     for (int i = 0; i < items.length; i++) {
       Item item = items[i] = new Item();
       item.setUuid(DefinedPacket.readUUID(buf));
       switch (action) {
         case ADD_PLAYER:
           item.username = DefinedPacket.readString(buf);
           item.properties = new String[DefinedPacket.readVarInt(buf)][];
           for (int j = 0; j < item.properties.length; j++) {
             String name = DefinedPacket.readString(buf);
             String value = DefinedPacket.readString(buf);
             if (buf.readBoolean()) {
               item.properties[j] = new String[] {name, value, DefinedPacket.readString(buf)};
             } else {
               item.properties[j] = new String[] {name, value};
             }
           }
           item.gamemode = DefinedPacket.readVarInt(buf);
           item.ping = DefinedPacket.readVarInt(buf);
           if (buf.readBoolean()) {
             item.displayName = DefinedPacket.readString(buf);
           }
           break;
         case UPDATE_GAMEMODE:
           item.gamemode = DefinedPacket.readVarInt(buf);
           break;
         case UPDATE_LATENCY:
           item.ping = DefinedPacket.readVarInt(buf);
           break;
         case UPDATE_DISPLAY_NAME:
           if (buf.readBoolean()) {
             item.displayName = DefinedPacket.readString(buf);
           }
       }
     }
   }
 }