diff --git a/bukkit/pom.xml b/bukkit/pom.xml index b77f6ea56..b8e8adc57 100644 --- a/bukkit/pom.xml +++ b/bukkit/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.4.0-1.13-pre10 + 1.4.0-DEV 4.0.0 diff --git a/bungee/pom.xml b/bungee/pom.xml index 15aa94fef..e6a872955 100644 --- a/bungee/pom.xml +++ b/bungee/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.4.0-1.13-pre10 + 1.4.0-DEV 4.0.0 diff --git a/common/pom.xml b/common/pom.xml index 8eb581109..d4798d2a5 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.4.0-1.13-pre10 + 1.4.0-DEV 4.0.0 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 5601c59f1..6e3e7cd60 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 @@ -5,16 +5,62 @@ import io.netty.buffer.ByteBuf; import java.util.List; public interface ChunkSection { + /** + * Gets a block state id (< 1.13: block_id << 4 | data & 0xF) + * @param x Block X + * @param y Block Y + * @param z Block Z + * @return Block raw id + */ int getBlock(int x, int y, int z); + /** + * Set a block in the chunks + * + * @param x Block X + * @param y Block Y + * @param z Block Z + * @param type The block id + * @param data The data value of the block + */ void setBlock(int x, int y, int z, int type, int data); - void setFlatBlock(int x, int y, int z, int type); + /** + * Set a block state in the chunk + * + * @param x Block X + * @param y Block Y + * @param z Block Z + * @param blockState The block state id + */ + void setFlatBlock(int x, int y, int z, int blockState); + /** + * Gets a block id (without data) + * /!\ YOU SHOULD NOT USE THIS ON 1.13 + * @param x Block X + * @param y Block Y + * @param z Block Z + * @return Block id (without data) + */ int getBlockId(int x, int y, int z); + /** + * Write the blocks in < 1.13 format to a buffer. + * + * @param output The buffer to write to. + * @throws Exception Throws if it failed to write. + */ void writeBlocks(ByteBuf output) throws Exception; + /** + * Write the blocks in 1.13 format to a buffer. + * + * @param output The buffer to write to. + * @throws Exception Throws if it failed to write. + */ + void writeBlocks1_13(ByteBuf output) throws Exception; + void writeBlockLight(ByteBuf output) throws Exception; boolean hasSkyLight(); diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/types/MetaType1_13.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/types/MetaType1_13.java index 6638deeea..7295201fe 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/types/MetaType1_13.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/types/MetaType1_13.java @@ -4,7 +4,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import us.myles.ViaVersion.api.minecraft.metadata.MetaType; import us.myles.ViaVersion.api.type.Type; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.ProtocolSnapshotTo1_12_2; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2; @RequiredArgsConstructor @Getter @@ -24,7 +24,7 @@ public enum MetaType1_13 implements MetaType { OptUUID(12, Type.OPTIONAL_UUID), BlockID(13, Type.VAR_INT), NBTTag(14, Type.NBT), - PARTICLE(15, ProtocolSnapshotTo1_12_2.PARTICLE_TYPE), + PARTICLE(15, Protocol1_13To1_12_2.PARTICLE_TYPE), Discontinued(99, null); private final int typeID; diff --git a/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolRegistry.java b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolRegistry.java index c566a4fca..8013ded62 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolRegistry.java +++ b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolRegistry.java @@ -18,7 +18,7 @@ import us.myles.ViaVersion.protocols.protocol1_9_1to1_9.Protocol1_9_1TO1_9; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.Protocol1_9_3TO1_9_1_2; import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; import us.myles.ViaVersion.protocols.protocol1_9to1_9_1.Protocol1_9TO1_9_1; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.ProtocolSnapshotTo1_12_2; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -55,7 +55,7 @@ public class ProtocolRegistry { registerProtocol(new Protocol1_12_2TO1_12_1(), Collections.singletonList(ProtocolVersion.v1_12_2.getId()), ProtocolVersion.v1_12_1.getId()); // 1.13 support in development! (: - registerProtocol(new ProtocolSnapshotTo1_12_2(), Collections.singletonList(ProtocolVersion.v1_13.getId()), ProtocolVersion.v1_12_2.getId()); + registerProtocol(new Protocol1_13To1_12_2(), Collections.singletonList(ProtocolVersion.v1_13.getId()), ProtocolVersion.v1_12_2.getId()); } /** diff --git a/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java index 855eff31c..9c10b95ab 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java +++ b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java @@ -62,7 +62,7 @@ public class ProtocolVersion { register(v1_12 = new ProtocolVersion(335, "1.12")); register(v1_12_1 = new ProtocolVersion(338, "1.12.1")); register(v1_12_2 = new ProtocolVersion(340, "1.12.2")); - register(v1_13 = new ProtocolVersion(392, "1.13-pre10")); + register(v1_13 = new ProtocolVersion(393, "1.13")); register(unknown = new ProtocolVersion(-1, "UNKNOWN")); } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/MetadataRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/MetadataRewriter.java similarity index 91% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/MetadataRewriter.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/MetadataRewriter.java index 88064b33d..595f865fb 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/MetadataRewriter.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/MetadataRewriter.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.UserConnection; @@ -7,10 +7,10 @@ import us.myles.ViaVersion.api.minecraft.item.Item; import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13; import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data.Particle; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data.ParticleRewriter; -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.protocol1_13to1_12_2.data.Particle; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.ParticleRewriter; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.WorldPackets; import java.util.ArrayList; import java.util.List; 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/protocol1_13to1_12_2/Protocol1_13To1_12_2.java similarity index 94% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/ProtocolSnapshotTo1_12_2.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java index a5934fc5a..25baaaba7 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/protocol1_13to1_12_2/Protocol1_13To1_12_2.java @@ -1,772 +1,772 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2; - -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.chat.ComponentSerializer; -import us.myles.ViaVersion.api.PacketWrapper; -import us.myles.ViaVersion.api.data.UserConnection; -import us.myles.ViaVersion.api.entities.Entity1_13Types; -import us.myles.ViaVersion.api.minecraft.Position; -import us.myles.ViaVersion.api.minecraft.item.Item; -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; -import us.myles.ViaVersion.api.remapper.ValueCreator; -import us.myles.ViaVersion.api.remapper.ValueTransformer; -import us.myles.ViaVersion.api.type.Type; -import us.myles.ViaVersion.packets.State; -import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data.MappingData; -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.providers.PaintingProvider; -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; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.types.Particle1_13Type; - -import java.util.Map; - -// Development of 1.13 support! -public class ProtocolSnapshotTo1_12_2 extends Protocol { - public static final Particle1_13Type PARTICLE_TYPE = new Particle1_13Type(); - - public static String legacyTextToJson(String legacyText) { - return ComponentSerializer.toString( - TextComponent.fromLegacyText(legacyText) - ); - } - - public static final PacketHandler POS_TO_3_INT = new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - Position position = wrapper.read(Type.POSITION); - wrapper.write(Type.INT, position.getX().intValue()); - wrapper.write(Type.INT, position.getY().intValue()); - wrapper.write(Type.INT, position.getZ().intValue()); - } - }; - - public static final PacketHandler SEND_DECLARE_COMMANDS_AND_TAGS = new PacketHandler() { // *insert here a good name* - @Override - public void handle(PacketWrapper w) throws Exception { - // Send fake declare commands - w.create(0x11, new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) { - wrapper.write(Type.VAR_INT, 2); // Size - // Write root node - wrapper.write(Type.VAR_INT, 0); // Mark as command - wrapper.write(Type.VAR_INT, 1); // 1 child - wrapper.write(Type.VAR_INT, 1); // Child is at 1 - - // Write arg node - wrapper.write(Type.VAR_INT, 0x02 | 0x04 | 0x10); // Mark as command - wrapper.write(Type.VAR_INT, 0); // No children - // Extra data - wrapper.write(Type.STRING, "args"); // Arg name - wrapper.write(Type.STRING, "brigadier:string"); - wrapper.write(Type.VAR_INT, 2); // Greedy - wrapper.write(Type.STRING, "minecraft:ask_server"); // Ask server - - wrapper.write(Type.VAR_INT, 0); // Root node index - } - }).send(ProtocolSnapshotTo1_12_2.class); - - // Send tags packet - w.create(0x55, new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) throws Exception { - wrapper.write(Type.VAR_INT, MappingData.blockTags.size()); // block tags - for (Map.Entry tag : MappingData.blockTags.entrySet()) { - wrapper.write(Type.STRING, tag.getKey()); - wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); - } - wrapper.write(Type.VAR_INT, MappingData.itemTags.size()); // item tags - for (Map.Entry tag : MappingData.itemTags.entrySet()) { - wrapper.write(Type.STRING, tag.getKey()); - wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); - } - wrapper.write(Type.VAR_INT, MappingData.fluidTags.size()); // fluid tags - for (Map.Entry tag : MappingData.fluidTags.entrySet()) { - wrapper.write(Type.STRING, tag.getKey()); - wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); - } - } - }).send(ProtocolSnapshotTo1_12_2.class); - } - }; - - static { - MappingData.init(); - } - - public static String jsonTextToLegacy(String value) { - return TextComponent.toLegacyText(ComponentSerializer.parse(value)); - } - - @Override - protected void registerPackets() { - // Register grouped packet changes - EntityPackets.register(this); - WorldPackets.register(this); - InventoryPackets.register(this); - - // Outgoing packets - - // New packet 0x04 - Login Plugin Message - - // Statistics - registerOutgoing(State.PLAY, 0x07, 0x07, new PacketRemapper() { - @Override - public void registerMap() { - // TODO: This packet has changed - - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - wrapper.cancel(); - } - }); - } - }); - - registerOutgoing(State.PLAY, 0xF, 0xE); - // WorldPackets 0x10 -> 0x0F - - // Tab-Complete - registerOutgoing(State.PLAY, 0xE, 0x10, new PacketRemapper() { - @Override - public void registerMap() { - create(new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) throws Exception { - wrapper.write(Type.VAR_INT, wrapper.user().get(TabCompleteTracker.class).getTransactionId()); - - String input = wrapper.user().get(TabCompleteTracker.class).getInput(); - // Start & End - int index; - int length; - // If no input or new word (then it's the start) - if (input.endsWith(" ") || input.length() == 0) { - index = input.length(); - length = 0; - } else { - // Otherwise find the last space (+1 as we include it) - int lastSpace = input.lastIndexOf(" ") + 1; - index = lastSpace; - length = input.length() - lastSpace; - } - // Write index + length - wrapper.write(Type.VAR_INT, index); - wrapper.write(Type.VAR_INT, length); - - int count = wrapper.passthrough(Type.VAR_INT); - for (int i = 0; i < count; i++) { - String suggestion = wrapper.read(Type.STRING); - // If we're at the start then handle removing slash - if (suggestion.startsWith("/") && index == 0) { - suggestion = suggestion.substring(1); - } - wrapper.write(Type.STRING, suggestion); - wrapper.write(Type.BOOLEAN, false); - } - } - }); - } - }); - - // New packet 0x11, declare commands - registerOutgoing(State.PLAY, 0x11, 0x12); - registerOutgoing(State.PLAY, 0x12, 0x13); - registerOutgoing(State.PLAY, 0x13, 0x14); - // InventoryPackets 0x14 -> 0x15 - registerOutgoing(State.PLAY, 0x15, 0x16); - // InventoryPackets 0x16 -> 0x17 - registerOutgoing(State.PLAY, 0x17, 0x18); - // InventoryPackets 0x18 -> 0x19 - registerOutgoing(State.PLAY, 0x1A, 0x1B); - registerOutgoing(State.PLAY, 0x1B, 0x1C); - // New packet 0x1D - NBT Query - registerOutgoing(State.PLAY, 0x1C, 0x1E); - registerOutgoing(State.PLAY, 0x1D, 0x1F); - registerOutgoing(State.PLAY, 0x1E, 0x20); - registerOutgoing(State.PLAY, 0x1F, 0x21); - // WorldPackets 0x20 -> 0x22 - registerOutgoing(State.PLAY, 0x21, 0x23); - // WorldPackets 0x22 -> 0x24 - // Join (save dimension id) - registerOutgoing(State.PLAY, 0x23, 0x25, 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 { - // Store the player - int entityId = wrapper.get(Type.INT, 0); - wrapper.user().get(EntityTracker.class).addEntity(entityId, Entity1_13Types.EntityType.PLAYER); - - ClientWorld clientChunks = wrapper.user().get(ClientWorld.class); - int dimensionId = wrapper.get(Type.INT, 1); - clientChunks.setEnvironment(dimensionId); - } - }); - handler(SEND_DECLARE_COMMANDS_AND_TAGS); - } - }); - - // Map packet - registerOutgoing(State.PLAY, 0x24, 0x26, new PacketRemapper() { - @Override - public void registerMap() { - map(Type.VAR_INT); // 0 - Map id - map(Type.BYTE); // 1 - Scale - map(Type.BOOLEAN); // 2 - Tracking Position - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - int iconCount = wrapper.passthrough(Type.VAR_INT); - for (int i = 0; i < iconCount; i++) { - byte directionAndType = wrapper.read(Type.BYTE); - int type = (directionAndType & 0xF0) >> 4; - wrapper.write(Type.VAR_INT, type); - wrapper.passthrough(Type.BYTE); // Icon X - wrapper.passthrough(Type.BYTE); // Icon Z - byte direction = (byte) (directionAndType & 0x0F); - wrapper.write(Type.BYTE, direction); - wrapper.write(Type.OPTIONAL_CHAT, null); // Display Name - } - } - }); - } - }); - registerOutgoing(State.PLAY, 0x25, 0x27); - registerOutgoing(State.PLAY, 0x26, 0x28); - registerOutgoing(State.PLAY, 0x27, 0x29); - registerOutgoing(State.PLAY, 0x28, 0x2A); - registerOutgoing(State.PLAY, 0x29, 0x2B); - registerOutgoing(State.PLAY, 0x2A, 0x2C); - // Craft recipe response - registerOutgoing(State.PLAY, 0x2B, 0x2D, new PacketRemapper() { - @Override - public void registerMap() { - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - // TODO This packet changed - wrapper.cancel(); - } - }); - } - }); - registerOutgoing(State.PLAY, 0x2C, 0x2E); - registerOutgoing(State.PLAY, 0x2D, 0x2F); - registerOutgoing(State.PLAY, 0x2E, 0x30); - // New 0x31 - Face Player - registerOutgoing(State.PLAY, 0x2F, 0x32); - registerOutgoing(State.PLAY, 0x30, 0x33); - // Recipe - registerOutgoing(State.PLAY, 0x31, 0x34, new PacketRemapper() { - @Override - public void registerMap() { - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - // TODO: This has changed >.> - wrapper.cancel(); - } - }); - } - }); - - // EntityPackets 0x32 -> 0x35 - registerOutgoing(State.PLAY, 0x33, 0x36); - registerOutgoing(State.PLAY, 0x34, 0x37); - - // Respawn (save dimension id) - registerOutgoing(State.PLAY, 0x35, 0x38, 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); - } - }); - handler(SEND_DECLARE_COMMANDS_AND_TAGS); - } - }); - - registerOutgoing(State.PLAY, 0x36, 0x39); - registerOutgoing(State.PLAY, 0x37, 0x3A); - registerOutgoing(State.PLAY, 0x38, 0x3B); - registerOutgoing(State.PLAY, 0x39, 0x3C); - registerOutgoing(State.PLAY, 0x3A, 0x3D); - registerOutgoing(State.PLAY, 0x3B, 0x3E); - // EntityPackets 0x3C -> 0x3F - registerOutgoing(State.PLAY, 0x3D, 0x40); - registerOutgoing(State.PLAY, 0x3E, 0x41); - // InventoryPackets 0x3F -> 0x42 - registerOutgoing(State.PLAY, 0x40, 0x43); - registerOutgoing(State.PLAY, 0x41, 0x44); - // Scoreboard Objective - registerOutgoing(State.PLAY, 0x42, 0x45, new PacketRemapper() { - @Override - public void registerMap() { - map(Type.STRING); // 0 - Objective name - map(Type.BYTE); // 1 - Mode - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - byte mode = wrapper.get(Type.BYTE, 0); - // On create or update - if (mode == 0 || mode == 2) { - String value = wrapper.read(Type.STRING); // Value - value = legacyTextToJson(value); - wrapper.write(Type.STRING, value); - - String type = wrapper.read(Type.STRING); - // integer or hearts - wrapper.write(Type.VAR_INT, type.equals("integer") ? 0 : 1); - } - } - }); - } - }); - - registerOutgoing(State.PLAY, 0x43, 0x46); - // Team packet - registerOutgoing(State.PLAY, 0x44, 0x47, new PacketRemapper() { - @Override - public void registerMap() { - map(Type.STRING); // 0 - Team Name - map(Type.BYTE); // 1 - Mode - - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - byte action = wrapper.get(Type.BYTE, 0); - - if (action == 0 || action == 2) { - String displayName = wrapper.read(Type.STRING); // Display Name - displayName = legacyTextToJson(displayName); - wrapper.write(Type.STRING, displayName); - - String prefix = wrapper.read(Type.STRING); // Prefix moved - String suffix = wrapper.read(Type.STRING); // Suffix moved - - wrapper.passthrough(Type.BYTE); // Flags - - wrapper.passthrough(Type.STRING); // Name Tag Visibility - wrapper.passthrough(Type.STRING); // Collision rule - - // Handle new colors - byte color = wrapper.read(Type.BYTE); - - if (color == -1) // -1 changed to 21 - wrapper.write(Type.VAR_INT, 21); // RESET - else - wrapper.write(Type.VAR_INT, (int) color); - - wrapper.write(Type.STRING, legacyTextToJson(prefix)); // Prefix - wrapper.write(Type.STRING, legacyTextToJson(suffix)); // Suffix - } - } - }); - - } - }); - registerOutgoing(State.PLAY, 0x45, 0x48); - registerOutgoing(State.PLAY, 0x46, 0x49); - registerOutgoing(State.PLAY, 0x47, 0x4A); - registerOutgoing(State.PLAY, 0x48, 0x4B); - // New 0x4C - Stop Sound - - // Sound Effect packet - registerOutgoing(State.PLAY, 0x49, 0x4D, new PacketRemapper() { - @Override - public void registerMap() { - map(Type.VAR_INT); // 0 - Sound ID - - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - int soundId = wrapper.get(Type.VAR_INT, 0); - wrapper.set(Type.VAR_INT, 0, getNewSoundID(soundId)); - } - }); - } - }); - registerOutgoing(State.PLAY, 0x4A, 0x4E); - registerOutgoing(State.PLAY, 0x4B, 0x4F); - registerOutgoing(State.PLAY, 0x4C, 0x50); - // Advancements - registerOutgoing(State.PLAY, 0x4D, 0x51, new PacketRemapper() { - @Override - public void registerMap() { - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - // TODO Temporary cancel advancements because of 'Non [a-z0-9/._-] character in path of location: minecraft:? https://fs.matsv.nl/media?id=auwje4z4lxw.png - wrapper.cancel(); - } - }); - } - }); - registerOutgoing(State.PLAY, 0x4E, 0x52); - registerOutgoing(State.PLAY, 0x4F, 0x53); - // New packet 0x54 - Declare Recipes - // New packet 0x55 - Tags - - // Incoming packets - - // New packet 0x02 - Login Plugin Message - registerIncoming(State.LOGIN, -1, 0x02, new PacketRemapper() { - @Override - public void registerMap() { - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - wrapper.cancel(); - } - }); - } - }); - - // New 0x01 - Query Block NBT - registerIncoming(State.PLAY, -1, 0x01, new PacketRemapper() { - @Override - public void registerMap() { - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - wrapper.cancel(); - } - }); - } - }); - - // Tab-Complete - registerIncoming(State.PLAY, 0x1, 0x5, new PacketRemapper() { - @Override - public void registerMap() { - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - int tid = wrapper.read(Type.VAR_INT); - // Save transaction id - wrapper.user().get(TabCompleteTracker.class).setTransactionId(tid); - } - }); - // Prepend / - map(Type.STRING, new ValueTransformer(Type.STRING) { - @Override - public String transform(PacketWrapper wrapper, String inputValue) { - wrapper.user().get(TabCompleteTracker.class).setInput(inputValue); - return "/" + inputValue; - } - }); - // Fake the end of the packet - create(new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) { - wrapper.write(Type.BOOLEAN, false); - wrapper.write(Type.OPTIONAL_POSITION, null); - } - }); - } - }); - - registerIncoming(State.PLAY, 0x05, 0x06); - registerIncoming(State.PLAY, 0x06, 0x07); - // InventoryPackets 0x07, 0x08 - registerIncoming(State.PLAY, 0x08, 0x09); - // InventoryPackets 0x09 -> 0x0A - - // New 0x0A - Edit book -> Plugin Message - registerIncoming(State.PLAY, 0x09, 0x0B, new PacketRemapper() { - @Override - public void registerMap() { - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - Item item = wrapper.read(Type.FLAT_ITEM); - boolean isSigning = wrapper.read(Type.BOOLEAN); - - InventoryPackets.toServer(item); - - wrapper.write(Type.STRING, isSigning ? "MC|BSign" : "MC|BEdit"); // Channel - wrapper.write(Type.ITEM, item); - } - }); - } - }); - // New 0x0C - Query Entity NBT - registerIncoming(State.PLAY, -1, 0x0C, new PacketRemapper() { - @Override - public void registerMap() { - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - wrapper.cancel(); - } - }); - } - }); - registerIncoming(State.PLAY, 0x0A, 0x0D); - registerIncoming(State.PLAY, 0x0B, 0x0E); - registerIncoming(State.PLAY, 0x0C, 0x0F); - registerIncoming(State.PLAY, 0x0D, 0x10); - registerIncoming(State.PLAY, 0x0E, 0x11); - registerIncoming(State.PLAY, 0x0F, 0x12); - registerIncoming(State.PLAY, 0x10, 0x13); - registerIncoming(State.PLAY, 0x11, 0x14); - // New 0x15 - Pick Item -> Plugin Message - registerIncoming(State.PLAY, 0x09, 0x15, new PacketRemapper() { - @Override - public void registerMap() { - create(new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) throws Exception { - wrapper.write(Type.STRING, "MC|PickItem"); // Channel - } - }); - } - }); - - // Craft recipe request - registerIncoming(State.PLAY, 0x12, 0x16, new PacketRemapper() { - @Override - public void registerMap() { - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - // TODO: This has changed >.> - wrapper.cancel(); - } - }); - } - }); - - registerIncoming(State.PLAY, 0x13, 0x17); - registerIncoming(State.PLAY, 0x14, 0x18); - registerIncoming(State.PLAY, 0x15, 0x19); - registerIncoming(State.PLAY, 0x16, 0x1A); - // Recipe Book Data - registerIncoming(State.PLAY, 0x17, 0x1B, new PacketRemapper() { - @Override - public void registerMap() { - map(Type.VAR_INT); // 0 - Type - - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - int type = wrapper.get(Type.VAR_INT, 0); - - if (type == 1) { - wrapper.passthrough(Type.BOOLEAN); // Crafting Recipe Book Open - wrapper.passthrough(Type.BOOLEAN); // Crafting Recipe Filter Active - wrapper.read(Type.BOOLEAN); // Smelting Recipe Book Open | IGNORE NEW 1.13 FIELD - wrapper.read(Type.BOOLEAN); // Smelting Recipe Filter Active | IGNORE NEW 1.13 FIELD - } - } - }); - } - }); - - // New 0x1C - Name Item -> Plugin Message - registerIncoming(State.PLAY, 0x09, 0x1C, new PacketRemapper() { - @Override - public void registerMap() { - create(new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) throws Exception { - wrapper.write(Type.STRING, "MC|ItemName"); // Channel - } - }); - } - }); - - registerIncoming(State.PLAY, 0x18, 0x1D); - registerIncoming(State.PLAY, 0x19, 0x1E); - - // New 0x1F - Select Trade -> Plugin Message - registerIncoming(State.PLAY, 0x09, 0x1F, new PacketRemapper() { - @Override - public void registerMap() { - create(new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) throws Exception { - wrapper.write(Type.STRING, "MC|TrSel"); // Channel - } - }); - map(Type.VAR_INT, Type.INT); // Slot - } - }); - // New 0x20 - Set Beacon Effect -> Plugin Message - registerIncoming(State.PLAY, 0x09, 0x20, new PacketRemapper() { - @Override - public void registerMap() { - create(new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) throws Exception { - wrapper.write(Type.STRING, "MC|Beacon"); // Channel - } - }); - map(Type.VAR_INT, Type.INT); // Primary Effect - map(Type.VAR_INT, Type.INT); // Secondary Effect - } - }); - - registerIncoming(State.PLAY, 0x1A, 0x21); - - // New 0x22 - Update Command Block -> Plugin Message - registerIncoming(State.PLAY, 0x09, 0x22, new PacketRemapper() { - @Override - public void registerMap() { - create(new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) throws Exception { - wrapper.write(Type.STRING, "MC|AutoCmd"); - } - }); - handler(POS_TO_3_INT); - map(Type.STRING); // Command - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - int mode = wrapper.read(Type.VAR_INT); - byte flags = wrapper.read(Type.BYTE); - - String stringMode = mode == 0 ? "SEQUENCE" - : mode == 1 ? "AUTO" - : "REDSTONE"; - - wrapper.write(Type.BOOLEAN, (flags & 0x1) != 0); // Track output - wrapper.write(Type.STRING, stringMode); - wrapper.write(Type.BOOLEAN, (flags & 0x2) != 0); // Is conditional - wrapper.write(Type.BOOLEAN, (flags & 0x4) != 0); // Automatic - } - }); - } - }); - // New 0x23 - Update Command Block Minecart -> Plugin Message - registerIncoming(State.PLAY, 0x09, 0x23, new PacketRemapper() { - @Override - public void registerMap() { - create(new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) throws Exception { - wrapper.write(Type.STRING, "MC|AdvCmd"); - wrapper.write(Type.BYTE, (byte) 1); // Type 1 for Entity - } - }); - map(Type.VAR_INT, Type.INT); // Entity Id - } - }); - - // 0x1B -> 0x24 in InventoryPackets - - // New 0x25 - Update Structure Block -> Message Channel - registerIncoming(State.PLAY, 0x09, 0x25, new PacketRemapper() { - @Override - public void registerMap() { - create(new ValueCreator() { - @Override - public void write(PacketWrapper wrapper) throws Exception { - wrapper.write(Type.STRING, "MC|Struct"); // Channel - } - }); - handler(POS_TO_3_INT); - map(Type.VAR_INT, new ValueTransformer(Type.BYTE) { // Action - @Override - public Byte transform(PacketWrapper wrapper, Integer action) throws Exception { - return (byte) (action + 1); - } - }); // Action - map(Type.VAR_INT, new ValueTransformer(Type.STRING) { - @Override - public String transform(PacketWrapper wrapper, Integer mode) throws Exception { - return mode == 0 ? "SAVE" - : mode == 1 ? "LOAD" - : mode == 2 ? "CORNER" - : "DATA"; - } - }); - map(Type.STRING); // Name - map(Type.BYTE, Type.INT); // Offset X - map(Type.BYTE, Type.INT); // Offset Y - map(Type.BYTE, Type.INT); // Offset Z - map(Type.BYTE, Type.INT); // Size X - map(Type.BYTE, Type.INT); // Size Y - map(Type.BYTE, Type.INT); // Size Z - map(Type.VAR_INT, new ValueTransformer(Type.STRING) { // Mirror - @Override - public String transform(PacketWrapper wrapper, Integer mirror) throws Exception { - return mirror == 0 ? "NONE" - : mirror == 1 ? "LEFT_RIGHT" - : "FRONT_BACK"; - } - }); - map(Type.VAR_INT, new ValueTransformer(Type.STRING) { // Rotation - @Override - public String transform(PacketWrapper wrapper, Integer rotation) throws Exception { - return rotation == 0 ? "NONE" - : rotation == 1 ? "CLOCKWISE_90" - : rotation == 2 ? "CLOCKWISE_180" - : "COUNTERCLOCKWISE_90"; - } - }); - map(Type.STRING); - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { - float integrity = wrapper.read(Type.FLOAT); - long seed = wrapper.read(Type.VAR_LONG); - byte flags = wrapper.read(Type.BYTE); - - wrapper.write(Type.BOOLEAN, (flags & 0x1) != 0); // Ignore Entities - wrapper.write(Type.BOOLEAN, (flags & 0x2) != 0); // Show air - wrapper.write(Type.BOOLEAN, (flags & 0x4) != 0); // Show bounding box - wrapper.write(Type.FLOAT, integrity); - wrapper.write(Type.VAR_LONG, seed); - } - }); - } - }); - - registerIncoming(State.PLAY, 0x1C, 0x26); - registerIncoming(State.PLAY, 0x1D, 0x27); - registerIncoming(State.PLAY, 0x1E, 0x28); - registerIncoming(State.PLAY, 0x1F, 0x29); - registerIncoming(State.PLAY, 0x20, 0x2A); - } - - @Override - public void init(UserConnection userConnection) { - userConnection.put(new EntityTracker(userConnection)); - 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()); - providers.register(PaintingProvider.class, new PaintingProvider()); - } - - private int getNewSoundID(final int oldID) { - return MappingData.oldToNewSounds.get(oldID); - } -} +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2; + +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.entities.Entity1_13Types; +import us.myles.ViaVersion.api.minecraft.Position; +import us.myles.ViaVersion.api.minecraft.item.Item; +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; +import us.myles.ViaVersion.api.remapper.ValueCreator; +import us.myles.ViaVersion.api.remapper.ValueTransformer; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.packets.State; +import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.EntityPackets; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.WorldPackets; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.PaintingProvider; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.EntityTracker; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.TabCompleteTracker; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Particle1_13Type; + +import java.util.Map; + +// Development of 1.13 support! +public class Protocol1_13To1_12_2 extends Protocol { + public static final Particle1_13Type PARTICLE_TYPE = new Particle1_13Type(); + + public static String legacyTextToJson(String legacyText) { + return ComponentSerializer.toString( + TextComponent.fromLegacyText(legacyText) + ); + } + + public static final PacketHandler POS_TO_3_INT = new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Position position = wrapper.read(Type.POSITION); + wrapper.write(Type.INT, position.getX().intValue()); + wrapper.write(Type.INT, position.getY().intValue()); + wrapper.write(Type.INT, position.getZ().intValue()); + } + }; + + public static final PacketHandler SEND_DECLARE_COMMANDS_AND_TAGS = new PacketHandler() { // *insert here a good name* + @Override + public void handle(PacketWrapper w) throws Exception { + // Send fake declare commands + w.create(0x11, new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) { + wrapper.write(Type.VAR_INT, 2); // Size + // Write root node + wrapper.write(Type.VAR_INT, 0); // Mark as command + wrapper.write(Type.VAR_INT, 1); // 1 child + wrapper.write(Type.VAR_INT, 1); // Child is at 1 + + // Write arg node + wrapper.write(Type.VAR_INT, 0x02 | 0x04 | 0x10); // Mark as command + wrapper.write(Type.VAR_INT, 0); // No children + // Extra data + wrapper.write(Type.STRING, "args"); // Arg name + wrapper.write(Type.STRING, "brigadier:string"); + wrapper.write(Type.VAR_INT, 2); // Greedy + wrapper.write(Type.STRING, "minecraft:ask_server"); // Ask server + + wrapper.write(Type.VAR_INT, 0); // Root node index + } + }).send(Protocol1_13To1_12_2.class); + + // Send tags packet + w.create(0x55, new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.VAR_INT, MappingData.blockTags.size()); // block tags + for (Map.Entry tag : MappingData.blockTags.entrySet()) { + wrapper.write(Type.STRING, tag.getKey()); + wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); + } + wrapper.write(Type.VAR_INT, MappingData.itemTags.size()); // item tags + for (Map.Entry tag : MappingData.itemTags.entrySet()) { + wrapper.write(Type.STRING, tag.getKey()); + wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); + } + wrapper.write(Type.VAR_INT, MappingData.fluidTags.size()); // fluid tags + for (Map.Entry tag : MappingData.fluidTags.entrySet()) { + wrapper.write(Type.STRING, tag.getKey()); + wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone()); + } + } + }).send(Protocol1_13To1_12_2.class); + } + }; + + static { + MappingData.init(); + } + + public static String jsonTextToLegacy(String value) { + return TextComponent.toLegacyText(ComponentSerializer.parse(value)); + } + + @Override + protected void registerPackets() { + // Register grouped packet changes + EntityPackets.register(this); + WorldPackets.register(this); + InventoryPackets.register(this); + + // Outgoing packets + + // New packet 0x04 - Login Plugin Message + + // Statistics + registerOutgoing(State.PLAY, 0x07, 0x07, new PacketRemapper() { + @Override + public void registerMap() { + // TODO: This packet has changed + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.cancel(); + } + }); + } + }); + + registerOutgoing(State.PLAY, 0xF, 0xE); + // WorldPackets 0x10 -> 0x0F + + // Tab-Complete + registerOutgoing(State.PLAY, 0xE, 0x10, new PacketRemapper() { + @Override + public void registerMap() { + create(new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.VAR_INT, wrapper.user().get(TabCompleteTracker.class).getTransactionId()); + + String input = wrapper.user().get(TabCompleteTracker.class).getInput(); + // Start & End + int index; + int length; + // If no input or new word (then it's the start) + if (input.endsWith(" ") || input.length() == 0) { + index = input.length(); + length = 0; + } else { + // Otherwise find the last space (+1 as we include it) + int lastSpace = input.lastIndexOf(" ") + 1; + index = lastSpace; + length = input.length() - lastSpace; + } + // Write index + length + wrapper.write(Type.VAR_INT, index); + wrapper.write(Type.VAR_INT, length); + + int count = wrapper.passthrough(Type.VAR_INT); + for (int i = 0; i < count; i++) { + String suggestion = wrapper.read(Type.STRING); + // If we're at the start then handle removing slash + if (suggestion.startsWith("/") && index == 0) { + suggestion = suggestion.substring(1); + } + wrapper.write(Type.STRING, suggestion); + wrapper.write(Type.BOOLEAN, false); + } + } + }); + } + }); + + // New packet 0x11, declare commands + registerOutgoing(State.PLAY, 0x11, 0x12); + registerOutgoing(State.PLAY, 0x12, 0x13); + registerOutgoing(State.PLAY, 0x13, 0x14); + // InventoryPackets 0x14 -> 0x15 + registerOutgoing(State.PLAY, 0x15, 0x16); + // InventoryPackets 0x16 -> 0x17 + registerOutgoing(State.PLAY, 0x17, 0x18); + // InventoryPackets 0x18 -> 0x19 + registerOutgoing(State.PLAY, 0x1A, 0x1B); + registerOutgoing(State.PLAY, 0x1B, 0x1C); + // New packet 0x1D - NBT Query + registerOutgoing(State.PLAY, 0x1C, 0x1E); + registerOutgoing(State.PLAY, 0x1D, 0x1F); + registerOutgoing(State.PLAY, 0x1E, 0x20); + registerOutgoing(State.PLAY, 0x1F, 0x21); + // WorldPackets 0x20 -> 0x22 + registerOutgoing(State.PLAY, 0x21, 0x23); + // WorldPackets 0x22 -> 0x24 + // Join (save dimension id) + registerOutgoing(State.PLAY, 0x23, 0x25, 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 { + // Store the player + int entityId = wrapper.get(Type.INT, 0); + wrapper.user().get(EntityTracker.class).addEntity(entityId, Entity1_13Types.EntityType.PLAYER); + + ClientWorld clientChunks = wrapper.user().get(ClientWorld.class); + int dimensionId = wrapper.get(Type.INT, 1); + clientChunks.setEnvironment(dimensionId); + } + }); + handler(SEND_DECLARE_COMMANDS_AND_TAGS); + } + }); + + // Map packet + registerOutgoing(State.PLAY, 0x24, 0x26, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Map id + map(Type.BYTE); // 1 - Scale + map(Type.BOOLEAN); // 2 - Tracking Position + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int iconCount = wrapper.passthrough(Type.VAR_INT); + for (int i = 0; i < iconCount; i++) { + byte directionAndType = wrapper.read(Type.BYTE); + int type = (directionAndType & 0xF0) >> 4; + wrapper.write(Type.VAR_INT, type); + wrapper.passthrough(Type.BYTE); // Icon X + wrapper.passthrough(Type.BYTE); // Icon Z + byte direction = (byte) (directionAndType & 0x0F); + wrapper.write(Type.BYTE, direction); + wrapper.write(Type.OPTIONAL_CHAT, null); // Display Name + } + } + }); + } + }); + registerOutgoing(State.PLAY, 0x25, 0x27); + registerOutgoing(State.PLAY, 0x26, 0x28); + registerOutgoing(State.PLAY, 0x27, 0x29); + registerOutgoing(State.PLAY, 0x28, 0x2A); + registerOutgoing(State.PLAY, 0x29, 0x2B); + registerOutgoing(State.PLAY, 0x2A, 0x2C); + // Craft recipe response + registerOutgoing(State.PLAY, 0x2B, 0x2D, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + // TODO This packet changed + wrapper.cancel(); + } + }); + } + }); + registerOutgoing(State.PLAY, 0x2C, 0x2E); + registerOutgoing(State.PLAY, 0x2D, 0x2F); + registerOutgoing(State.PLAY, 0x2E, 0x30); + // New 0x31 - Face Player + registerOutgoing(State.PLAY, 0x2F, 0x32); + registerOutgoing(State.PLAY, 0x30, 0x33); + // Recipe + registerOutgoing(State.PLAY, 0x31, 0x34, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + // TODO: This has changed >.> + wrapper.cancel(); + } + }); + } + }); + + // EntityPackets 0x32 -> 0x35 + registerOutgoing(State.PLAY, 0x33, 0x36); + registerOutgoing(State.PLAY, 0x34, 0x37); + + // Respawn (save dimension id) + registerOutgoing(State.PLAY, 0x35, 0x38, 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); + } + }); + handler(SEND_DECLARE_COMMANDS_AND_TAGS); + } + }); + + registerOutgoing(State.PLAY, 0x36, 0x39); + registerOutgoing(State.PLAY, 0x37, 0x3A); + registerOutgoing(State.PLAY, 0x38, 0x3B); + registerOutgoing(State.PLAY, 0x39, 0x3C); + registerOutgoing(State.PLAY, 0x3A, 0x3D); + registerOutgoing(State.PLAY, 0x3B, 0x3E); + // EntityPackets 0x3C -> 0x3F + registerOutgoing(State.PLAY, 0x3D, 0x40); + registerOutgoing(State.PLAY, 0x3E, 0x41); + // InventoryPackets 0x3F -> 0x42 + registerOutgoing(State.PLAY, 0x40, 0x43); + registerOutgoing(State.PLAY, 0x41, 0x44); + // Scoreboard Objective + registerOutgoing(State.PLAY, 0x42, 0x45, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.STRING); // 0 - Objective name + map(Type.BYTE); // 1 - Mode + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + byte mode = wrapper.get(Type.BYTE, 0); + // On create or update + if (mode == 0 || mode == 2) { + String value = wrapper.read(Type.STRING); // Value + value = legacyTextToJson(value); + wrapper.write(Type.STRING, value); + + String type = wrapper.read(Type.STRING); + // integer or hearts + wrapper.write(Type.VAR_INT, type.equals("integer") ? 0 : 1); + } + } + }); + } + }); + + registerOutgoing(State.PLAY, 0x43, 0x46); + // Team packet + registerOutgoing(State.PLAY, 0x44, 0x47, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.STRING); // 0 - Team Name + map(Type.BYTE); // 1 - Mode + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + byte action = wrapper.get(Type.BYTE, 0); + + if (action == 0 || action == 2) { + String displayName = wrapper.read(Type.STRING); // Display Name + displayName = legacyTextToJson(displayName); + wrapper.write(Type.STRING, displayName); + + String prefix = wrapper.read(Type.STRING); // Prefix moved + String suffix = wrapper.read(Type.STRING); // Suffix moved + + wrapper.passthrough(Type.BYTE); // Flags + + wrapper.passthrough(Type.STRING); // Name Tag Visibility + wrapper.passthrough(Type.STRING); // Collision rule + + // Handle new colors + byte color = wrapper.read(Type.BYTE); + + if (color == -1) // -1 changed to 21 + wrapper.write(Type.VAR_INT, 21); // RESET + else + wrapper.write(Type.VAR_INT, (int) color); + + wrapper.write(Type.STRING, legacyTextToJson(prefix)); // Prefix + wrapper.write(Type.STRING, legacyTextToJson(suffix)); // Suffix + } + } + }); + + } + }); + registerOutgoing(State.PLAY, 0x45, 0x48); + registerOutgoing(State.PLAY, 0x46, 0x49); + registerOutgoing(State.PLAY, 0x47, 0x4A); + registerOutgoing(State.PLAY, 0x48, 0x4B); + // New 0x4C - Stop Sound + + // Sound Effect packet + registerOutgoing(State.PLAY, 0x49, 0x4D, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Sound ID + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int soundId = wrapper.get(Type.VAR_INT, 0); + wrapper.set(Type.VAR_INT, 0, getNewSoundID(soundId)); + } + }); + } + }); + registerOutgoing(State.PLAY, 0x4A, 0x4E); + registerOutgoing(State.PLAY, 0x4B, 0x4F); + registerOutgoing(State.PLAY, 0x4C, 0x50); + // Advancements + registerOutgoing(State.PLAY, 0x4D, 0x51, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + // TODO Temporary cancel advancements because of 'Non [a-z0-9/._-] character in path of location: minecraft:? https://fs.matsv.nl/media?id=auwje4z4lxw.png + wrapper.cancel(); + } + }); + } + }); + registerOutgoing(State.PLAY, 0x4E, 0x52); + registerOutgoing(State.PLAY, 0x4F, 0x53); + // New packet 0x54 - Declare Recipes + // New packet 0x55 - Tags + + // Incoming packets + + // New packet 0x02 - Login Plugin Message + registerIncoming(State.LOGIN, -1, 0x02, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.cancel(); + } + }); + } + }); + + // New 0x01 - Query Block NBT + registerIncoming(State.PLAY, -1, 0x01, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.cancel(); + } + }); + } + }); + + // Tab-Complete + registerIncoming(State.PLAY, 0x1, 0x5, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int tid = wrapper.read(Type.VAR_INT); + // Save transaction id + wrapper.user().get(TabCompleteTracker.class).setTransactionId(tid); + } + }); + // Prepend / + map(Type.STRING, new ValueTransformer(Type.STRING) { + @Override + public String transform(PacketWrapper wrapper, String inputValue) { + wrapper.user().get(TabCompleteTracker.class).setInput(inputValue); + return "/" + inputValue; + } + }); + // Fake the end of the packet + create(new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) { + wrapper.write(Type.BOOLEAN, false); + wrapper.write(Type.OPTIONAL_POSITION, null); + } + }); + } + }); + + registerIncoming(State.PLAY, 0x05, 0x06); + registerIncoming(State.PLAY, 0x06, 0x07); + // InventoryPackets 0x07, 0x08 + registerIncoming(State.PLAY, 0x08, 0x09); + // InventoryPackets 0x09 -> 0x0A + + // New 0x0A - Edit book -> Plugin Message + registerIncoming(State.PLAY, 0x09, 0x0B, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item item = wrapper.read(Type.FLAT_ITEM); + boolean isSigning = wrapper.read(Type.BOOLEAN); + + InventoryPackets.toServer(item); + + wrapper.write(Type.STRING, isSigning ? "MC|BSign" : "MC|BEdit"); // Channel + wrapper.write(Type.ITEM, item); + } + }); + } + }); + // New 0x0C - Query Entity NBT + registerIncoming(State.PLAY, -1, 0x0C, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.cancel(); + } + }); + } + }); + registerIncoming(State.PLAY, 0x0A, 0x0D); + registerIncoming(State.PLAY, 0x0B, 0x0E); + registerIncoming(State.PLAY, 0x0C, 0x0F); + registerIncoming(State.PLAY, 0x0D, 0x10); + registerIncoming(State.PLAY, 0x0E, 0x11); + registerIncoming(State.PLAY, 0x0F, 0x12); + registerIncoming(State.PLAY, 0x10, 0x13); + registerIncoming(State.PLAY, 0x11, 0x14); + // New 0x15 - Pick Item -> Plugin Message + registerIncoming(State.PLAY, 0x09, 0x15, new PacketRemapper() { + @Override + public void registerMap() { + create(new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.STRING, "MC|PickItem"); // Channel + } + }); + } + }); + + // Craft recipe request + registerIncoming(State.PLAY, 0x12, 0x16, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + // TODO: This has changed >.> + wrapper.cancel(); + } + }); + } + }); + + registerIncoming(State.PLAY, 0x13, 0x17); + registerIncoming(State.PLAY, 0x14, 0x18); + registerIncoming(State.PLAY, 0x15, 0x19); + registerIncoming(State.PLAY, 0x16, 0x1A); + // Recipe Book Data + registerIncoming(State.PLAY, 0x17, 0x1B, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Type + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int type = wrapper.get(Type.VAR_INT, 0); + + if (type == 1) { + wrapper.passthrough(Type.BOOLEAN); // Crafting Recipe Book Open + wrapper.passthrough(Type.BOOLEAN); // Crafting Recipe Filter Active + wrapper.read(Type.BOOLEAN); // Smelting Recipe Book Open | IGNORE NEW 1.13 FIELD + wrapper.read(Type.BOOLEAN); // Smelting Recipe Filter Active | IGNORE NEW 1.13 FIELD + } + } + }); + } + }); + + // New 0x1C - Name Item -> Plugin Message + registerIncoming(State.PLAY, 0x09, 0x1C, new PacketRemapper() { + @Override + public void registerMap() { + create(new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.STRING, "MC|ItemName"); // Channel + } + }); + } + }); + + registerIncoming(State.PLAY, 0x18, 0x1D); + registerIncoming(State.PLAY, 0x19, 0x1E); + + // New 0x1F - Select Trade -> Plugin Message + registerIncoming(State.PLAY, 0x09, 0x1F, new PacketRemapper() { + @Override + public void registerMap() { + create(new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.STRING, "MC|TrSel"); // Channel + } + }); + map(Type.VAR_INT, Type.INT); // Slot + } + }); + // New 0x20 - Set Beacon Effect -> Plugin Message + registerIncoming(State.PLAY, 0x09, 0x20, new PacketRemapper() { + @Override + public void registerMap() { + create(new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.STRING, "MC|Beacon"); // Channel + } + }); + map(Type.VAR_INT, Type.INT); // Primary Effect + map(Type.VAR_INT, Type.INT); // Secondary Effect + } + }); + + registerIncoming(State.PLAY, 0x1A, 0x21); + + // New 0x22 - Update Command Block -> Plugin Message + registerIncoming(State.PLAY, 0x09, 0x22, new PacketRemapper() { + @Override + public void registerMap() { + create(new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.STRING, "MC|AutoCmd"); + } + }); + handler(POS_TO_3_INT); + map(Type.STRING); // Command + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int mode = wrapper.read(Type.VAR_INT); + byte flags = wrapper.read(Type.BYTE); + + String stringMode = mode == 0 ? "SEQUENCE" + : mode == 1 ? "AUTO" + : "REDSTONE"; + + wrapper.write(Type.BOOLEAN, (flags & 0x1) != 0); // Track output + wrapper.write(Type.STRING, stringMode); + wrapper.write(Type.BOOLEAN, (flags & 0x2) != 0); // Is conditional + wrapper.write(Type.BOOLEAN, (flags & 0x4) != 0); // Automatic + } + }); + } + }); + // New 0x23 - Update Command Block Minecart -> Plugin Message + registerIncoming(State.PLAY, 0x09, 0x23, new PacketRemapper() { + @Override + public void registerMap() { + create(new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.STRING, "MC|AdvCmd"); + wrapper.write(Type.BYTE, (byte) 1); // Type 1 for Entity + } + }); + map(Type.VAR_INT, Type.INT); // Entity Id + } + }); + + // 0x1B -> 0x24 in InventoryPackets + + // New 0x25 - Update Structure Block -> Message Channel + registerIncoming(State.PLAY, 0x09, 0x25, new PacketRemapper() { + @Override + public void registerMap() { + create(new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.STRING, "MC|Struct"); // Channel + } + }); + handler(POS_TO_3_INT); + map(Type.VAR_INT, new ValueTransformer(Type.BYTE) { // Action + @Override + public Byte transform(PacketWrapper wrapper, Integer action) throws Exception { + return (byte) (action + 1); + } + }); // Action + map(Type.VAR_INT, new ValueTransformer(Type.STRING) { + @Override + public String transform(PacketWrapper wrapper, Integer mode) throws Exception { + return mode == 0 ? "SAVE" + : mode == 1 ? "LOAD" + : mode == 2 ? "CORNER" + : "DATA"; + } + }); + map(Type.STRING); // Name + map(Type.BYTE, Type.INT); // Offset X + map(Type.BYTE, Type.INT); // Offset Y + map(Type.BYTE, Type.INT); // Offset Z + map(Type.BYTE, Type.INT); // Size X + map(Type.BYTE, Type.INT); // Size Y + map(Type.BYTE, Type.INT); // Size Z + map(Type.VAR_INT, new ValueTransformer(Type.STRING) { // Mirror + @Override + public String transform(PacketWrapper wrapper, Integer mirror) throws Exception { + return mirror == 0 ? "NONE" + : mirror == 1 ? "LEFT_RIGHT" + : "FRONT_BACK"; + } + }); + map(Type.VAR_INT, new ValueTransformer(Type.STRING) { // Rotation + @Override + public String transform(PacketWrapper wrapper, Integer rotation) throws Exception { + return rotation == 0 ? "NONE" + : rotation == 1 ? "CLOCKWISE_90" + : rotation == 2 ? "CLOCKWISE_180" + : "COUNTERCLOCKWISE_90"; + } + }); + map(Type.STRING); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + float integrity = wrapper.read(Type.FLOAT); + long seed = wrapper.read(Type.VAR_LONG); + byte flags = wrapper.read(Type.BYTE); + + wrapper.write(Type.BOOLEAN, (flags & 0x1) != 0); // Ignore Entities + wrapper.write(Type.BOOLEAN, (flags & 0x2) != 0); // Show air + wrapper.write(Type.BOOLEAN, (flags & 0x4) != 0); // Show bounding box + wrapper.write(Type.FLOAT, integrity); + wrapper.write(Type.VAR_LONG, seed); + } + }); + } + }); + + registerIncoming(State.PLAY, 0x1C, 0x26); + registerIncoming(State.PLAY, 0x1D, 0x27); + registerIncoming(State.PLAY, 0x1E, 0x28); + registerIncoming(State.PLAY, 0x1F, 0x29); + registerIncoming(State.PLAY, 0x20, 0x2A); + } + + @Override + public void init(UserConnection userConnection) { + userConnection.put(new EntityTracker(userConnection)); + 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()); + providers.register(PaintingProvider.class, new PaintingProvider()); + } + + private int getNewSoundID(final int oldID) { + return MappingData.oldToNewSounds.get(oldID); + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/Chunk1_13.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/Chunk1_13.java new file mode 100644 index 000000000..92cd1b675 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/Chunk1_13.java @@ -0,0 +1,25 @@ +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.chunks; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import lombok.AllArgsConstructor; +import lombok.Data; +import us.myles.ViaVersion.api.minecraft.chunks.Chunk; + +import java.util.List; + +@Data +@AllArgsConstructor +public class Chunk1_13 implements Chunk { + private int x; + private int z; + private boolean groundUp; + private int bitmask; + private ChunkSection1_13[] sections; + private byte[] biomeData; + private List blockEntities; + + @Override + public boolean isBiomeData() { + return biomeData != null; + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/ChunkSection1_13.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/ChunkSection1_13.java new file mode 100644 index 000000000..0cf10ca41 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/ChunkSection1_13.java @@ -0,0 +1,306 @@ +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.chunks; + +import com.google.common.collect.Lists; +import io.netty.buffer.ByteBuf; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; +import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; +import us.myles.ViaVersion.api.type.Type; + +import java.util.List; + +public class ChunkSection1_13 implements ChunkSection { + /** + * Size (dimensions) of blocks in a chunks section. + */ + public static final int SIZE = 16 * 16 * 16; // width * depth * height + /** + * Length of the sky and block light nibble arrays. + */ + public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) + /** + * Length of the block data array. + */ + private final List palette = Lists.newArrayList(); + private final int[] blocks; + private final NibbleArray blockLight; + private NibbleArray skyLight; + + public ChunkSection1_13() { + this.blocks = new int[SIZE]; + this.blockLight = new NibbleArray(SIZE); + palette.add(0); // AIR + } + + public void setBlock(int x, int y, int z, int type, int data) { + setBlock(index(x, y, z), type, data); + } + + @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; + } + + public int getBlock(int x, int y, int z) { + int index = blocks[index(x, y, z)]; + return palette.get(index); + } + + /** + * Set a block in the chunks based on the index + * + * @param idx Index + * @param type The type of the block + * @param data The data value of the block + */ + public void setBlock(int idx, int type, int data) { + int hash = type << 4 | (data & 0xF); + int index = palette.indexOf(hash); + if (index == -1) { + index = palette.size(); + palette.add(hash); + } + + blocks[idx] = index; + } + + /** + * Set the block light array + * + * @param data The value to set the block light to + */ + public void setBlockLight(byte[] data) { + blockLight.setHandle(data); + } + + /** + * Set the sky light array + * + * @param data The value to set the sky light to + */ + public void setSkyLight(byte[] data) { + if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); + this.skyLight = new NibbleArray(data); + } + + private int index(int x, int y, int z) { + return y << 8 | z << 4 | x; + } + + /** + * Read blocks from input stream. + * This reads all the block related data: + *
    + *
  • Block length/palette type
  • + *
  • Palette
  • + *
  • Block hashes/palette reference
  • + *
+ * + * @param input The buffer to read from. + * @throws Exception If it fails to read + */ + public void readBlocks(ByteBuf input) throws Exception { + palette.clear(); + + // Read bits per block + int bitsPerBlock = input.readUnsignedByte(); + long maxEntryValue = (1L << bitsPerBlock) - 1; + + boolean directPalette = false; + + if (bitsPerBlock == 0) { + bitsPerBlock = 14; + } + if (bitsPerBlock < 4) { + bitsPerBlock = 4; + } + if (bitsPerBlock > 9) { + directPalette = true; + bitsPerBlock = 14; + } + + int paletteLength = directPalette ? 0 : Type.VAR_INT.read(input); + // Read palette + for (int i = 0; i < paletteLength; i++) { + palette.add(Type.VAR_INT.read(input)); + } + + // Read blocks + Long[] blockData = Type.LONG_ARRAY.read(input); + if (blockData.length > 0) { + for (int i = 0; i < blocks.length; i++) { + int bitIndex = i * bitsPerBlock; + int startIndex = bitIndex >> 6; // /64 + int endIndex = ((i + 1) * bitsPerBlock - 1) >> 6; // /64 + int startBitSubIndex = bitIndex & 0x3F; // % 64 + int val; + if (startIndex == endIndex) { + val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); + } else { + int endBitSubIndex = 64 - startBitSubIndex; + val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); + } + + if (directPalette) { + int type = val >> 4; + int data = val & 0xF; + + setBlock(i, type, data); + } else { + blocks[i] = val; + } + } + } + } + + /** + * Read block light from buffer. + * + * @param input The buffer to read from + */ + public void readBlockLight(ByteBuf input) { + byte[] handle = new byte[LIGHT_LENGTH]; + input.readBytes(handle); + blockLight.setHandle(handle); + } + + /** + * Read sky light from buffer. + * Note: Only sent in overworld! + * + * @param input The buffer to read from + */ + public void readSkyLight(ByteBuf input) { + byte[] handle = new byte[LIGHT_LENGTH]; + input.readBytes(handle); + if (skyLight != null) { + skyLight.setHandle(handle); + return; + } + + this.skyLight = new NibbleArray(handle); + } + + + public void writeBlocks(ByteBuf output) throws Exception { + // Write bits per block + int bitsPerBlock = 4; + while (palette.size() > 1 << bitsPerBlock) { + bitsPerBlock += 1; + } + long maxEntryValue = (1L << bitsPerBlock) - 1; + output.writeByte(bitsPerBlock); + + // Write pallet (or not) + Type.VAR_INT.write(output, palette.size()); + for (int mappedId : palette) { + Type.VAR_INT.write(output, mappedId); + } + + int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); + Type.VAR_INT.write(output, length); + long[] data = new long[length]; + for (int index = 0; index < blocks.length; index++) { + int value = blocks[index]; + int bitIndex = index * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; + if (startIndex != endIndex) { + int endBitSubIndex = 64 - startBitSubIndex; + data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; + } + } + for (long l : data) { + Type.LONG.write(output, l); + } + } + + @Override + public void writeBlocks1_13(ByteBuf output) throws Exception { + // Write bits per block + int bitsPerBlock = 4; + while (palette.size() > 1 << bitsPerBlock) { + bitsPerBlock++; + } + boolean directPalette = false; + if (bitsPerBlock > 9) { + bitsPerBlock = 14; + directPalette = true; + } + long maxEntryValue = (1L << bitsPerBlock) - 1; + output.writeByte(bitsPerBlock); + + // Write pallet (or not) + if (!directPalette) { + Type.VAR_INT.write(output, palette.size()); + for (int mappedId : palette) { + Type.VAR_INT.write(output, mappedId); + } + } + + int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); + Type.VAR_INT.write(output, length); + long[] data = new long[length]; + for (int index = 0; index < blocks.length; index++) { + int value = directPalette ? palette.get(blocks[index]) : blocks[index]; + int bitIndex = index * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; + if (startIndex != endIndex) { + int endBitSubIndex = 64 - startBitSubIndex; + data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; + } + } + for (long l : data) { + Type.LONG.write(output, l); + } + } + + /** + * Write the block light to a buffer + * + * @param output The buffer to write to + */ + @Override + public void writeBlockLight(ByteBuf output) { + output.writeBytes(blockLight.getHandle()); + } + + /** + * Write the sky light to a buffer + * + * @param output The buffer to write to + */ + @Override + public void writeSkyLight(ByteBuf output) { + output.writeBytes(skyLight.getHandle()); + } + + /** + * Check if sky light is present + * + * @return True if skylight is present + */ + @Override + public boolean hasSkyLight() { + return skyLight != null; + } + + @Override + public List getPalette() { + return palette; + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/EntityTypeRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/EntityTypeRewriter.java similarity index 98% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/EntityTypeRewriter.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/EntityTypeRewriter.java index 779755e89..8fe62e6db 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/EntityTypeRewriter.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/EntityTypeRewriter.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data; import com.google.common.base.Optional; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/MappingData.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/MappingData.java similarity index 98% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/MappingData.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/MappingData.java index 53a134aca..c51cd40dc 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/MappingData.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/MappingData.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/Particle.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/Particle.java similarity index 87% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/Particle.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/Particle.java index 702eef20b..b6e786120 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/Particle.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/Particle.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/ParticleRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/ParticleRewriter.java similarity index 97% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/ParticleRewriter.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/ParticleRewriter.java index d0fa577ee..4bfcc6bf2 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/ParticleRewriter.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/ParticleRewriter.java @@ -1,12 +1,12 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data; import lombok.Data; import lombok.RequiredArgsConstructor; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.minecraft.item.Item; import us.myles.ViaVersion.api.type.Type; -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.protocol1_13to1_12_2.packets.InventoryPackets; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.WorldPackets; import java.util.Arrays; import java.util.LinkedList; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/SoundSource.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/SoundSource.java similarity index 91% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/SoundSource.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/SoundSource.java index f2833d303..c6aeeabed 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/SoundSource.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/SoundSource.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data; import com.google.common.base.Optional; import lombok.AllArgsConstructor; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/SpawnEggRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/SpawnEggRewriter.java similarity index 97% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/SpawnEggRewriter.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/SpawnEggRewriter.java index 9d79f5cb0..80ce89112 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/data/SpawnEggRewriter.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/data/SpawnEggRewriter.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data; import com.google.common.base.Optional; import com.google.common.collect.BiMap; 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/protocol1_13to1_12_2/packets/EntityPackets.java similarity index 95% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/EntityPackets.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/EntityPackets.java index 07d712f87..6ab4ca27a 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/protocol1_13to1_12_2/packets/EntityPackets.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets; import com.google.common.base.Optional; import us.myles.ViaVersion.api.PacketWrapper; @@ -10,9 +10,9 @@ import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.types.version.Types1_12; import us.myles.ViaVersion.api.type.types.version.Types1_13; import us.myles.ViaVersion.packets.State; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.MetadataRewriter; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data.EntityTypeRewriter; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.EntityTracker; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.MetadataRewriter; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.EntityTypeRewriter; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.EntityTracker; public class EntityPackets { public static void register(Protocol protocol) { diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/InventoryPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java similarity index 97% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/InventoryPackets.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java index 0c2eec81a..f451158d7 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/InventoryPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets; import com.github.steveice10.opennbt.tag.builtin.*; import com.google.common.base.Joiner; @@ -11,10 +11,10 @@ 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.protocolsnapshotto1_12_2.ProtocolSnapshotTo1_12_2; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data.MappingData; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data.SoundSource; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data.SpawnEggRewriter; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.SoundSource; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.SpawnEggRewriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -295,7 +295,7 @@ public class InventoryPackets { if (((CompoundTag) tag.get("display")).get("Name") instanceof StringTag) { StringTag name = ((CompoundTag) tag.get("display")).get("Name"); name.setValue( - ProtocolSnapshotTo1_12_2.legacyTextToJson( + Protocol1_13To1_12_2.legacyTextToJson( name.getValue() ) ); @@ -441,7 +441,7 @@ public class InventoryPackets { if (((CompoundTag) tag.get("display")).get("Name") instanceof StringTag) { StringTag name = ((CompoundTag) tag.get("display")).get("Name"); name.setValue( - ProtocolSnapshotTo1_12_2.jsonTextToLegacy( + Protocol1_13To1_12_2.jsonTextToLegacy( name.getValue() ) ); 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/protocol1_13to1_12_2/packets/WorldPackets.java similarity index 94% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/packets/WorldPackets.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java index ab9308e92..055957a56 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/protocol1_13to1_12_2/packets/WorldPackets.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.packets; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.google.common.base.Optional; @@ -16,13 +16,13 @@ import us.myles.ViaVersion.api.type.Type; 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.data.MappingData; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data.Particle; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data.ParticleRewriter; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.BlockEntityProvider; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.PaintingProvider; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage.BlockStorage; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.types.Chunk1_13Type; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.Particle; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.ParticleRewriter; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.PaintingProvider; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Chunk1_13Type; public class WorldPackets { public static void register(Protocol protocol) { 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/protocol1_13to1_12_2/providers/BlockEntityProvider.java similarity index 77% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/BlockEntityProvider.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/BlockEntityProvider.java index 8256294f0..1d7352a9c 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/BlockEntityProvider.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/BlockEntityProvider.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import us.myles.ViaVersion.api.PacketWrapper; @@ -6,11 +6,11 @@ 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 us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities.SkullHandler; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.blockentities.BannerHandler; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.blockentities.BedHandler; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.blockentities.FlowerPotHandler; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.blockentities.SkullHandler; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -63,7 +63,7 @@ public class BlockEntityProvider implements Provider { wrapper.write(Type.POSITION, position); wrapper.write(Type.VAR_INT, blockId); - wrapper.send(ProtocolSnapshotTo1_12_2.class, true, true); + wrapper.send(Protocol1_13To1_12_2.class, true, true); } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/PaintingProvider.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/PaintingProvider.java similarity index 94% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/PaintingProvider.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/PaintingProvider.java index 10798027c..505e476cb 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/PaintingProvider.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/PaintingProvider.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers; import com.google.common.base.Optional; import us.myles.ViaVersion.api.platform.providers.Provider; 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/protocol1_13to1_12_2/providers/blockentities/BannerHandler.java similarity index 85% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/BannerHandler.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/BannerHandler.java index 632419d7d..cf4c25a64 100644 --- 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/protocol1_13to1_12_2/providers/blockentities/BannerHandler.java @@ -1,11 +1,11 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities; +package us.myles.ViaVersion.protocols.protocol1_13to1_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; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage; public class BannerHandler implements BlockEntityProvider.BlockEntityHandler { private final int WALL_BANNER_START = 7110; // 4 each 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/protocol1_13to1_12_2/providers/blockentities/BedHandler.java similarity index 80% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/BedHandler.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/BedHandler.java index 6e82073c2..312cf2520 100644 --- 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/protocol1_13to1_12_2/providers/blockentities/BedHandler.java @@ -1,11 +1,11 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities; +package us.myles.ViaVersion.protocols.protocol1_13to1_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; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage; public class BedHandler implements BlockEntityProvider.BlockEntityHandler { 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/protocol1_13to1_12_2/providers/blockentities/FlowerPotHandler.java similarity index 94% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/FlowerPotHandler.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/FlowerPotHandler.java index 79ac4807d..536227486 100644 --- 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/protocol1_13to1_12_2/providers/blockentities/FlowerPotHandler.java @@ -1,9 +1,9 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities; +package us.myles.ViaVersion.protocols.protocol1_13to1_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 us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/SkullHandler.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/SkullHandler.java similarity index 83% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/SkullHandler.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/SkullHandler.java index 34d63f247..85458e23c 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/providers/blockentities/SkullHandler.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/SkullHandler.java @@ -1,11 +1,11 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.providers.blockentities; +package us.myles.ViaVersion.protocols.protocol1_13to1_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; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage; public class SkullHandler implements BlockEntityProvider.BlockEntityHandler { private final int SKULL_WALL_START = 5447; 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/protocol1_13to1_12_2/storage/BlockStorage.java similarity index 96% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/BlockStorage.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockStorage.java index 3ccc8fd6c..421ca58e2 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/BlockStorage.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockStorage.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage; import com.google.common.collect.Sets; import lombok.AllArgsConstructor; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/EntityTracker.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/EntityTracker.java similarity index 93% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/EntityTracker.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/EntityTracker.java index e3aa2cd60..db7994407 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/EntityTracker.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/EntityTracker.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage; import com.google.common.base.Optional; import us.myles.ViaVersion.api.data.StoredObject; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/TabCompleteTracker.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/TabCompleteTracker.java similarity index 89% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/TabCompleteTracker.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/TabCompleteTracker.java index 2699ef61f..4f5d4eaac 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/storage/TabCompleteTracker.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/TabCompleteTracker.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.storage; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage; import us.myles.ViaVersion.api.data.StoredObject; import us.myles.ViaVersion.api.data.UserConnection; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/types/Chunk1_13Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java similarity index 86% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/types/Chunk1_13Type.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java index b7960320d..47d3d3702 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/types/Chunk1_13Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java @@ -1,4 +1,4 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.types; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.ByteBuf; @@ -10,16 +10,15 @@ 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 us.myles.ViaVersion.protocols.protocol1_13to1_12_2.chunks.Chunk1_13; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.chunks.ChunkSection1_13; import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; import java.util.List; -// todo 1.13-pre2 direct pallete changes public class Chunk1_13Type extends PartialType { public Chunk1_13Type(ClientWorld param) { super(param, Chunk.class); @@ -35,7 +34,7 @@ public class Chunk1_13Type extends PartialType { Type.VAR_INT.read(input); BitSet usedSections = new BitSet(16); - ChunkSection1_9_3_4[] sections = new ChunkSection1_9_3_4[16]; + ChunkSection1_13[] sections = new ChunkSection1_13[16]; // Calculate section count from bitmask for (int i = 0; i < 16; i++) { if ((primaryBitmask & (1 << i)) != 0) { @@ -46,7 +45,7 @@ public class Chunk1_13Type extends PartialType { // 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(); + ChunkSection1_13 section = new ChunkSection1_13(); sections[i] = section; section.readBlocks(input); section.readBlockLight(input); @@ -72,7 +71,7 @@ public class Chunk1_13Type extends PartialType { System.out.println("Found " + array.length + " more bytes than expected while reading the chunk: " + chunkX + "/" + chunkZ); } - return new Chunk1_9_3_4(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); + return new Chunk1_13(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); } @Override @@ -87,7 +86,7 @@ public class Chunk1_13Type extends PartialType { for (int i = 0; i < 16; i++) { ChunkSection section = chunk.getSections()[i]; if (section == null) continue; // Section not set - section.writeBlocks(buf); + section.writeBlocks1_13(buf); section.writeBlockLight(buf); if (!section.hasSkyLight()) continue; // No sky light, we're done here. diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/types/Particle1_13Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Particle1_13Type.java similarity index 92% rename from common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/types/Particle1_13Type.java rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Particle1_13Type.java index b472cd724..0002e4859 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_12_2/types/Particle1_13Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Particle1_13Type.java @@ -1,8 +1,8 @@ -package us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.types; +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.type.Type; -import us.myles.ViaVersion.protocols.protocolsnapshotto1_12_2.data.Particle; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.Particle; // TODO make future proof public class Particle1_13Type extends Type { 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 0b3269d0a..ca4b45d6d 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 @@ -249,6 +249,49 @@ public class ChunkSection1_9_3_4 implements ChunkSection { } } + @Override + public void writeBlocks1_13(ByteBuf output) throws Exception { + // Write bits per block + int bitsPerBlock = 4; + while (palette.size() > 1 << bitsPerBlock) { + bitsPerBlock++; + } + boolean directPalette = false; + if (bitsPerBlock > 9) { + bitsPerBlock = 14; + directPalette = true; + } + long maxEntryValue = (1L << bitsPerBlock) - 1; + output.writeByte(bitsPerBlock); + + // Write pallet (or not) + if (!directPalette) { + Type.VAR_INT.write(output, palette.size()); + for (int mappedId : palette) { + Type.VAR_INT.write(output, mappedId); + } + } + + int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); + Type.VAR_INT.write(output, length); + long[] data = new long[length]; + for (int index = 0; index < blocks.length; index++) { + int value = directPalette ? palette.get(blocks[index]) : blocks[index]; + int bitIndex = index * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; + if (startIndex != endIndex) { + int endBitSubIndex = 64 - startBitSubIndex; + data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; + } + } + for (long l : data) { + Type.LONG.write(output, l); + } + } + /** * Write the block light to a buffer * 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 0c5cba766..45131c509 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 @@ -241,6 +241,49 @@ public class ChunkSection1_9_1_2 implements ChunkSection { } } + @Override + public void writeBlocks1_13(ByteBuf output) throws Exception { + // Write bits per block + int bitsPerBlock = 4; + while (palette.size() > 1 << bitsPerBlock) { + bitsPerBlock++; + } + boolean directPalette = false; + if (bitsPerBlock > 9) { + bitsPerBlock = 14; + directPalette = true; + } + long maxEntryValue = (1L << bitsPerBlock) - 1; + output.writeByte(bitsPerBlock); + + // Write pallet (or not) + if (!directPalette) { + Type.VAR_INT.write(output, palette.size()); + for (int mappedId : palette) { + Type.VAR_INT.write(output, mappedId); + } + } + + int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); + Type.VAR_INT.write(output, length); + long[] data = new long[length]; + for (int index = 0; index < blocks.length; index++) { + int value = directPalette ? palette.get(blocks[index]) : blocks[index]; + int bitIndex = index * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; + if (startIndex != endIndex) { + int endBitSubIndex = 64 - startBitSubIndex; + data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; + } + } + for (long l : data) { + Type.LONG.write(output, l); + } + } + /** * Write the block light to a buffer * 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 169da097e..9033929ab 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 @@ -148,6 +148,49 @@ public class ChunkSection1_9to1_8 implements ChunkSection { } } + @Override + public void writeBlocks1_13(ByteBuf output) throws Exception { + // Write bits per block + int bitsPerBlock = 4; + while (palette.size() > 1 << bitsPerBlock) { + bitsPerBlock++; + } + boolean directPalette = false; + if (bitsPerBlock > 9) { + bitsPerBlock = 14; + directPalette = true; + } + long maxEntryValue = (1L << bitsPerBlock) - 1; + output.writeByte(bitsPerBlock); + + // Write pallet (or not) + if (!directPalette) { + Type.VAR_INT.write(output, palette.size()); + for (int mappedId : palette) { + Type.VAR_INT.write(output, mappedId); + } + } + + int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); + Type.VAR_INT.write(output, length); + long[] data = new long[length]; + for (int index = 0; index < blocks.length; index++) { + int value = directPalette ? palette.get(blocks[index]) : blocks[index]; + int bitIndex = index * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; + if (startIndex != endIndex) { + int endBitSubIndex = 64 - startBitSubIndex; + data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; + } + } + for (long l : data) { + Type.LONG.write(output, l); + } + } + /** * Write the block light to a buffer * diff --git a/jar/pom.xml b/jar/pom.xml index 6d57b8b20..edda39cf8 100644 --- a/jar/pom.xml +++ b/jar/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.4.0-1.13-pre10 + 1.4.0-DEV 4.0.0 viaversion-jar diff --git a/pom.xml b/pom.xml index d6fc8f267..de7e9b13c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ us.myles viaversion-parent - 1.4.0-1.13-pre10 + 1.4.0-DEV pom viaversion-parent diff --git a/sponge-legacy/pom.xml b/sponge-legacy/pom.xml index ab1ab0284..1107c7248 100644 --- a/sponge-legacy/pom.xml +++ b/sponge-legacy/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.4.0-1.13-pre10 + 1.4.0-DEV 4.0.0 diff --git a/sponge/pom.xml b/sponge/pom.xml index c9e2d0040..459095939 100644 --- a/sponge/pom.xml +++ b/sponge/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.4.0-1.13-pre10 + 1.4.0-DEV 4.0.0