From 667ad0d059f5ce160f6bc6e18c9d2b7e5259b8a3 Mon Sep 17 00:00:00 2001 From: Matsv Date: Sun, 14 May 2017 16:02:04 +0200 Subject: [PATCH] Rewrite Spawner entity ID, fix #643 --- ...temRewriter.java => EntityIdRewriter.java} | 30 +++-- .../Protocol1_11To1_10.java | 89 +++++++++++++++ .../packets/InventoryPackets.java | 18 +-- .../types/Chunk1_11Type.java | 103 ++++++++++++++++++ .../Protocol1_9_1_2TO1_9_3_4.java | 1 + 5 files changed, 223 insertions(+), 18 deletions(-) rename common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/{ItemRewriter.java => EntityIdRewriter.java} (89%) create mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/types/Chunk1_11Type.java diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/ItemRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/EntityIdRewriter.java similarity index 89% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/ItemRewriter.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/EntityIdRewriter.java index f55cc9ec5..a840c182b 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/ItemRewriter.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/EntityIdRewriter.java @@ -6,7 +6,7 @@ import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import us.myles.ViaVersion.api.minecraft.item.Item; -public class ItemRewriter { +public class EntityIdRewriter { private static BiMap oldToNewNames = HashBiMap.create(); static { @@ -87,20 +87,32 @@ public class ItemRewriter { oldToNewNames.put("ZombieVillager", "minecraft:zombie_villager"); } - public static void toClient(Item item) { + public static void toClient(CompoundTag tag) { + if (tag.get("id") instanceof StringTag) { + StringTag id = tag.get("id"); + if (oldToNewNames.containsKey(id.getValue())) { + id.setValue(oldToNewNames.get(id.getValue())); + } + } + } + + public static void toClientSpawner(CompoundTag tag) { + if (tag != null && tag.contains("SpawnData")) { + CompoundTag spawnData = tag.get("SpawnData"); + if (spawnData != null && spawnData.contains("id")) + toClient(spawnData); + } + } + + public static void toClientItem(Item item) { if (hasEntityTag(item)) { CompoundTag entityTag = item.getTag().get("EntityTag"); - if (entityTag.get("id") instanceof StringTag) { - StringTag id = entityTag.get("id"); - if (oldToNewNames.containsKey(id.getValue())) { - id.setValue(oldToNewNames.get(id.getValue())); - } - } + toClient(entityTag); } if (item != null && item.getAmount() <= 0) item.setAmount((byte) 1); } - public static void toServer(Item item) { + public static void toServerItem(Item item) { if (hasEntityTag(item)) { CompoundTag entityTag = item.getTag().get("EntityTag"); if (entityTag.get("id") instanceof StringTag) { diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/Protocol1_11To1_10.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/Protocol1_11To1_10.java index d28981ca6..3e5a0c436 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/Protocol1_11To1_10.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/Protocol1_11To1_10.java @@ -1,10 +1,13 @@ package us.myles.ViaVersion.protocols.protocol1_11to1_10; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.google.common.base.Optional; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.entities.Entity1_11Types; +import us.myles.ViaVersion.api.minecraft.chunks.Chunk; import us.myles.ViaVersion.api.protocol.Protocol; import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; @@ -15,6 +18,8 @@ import us.myles.ViaVersion.api.type.types.version.Types1_9; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.protocols.protocol1_11to1_10.packets.InventoryPackets; import us.myles.ViaVersion.protocols.protocol1_11to1_10.storage.EntityTracker; +import us.myles.ViaVersion.protocols.protocol1_11to1_10.types.Chunk1_11Type; +import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; public class Protocol1_11To1_10 extends Protocol { private static final ValueTransformer toOldByte = new ValueTransformer(Type.UNSIGNED_BYTE) { @@ -243,6 +248,88 @@ public class Protocol1_11To1_10 extends Protocol { } }); + // Update Block Entity + registerOutgoing(State.PLAY, 0x09, 0x09, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.POSITION); // 0 - Position + map(Type.UNSIGNED_BYTE); // 1 - Action + map(Type.NBT); // 2 - NBT data + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + if (wrapper.get(Type.UNSIGNED_BYTE, 0) == 1) { + CompoundTag tag = wrapper.get(Type.NBT, 0); + EntityIdRewriter.toClientSpawner(tag); + } + } + }); + } + }); + + // Chunk Data + registerOutgoing(State.PLAY, 0x20, 0x20, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + + Chunk1_11Type type = new Chunk1_11Type(clientWorld); + Chunk chunk = wrapper.passthrough(type); + + if (chunk.getBlockEntities() == null) return; + for (CompoundTag tag : chunk.getBlockEntities()) { + if (tag.contains("id") && + ((StringTag) tag.get("id")).getValue().equals("MobSpawner")) { + EntityIdRewriter.toClientSpawner(tag); + } + } + } + }); + } + }); + + // Join (save dimension id) + registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.INT); // 0 - Entity ID + map(Type.UNSIGNED_BYTE); // 1 - Gamemode + map(Type.INT); // 2 - Dimension + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + ClientWorld clientChunks = wrapper.user().get(ClientWorld.class); + + int dimensionId = wrapper.get(Type.INT, 1); + clientChunks.setEnvironment(dimensionId); + } + }); + } + }); + + // Respawn (save dimension id) + registerOutgoing(State.PLAY, 0x33, 0x33, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.INT); // 0 - Dimension ID + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + + int dimensionId = wrapper.get(Type.INT, 0); + clientWorld.setEnvironment(dimensionId); + } + }); + } + }); + /* INCOMING PACKETS */ @@ -314,5 +401,7 @@ public class Protocol1_11To1_10 extends Protocol { @Override public void init(UserConnection userConnection) { userConnection.put(new EntityTracker(userConnection)); + if (!userConnection.has(ClientWorld.class)) + userConnection.put(new ClientWorld(userConnection)); } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/packets/InventoryPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/packets/InventoryPackets.java index 6a3d16a03..2622fdbb5 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/packets/InventoryPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/packets/InventoryPackets.java @@ -6,7 +6,7 @@ import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.packets.State; -import us.myles.ViaVersion.protocols.protocol1_11to1_10.ItemRewriter; +import us.myles.ViaVersion.protocols.protocol1_11to1_10.EntityIdRewriter; import us.myles.ViaVersion.protocols.protocol1_11to1_10.Protocol1_11To1_10; public class InventoryPackets { @@ -27,7 +27,7 @@ public class InventoryPackets { @Override public void handle(PacketWrapper wrapper) throws Exception { Item stack = wrapper.get(Type.ITEM, 0); - ItemRewriter.toClient(stack); + EntityIdRewriter.toClientItem(stack); } }); } @@ -45,7 +45,7 @@ public class InventoryPackets { public void handle(PacketWrapper wrapper) throws Exception { Item[] stacks = wrapper.get(Type.ITEM_ARRAY, 0); for (Item stack : stacks) - ItemRewriter.toClient(stack); + EntityIdRewriter.toClientItem(stack); } }); } @@ -63,7 +63,7 @@ public class InventoryPackets { @Override public void handle(PacketWrapper wrapper) throws Exception { Item stack = wrapper.get(Type.ITEM, 0); - ItemRewriter.toClient(stack); + EntityIdRewriter.toClientItem(stack); } }); } @@ -83,12 +83,12 @@ public class InventoryPackets { int size = wrapper.passthrough(Type.UNSIGNED_BYTE); for (int i = 0; i < size; i++) { - ItemRewriter.toClient(wrapper.passthrough(Type.ITEM)); // Input Item - ItemRewriter.toClient(wrapper.passthrough(Type.ITEM)); // Output Item + EntityIdRewriter.toClientItem(wrapper.passthrough(Type.ITEM)); // Input Item + EntityIdRewriter.toClientItem(wrapper.passthrough(Type.ITEM)); // Output Item boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item if (secondItem) - ItemRewriter.toClient(wrapper.passthrough(Type.ITEM)); // Second Item + EntityIdRewriter.toClientItem(wrapper.passthrough(Type.ITEM)); // Second Item wrapper.passthrough(Type.BOOLEAN); // Trade disabled wrapper.passthrough(Type.INT); // Number of tools uses @@ -119,7 +119,7 @@ public class InventoryPackets { @Override public void handle(PacketWrapper wrapper) throws Exception { Item item = wrapper.get(Type.ITEM, 0); - ItemRewriter.toServer(item); + EntityIdRewriter.toServerItem(item); } }); } @@ -137,7 +137,7 @@ public class InventoryPackets { @Override public void handle(PacketWrapper wrapper) throws Exception { Item item = wrapper.get(Type.ITEM, 0); - ItemRewriter.toServer(item); + EntityIdRewriter.toServerItem(item); } }); } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/types/Chunk1_11Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/types/Chunk1_11Type.java new file mode 100644 index 000000000..ad802a61b --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/types/Chunk1_11Type.java @@ -0,0 +1,103 @@ +package us.myles.ViaVersion.protocols.protocol1_11to1_10.types; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import us.myles.ViaVersion.api.minecraft.Environment; +import us.myles.ViaVersion.api.minecraft.chunks.Chunk; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; +import us.myles.ViaVersion.api.type.PartialType; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType; +import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.Chunk1_9_3_4; +import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.ChunkSection1_9_3_4; +import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; + +import java.util.Arrays; +import java.util.BitSet; +import java.util.List; + +public class Chunk1_11Type extends PartialType { + + public Chunk1_11Type(ClientWorld param) { + super(param, Chunk.class); + } + + @Override + public Chunk read(ByteBuf input, ClientWorld world) throws Exception { + int chunkX = input.readInt(); + int chunkZ = input.readInt(); + + boolean groundUp = input.readBoolean(); + int primaryBitmask = Type.VAR_INT.read(input); + Type.VAR_INT.read(input); + + BitSet usedSections = new BitSet(16); + ChunkSection1_9_3_4[] sections = new ChunkSection1_9_3_4[16]; + // Calculate section count from bitmask + for (int i = 0; i < 16; i++) { + if ((primaryBitmask & (1 << i)) != 0) { + usedSections.set(i); + } + } + + // Read sections + for (int i = 0; i < 16; i++) { + if (!usedSections.get(i)) continue; // Section not set + ChunkSection1_9_3_4 section = new ChunkSection1_9_3_4(); + sections[i] = section; + section.readBlocks(input); + section.readBlockLight(input); + if (world.getEnvironment() == Environment.NORMAL) { + section.readSkyLight(input); + } + } + + byte[] biomeData = groundUp ? new byte[256] : null; + if (groundUp) { + input.readBytes(biomeData); + } + + List nbtData = Arrays.asList(Type.NBT_ARRAY.read(input)); + + return new Chunk1_9_3_4(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); + } + + @Override + public void write(ByteBuf output, ClientWorld world, Chunk chunk) throws Exception { + output.writeInt(chunk.getX()); + output.writeInt(chunk.getZ()); + + output.writeBoolean(chunk.isGroundUp()); + Type.VAR_INT.write(output, chunk.getBitmask()); + + ByteBuf buf = Unpooled.buffer(); + for (int i = 0; i < 16; i++) { + ChunkSection section = chunk.getSections()[i]; + if (section == null) continue; // Section not set + section.writeBlocks(buf); + section.writeBlockLight(buf); + + if (!section.hasSkyLight()) continue; // No sky light, we're done here. + section.writeSkyLight(buf); + + } + buf.readerIndex(0); + Type.VAR_INT.write(output, buf.readableBytes() + (chunk.isBiomeData() ? 256 : 0)); + output.writeBytes(buf); + buf.release(); // release buffer + + // Write biome data + if (chunk.isBiomeData()) { + output.writeBytes(chunk.getBiomeData()); + } + + // Write Block Entities + Type.NBT_ARRAY.write(output, chunk.getBlockEntities().toArray(new CompoundTag[0])); + } + + @Override + public Class getBaseClass() { + return BaseChunkType.class; + } +} \ No newline at end of file diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/Protocol1_9_1_2TO1_9_3_4.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/Protocol1_9_1_2TO1_9_3_4.java index 3a5781d26..52d7f59d8 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/Protocol1_9_1_2TO1_9_3_4.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/Protocol1_9_1_2TO1_9_3_4.java @@ -53,6 +53,7 @@ public class Protocol1_9_1_2TO1_9_3_4 extends Protocol { } }); + // Chunk Packet registerOutgoing(State.PLAY, 0x20, 0x20, new PacketRemapper() { @Override public void registerMap() {