From 012aac97ee1b5ab5aaca0472b9c172d33a213597 Mon Sep 17 00:00:00 2001 From: Matsv Date: Sat, 6 Jan 2018 15:23:49 +0100 Subject: [PATCH] Handle changed block entities. Fixes banners,beds & flowerpots --- .../api/minecraft/chunks/ChunkSection.java | 2 + .../chunks/ChunkSection1_9_3_4.java | 20 ++- .../chunks/ChunkSection1_9_1_2.java | 7 +- .../chunks/ChunkSection1_9to1_8.java | 6 + .../ProtocolSnapshotTo1_12_2.java | 9 ++ .../packets/EntityPackets.java | 1 - .../packets/WorldPackets.java | 124 ++++++++++++++++-- .../providers/BlockEntityProvider.java | 68 ++++++++++ .../blockentities/BannerHandler.java | 45 +++++++ .../providers/blockentities/BedHandler.java | 34 +++++ .../blockentities/FlowerPotHandler.java | 59 +++++++++ .../storage/BlockStorage.java | 79 +++++++++++ .../assets/viaversion/data/mapping-1.12.json | 48 ++++--- 13 files changed, 469 insertions(+), 33 deletions(-) create mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/BlockEntityProvider.java create mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/BannerHandler.java create mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/BedHandler.java create mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/FlowerPotHandler.java create mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/BlockStorage.java diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java index 14d74ee70..5601c59f1 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java @@ -9,6 +9,8 @@ public interface ChunkSection { void setBlock(int x, int y, int z, int type, int data); + void setFlatBlock(int x, int y, int z, int type); + int getBlockId(int x, int y, int z); void writeBlocks(ByteBuf output) throws Exception; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java index 8f7371d3b..0b3269d0a 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java @@ -3,7 +3,6 @@ package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks; import com.google.common.collect.Lists; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import lombok.Getter; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; import us.myles.ViaVersion.api.type.Type; @@ -46,6 +45,25 @@ public class ChunkSection1_9_3_4 implements ChunkSection { setBlock(index(x, y, z), type, data); } + /** + * Set a flat block in the chunks + * + * @param x Block X + * @param y Block Y + * @param z Block Z + * @param type The type of the block + */ + @Override + public void setFlatBlock(int x, int y, int z, int type) { + int index = palette.indexOf(type); + if (index == -1) { + index = palette.size(); + palette.add(type); + } + + blocks[index(x, y, z)] = index; + } + public int getBlockId(int x, int y, int z) { return getBlock(x, y, z) >> 4; } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java index 6409c2397..07f019737 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java @@ -3,7 +3,7 @@ package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks; import com.google.common.collect.Lists; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import lombok.Getter; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; import us.myles.ViaVersion.api.type.Type; @@ -46,6 +46,11 @@ public class ChunkSection1_9_1_2 implements ChunkSection { setBlock(index(x, y, z), type, data); } + @Override + public void setFlatBlock(int x, int y, int z, int type) { + throw new NotImplementedException(); + } + public int getBlockId(int x, int y, int z) { return getBlock(x, y, z) >> 4; } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java index 9212da55e..796e0f221 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java @@ -3,6 +3,7 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks; import com.google.common.collect.Lists; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; import us.myles.ViaVersion.api.type.Type; @@ -46,6 +47,11 @@ public class ChunkSection1_9to1_8 implements ChunkSection { setBlock(index(x, y, z), type, data); } + @Override + public void setFlatBlock(int x, int y, int z, int type) { + throw new NotImplementedException(); + } + public int getBlockId(int x, int y, int z) { return getBlock(x, y, z) >> 4; } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/ProtocolSnapshotTo1_12_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/ProtocolSnapshotTo1_12_2.java index 9f25ba209..8f14a4be2 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/ProtocolSnapshotTo1_12_2.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/ProtocolSnapshotTo1_12_2.java @@ -2,6 +2,7 @@ package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.platform.providers.ViaProviders; import us.myles.ViaVersion.api.protocol.Protocol; import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; @@ -13,6 +14,8 @@ import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets.EntityPackets; import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets.InventoryPackets; import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets.WorldPackets; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.BlockStorage; import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.EntityTracker; import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.TabCompleteTracker; @@ -364,5 +367,11 @@ public class ProtocolSnapshotTo1_12_2 extends Protocol { userConnection.put(new TabCompleteTracker(userConnection)); if (!userConnection.has(ClientWorld.class)) userConnection.put(new ClientWorld(userConnection)); + userConnection.put(new BlockStorage(userConnection)); + } + + @Override + protected void register(ViaProviders providers) { + providers.register(BlockEntityProvider.class, new BlockEntityProvider()); } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/EntityPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/EntityPackets.java index 3c88abcba..614742aea 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/EntityPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/EntityPackets.java @@ -94,7 +94,6 @@ public class EntityPackets { int entityId = wrapper.get(Type.VAR_INT, 0); Entity1_12Types.EntityType entType = Entity1_12Types.EntityType.PLAYER; - System.out.println("REGISTER PLAYER"); // Register Type ID wrapper.user().get(EntityTracker.class).addEntity(entityId, entType); MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_13.METADATA_LIST, 0), wrapper.user()); diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/WorldPackets.java index a6ead6f6c..75772eeb9 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/WorldPackets.java @@ -1,7 +1,11 @@ package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.minecraft.BlockChangeRecord; +import us.myles.ViaVersion.api.minecraft.Position; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.protocol.Protocol; @@ -12,12 +16,38 @@ import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.MappingData; - -import java.util.List; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.BlockStorage; public class WorldPackets { public static void register(Protocol protocol) { // Outgoing packets + // Update Block Entity + protocol.registerOutgoing(State.PLAY, 0x09, 0x09, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.POSITION); // 0 - Location + map(Type.UNSIGNED_BYTE); // 1 - Action + map(Type.NBT); // 2 - NBT data + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Position position = wrapper.get(Type.POSITION, 0); + CompoundTag tag = wrapper.get(Type.NBT, 0); + + BlockEntityProvider provider = Via.getManager().getProviders().get(BlockEntityProvider.class); + int newId = provider.transform(wrapper.user(), position, tag, true); + + if (newId != -1) { + BlockStorage storage = wrapper.user().get(BlockStorage.class); + if (storage.contains(position)) + storage.get(position).setReplacement(newId); + } + } + }); + } + }); // Block Change protocol.registerOutgoing(State.PLAY, 0xB, 0xB, new PacketRemapper() { @@ -28,7 +58,10 @@ public class WorldPackets { handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { - wrapper.set(Type.VAR_INT, 0, toNewId(wrapper.get(Type.VAR_INT, 0))); + Position position = wrapper.get(Type.POSITION, 0); + int newId = toNewId(wrapper.get(Type.VAR_INT, 0)); + + wrapper.set(Type.VAR_INT, 0, checkStorage(wrapper.user(), position, newId)); } }); } @@ -38,15 +71,24 @@ public class WorldPackets { protocol.registerOutgoing(State.PLAY, 0x10, 0xF, new PacketRemapper() { @Override public void registerMap() { - map(Type.INT); - map(Type.INT); - map(Type.BLOCK_CHANGE_RECORD_ARRAY); + map(Type.INT); // 0 - Chunk X + map(Type.INT); // 1 - Chunk Z + map(Type.BLOCK_CHANGE_RECORD_ARRAY); // 2 - Records handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { + BlockStorage storage = wrapper.user().get(BlockStorage.class); + int chunkX = wrapper.get(Type.INT, 0); + int chunkZ = wrapper.get(Type.INT, 0); // Convert ids for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) { - record.setBlockId(toNewId(record.getBlockId())); + int newBlock = toNewId(record.getBlockId()); + Position position = new Position( + (long) (record.getHorizontal() >> 4 & 15) + (chunkX * 16), + (long) record.getY(), + (long) ((record.getHorizontal() & 15) + (chunkZ * 16))); + + record.setBlockId(checkStorage(wrapper.user(), position, newBlock)); } } }); @@ -64,17 +106,52 @@ public class WorldPackets { @Override public void handle(PacketWrapper wrapper) throws Exception { ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + BlockStorage storage = wrapper.user().get(BlockStorage.class); Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld); Chunk chunk = wrapper.passthrough(type); - // Remap palette ids - for (ChunkSection section : chunk.getSections()) { - if (section == null) continue; - List palette = section.getPalette(); - for (int i = 0; i < palette.size(); i++) { - int newId = toNewId(palette.get(i)); - palette.set(i, newId); + for (int i = 0; i < chunk.getSections().length; i++) { + ChunkSection section = chunk.getSections()[i]; + if (section == null) + continue; + + // TODO improve performance + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + int block = section.getBlock(x, y, z); + + int newId = toNewId(block); + section.setFlatBlock(x, y, z, newId); + + if (storage.isWelcome(newId)) { + storage.store(new Position( + (long) (x + (chunk.getX() << 4)), + (long) (y + (i << 4)), + (long) (z + (chunk.getZ() << 4)) + ), newId); + } + } + } + } + } + + // Rewrite BlockEntities to normal blocks + BlockEntityProvider provider = Via.getManager().getProviders().get(BlockEntityProvider.class); + for (CompoundTag tag : chunk.getBlockEntities()) { + int newId = provider.transform(wrapper.user(), null, tag, false); + if (newId != -1) { + int x = (int) tag.get("x").getValue() & 0xF; + int y = (int) tag.get("y").getValue(); + int z = (int) tag.get("z").getValue() & 0xF; + + Position position = new Position((long) x, (long) y, (long) z); + // Store the replacement blocks for blockupdates + if (storage.contains(position)) + storage.get(position).setReplacement(newId); + + chunk.getSections()[y >> 4].setFlatBlock(x, y, z, newId); } } } @@ -111,4 +188,23 @@ public class WorldPackets { } } + private static int checkStorage(UserConnection user, Position position, int newId) { + BlockStorage storage = user.get(BlockStorage.class); + if (storage.contains(position)) { + BlockStorage.ReplacementData data = storage.get(position); + + if (data.getOriginal() == newId) { + if (data.getReplacement() != -1) { + return data.getReplacement(); + } + } else { + storage.remove(position); + // Check if the new id has to be stored + if (storage.isWelcome(newId)) + storage.store(position, newId); + } + } else if (storage.isWelcome(newId)) + storage.store(position, newId); + return newId; + } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/BlockEntityProvider.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/BlockEntityProvider.java new file mode 100644 index 000000000..188ba1ed5 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/BlockEntityProvider.java @@ -0,0 +1,68 @@ +package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.minecraft.Position; +import us.myles.ViaVersion.api.platform.providers.Provider; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.ProtocolSnapshotTo1_12_2; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities.BannerHandler; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities.BedHandler; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities.FlowerPotHandler; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class BlockEntityProvider implements Provider { + private final Map handlers = new ConcurrentHashMap<>(); + + public BlockEntityProvider() { + handlers.put("minecraft:flower_pot", new FlowerPotHandler()); + handlers.put("minecraft:bed", new BedHandler()); + handlers.put("minecraft:banner", new BannerHandler()); + } + + /** + * Transforms the BlockEntities to blocks! + * + * @param user UserConnection instance + * @param position Block Position - WARNING: Position is null when called from a chunk + * @param tag BlockEntity NBT + * @param sendUpdate send a block change update + * @return new block id + * @throws Exception Gotta throw that exception + */ + public int transform(UserConnection user, Position position, CompoundTag tag, boolean sendUpdate) throws Exception { + if (!tag.contains("id")) + return -1; + + String id = (String) tag.get("id").getValue(); + + if (!handlers.containsKey(id)) { + System.out.println("Unhandled BlockEntity " + id + " full tag: " + tag); + return -1; + } + + int newBlock = handlers.get(id).transform(user, tag); + + if (sendUpdate && newBlock != -1) + sendBlockChange(user, position, newBlock); + + return newBlock; + } + + public interface BlockEntityHandler { + int transform(UserConnection user, CompoundTag tag); + } + + private void sendBlockChange(UserConnection user, Position position, int blockId) throws Exception { + PacketWrapper wrapper = new PacketWrapper(0x0B, null, user); + wrapper.write(Type.POSITION, position); + wrapper.write(Type.VAR_INT, blockId); + + wrapper.send(ProtocolSnapshotTo1_12_2.class); + } + + +} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/BannerHandler.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/BannerHandler.java new file mode 100644 index 000000000..7930a7c34 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/BannerHandler.java @@ -0,0 +1,45 @@ +package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.minecraft.Position; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.BlockStorage; + +public class BannerHandler implements BlockEntityProvider.BlockEntityHandler { + private final int WALL_BANNER_START = 5633; // 4 each + private final int WALL_BANNER_STOP = 5696; + + private final int BANNER_START = 5377; // 16 each + private final int BANNER_STOP = 5632; + + @Override + public int transform(UserConnection user, CompoundTag tag) { + BlockStorage storage = user.get(BlockStorage.class); + Position position = new Position(getLong(tag.get("x")), getLong(tag.get("y")), getLong(tag.get("z"))); + + if (!storage.contains(position)) { + System.out.println("Received an banner color update packet, but there is no banner! O_o " + tag); + return -1; + } + + int blockId = storage.get(position).getOriginal(); + + int color = (int) tag.get("Base").getValue(); + // Standing banner + if (blockId >= BANNER_START && blockId <= BANNER_STOP) + blockId += ((15 - color) * 16); + // Wall banner + else if (blockId >= WALL_BANNER_START && blockId <= WALL_BANNER_STOP) + blockId += ((15 - color) * 4); + else + System.out.println("Why does this block have the banner block entity? :(" + tag); + + return blockId; + } + + private long getLong(Tag tag) { + return ((Integer) tag.getValue()).longValue(); + } +} \ No newline at end of file diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/BedHandler.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/BedHandler.java new file mode 100644 index 000000000..dd0b80b7b --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/BedHandler.java @@ -0,0 +1,34 @@ +package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.minecraft.Position; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.BlockStorage; + +public class BedHandler implements BlockEntityProvider.BlockEntityHandler { + + @Override + public int transform(UserConnection user, CompoundTag tag) { + BlockStorage storage = user.get(BlockStorage.class); + Position position = new Position(getLong(tag.get("x")), getLong(tag.get("y")), getLong(tag.get("z"))); + + if (!storage.contains(position)) { + System.out.println("Received an bed color update packet, but there is no bed! O_o " + tag); + return -1; + } + + // RED_BED + FIRST_BED + int blockId = storage.get(position).getOriginal() - 896 + 672; + + int color = (int) tag.get("color").getValue(); + blockId += (color * 16); + + return blockId; + } + + private long getLong(Tag tag) { + return ((Integer) tag.getValue()).longValue(); + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/FlowerPotHandler.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/FlowerPotHandler.java new file mode 100644 index 000000000..7073fe1ca --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/FlowerPotHandler.java @@ -0,0 +1,59 @@ +package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import us.myles.ViaVersion.api.Pair; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class FlowerPotHandler implements BlockEntityProvider.BlockEntityHandler { + private static final Map, Integer> flowers = new ConcurrentHashMap<>(); + + static { + register("minecraft:air", 0, 4466); + register("minecraft:sapling", 0, 4467); + register("minecraft:sapling", 1, 4468); + register("minecraft:sapling", 2, 4469); + register("minecraft:sapling", 3, 4470); + register("minecraft:sapling", 4, 4471); + register("minecraft:sapling", 5, 4472); + register("minecraft:tallgrass", 2, 4473); + register("minecraft:yellow_flower", 0, 4474); + register("minecraft:red_flower", 0, 4475); + register("minecraft:red_flower", 1, 4476); + register("minecraft:red_flower", 2, 4477); + register("minecraft:red_flower", 3, 4478); + register("minecraft:red_flower", 4, 4479); + register("minecraft:red_flower", 5, 4480); + register("minecraft:red_flower", 6, 4481); + register("minecraft:red_flower", 7, 4482); + register("minecraft:red_flower", 8, 4483); + register("minecraft:red_mushroom", 0, 4484); + register("minecraft:brown_mushroom", 0, 4485); + register("minecraft:deadbush", 0, 4486); + register("minecraft:cactus", 0, 4487); + + } + + public static void register(String identifier, int blockData, int newId) { + flowers.put(new Pair<>(identifier, blockData), newId); + } + + @Override + public int transform(UserConnection user, CompoundTag tag) { + String item = (String) tag.get("Item").getValue(); + int data = (int) tag.get("Data").getValue(); + + Pair pair = new Pair<>(item, data); + + if (flowers.containsKey(pair)) { + return flowers.get(pair); + } else { + System.out.println("Could not find flowerpot content " + item + " for " + tag); + } + + return -1; + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/BlockStorage.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/BlockStorage.java new file mode 100644 index 000000000..3d572da85 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/BlockStorage.java @@ -0,0 +1,79 @@ +package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage; + +import lombok.AllArgsConstructor; +import lombok.Data; +import us.myles.ViaVersion.api.data.StoredObject; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.minecraft.Position; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + +public class BlockStorage extends StoredObject { + // This BlockStorage is very exclusive (; + private static final List whitelist = new CopyOnWriteArrayList<>(); + + static { + // Flower pots + whitelist.add(4466); + + // Add those red beds + for (int i = 0; i < 16; i++) + whitelist.add(896 + i); + + // Add the white banners + for (int i = 0; i < 20; i++) + whitelist.add(5377 + i); + + // Add the whhite wall banners + for (int i = 0; i < 4; i++) { + whitelist.add(5633 + i); + } + } + + private Map blocks = new ConcurrentHashMap<>(); + + public BlockStorage(UserConnection user) { + super(user); + } + + public static void main(String[] args) { + new BlockStorage(null); + } + + public void store(Position position, int block) { + store(position, block, -1); + } + + public void store(Position position, int block, int replacementId) { + if (!whitelist.contains(block)) + return; + + blocks.put(position, new ReplacementData(block, replacementId)); + } + + public boolean isWelcome(int block) { + return whitelist.contains(block); + } + + public boolean contains(Position position) { + return blocks.containsKey(position); + } + + public ReplacementData get(Position position) { + return blocks.get(position); + } + + public ReplacementData remove(Position position) { + return blocks.remove(position); + } + + @Data + @AllArgsConstructor + public class ReplacementData { + private int original; + private int replacement; + } +} diff --git a/common/src/main/resources/assets/viaversion/data/mapping-1.12.json b/common/src/main/resources/assets/viaversion/data/mapping-1.12.json index 632bf056f..f458ed27d 100644 --- a/common/src/main/resources/assets/viaversion/data/mapping-1.12.json +++ b/common/src/main/resources/assets/viaversion/data/mapping-1.12.json @@ -894,22 +894,22 @@ "2208": "minecraft:beacon", "2224": "minecraft:cobblestone_wall[east=false,north=false,south=false,up=false,west=false]", "2225": "minecraft:mossy_cobblestone_wall[east=false,north=false,south=false,up=false,west=false]", - "2240": "minecraft:potted_cactus", - "2241": "minecraft:potted_cactus", - "2242": "minecraft:potted_cactus", - "2243": "minecraft:potted_cactus", - "2244": "minecraft:potted_cactus", - "2245": "minecraft:potted_cactus", - "2246": "minecraft:potted_cactus", - "2247": "minecraft:potted_cactus", - "2248": "minecraft:potted_cactus", - "2249": "minecraft:potted_cactus", - "2250": "minecraft:potted_cactus", - "2251": "minecraft:potted_cactus", - "2252": "minecraft:potted_cactus", - "2253": "minecraft:potted_cactus", - "2254": "minecraft:potted_cactus", - "2255": "minecraft:potted_cactus", + "2240": "minecraft:flower_pot", + "2241": "minecraft:flower_pot", + "2242": "minecraft:flower_pot", + "2243": "minecraft:flower_pot", + "2244": "minecraft:flower_pot", + "2245": "minecraft:flower_pot", + "2246": "minecraft:flower_pot", + "2247": "minecraft:flower_pot", + "2248": "minecraft:flower_pot", + "2249": "minecraft:flower_pot", + "2250": "minecraft:flower_pot", + "2251": "minecraft:flower_pot", + "2252": "minecraft:flower_pot", + "2253": "minecraft:flower_pot", + "2254": "minecraft:flower_pot", + "2255": "minecraft:flower_pot", "2256": "minecraft:carrots[age=0]", "2257": "minecraft:carrots[age=1]", "2258": "minecraft:carrots[age=2]", @@ -2170,6 +2170,22 @@ "6720": "minecraft:lead", "6736": "minecraft:name_tag", "6752": "minecraft:command_block_minecart", + "6800": "minecraft:black_banner", + "6801": "minecraft:red_banner", + "6802": "minecraft:green_banner", + "6803": "minecraft:brown_banner", + "6804": "minecraft:blue_banner", + "6805": "minecraft:purple_banner", + "6806": "minecraft:cyan_banner", + "6807": "minecraft:light_gray_banner", + "6808": "minecraft:gray_banner", + "6809": "minecraft:pink_banner", + "6810": "minecraft:lime_banner", + "6811": "minecraft:yellow_banner", + "6812": "minecraft:light_blue_banner", + "6813": "minecraft:magenta_banner", + "6814": "minecraft:orange_banner", + "6815": "minecraft:white_banner", "36096": "minecraft:music_disc_13", "36112": "minecraft:music_disc_cat", "36128": "minecraft:music_disc_blocks",