From 741e0f8fda24837868fd75e4760dcbe2dbda2a20 Mon Sep 17 00:00:00 2001 From: Marco Neuhaus Date: Wed, 1 Aug 2018 20:20:52 +0200 Subject: [PATCH] add support for 18w31a --- .../api/protocol/ProtocolRegistry.java | 4 +- .../api/protocol/ProtocolVersion.java | 2 + .../MetadataRewriter.java | 42 ++ .../Protocol18w31aTO1_13.java | 365 ++++++++++++++++++ .../types/Chunk1_13Type.java | 2 +- 5 files changed, 413 insertions(+), 2 deletions(-) create mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocol18w31ato1_13/MetadataRewriter.java create mode 100644 common/src/main/java/us/myles/ViaVersion/protocols/protocol18w31ato1_13/Protocol18w31aTO1_13.java 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 8013ded62..cddf1a730 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 @@ -13,12 +13,13 @@ import us.myles.ViaVersion.protocols.protocol1_11to1_10.Protocol1_11To1_10; import us.myles.ViaVersion.protocols.protocol1_12_1to1_12.Protocol1_12_1TO1_12; import us.myles.ViaVersion.protocols.protocol1_12_2to1_12_1.Protocol1_12_2TO1_12_1; import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.Protocol1_12To1_11_1; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2; import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.Protocol1_9_1_2TO1_9_3_4; 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.protocol1_13to1_12_2.Protocol1_13To1_12_2; +import us.myles.ViaVersion.protocols.protocol18w31ato1_13.Protocol18w31aTO1_13; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -56,6 +57,7 @@ public class ProtocolRegistry { // 1.13 support in development! (: registerProtocol(new Protocol1_13To1_12_2(), Collections.singletonList(ProtocolVersion.v1_13.getId()), ProtocolVersion.v1_12_2.getId()); + registerProtocol(new Protocol18w31aTO1_13(), Arrays.asList(ProtocolVersion.v18w31a.getId()), ProtocolVersion.v1_13.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 9c10b95ab..1041961e4 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 @@ -34,6 +34,7 @@ public class ProtocolVersion { public static final ProtocolVersion v1_12_2; // v1_13 as name for better ViaBackwards compatibility. public static final ProtocolVersion v1_13; + public static final ProtocolVersion v18w31a; public static final ProtocolVersion unknown; private final int id; @@ -63,6 +64,7 @@ public class ProtocolVersion { 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(393, "1.13")); + register(v18w31a = new ProtocolVersion(396, "18w31a")); register(unknown = new ProtocolVersion(-1, "UNKNOWN")); } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol18w31ato1_13/MetadataRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol18w31ato1_13/MetadataRewriter.java new file mode 100644 index 000000000..5b12f6fad --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol18w31ato1_13/MetadataRewriter.java @@ -0,0 +1,42 @@ +package us.myles.ViaVersion.protocols.protocol18w31ato1_13; + +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.minecraft.metadata.Metadata; +import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Marco Neuhaus on 28.07.2018 for the Project ViaVersion. + */ +public class MetadataRewriter { + + public static void handleMetadata(int entityId, Entity1_13Types.EntityType type, List metadatas, UserConnection connection) { + for (Metadata metadata : new ArrayList<>(metadatas)) { + try { + if (metadata.getMetaType() == MetaType1_13.BlockID) { + // Convert to new block id + int data = (int) metadata.getValue(); + metadata.setValue(Protocol18w31aTO1_13.getMapBlockId(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(Protocol18w31aTO1_13.getMapBlockId(data)); + } + } 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/common/src/main/java/us/myles/ViaVersion/protocols/protocol18w31ato1_13/Protocol18w31aTO1_13.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol18w31ato1_13/Protocol18w31aTO1_13.java new file mode 100644 index 000000000..c291edd3f --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol18w31ato1_13/Protocol18w31aTO1_13.java @@ -0,0 +1,365 @@ +package us.myles.ViaVersion.protocols.protocol18w31ato1_13; + +import com.google.common.base.Optional; +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.entities.Entity1_13Types.EntityType; +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.api.type.types.version.Types1_13; +import us.myles.ViaVersion.packets.State; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.EntityTracker; +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; + +/** + * Created by Marco Neuhaus on 28.07.2018 for the Project ViaVersion. + */ +public class Protocol18w31aTO1_13 extends Protocol { + + @Override + protected void registerPackets() { + //Tab complete + registerIncoming(State.PLAY, 0x05, 0x05, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + String s = wrapper.passthrough(Type.STRING); + if(s.length() > 256){ + wrapper.cancel(); + } + } + }); + } + }); + + //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 { + int hand = wrapper.read(Type.VAR_INT); + if(hand == 1){ + wrapper.cancel(); + } + } + }); + } + }); + + //Chunk + 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 (int i = 0; i < chunk.getSections().length; i++) { + ChunkSection section = chunk.getSections()[i]; + if (section == null) + continue; + + // TODO improve performance + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + int block = section.getBlock(x, y, z); + + section.setFlatBlock(x, y, z, getMapBlockId(block)); + } + } + } + } + + } + }); + } + }); + + // Block Change + 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, getMapBlockId(id)); + } + }); + } + }); + + // Multi Block Change + 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(getMapBlockId(id)); + } + } + }); + } + }); + + //join game + 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 + 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); + } + }); + } + }); + + //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 & 0x02) != 0) flags |= 0x04; + wrapper.write(Type.UNSIGNED_BYTE, flags); + } + } + }); + } + }); + + //spawn particle + 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, getMapBlockId(data)); + } + } + }); + } + }); + + //spawn entity + 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, getMapBlockId(data)); + } + } + // Register Type ID + wrapper.user().get(EntityTracker.class).addEntity(entityId, entType); + } + }); + } + }); + // Spawn mob packet + 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 + 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 + 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 + 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()); + } + }); + } + }); + } + + @Override + public void init(UserConnection userConnection) { + userConnection.put(new EntityTracker(userConnection)); + if (!userConnection.has(ClientWorld.class)) + userConnection.put(new ClientWorld(userConnection)); + } + + + public static int getMapBlockId(int blockId){ + if(blockId > 8573){ + return blockId +2; + }else if(blockId > 1126){ + return blockId +1; + } + return blockId; + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java index ba1247c84..f83308cdb 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/types/Chunk1_13Type.java @@ -58,7 +58,7 @@ public class Chunk1_13Type extends PartialType { if (groundUp) { for (int i = 0; i < 256; i++) { // todo use int in Chunk? - biomeData[i] = 0; + biomeData[i] = (byte) input.readInt();; } }