diff --git a/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsPlatform.java b/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsPlatform.java index df716c7c..f6e13725 100644 --- a/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsPlatform.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsPlatform.java @@ -17,6 +17,8 @@ import nl.matsv.viabackwards.protocol.protocol1_12_1to1_12_2.Protocol1_12_1To1_1 import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.Protocol1_12_2To1_13; import nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.Protocol1_11_1To1_12; import nl.matsv.viabackwards.protocol.protocol1_12to1_12_1.Protocol1_12To1_12_1; +import nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.Protocol1_13_1To1_13_2; +import nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.Protocol1_13To1_13_1; import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9_4To1_10; import us.myles.ViaVersion.api.protocol.ProtocolRegistry; import us.myles.ViaVersion.api.protocol.ProtocolVersion; @@ -40,6 +42,8 @@ public interface ViaBackwardsPlatform { ProtocolRegistry.registerProtocol(new Protocol1_12To1_12_1(), Collections.singletonList(ProtocolVersion.v1_12.getId()), ProtocolVersion.v1_12_1.getId()); ProtocolRegistry.registerProtocol(new Protocol1_12_1To1_12_2(), Collections.singletonList(ProtocolVersion.v1_12_1.getId()), ProtocolVersion.v1_12_2.getId()); ProtocolRegistry.registerProtocol(new Protocol1_12_2To1_13(), Collections.singletonList(ProtocolVersion.v1_12_2.getId()), ProtocolVersion.v1_13.getId()); + ProtocolRegistry.registerProtocol(new Protocol1_13To1_13_1(), Collections.singletonList(ProtocolVersion.v1_13.getId()), ProtocolVersion.v1_13_1.getId()); + ProtocolRegistry.registerProtocol(new Protocol1_13_1To1_13_2(), Collections.singletonList(ProtocolVersion.v1_13_1.getId()), ProtocolVersion.v1_13_2.getId()); } } diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/Protocol1_13_1To1_13_2.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/Protocol1_13_1To1_13_2.java new file mode 100644 index 00000000..d724dce7 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/Protocol1_13_1To1_13_2.java @@ -0,0 +1,79 @@ +package nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2; + +import nl.matsv.viabackwards.api.BackwardsProtocol; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.minecraft.item.Item; +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 nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.packets.EntityPackets; +import nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.packets.InventoryPackets; +import nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.packets.WorldPackets; + +public class Protocol1_13_1To1_13_2 extends BackwardsProtocol { + + @Override + protected void registerPackets() { + InventoryPackets.register(this); + WorldPackets.register(this); + EntityPackets.register(this); + + //Edit Book + registerIncoming(State.PLAY, 0x0B, 0x0B, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.FLAT_ITEM, Type.FLAT_VAR_INT_ITEM); + } + }); + + // Advancements + registerOutgoing(State.PLAY, 0x51, 0x51, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.passthrough(Type.BOOLEAN); // Reset/clear + int size = wrapper.passthrough(Type.VAR_INT); // Mapping size + + for (int i = 0; i < size; i++) { + wrapper.passthrough(Type.STRING); // Identifier + + // Parent + if (wrapper.passthrough(Type.BOOLEAN)) + wrapper.passthrough(Type.STRING); + + // Display data + if (wrapper.passthrough(Type.BOOLEAN)) { + wrapper.passthrough(Type.STRING); // Title + wrapper.passthrough(Type.STRING); // Description + Item icon = wrapper.read(Type.FLAT_VAR_INT_ITEM); + wrapper.write(Type.FLAT_ITEM, icon); + wrapper.passthrough(Type.VAR_INT); // Frame type + int flags = wrapper.passthrough(Type.INT); // Flags + if ((flags & 1) != 0) + wrapper.passthrough(Type.STRING); // Background texture + wrapper.passthrough(Type.FLOAT); // X + wrapper.passthrough(Type.FLOAT); // Y + } + + wrapper.passthrough(Type.STRING_ARRAY); // Criteria + + int arrayLength = wrapper.passthrough(Type.VAR_INT); + for (int array = 0; array < arrayLength; array++) { + wrapper.passthrough(Type.STRING_ARRAY); // String array + } + } + } + }); + } + }); + } + + @Override + public void init(UserConnection userConnection) { + + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/packets/EntityPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/packets/EntityPackets.java new file mode 100644 index 00000000..ad4ecd2d --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/packets/EntityPackets.java @@ -0,0 +1,98 @@ +package nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.packets; + +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.minecraft.metadata.Metadata; +import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13; +import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13_2; +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.type.Type; +import us.myles.ViaVersion.api.type.types.version.Types1_13; +import us.myles.ViaVersion.api.type.types.version.Types1_13_2; +import us.myles.ViaVersion.packets.State; + +public class EntityPackets { + + + public static void register(Protocol protocol) { + // Spawn mob packet + protocol.registerOutgoing(State.PLAY, 0x3, 0x3, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Entity ID + map(Type.UUID); // 1 - Entity UUID + map(Type.VAR_INT); // 2 - Entity Type + map(Type.DOUBLE); // 3 - X + map(Type.DOUBLE); // 4 - Y + map(Type.DOUBLE); // 5 - Z + map(Type.BYTE); // 6 - Yaw + map(Type.BYTE); // 7 - Pitch + map(Type.BYTE); // 8 - Head Pitch + map(Type.SHORT); // 9 - Velocity X + map(Type.SHORT); // 10 - Velocity Y + map(Type.SHORT); // 11 - Velocity Z + map(Types1_13_2.METADATA_LIST, Types1_13.METADATA_LIST); // 12 - Metadata + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + for (Metadata metadata : wrapper.get(Types1_13.METADATA_LIST, 0)) { + if (metadata.getMetaType() == MetaType1_13_2.Slot) { + metadata.setMetaType(MetaType1_13.Slot); + } + } + } + }); + } + }); + + // Spawn player packet + protocol.registerOutgoing(State.PLAY, 0x05, 0x05, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Entity ID + map(Type.UUID); // 1 - Player UUID + map(Type.DOUBLE); // 2 - X + map(Type.DOUBLE); // 3 - Y + map(Type.DOUBLE); // 4 - Z + map(Type.BYTE); // 5 - Yaw + map(Type.BYTE); // 6 - Pitch + map(Types1_13_2.METADATA_LIST, Types1_13.METADATA_LIST); // 7 - Metadata + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + for (Metadata metadata : wrapper.get(Types1_13.METADATA_LIST, 0)) { + if (metadata.getMetaType() == MetaType1_13_2.Slot) { + metadata.setMetaType(MetaType1_13.Slot); + } + } + } + }); + } + }); + + + // Metadata packet + protocol.registerOutgoing(State.PLAY, 0x3F, 0x3F, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Entity ID + map(Types1_13_2.METADATA_LIST, Types1_13.METADATA_LIST); // 1 - Metadata list + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + for (Metadata metadata : wrapper.get(Types1_13.METADATA_LIST, 0)) { + if (metadata.getMetaType() == MetaType1_13_2.Slot) { + metadata.setMetaType(MetaType1_13.Slot); + } + } + } + }); + } + }); + } + +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/packets/InventoryPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/packets/InventoryPackets.java new file mode 100644 index 00000000..cf43be02 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/packets/InventoryPackets.java @@ -0,0 +1,151 @@ +package nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.packets; + +import us.myles.ViaVersion.api.PacketWrapper; +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.type.Type; +import us.myles.ViaVersion.packets.State; + +public class InventoryPackets { + + public static void register(Protocol protocol) { + + /* + Outgoing packets + */ + + // Set slot packet + protocol.registerOutgoing(State.PLAY, 0x17, 0x17, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.BYTE); // 0 - Window ID + map(Type.SHORT); // 1 - Slot ID + map(Type.FLAT_VAR_INT_ITEM, Type.FLAT_ITEM); // 2 - Slot Value + } + }); + + // Window items packet + protocol.registerOutgoing(State.PLAY, 0x15, 0x15, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.UNSIGNED_BYTE); // 0 - Window ID + map(Type.FLAT_VAR_INT_ITEM_ARRAY, Type.FLAT_ITEM_ARRAY); // 1 - Window Values + } + }); + + // Plugin message + protocol.registerOutgoing(State.PLAY, 0x19, 0x19, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.STRING); // Channel + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + String channel = wrapper.get(Type.STRING, 0); + if (channel.equals("minecraft:trader_list") || channel.equals("trader_list")) { + wrapper.passthrough(Type.INT); // Passthrough Window ID + + int size = wrapper.passthrough(Type.UNSIGNED_BYTE); + for (int i = 0; i < size; i++) { + // Input Item + wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM)); + // Output Item + wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM)); + + boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item + if (secondItem) { + wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM)); + } + + wrapper.passthrough(Type.BOOLEAN); // Trade disabled + wrapper.passthrough(Type.INT); // Number of tools uses + wrapper.passthrough(Type.INT); // Maximum number of trade uses + } + } + } + }); + } + }); + + // Entity Equipment Packet + protocol.registerOutgoing(State.PLAY, 0x42, 0x42, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Entity ID + map(Type.VAR_INT); // 1 - Slot ID + map(Type.FLAT_VAR_INT_ITEM, Type.FLAT_ITEM); // 2 - Item + } + }); + + // // Declare Recipes + protocol.registerOutgoing(State.PLAY, 0x54, 0x54, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int recipesNo = wrapper.passthrough(Type.VAR_INT); + for (int i = 0; i < recipesNo; i++) { + wrapper.passthrough(Type.STRING); // Id + String type = wrapper.passthrough(Type.STRING); + if (type.equals("crafting_shapeless")) { + wrapper.passthrough(Type.STRING); // Group + int ingredientsNo = wrapper.passthrough(Type.VAR_INT); + for (int i1 = 0; i1 < ingredientsNo; i1++) { + wrapper.write(Type.FLAT_ITEM_ARRAY_VAR_INT, wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT)); + } + wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM)); + } else if (type.equals("crafting_shaped")) { + int ingredientsNo = wrapper.passthrough(Type.VAR_INT) * wrapper.passthrough(Type.VAR_INT); + wrapper.passthrough(Type.STRING); // Group + for (int i1 = 0; i1 < ingredientsNo; i1++) { + wrapper.write(Type.FLAT_ITEM_ARRAY_VAR_INT, wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT)); + } + wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM)); + } else if (type.equals("smelting")) { + wrapper.passthrough(Type.STRING); // Group + // Ingredient start + wrapper.write(Type.FLAT_ITEM_ARRAY_VAR_INT, wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT)); + // Ingredient end + wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM)); + wrapper.passthrough(Type.FLOAT); // EXP + wrapper.passthrough(Type.VAR_INT); // Cooking time + } + } + } + }); + } + }); + + + /* + Incoming packets + */ + + // Click window packet + protocol.registerIncoming(State.PLAY, 0x08, 0x08, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.UNSIGNED_BYTE); // 0 - Window ID + map(Type.SHORT); // 1 - Slot + map(Type.BYTE); // 2 - Button + map(Type.SHORT); // 3 - Action number + map(Type.VAR_INT); // 4 - Mode + map(Type.FLAT_ITEM, Type.FLAT_VAR_INT_ITEM); // 5 - Clicked Item + } + } + ); + + // Creative Inventory Action + protocol.registerIncoming(State.PLAY, 0x24, 0x24, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.SHORT); // 0 - Slot + map(Type.FLAT_ITEM, Type.FLAT_VAR_INT_ITEM); // 1 - Clicked Item + } + } + ); + } + +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/packets/WorldPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/packets/WorldPackets.java new file mode 100644 index 00000000..9fc17e0a --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_1to1_13_2/packets/WorldPackets.java @@ -0,0 +1,39 @@ +package nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.packets; + +import us.myles.ViaVersion.api.PacketWrapper; +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.type.Type; +import us.myles.ViaVersion.packets.State; + +public class WorldPackets { + + public static void register(Protocol protocol) { + //spawn particle + protocol.registerOutgoing(State.PLAY, 0x24, 0x24, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.INT); // 0 - Particle ID + map(Type.BOOLEAN); // 1 - Long Distance + map(Type.FLOAT); // 2 - X + map(Type.FLOAT); // 3 - Y + map(Type.FLOAT); // 4 - Z + map(Type.FLOAT); // 5 - Offset X + map(Type.FLOAT); // 6 - Offset Y + map(Type.FLOAT); // 7 - Offset Z + map(Type.FLOAT); // 8 - Particle Data + map(Type.INT); // 9 - Particle Count + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int id = wrapper.get(Type.INT, 0); + if (id == 27) { + wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM)); + } + } + }); + } + }); + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/MetadataRewriter.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/MetadataRewriter.java new file mode 100644 index 00000000..72ebe475 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/MetadataRewriter.java @@ -0,0 +1,48 @@ +package nl.matsv.viabackwards.protocol.protocol1_13to1_13_1; + +import nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.packets.InventoryPackets; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.entities.Entity1_13Types; +import us.myles.ViaVersion.api.entities.Entity1_13Types.EntityType; +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 java.util.ArrayList; +import java.util.List; + +public class MetadataRewriter { + + public static void handleMetadata(int entityId, Entity1_13Types.EntityType type, List metadatas, UserConnection connection) { + for (Metadata metadata : new ArrayList<>(metadatas)) { + try { + // 1.13 changed item to flat item (no data) + if (metadata.getMetaType() == MetaType1_13.Slot) { + InventoryPackets.toClient((Item) metadata.getValue()); + } else if (metadata.getMetaType() == MetaType1_13.BlockID) { + // Convert to new block id + int data = (int) metadata.getValue(); + metadata.setValue(Protocol1_13To1_13_1.getNewBlockStateId(data)); + } + if (type == null) continue; + if (type.isOrHasParent(Entity1_13Types.EntityType.MINECART_ABSTRACT) && metadata.getId() == 9) { + // New block format + int data = (int) metadata.getValue(); + metadata.setValue(Protocol1_13To1_13_1.getNewBlockStateId(data)); + } + if(type.is(EntityType.ITEM)){ + + } + } catch (Exception e) { + metadatas.remove(metadata); + if (!Via.getConfig().isSuppressMetadataErrors() || Via.getManager().isDebug()) { + Via.getPlatform().getLogger().warning("An error occurred with entity metadata handler"); + Via.getPlatform().getLogger().warning("Metadata: " + metadata); + e.printStackTrace(); + } + } + } + } + +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/Protocol1_13To1_13_1.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/Protocol1_13To1_13_1.java new file mode 100644 index 00000000..b884a825 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/Protocol1_13To1_13_1.java @@ -0,0 +1,220 @@ +package nl.matsv.viabackwards.protocol.protocol1_13to1_13_1; + +import nl.matsv.viabackwards.api.BackwardsProtocol; +import nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.packets.EntityPackets; +import nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.packets.InventoryPackets; +import nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.packets.WorldPackets; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.minecraft.item.Item; +import us.myles.ViaVersion.api.remapper.PacketHandler; +import us.myles.ViaVersion.api.remapper.PacketRemapper; +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_13to1_12_2.storage.EntityTracker; +import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; + +public class Protocol1_13To1_13_1 extends BackwardsProtocol { + + @Override + protected void registerPackets() { + EntityPackets.register(this); + InventoryPackets.register(this); + WorldPackets.register(this); + + //Tab complete + registerIncoming(State.PLAY, 0x05, 0x05, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); + map(Type.STRING, new ValueTransformer(Type.STRING) { + @Override + public String transform(PacketWrapper wrapper, String inputValue) { + // 1.13 starts sending slash at start, so we remove it for compatibility + return !inputValue.startsWith("/") ? "/" + inputValue : inputValue; + } + }); + } + }); + + //Edit Book + registerIncoming(State.PLAY, 0x0B, 0x0B, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.FLAT_ITEM); + map(Type.BOOLEAN); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.VAR_INT, 0); + } + }); + } + }); + + // Tab complete + registerOutgoing(State.PLAY, 0x10, 0x10, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // Transaction id + map(Type.VAR_INT); // Start + map(Type.VAR_INT); // Length + map(Type.VAR_INT); // Count + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int start = wrapper.get(Type.VAR_INT, 1); + wrapper.set(Type.VAR_INT, 1, start - 1); // Offset by +1 to take into account / at beginning + // Passthrough suggestions + int count = wrapper.get(Type.VAR_INT, 3); + for (int i = 0; i < count; i++) { + wrapper.passthrough(Type.STRING); + boolean hasTooltip = wrapper.passthrough(Type.BOOLEAN); + if (hasTooltip) { + wrapper.passthrough(Type.STRING); // JSON Tooltip + } + } + } + }); + } + }); + + //boss bar + registerOutgoing(State.PLAY, 0x0C, 0x0C, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.UUID); + map(Type.VAR_INT); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int action = wrapper.get(Type.VAR_INT, 0); + if (action == 0) { + wrapper.passthrough(Type.STRING); + wrapper.passthrough(Type.FLOAT); + wrapper.passthrough(Type.VAR_INT); + short flags = wrapper.read(Type.UNSIGNED_BYTE); + if ((flags & 0x04) != 0) flags |= 0x02; + wrapper.write(Type.UNSIGNED_BYTE, flags); + } + } + }); + } + }); + + + // Advancements + registerOutgoing(State.PLAY, 0x51, 0x51, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.passthrough(Type.BOOLEAN); // Reset/clear + int size = wrapper.passthrough(Type.VAR_INT); // Mapping size + + for (int i = 0; i < size; i++) { + wrapper.passthrough(Type.STRING); // Identifier + + // Parent + if (wrapper.passthrough(Type.BOOLEAN)) + wrapper.passthrough(Type.STRING); + + // Display data + if (wrapper.passthrough(Type.BOOLEAN)) { + wrapper.passthrough(Type.STRING); // Title + wrapper.passthrough(Type.STRING); // Description + Item icon = wrapper.passthrough(Type.FLAT_ITEM); + InventoryPackets.toClient(icon); + wrapper.passthrough(Type.VAR_INT); // Frame type + int flags = wrapper.passthrough(Type.INT); // Flags + if ((flags & 1) != 0) + wrapper.passthrough(Type.STRING); // Background texture + wrapper.passthrough(Type.FLOAT); // X + wrapper.passthrough(Type.FLOAT); // Y + } + + wrapper.passthrough(Type.STRING_ARRAY); // Criteria + + int arrayLength = wrapper.passthrough(Type.VAR_INT); + for (int array = 0; array < arrayLength; array++) { + wrapper.passthrough(Type.STRING_ARRAY); // String array + } + } + } + }); + } + }); + + //Tags + registerOutgoing(State.PLAY, 0x55, 0x55, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int blockTagsSize = wrapper.passthrough(Type.VAR_INT); // block tags + for (int i = 0; i < blockTagsSize; i++) { + wrapper.passthrough(Type.STRING); + Integer[] blocks = wrapper.passthrough(Type.VAR_INT_ARRAY); + for (int j = 0; j < blocks.length; j++) { + blocks[j] = getNewBlockId(blocks[j]); + } + } + int itemTagsSize = wrapper.passthrough(Type.VAR_INT); // item tags + for (int i = 0; i < itemTagsSize; i++) { + wrapper.passthrough(Type.STRING); + Integer[] items = wrapper.passthrough(Type.VAR_INT_ARRAY); + for (int j = 0; j < items.length; j++) { + items[j] = InventoryPackets.getOldItemId(items[j]); + } + } + } + }); + } + }); + + } + + public static int getNewBlockStateId(int blockId) { + if (blockId > 8590) { + blockId -= 17; + } else if (blockId > 8573) { + blockId = 0; //TODO replace new blocks + } else if (blockId > 8479) { + blockId -= 16; + } else if (blockId > 8469 && blockId % 2 == 0) { + if (blockId % 2 == 0) { + blockId = 8459 + (blockId - 8470) / 2; + } else { + blockId = 0; //TODO replace new blocks + } + } else if (blockId > 8463) { + blockId = 0; //TODO replace new blocks + } else if (blockId > 1127) { + blockId -= 1; + } else if (blockId == 1127) { + blockId = 1126; + } + + return blockId; + } + + public static int getNewBlockId(int blockId) { + if (blockId > 565) { + blockId -= 5; + } else if (blockId > 561) { + blockId = 0; //TODO replace new blocks + } + + return blockId; + } + + @Override + public void init(UserConnection userConnection) { + userConnection.put(new EntityTracker(userConnection)); + if (!userConnection.has(ClientWorld.class)) + userConnection.put(new ClientWorld(userConnection)); + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/packets/EntityPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/packets/EntityPackets.java new file mode 100644 index 00000000..d1eb8d2a --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/packets/EntityPackets.java @@ -0,0 +1,152 @@ +package nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.packets; + +import com.google.common.base.Optional; +import nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.MetadataRewriter; +import nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.Protocol1_13To1_13_1; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.entities.Entity1_13Types; +import us.myles.ViaVersion.api.entities.Entity1_13Types.EntityType; +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.type.Type; +import us.myles.ViaVersion.api.type.types.version.Types1_13; +import us.myles.ViaVersion.packets.State; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.EntityTracker; + +public class EntityPackets { + + public static void register(Protocol protocol) { + + //spawn entity + protocol.registerOutgoing(State.PLAY, 0x0, 0x0, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Entity id + map(Type.UUID); // 1 - UUID + map(Type.BYTE); // 2 - Type + map(Type.DOUBLE); // 3 - X + map(Type.DOUBLE); // 4 - Y + map(Type.DOUBLE); // 5 - Z + map(Type.BYTE); // 6 - Pitch + map(Type.BYTE); // 7 - Yaw + map(Type.INT); // 8 - Data + + // Track Entity + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int entityId = wrapper.get(Type.VAR_INT, 0); + byte type = wrapper.get(Type.BYTE, 0); + Entity1_13Types.EntityType entType = Entity1_13Types.getTypeFromId(type, true); + + if (entType != null) { + if (entType.is(Entity1_13Types.EntityType.FALLING_BLOCK)) { + int data = wrapper.get(Type.INT, 0); + wrapper.set(Type.INT, 0, Protocol1_13To1_13_1.getNewBlockStateId(data)); + } + } + // Register Type ID + wrapper.user().get(EntityTracker.class).addEntity(entityId, entType); + } + }); + } + }); + // Spawn mob packet + protocol.registerOutgoing(State.PLAY, 0x3, 0x3, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Entity ID + map(Type.UUID); // 1 - Entity UUID + map(Type.VAR_INT); // 2 - Entity Type + map(Type.DOUBLE); // 3 - X + map(Type.DOUBLE); // 4 - Y + map(Type.DOUBLE); // 5 - Z + map(Type.BYTE); // 6 - Yaw + map(Type.BYTE); // 7 - Pitch + map(Type.BYTE); // 8 - Head Pitch + map(Type.SHORT); // 9 - Velocity X + map(Type.SHORT); // 10 - Velocity Y + map(Type.SHORT); // 11 - Velocity Z + map(Types1_13.METADATA_LIST); // 12 - Metadata + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int entityId = wrapper.get(Type.VAR_INT, 0); + int type = wrapper.get(Type.VAR_INT, 1); + + Entity1_13Types.EntityType entType = Entity1_13Types.getTypeFromId(type, false); + + // Register Type ID + wrapper.user().get(EntityTracker.class).addEntity(entityId, entType); + + MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_13.METADATA_LIST, 0), wrapper.user()); + } + }); + } + }); + + // Spawn player packet + protocol.registerOutgoing(State.PLAY, 0x05, 0x05, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Entity ID + map(Type.UUID); // 1 - Player UUID + map(Type.DOUBLE); // 2 - X + map(Type.DOUBLE); // 3 - Y + map(Type.DOUBLE); // 4 - Z + map(Type.BYTE); // 5 - Yaw + map(Type.BYTE); // 6 - Pitch + map(Types1_13.METADATA_LIST); // 7 - Metadata + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int entityId = wrapper.get(Type.VAR_INT, 0); + + Entity1_13Types.EntityType entType = Entity1_13Types.EntityType.PLAYER; + // Register Type ID + wrapper.user().get(EntityTracker.class).addEntity(entityId, entType); + MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_13.METADATA_LIST, 0), wrapper.user()); + } + }); + } + }); + // Destroy entities + protocol.registerOutgoing(State.PLAY, 0x35, 0x35, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT_ARRAY); // 0 - Entity IDS + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + for (int entity : wrapper.get(Type.VAR_INT_ARRAY, 0)) + wrapper.user().get(EntityTracker.class).removeEntity(entity); + } + }); + } + }); + + + // Metadata packet + protocol.registerOutgoing(State.PLAY, 0x3F, 0x3F, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Entity ID + map(Types1_13.METADATA_LIST); // 1 - Metadata list + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int entityId = wrapper.get(Type.VAR_INT, 0); + + Optional type = wrapper.user().get(EntityTracker.class).get(entityId); + MetadataRewriter.handleMetadata(entityId, type.orNull(), wrapper.get(Types1_13.METADATA_LIST, 0), wrapper.user()); + } + }); + } + }); + } + +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/packets/InventoryPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/packets/InventoryPackets.java new file mode 100644 index 00000000..f1f94122 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/packets/InventoryPackets.java @@ -0,0 +1,144 @@ +package nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.packets; + +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.minecraft.item.Item; +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.type.Type; +import us.myles.ViaVersion.packets.State; + +public class InventoryPackets { + + public static void register(Protocol protocol) { + + /* + Outgoing packets + */ + + // Set slot packet + protocol.registerOutgoing(State.PLAY, 0x17, 0x17, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.BYTE); // 0 - Window ID + map(Type.SHORT); // 1 - Slot ID + map(Type.FLAT_ITEM, Type.FLAT_ITEM); // 2 - Slot Value + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item stack = wrapper.get(Type.FLAT_ITEM, 0); + toClient(stack); + } + }); + } + }); + + // Window items packet + protocol.registerOutgoing(State.PLAY, 0x15, 0x15, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.UNSIGNED_BYTE); // 0 - Window ID + map(Type.FLAT_ITEM_ARRAY, Type.FLAT_ITEM_ARRAY); // 1 - Window Values + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item[] stacks = wrapper.get(Type.FLAT_ITEM_ARRAY, 0); + for (Item stack : stacks) + toClient(stack); + } + }); + } + }); + + // Entity Equipment Packet + protocol.registerOutgoing(State.PLAY, 0x42, 0x42, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Entity ID + map(Type.VAR_INT); // 1 - Slot ID + map(Type.FLAT_ITEM, Type.FLAT_ITEM); // 2 - Item + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item stack = wrapper.get(Type.FLAT_ITEM, 0); + toClient(stack); + } + }); + } + }); + + + /* + Incoming packets + */ + + // Click window packet + protocol.registerIncoming(State.PLAY, 0x08, 0x08, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.UNSIGNED_BYTE); // 0 - Window ID + map(Type.SHORT); // 1 - Slot + map(Type.BYTE); // 2 - Button + map(Type.SHORT); // 3 - Action number + map(Type.VAR_INT); // 4 - Mode + map(Type.FLAT_ITEM, Type.FLAT_ITEM); // 5 - Clicked Item + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item item = wrapper.get(Type.FLAT_ITEM, 0); + toServer(item); + } + }); + } + } + ); + + // Creative Inventory Action + protocol.registerIncoming(State.PLAY, 0x24, 0x24, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.SHORT); // 0 - Slot + map(Type.FLAT_ITEM, Type.FLAT_ITEM); // 1 - Clicked Item + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item item = wrapper.get(Type.FLAT_ITEM, 0); + toServer(item); + } + }); + } + } + ); + } + + public static void toClient(Item item) { + if (item == null) return; + item.setId((short) getOldItemId(item.getId())); + } + + //1.13.1 Item Id + public static int getNewItemId(int itemId) { + if (itemId >= 443) { + return itemId + 5; + } + return itemId; + } + + public static void toServer(Item item) { + if (item == null) return; + item.setId((short) getNewItemId(item.getId())); + } + + //1.13 Item Id + public static int getOldItemId(int newId) { + if (newId >= 448) { + return newId - 5; + } + return newId; + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/packets/WorldPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/packets/WorldPackets.java new file mode 100644 index 00000000..3fd244d0 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13to1_13_1/packets/WorldPackets.java @@ -0,0 +1,187 @@ +package nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.packets; + +import nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.Protocol1_13To1_13_1; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.minecraft.BlockChangeRecord; +import us.myles.ViaVersion.api.minecraft.chunks.Chunk; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; +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.type.Type; +import us.myles.ViaVersion.packets.State; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Chunk1_13Type; +import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; + +public class WorldPackets { + + public static void register(Protocol protocol) { + //Chunk + protocol.registerOutgoing(State.PLAY, 0x22, 0x22, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + Chunk chunk = wrapper.passthrough(new Chunk1_13Type(clientWorld)); + + for (ChunkSection section : chunk.getSections()) { + if (section != null) { + for (int i = 0; i < section.getPalette().size(); i++) { + section.getPalette().set( + i, + Protocol1_13To1_13_1.getNewBlockStateId(section.getPalette().get(i)) + ); + } + } + } + + } + }); + } + }); + + // Block Action + protocol.registerOutgoing(State.PLAY, 0x0A, 0x0A, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.POSITION); // Location + map(Type.UNSIGNED_BYTE); // Action id + map(Type.UNSIGNED_BYTE); // Action param + map(Type.VAR_INT); // Block id - /!\ NOT BLOCK STATE + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.set(Type.VAR_INT, 0, Protocol1_13To1_13_1.getNewBlockId(wrapper.get(Type.VAR_INT, 0))); + } + }); + } + }); + + // Block Change + protocol.registerOutgoing(State.PLAY, 0xB, 0xB, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.POSITION); + map(Type.VAR_INT); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int id = wrapper.get(Type.VAR_INT, 0); + + wrapper.set(Type.VAR_INT, 0, Protocol1_13To1_13_1.getNewBlockStateId(id)); + } + }); + } + }); + + // Multi Block Change + protocol.registerOutgoing(State.PLAY, 0xF, 0xF, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.INT); // 0 - Chunk X + map(Type.INT); // 1 - Chunk Z + map(Type.BLOCK_CHANGE_RECORD_ARRAY); // 2 - Records + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + // Convert ids + for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) { + int id = record.getBlockId(); + record.setBlockId(Protocol1_13To1_13_1.getNewBlockStateId(id)); + } + } + }); + } + }); + + // Effect packet + protocol.registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.INT); // Effect Id + map(Type.POSITION); // Location + map(Type.INT); // Data + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int id = wrapper.get(Type.INT, 0); + int data = wrapper.get(Type.INT, 1); + if (id == 1010) { // Play record + wrapper.set(Type.INT, 1, data = InventoryPackets.getNewItemId(data)); + } else if (id == 2001) { // Block break + block break sound + wrapper.set(Type.INT, 1, data = Protocol1_13To1_13_1.getNewBlockStateId(data)); + } + } + }); + } + }); + + //join game + protocol.registerOutgoing(State.PLAY, 0x25, 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 + ClientWorld clientChunks = wrapper.user().get(ClientWorld.class); + int dimensionId = wrapper.get(Type.INT, 1); + clientChunks.setEnvironment(dimensionId); + } + }); + } + }); + + //respawn + protocol.registerOutgoing(State.PLAY, 0x38, 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); + } + }); + } + }); + + //spawn particle + protocol.registerOutgoing(State.PLAY, 0x24, 0x24, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.INT); // 0 - Particle ID + map(Type.BOOLEAN); // 1 - Long Distance + map(Type.FLOAT); // 2 - X + map(Type.FLOAT); // 3 - Y + map(Type.FLOAT); // 4 - Z + map(Type.FLOAT); // 5 - Offset X + map(Type.FLOAT); // 6 - Offset Y + map(Type.FLOAT); // 7 - Offset Z + map(Type.FLOAT); // 8 - Particle Data + map(Type.INT); // 9 - Particle Count + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int id = wrapper.get(Type.INT, 0); + if(id == 3 || id == 20){ + int data = wrapper.passthrough(Type.VAR_INT); + wrapper.set(Type.VAR_INT, 0, Protocol1_13To1_13_1.getNewBlockStateId(data)); + } else if (id == 27) { + InventoryPackets.toClient(wrapper.passthrough(Type.FLAT_ITEM)); + } + } + }); + } + }); + } + +}