diff --git a/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java b/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java index 31d16deed..d7d17ed5c 100644 --- a/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java +++ b/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java @@ -115,6 +115,16 @@ public class PacketWrapper { * @param value The value of the type to write. */ public void write(Type type, T value) { + if (value != null) { + if (!type.getOutputClass().isAssignableFrom(value.getClass())) { + // attempt conversion + if (type instanceof TypeConverter) { + value = (T) ((TypeConverter) type).from(value); + } else { + System.out.println("Possible type mismatch: " + value.getClass().getName() + " -> " + type.getOutputClass()); + } + } + } packetValues.add(new Pair(type, value)); } diff --git a/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java b/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java index b53dada45..80d13fde0 100644 --- a/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java +++ b/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java @@ -19,6 +19,10 @@ public class UserConnection { @Getter @Setter private Object lastPacket; + @Getter + private long sentPackets = 0L; + @Getter + private long receivedPackets = 0L; public UserConnection(SocketChannel socketChannel) { @@ -82,4 +86,18 @@ public class UserConnection { public void sendRawPacket(final ByteBuf packet) { sendRawPacket(packet, false); } + + /** + * Used for incrementing the number of packets sent to the client + */ + public void incrementSent() { + this.sentPackets++; + } + + /** + * Used for incrementing the number of packets received from the client + */ + public void incrementReceived() { + this.receivedPackets++; + } } diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java index a26624338..862ba80ee 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java @@ -30,6 +30,9 @@ public class ViaDecodeHandler extends ByteToMessageDecoder { // use transformers if (bytebuf.readableBytes() > 0) { if (info.isActive()) { + // Increment received + info.incrementReceived(); + // Handle ID int id = Type.VAR_INT.read(bytebuf); // Transform ByteBuf newPacket = ctx.alloc().buffer(); diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java index ece04ee44..44c0d67f3 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java @@ -41,6 +41,9 @@ public class ViaEncodeHandler extends MessageToByteEncoder { throw new CancelException(); } if (info.isActive()) { + // Increment sent + info.incrementSent(); + // Handle ID int id = Type.VAR_INT.read(bytebuf); // Transform ByteBuf oldPacket = bytebuf.copy(); diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java index bee3036f8..923111f48 100644 --- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java +++ b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java @@ -373,48 +373,6 @@ public class PlayerPackets { } }); - // Use Item Packet - protocol.registerIncoming(State.PLAY, -1, 0x1D, new PacketRemapper() { - @Override - public void registerMap() { - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - int hand = wrapper.read(Type.VAR_INT); - // Wipe the input buffer - wrapper.clearInputBuffer(); - // First set this packet ID to Block placement - wrapper.setId(0x08); - wrapper.write(Type.LONG, -1L); - wrapper.write(Type.BYTE, (byte) 255); - // Write item in hand - Item item = Item.getItem(Protocol1_9TO1_8.getHandItem(wrapper.user())); - // Blocking patch - if (item != null) { - if (Material.getMaterial(item.getId()).name().endsWith("SWORD")) { - if (hand == 0) { - EntityTracker tracker = wrapper.user().get(EntityTracker.class); - if (!tracker.isBlocking()) { - tracker.setBlocking(true); - Item shield = new Item((short) 442, (byte) 1, (short) 0, null); - tracker.setSecondHand(shield); - } - wrapper.cancel(); - } - - } - } - wrapper.write(Type.ITEM, item); - - wrapper.write(Type.BYTE, (byte) 0); - wrapper.write(Type.BYTE, (byte) 0); - wrapper.write(Type.BYTE, (byte) 0); - } - }); - - } - }); - // Packet Plugin Message Incoming protocol.registerIncoming(State.PLAY, 0x17, 0x09, new PacketRemapper() { @Override diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java index e10caadd5..28165d8f8 100644 --- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java +++ b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java @@ -5,6 +5,7 @@ import org.spacehq.opennbt.tag.builtin.CompoundTag; import org.spacehq.opennbt.tag.builtin.StringTag; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.ViaVersion; +import us.myles.ViaVersion.api.minecraft.Position; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; import us.myles.ViaVersion.api.minecraft.item.Item; import us.myles.ViaVersion.api.protocol.Protocol; @@ -216,6 +217,61 @@ public class WorldPackets { } }); + // Use Item Packet + protocol.registerIncoming(State.PLAY, -1, 0x1D, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + Long last = tracker.getLastPlaceBlock(); + if(last != -1){ + if((wrapper.user().getReceivedPackets() - last) < 5) { + wrapper.cancel(); + } + tracker.setLastPlaceBlock(-1L); + } + } + }); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int hand = wrapper.read(Type.VAR_INT); + // Wipe the input buffer + wrapper.clearInputBuffer(); + // First set this packet ID to Block placement + wrapper.setId(0x08); + wrapper.write(Type.LONG, -1L); + wrapper.write(Type.BYTE, (byte) 255); + // Write item in hand + Item item = Item.getItem(Protocol1_9TO1_8.getHandItem(wrapper.user())); + // Blocking patch + if (item != null) { + if (Material.getMaterial(item.getId()).name().endsWith("SWORD")) { + if (hand == 0) { + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + if (!tracker.isBlocking()) { + tracker.setBlocking(true); + Item shield = new Item((short) 442, (byte) 1, (short) 0, null); + tracker.setSecondHand(shield); + } + wrapper.cancel(); + } + + } + } + wrapper.write(Type.ITEM, item); + + wrapper.write(Type.BYTE, (byte) 0); + wrapper.write(Type.BYTE, (byte) 0); + wrapper.write(Type.BYTE, (byte) 0); + } + }); + + } + }); + // Block Placement Packet protocol.registerIncoming(State.PLAY, 0x08, 0x1C, new PacketRemapper() { @Override @@ -242,9 +298,25 @@ public class WorldPackets { if (item != null) { Material m = Material.getMaterial(item.getId()); if (m != null) { - if (!m.isBlock()) { - wrapper.cancel(); + // Prevent special items from sending certain info + // Books + boolean special = m == Material.WRITTEN_BOOK; + // Buckets + special = special || m == Material.WATER_BUCKET || m == Material.LAVA_BUCKET || m == Material.BUCKET; + // Food + special = special || m.isEdible(); + // Potions + special = special || m == Material.POTION || m == Material.GLASS_BOTTLE; + // Projectiles + special = special || m == Material.BOW; + special = special || m == Material.SNOW_BALL || m == Material.EGG || m == Material.EXP_BOTTLE || m == Material.ENDER_PEARL || m == Material.EYE_OF_ENDER; + // Don't send data if special + if (special) { + wrapper.set(Type.POSITION, 0, new Position(-1L, 255L, -1L)); + wrapper.set(Type.BYTE, 0, (byte) -1); } + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + tracker.setLastPlaceBlock(wrapper.user().getReceivedPackets()); } } } diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java index 8ad19c77e..7304543fa 100644 --- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java +++ b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java @@ -34,6 +34,8 @@ public class EntityTracker extends StoredObject { @Setter private boolean autoTeam = false; @Setter + private Long lastPlaceBlock = -1L; + @Setter private int entityID; private boolean teamExists = false;