diff --git a/api/src/main/java/net/elytrium/limboapi/api/chunk/BlockEntityVersion.java b/api/src/main/java/net/elytrium/limboapi/api/chunk/BlockEntityVersion.java index 986c6797..efd474a8 100644 --- a/api/src/main/java/net/elytrium/limboapi/api/chunk/BlockEntityVersion.java +++ b/api/src/main/java/net/elytrium/limboapi/api/chunk/BlockEntityVersion.java @@ -23,7 +23,8 @@ public enum BlockEntityVersion { MINECRAFT_1_20_2(EnumSet.of(ProtocolVersion.MINECRAFT_1_20_2)), MINECRAFT_1_20_3(EnumSet.of(ProtocolVersion.MINECRAFT_1_20_3)), MINECRAFT_1_20_5(EnumSet.of(ProtocolVersion.MINECRAFT_1_20_5)), - MINECRAFT_1_21(EnumSet.of(ProtocolVersion.MINECRAFT_1_21)); + MINECRAFT_1_21(EnumSet.of(ProtocolVersion.MINECRAFT_1_21)), + MINECRAFT_1_21_2(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_2)); private static final EnumMap MC_VERSION_TO_ITEM_VERSIONS = new EnumMap<>(ProtocolVersion.class); @@ -64,6 +65,7 @@ public static BlockEntityVersion parse(String from) { case "1.20.3" -> MINECRAFT_1_20_3; case "1.20.5" -> MINECRAFT_1_20_5; case "1.21" -> MINECRAFT_1_21; + case "1.21.2" -> MINECRAFT_1_21_2; default -> LEGACY; }; } diff --git a/api/src/main/java/net/elytrium/limboapi/api/material/WorldVersion.java b/api/src/main/java/net/elytrium/limboapi/api/material/WorldVersion.java index 1305d91e..83e8d892 100644 --- a/api/src/main/java/net/elytrium/limboapi/api/material/WorldVersion.java +++ b/api/src/main/java/net/elytrium/limboapi/api/material/WorldVersion.java @@ -27,7 +27,8 @@ public enum WorldVersion { MINECRAFT_1_19_4(EnumSet.range(ProtocolVersion.MINECRAFT_1_19_4, ProtocolVersion.MINECRAFT_1_20)), MINECRAFT_1_20(EnumSet.range(ProtocolVersion.MINECRAFT_1_20, ProtocolVersion.MINECRAFT_1_20_2)), MINECRAFT_1_20_3(ProtocolVersion.MINECRAFT_1_20_3), - MINECRAFT_1_20_5(EnumSet.range(ProtocolVersion.MINECRAFT_1_20_5, ProtocolVersion.MAXIMUM_VERSION)); + MINECRAFT_1_20_5(EnumSet.range(ProtocolVersion.MINECRAFT_1_20_5, ProtocolVersion.MINECRAFT_1_21)), + MINECRAFT_1_21_2(EnumSet.range(ProtocolVersion.MINECRAFT_1_21_2, ProtocolVersion.MAXIMUM_VERSION)); private static final EnumMap MC_VERSION_TO_ITEM_VERSIONS = new EnumMap<>(ProtocolVersion.class); @@ -72,6 +73,7 @@ public static WorldVersion parse(String from) { case "1.20" -> MINECRAFT_1_20; case "1.20.3" -> MINECRAFT_1_20_3; case "1.20.5" -> MINECRAFT_1_20_5; + case "1.21.2" -> MINECRAFT_1_21_2; default -> LEGACY; }; } diff --git a/gradle.properties b/gradle.properties index 532ad483..0fd62712 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,6 @@ org.gradle.jvmargs=-Xmx4096m fastPrepareVersion=1.0.13 -velocityVersion=3.3.0-SNAPSHOT -velocityApiVersion=3.4.0-SNAPSHOT +velocityVersion=3.4.0-SNAPSHOT nettyVersion=4.1.86.Final fastutilVersion=8.5.11 bstatsVersion=3.0.0 diff --git a/plugin/build.gradle b/plugin/build.gradle index fef6bed7..5bf07b13 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -25,7 +25,7 @@ dependencies() { implementation("net.elytrium.commons:kyori:$elytriumCommonsVersion") implementation("net.elytrium:fastprepare:$fastPrepareVersion") - compileOnly("com.velocitypowered:velocity-api:$velocityApiVersion") + compileOnly("com.velocitypowered:velocity-api:$velocityVersion") annotationProcessor("com.velocitypowered:velocity-api:$velocityVersion") compileOnly("com.velocitypowered:velocity-proxy:$velocityVersion") // From Elytrium Repo. compileOnly("com.velocitypowered:velocity-native:$velocityVersion") @@ -128,7 +128,8 @@ enum MinecraftVersion { MINECRAFT_1_20_2(764), MINECRAFT_1_20_3(765), MINECRAFT_1_20_5(766), - MINECRAFT_1_21(767) + MINECRAFT_1_21(767), + MINECRAFT_1_21_2(768) public static final List WORLD_VERSIONS = List.of( MINECRAFT_1_13, @@ -143,12 +144,8 @@ enum MinecraftVersion { MINECRAFT_1_19_4, MINECRAFT_1_20, MINECRAFT_1_20_3, - MINECRAFT_1_20_5 - ) - - public static final List COMPONENT_VERSIONS = List.of( MINECRAFT_1_20_5, - MINECRAFT_1_21 + MINECRAFT_1_21_2 ) public static final MinecraftVersion MINIMUM_VERSION = MINECRAFT_1_7_2 @@ -552,7 +549,7 @@ void generateRegistryMappings(File targetDir, Map regi .findAll({ e -> MinecraftVersion.WORLD_VERSIONS.contains(e.getKey()) })) this.generateRegistryMapping("block", targetDir, registriesReports) this.generateRegistryMapping("data_component_type", targetDir, registriesReports - .findAll({ e -> MinecraftVersion.COMPONENT_VERSIONS.contains(e.getKey()) })) + .findAll({ e -> e.getKey() >= MinecraftVersion.MINECRAFT_1_20_5 })) File blockEntitiesMappingFile = new File(targetDir, "blockentities_mapping.json"); diff --git a/plugin/mapping/fallbackdata.json b/plugin/mapping/fallbackdata.json index 3af5d262..b2177026 100755 --- a/plugin/mapping/fallbackdata.json +++ b/plugin/mapping/fallbackdata.json @@ -1,4 +1,30 @@ { + "MINECRAFT_1_21": { + "minecraft:pale_oak_wood": "minecraft:birch_wood", + "minecraft:pale_oak_planks": "minecraft:birch_planks", + "minecraft:pale_oak_sapling": "minecraft:birch_sapling", + "minecraft:pale_oak_log": "minecraft:birch_log", + "minecraft:stripped_pale_oak_log": "minecraft:stripped_birch_log", + "minecraft:stripped_pale_oak_wood": "minecraft:stripped_birch_wood", + "minecraft:pale_oak_leaves": "minecraft:birch_leaves", + "minecraft:creaking_heart": "minecraft:oak_wood", + "minecraft:pale_oak_sign": "minecraft:birch_sign", + "minecraft:pale_oak_wall_sign": "minecraft:birch_wall_sign", + "minecraft:pale_oak_hanging_sign": "minecraft:birch_hanging_sign", + "minecraft:pale_oak_wall_hanging_sign": "minecraft:birch_wall_hanging_sign", + "minecraft:pale_oak_pressure_plate": "minecraft:birch_pressure_plate", + "minecraft:pale_oak_trapdoor": "minecraft:birch_trapdoor", + "minecraft:potted_pale_oak_sapling": "minecraft:potted_birch_sapling", + "minecraft:pale_oak_button": "minecraft:birch_button", + "minecraft:pale_oak_stairs": "minecraft:birch_stairs", + "minecraft:pale_oak_slab": "minecraft:birch_slab", + "minecraft:pale_oak_fence_gate": "minecraft:birch_fence_gate", + "minecraft:pale_oak_fence": "minecraft:birch_fence", + "minecraft:pale_oak_door": "minecraft:birch_door", + "minecraft:pale_moss_block": "minecraft:moss_block", + "minecraft:pale_hanging_moss": "minecraft:hanging_roots", + "minecraft:pale_moss_carpet": "minecraft:moss_carpet" + }, "MINECRAFT_1_20_3": { "minecraft:vault": "minecraft:spawner", "minecraft:heavy_core": "minecraft:wither_skeleton_skull" diff --git a/plugin/src/main/java/net/elytrium/limboapi/LimboAPI.java b/plugin/src/main/java/net/elytrium/limboapi/LimboAPI.java index b715801f..2b0ac454 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/LimboAPI.java +++ b/plugin/src/main/java/net/elytrium/limboapi/LimboAPI.java @@ -128,7 +128,7 @@ @SuppressFBWarnings("MS_EXPOSE_REP") public class LimboAPI implements LimboFactory { - private static final int SUPPORTED_MAXIMUM_PROTOCOL_VERSION_NUMBER = 767; + private static final int SUPPORTED_MAXIMUM_PROTOCOL_VERSION_NUMBER = 768; @MonotonicNonNull private static Logger LOGGER; diff --git a/plugin/src/main/java/net/elytrium/limboapi/protocol/LimboProtocol.java b/plugin/src/main/java/net/elytrium/limboapi/protocol/LimboProtocol.java index bb834287..831a05fd 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/LimboProtocol.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/LimboProtocol.java @@ -194,7 +194,8 @@ public static void init() throws Throwable { createMapping(0x1C, ProtocolVersion.MINECRAFT_1_19_3, true), createMapping(0x1F, ProtocolVersion.MINECRAFT_1_19_4, true), createMapping(0x20, ProtocolVersion.MINECRAFT_1_20_2, true), - createMapping(0x22, ProtocolVersion.MINECRAFT_1_20_5, true) + createMapping(0x22, ProtocolVersion.MINECRAFT_1_20_5, true), + createMapping(0x23, ProtocolVersion.MINECRAFT_1_21_2, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, ChunkDataPacket.class, ChunkDataPacket::new, @@ -211,7 +212,8 @@ public static void init() throws Throwable { createMapping(0x20, ProtocolVersion.MINECRAFT_1_19_3, true), createMapping(0x24, ProtocolVersion.MINECRAFT_1_19_4, true), createMapping(0x25, ProtocolVersion.MINECRAFT_1_20_2, true), - createMapping(0x27, ProtocolVersion.MINECRAFT_1_20_5, true) + createMapping(0x27, ProtocolVersion.MINECRAFT_1_20_5, true), + createMapping(0x28, ProtocolVersion.MINECRAFT_1_21_2, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, DefaultSpawnPositionPacket.class, DefaultSpawnPositionPacket::new, @@ -230,7 +232,8 @@ public static void init() throws Throwable { createMapping(0x50, ProtocolVersion.MINECRAFT_1_19_4, true), createMapping(0x52, ProtocolVersion.MINECRAFT_1_20_2, true), createMapping(0x54, ProtocolVersion.MINECRAFT_1_20_3, true), - createMapping(0x56, ProtocolVersion.MINECRAFT_1_20_5, true) + createMapping(0x56, ProtocolVersion.MINECRAFT_1_20_5, true), + createMapping(0x5B, ProtocolVersion.MINECRAFT_1_21_2, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, MapDataPacket.class, MapDataPacket::new, @@ -246,7 +249,8 @@ public static void init() throws Throwable { createMapping(0x25, ProtocolVersion.MINECRAFT_1_19_3, true), createMapping(0x29, ProtocolVersion.MINECRAFT_1_19_4, true), createMapping(0x2A, ProtocolVersion.MINECRAFT_1_20_2, true), - createMapping(0x2C, ProtocolVersion.MINECRAFT_1_20_5, true) + createMapping(0x2C, ProtocolVersion.MINECRAFT_1_20_5, true), + createMapping(0x2D, ProtocolVersion.MINECRAFT_1_21_2, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, PlayerAbilitiesPacket.class, PlayerAbilitiesPacket::new, @@ -264,7 +268,8 @@ public static void init() throws Throwable { createMapping(0x30, ProtocolVersion.MINECRAFT_1_19_3, true), createMapping(0x34, ProtocolVersion.MINECRAFT_1_19_4, true), createMapping(0x36, ProtocolVersion.MINECRAFT_1_20_2, true), - createMapping(0x38, ProtocolVersion.MINECRAFT_1_20_5, true) + createMapping(0x38, ProtocolVersion.MINECRAFT_1_20_5, true), + createMapping(0x3A, ProtocolVersion.MINECRAFT_1_21_2, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, PositionRotationPacket.class, PositionRotationPacket::new, @@ -282,7 +287,8 @@ public static void init() throws Throwable { createMapping(0x38, ProtocolVersion.MINECRAFT_1_19_3, true), createMapping(0x3C, ProtocolVersion.MINECRAFT_1_19_4, true), createMapping(0x3E, ProtocolVersion.MINECRAFT_1_20_2, true), - createMapping(0x40, ProtocolVersion.MINECRAFT_1_20_5, true) + createMapping(0x40, ProtocolVersion.MINECRAFT_1_20_5, true), + createMapping(0x42, ProtocolVersion.MINECRAFT_1_21_2, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, SetExperiencePacket.class, SetExperiencePacket::new, @@ -299,7 +305,8 @@ public static void init() throws Throwable { createMapping(0x56, ProtocolVersion.MINECRAFT_1_19_4, true), createMapping(0x58, ProtocolVersion.MINECRAFT_1_20_2, true), createMapping(0x5A, ProtocolVersion.MINECRAFT_1_20_3, true), - createMapping(0x5C, ProtocolVersion.MINECRAFT_1_20_5, true) + createMapping(0x5C, ProtocolVersion.MINECRAFT_1_20_5, true), + createMapping(0x61, ProtocolVersion.MINECRAFT_1_21_2, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, SetSlotPacket.class, SetSlotPacket::new, @@ -333,7 +340,8 @@ public static void init() throws Throwable { createMapping(0x5E, ProtocolVersion.MINECRAFT_1_19_4, true), createMapping(0x60, ProtocolVersion.MINECRAFT_1_20_2, true), createMapping(0x62, ProtocolVersion.MINECRAFT_1_20_3, true), - createMapping(0x64, ProtocolVersion.MINECRAFT_1_20_5, true) + createMapping(0x64, ProtocolVersion.MINECRAFT_1_20_5, true), + createMapping(0x6B, ProtocolVersion.MINECRAFT_1_21_2, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, UpdateViewPositionPacket.class, UpdateViewPositionPacket::new, // ViewCentre, ChunkRenderDistanceCenter @@ -347,7 +355,8 @@ public static void init() throws Throwable { createMapping(0x4E, ProtocolVersion.MINECRAFT_1_19_4, true), createMapping(0x50, ProtocolVersion.MINECRAFT_1_20_2, true), createMapping(0x52, ProtocolVersion.MINECRAFT_1_20_3, true), - createMapping(0x54, ProtocolVersion.MINECRAFT_1_20_5, true) + createMapping(0x54, ProtocolVersion.MINECRAFT_1_20_5, true), + createMapping(0x58, ProtocolVersion.MINECRAFT_1_21_2, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, UpdateTagsPacket.class, UpdateTagsPacket::new, @@ -363,7 +372,8 @@ public static void init() throws Throwable { createMapping(0x6E, ProtocolVersion.MINECRAFT_1_19_4, true), createMapping(0x70, ProtocolVersion.MINECRAFT_1_20_2, true), createMapping(0x74, ProtocolVersion.MINECRAFT_1_20_3, true), - createMapping(0x78, ProtocolVersion.MINECRAFT_1_20_5, true) + createMapping(0x78, ProtocolVersion.MINECRAFT_1_20_5, true), + createMapping(0x7F, ProtocolVersion.MINECRAFT_1_21_2, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.SERVERBOUND, @@ -382,7 +392,8 @@ public static void init() throws Throwable { createMapping(0x15, ProtocolVersion.MINECRAFT_1_19_4, false), createMapping(0x17, ProtocolVersion.MINECRAFT_1_20_2, false), createMapping(0x18, ProtocolVersion.MINECRAFT_1_20_3, false), - createMapping(0x1B, ProtocolVersion.MINECRAFT_1_20_5, false) + createMapping(0x1B, ProtocolVersion.MINECRAFT_1_20_5, false), + createMapping(0x1D, ProtocolVersion.MINECRAFT_1_21_2, false) ); register(LIMBO_STATE_REGISTRY, PacketDirection.SERVERBOUND, MovePositionOnlyPacket.class, MovePositionOnlyPacket::new, @@ -400,7 +411,8 @@ public static void init() throws Throwable { createMapping(0x14, ProtocolVersion.MINECRAFT_1_19_4, false), createMapping(0x16, ProtocolVersion.MINECRAFT_1_20_2, false), createMapping(0x17, ProtocolVersion.MINECRAFT_1_20_3, false), - createMapping(0x1A, ProtocolVersion.MINECRAFT_1_20_5, false) + createMapping(0x1A, ProtocolVersion.MINECRAFT_1_20_5, false), + createMapping(0x1C, ProtocolVersion.MINECRAFT_1_21_2, false) ); register(LIMBO_STATE_REGISTRY, PacketDirection.SERVERBOUND, MoveRotationOnlyPacket.class, MoveRotationOnlyPacket::new, @@ -418,7 +430,8 @@ public static void init() throws Throwable { createMapping(0x16, ProtocolVersion.MINECRAFT_1_19_4, false), createMapping(0x18, ProtocolVersion.MINECRAFT_1_20_2, false), createMapping(0x19, ProtocolVersion.MINECRAFT_1_20_3, false), - createMapping(0x1C, ProtocolVersion.MINECRAFT_1_20_5, false) + createMapping(0x1C, ProtocolVersion.MINECRAFT_1_20_5, false), + createMapping(0x1E, ProtocolVersion.MINECRAFT_1_21_2, false) ); register(LIMBO_STATE_REGISTRY, PacketDirection.SERVERBOUND, MoveOnGroundOnlyPacket.class, MoveOnGroundOnlyPacket::new, @@ -436,7 +449,8 @@ public static void init() throws Throwable { createMapping(0x17, ProtocolVersion.MINECRAFT_1_19_4, false), createMapping(0x19, ProtocolVersion.MINECRAFT_1_20_2, false), createMapping(0x1A, ProtocolVersion.MINECRAFT_1_20_3, false), - createMapping(0x1D, ProtocolVersion.MINECRAFT_1_20_5, false) + createMapping(0x1D, ProtocolVersion.MINECRAFT_1_20_5, false), + createMapping(0x1F, ProtocolVersion.MINECRAFT_1_21_2, false) ); register(LIMBO_STATE_REGISTRY, PacketDirection.SERVERBOUND, TeleportConfirmPacket.class, TeleportConfirmPacket::new, @@ -447,7 +461,8 @@ public static void init() throws Throwable { PlayerChatSessionPacket.class, PlayerChatSessionPacket::new, createMapping(0x20, ProtocolVersion.MINECRAFT_1_19_3, false), createMapping(0x06, ProtocolVersion.MINECRAFT_1_19_4, false), - createMapping(0x07, ProtocolVersion.MINECRAFT_1_20_5, false) + createMapping(0x07, ProtocolVersion.MINECRAFT_1_20_5, false), + createMapping(0x08, ProtocolVersion.MINECRAFT_1_21_2, false) ); } diff --git a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MoveOnGroundOnlyPacket.java b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MoveOnGroundOnlyPacket.java index 04de82f0..40d6942e 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MoveOnGroundOnlyPacket.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MoveOnGroundOnlyPacket.java @@ -27,10 +27,17 @@ public class MoveOnGroundOnlyPacket implements MinecraftPacket { private boolean onGround; + private boolean collideHorizontally; @Override public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) { - this.onGround = buf.readBoolean(); + if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_21_2)) { + this.onGround = buf.readBoolean(); + } else { + int flags = buf.readUnsignedByte(); + this.onGround = (flags & 1) != 0; + this.collideHorizontally = (flags & 2) != 0; + } } @Override @@ -61,10 +68,15 @@ public int expectedMinLength(ByteBuf buf, ProtocolUtils.Direction direction, Pro public String toString() { return "Player{" + "onGround=" + this.onGround + + ", collideHorizontally=" + this.collideHorizontally + "}"; } public boolean isOnGround() { return this.onGround; } + + public boolean isCollideHorizontally() { + return this.collideHorizontally; + } } diff --git a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MovePacket.java b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MovePacket.java index b4cc2fb6..cdac72dd 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MovePacket.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MovePacket.java @@ -33,6 +33,7 @@ public class MovePacket implements MinecraftPacket { private float yaw; private float pitch; private boolean onGround; + private boolean collideHorizontally; @Override public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) { @@ -44,7 +45,14 @@ public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVer this.posZ = buf.readDouble(); this.yaw = buf.readFloat(); this.pitch = buf.readFloat(); - this.onGround = buf.readBoolean(); + + if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_21_2)) { + this.onGround = buf.readBoolean(); + } else { + int flags = buf.readUnsignedByte(); + this.onGround = (flags & 1) != 0; + this.collideHorizontally = (flags & 2) != 0; + } } @Override @@ -80,6 +88,7 @@ public String toString() { + ", yaw=" + this.yaw + ", pitch=" + this.pitch + ", onGround=" + this.onGround + + ", collideHorizontally=" + this.collideHorizontally + "}"; } @@ -106,4 +115,8 @@ public float getPitch() { public boolean isOnGround() { return this.onGround; } + + public boolean isCollideHorizontally() { + return this.collideHorizontally; + } } diff --git a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MovePositionOnlyPacket.java b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MovePositionOnlyPacket.java index bd71a6a3..7249aed2 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MovePositionOnlyPacket.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MovePositionOnlyPacket.java @@ -30,6 +30,7 @@ public class MovePositionOnlyPacket implements MinecraftPacket { private double posY; private double posZ; private boolean onGround; + private boolean collideHorizontally; @Override public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) { @@ -39,7 +40,14 @@ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi } this.posY = buf.readDouble(); this.posZ = buf.readDouble(); - this.onGround = buf.readBoolean(); + + if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_21_2)) { + this.onGround = buf.readBoolean(); + } else { + int flags = buf.readUnsignedByte(); + this.onGround = (flags & 1) != 0; + this.collideHorizontally = (flags & 2) != 0; + } } @Override @@ -73,6 +81,7 @@ public String toString() { + ", posY=" + this.posY + ", posZ=" + this.posZ + ", onGround=" + this.onGround + + ", collideHorizontally=" + this.collideHorizontally + "}"; } @@ -91,4 +100,8 @@ public double getZ() { public boolean isOnGround() { return this.onGround; } + + public boolean isCollideHorizontally() { + return this.collideHorizontally; + } } diff --git a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MoveRotationOnlyPacket.java b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MoveRotationOnlyPacket.java index a770851d..85a6bd3a 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MoveRotationOnlyPacket.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/c2s/MoveRotationOnlyPacket.java @@ -30,12 +30,20 @@ public class MoveRotationOnlyPacket implements MinecraftPacket { private float yaw; private float pitch; private boolean onGround; + private boolean collideHorizontally; @Override public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) { this.yaw = buf.readFloat(); this.pitch = buf.readFloat(); - this.onGround = buf.readBoolean(); + + if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_21_2)) { + this.onGround = buf.readBoolean(); + } else { + int flags = buf.readUnsignedByte(); + this.onGround = (flags & 1) != 0; + this.collideHorizontally = (flags & 2) != 0; + } } @Override @@ -68,6 +76,7 @@ public String toString() { + ", yaw=" + this.yaw + ", pitch=" + this.pitch + ", onGround=" + this.onGround + + ", collideHorizontally=" + this.collideHorizontally + "}"; } @@ -82,4 +91,8 @@ public float getPitch() { public boolean isOnGround() { return this.onGround; } + + public boolean isCollideHorizontally() { + return this.collideHorizontally; + } } diff --git a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/PositionRotationPacket.java b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/PositionRotationPacket.java index d775d8cf..da343d3c 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/PositionRotationPacket.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/PositionRotationPacket.java @@ -59,7 +59,34 @@ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi throw new IllegalStateException(); } + @Override public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) { + if (protocolVersion.noLessThan(ProtocolVersion.MINECRAFT_1_21_2)) { + this.encodeModern(buf, protocolVersion); + } else { + this.encodeLegacy(buf, protocolVersion); + } + } + + public void encodeModern(ByteBuf buf, ProtocolVersion protocolVersion) { + ProtocolUtils.writeVarInt(buf, this.teleportID); + + buf.writeDouble(this.posX); + buf.writeDouble(this.posY); + buf.writeDouble(this.posZ); + + // velocity + buf.writeDouble(0); + buf.writeDouble(0); + buf.writeDouble(0); + + buf.writeFloat(this.yaw); + buf.writeFloat(this.pitch); + + buf.writeInt(0); // not relative + } + + public void encodeLegacy(ByteBuf buf, ProtocolVersion protocolVersion) { buf.writeDouble(this.posX); buf.writeDouble(this.posY); buf.writeDouble(this.posZ); diff --git a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/SetSlotPacket.java b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/SetSlotPacket.java index 13258561..ab338a5b 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/SetSlotPacket.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/SetSlotPacket.java @@ -24,6 +24,7 @@ import io.netty.buffer.ByteBuf; import net.elytrium.limboapi.api.material.VirtualItem; import net.elytrium.limboapi.api.protocol.item.ItemComponentMap; +import net.elytrium.limboapi.utils.ProtocolTools; import net.kyori.adventure.nbt.CompoundBinaryTag; import org.checkerframework.checker.nullness.qual.Nullable; @@ -69,7 +70,7 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi } public void encodeModern(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) { - buf.writeByte(this.windowID); + ProtocolTools.writeContainerId(buf, protocolVersion, this.windowID); ProtocolUtils.writeVarInt(buf, 0); buf.writeShort(this.slot); diff --git a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/TimeUpdatePacket.java b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/TimeUpdatePacket.java index e0dd09a5..15d08b98 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/TimeUpdatePacket.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/TimeUpdatePacket.java @@ -46,6 +46,10 @@ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) { buf.writeLong(this.worldAge); buf.writeLong(this.timeOfDay); + + if (protocolVersion.noLessThan(ProtocolVersion.MINECRAFT_1_21_2)) { + buf.writeBoolean(false); // no ticking + } } @Override diff --git a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/UpdateTagsPacket.java b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/UpdateTagsPacket.java index 55658f21..05fdcc8c 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/UpdateTagsPacket.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/UpdateTagsPacket.java @@ -22,7 +22,7 @@ import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; import io.netty.buffer.ByteBuf; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -40,9 +40,9 @@ public UpdateTagsPacket(Map>> tags) { } public Map> toVelocityTags() { - Map> newTags = new HashMap<>(); + Map> newTags = new LinkedHashMap<>(); for (Entry>> entry : this.tags.entrySet()) { - Map tagRegistry = new HashMap<>(); + Map tagRegistry = new LinkedHashMap<>(); for (Entry> tagEntry : entry.getValue().entrySet()) { tagRegistry.put(tagEntry.getKey(), diff --git a/plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java b/plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java index 52416e6e..5b7dff2e 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java +++ b/plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java @@ -195,6 +195,8 @@ protected void refresh() { JoinGamePacket joinGame1191 = this.createJoinGamePacket(ProtocolVersion.MINECRAFT_1_19_1); JoinGamePacket joinGame1194 = this.createJoinGamePacket(ProtocolVersion.MINECRAFT_1_19_4); JoinGamePacket joinGame120 = this.createJoinGamePacket(ProtocolVersion.MINECRAFT_1_20); + JoinGamePacket joinGame121 = this.createJoinGamePacket(ProtocolVersion.MINECRAFT_1_21); + JoinGamePacket joinGame1212 = this.createJoinGamePacket(ProtocolVersion.MINECRAFT_1_21_2); final PreparedPacket joinPackets = this.plugin.createPreparedPacket() .prepare(legacyJoinGame, ProtocolVersion.MINIMUM_VERSION, ProtocolVersion.MINECRAFT_1_15_2) @@ -204,7 +206,9 @@ protected void refresh() { .prepare(joinGame119, ProtocolVersion.MINECRAFT_1_19, ProtocolVersion.MINECRAFT_1_19) .prepare(joinGame1191, ProtocolVersion.MINECRAFT_1_19_1, ProtocolVersion.MINECRAFT_1_19_3) .prepare(joinGame1194, ProtocolVersion.MINECRAFT_1_19_4, ProtocolVersion.MINECRAFT_1_19_4) - .prepare(joinGame120, ProtocolVersion.MINECRAFT_1_20); + .prepare(joinGame120, ProtocolVersion.MINECRAFT_1_20, ProtocolVersion.MINECRAFT_1_20_5) + .prepare(joinGame121, ProtocolVersion.MINECRAFT_1_21, ProtocolVersion.MINECRAFT_1_21) + .prepare(joinGame1212, ProtocolVersion.MINECRAFT_1_21_2); PreparedPacket fastRejoinPackets = this.plugin.createPreparedPacket(); this.createFastClientServerSwitch(legacyJoinGame, ProtocolVersion.MINECRAFT_1_7_2) @@ -222,7 +226,11 @@ protected void refresh() { this.createFastClientServerSwitch(joinGame1194, ProtocolVersion.MINECRAFT_1_19_4) .forEach(minecraftPacket -> fastRejoinPackets.prepare(minecraftPacket, ProtocolVersion.MINECRAFT_1_19_4, ProtocolVersion.MINECRAFT_1_19_4)); this.createFastClientServerSwitch(joinGame120, ProtocolVersion.MINECRAFT_1_20) - .forEach(minecraftPacket -> fastRejoinPackets.prepare(minecraftPacket, ProtocolVersion.MINECRAFT_1_20)); + .forEach(minecraftPacket -> fastRejoinPackets.prepare(minecraftPacket, ProtocolVersion.MINECRAFT_1_20, ProtocolVersion.MINECRAFT_1_20_5)); + this.createFastClientServerSwitch(joinGame121, ProtocolVersion.MINECRAFT_1_21) + .forEach(minecraftPacket -> fastRejoinPackets.prepare(minecraftPacket, ProtocolVersion.MINECRAFT_1_21, ProtocolVersion.MINECRAFT_1_21)); + this.createFastClientServerSwitch(joinGame1212, ProtocolVersion.MINECRAFT_1_21_2) + .forEach(minecraftPacket -> fastRejoinPackets.prepare(minecraftPacket, ProtocolVersion.MINECRAFT_1_21_2)); this.joinPackets = this.addPostJoin(joinPackets); this.fastRejoinPackets = this.addPostJoin(fastRejoinPackets); @@ -236,7 +244,8 @@ protected void refresh() { PreparedPacket configPackets = this.plugin.createConfigPreparedPacket(); configPackets.prepare(this::createRegistrySyncLegacy, ProtocolVersion.MINECRAFT_1_20_2, ProtocolVersion.MINECRAFT_1_20_3); this.createRegistrySyncModern(configPackets, ProtocolVersion.MINECRAFT_1_20_5, ProtocolVersion.MINECRAFT_1_20_5); - this.createRegistrySyncModern(configPackets, ProtocolVersion.MINECRAFT_1_21, ProtocolVersion.MAXIMUM_VERSION); + this.createRegistrySyncModern(configPackets, ProtocolVersion.MINECRAFT_1_21, ProtocolVersion.MINECRAFT_1_21); + this.createRegistrySyncModern(configPackets, ProtocolVersion.MINECRAFT_1_21_2, ProtocolVersion.MAXIMUM_VERSION); if (this.shouldUpdateTags) { configPackets.prepare(this::createTagsUpdate, ProtocolVersion.MINECRAFT_1_20_2); } @@ -307,7 +316,7 @@ private void createRegistrySyncModern(PreparedPacket packet, ProtocolVersion fro for (int i = 0; i < tags.length; i++) { if (tags[i] == null) { - tags[i] = emptyTag; + tags[i] = Pair.of("limboapi_padding_" + i, emptyTag.value()); } } @@ -544,7 +553,7 @@ protected void onSpawn(Class handlerClass, MinecraftConnection connection, ConnectedPlayer player, LimboSessionHandlerImpl sessionHandler) { if (this.plugin.isLimboJoined(player)) { if (this.shouldRejoin) { - sessionHandler.setMitigateChatSessionDesync(true); + sessionHandler.setJoinGameTriggered(true); if (connection.getType() == ConnectionTypes.LEGACY_FORGE) { connection.delayedWrite(this.safeRejoinPackets); } else { @@ -554,7 +563,7 @@ protected void onSpawn(Class handlerClass, connection.delayedWrite(this.postJoinPackets); } } else { - sessionHandler.setMitigateChatSessionDesync(true); + sessionHandler.setJoinGameTriggered(true); connection.delayedWrite(this.joinPackets); } @@ -942,12 +951,22 @@ private JoinGamePacket createJoinGamePacket(ProtocolVersion version) { tags.add((CompoundBinaryTag) tag); } - CompoundBinaryTag.Builder campfileType = CompoundBinaryTag.builder() - .putString("name", "minecraft:campfire") - .putInt("id", values.size()) - .put("element", values.getCompound(0).getCompound("element")); + String[] types; + if (version.compareTo(ProtocolVersion.MINECRAFT_1_21_2) >= 0) { + types = new String[] { "minecraft:campfire", "minecraft:ender_pearl", "minecraft:mace_smash" }; + } else { + types = new String[] { "minecraft:campfire" }; + } - tags.add(campfileType.build()); + int id = values.size(); + for (String name : types) { + CompoundBinaryTag.Builder type = CompoundBinaryTag.builder() + .putString("name", name) + .putInt("id", id++) + .put("element", values.getCompound(0).getCompound("element")); + + tags.add(type.build()); + } registryContainer.put("minecraft:damage_type", this.createRegistry("minecraft:damage_type", tags.build())); } else if (version.compareTo(ProtocolVersion.MINECRAFT_1_20) >= 0) { diff --git a/plugin/src/main/java/net/elytrium/limboapi/server/LimboSessionHandlerImpl.java b/plugin/src/main/java/net/elytrium/limboapi/server/LimboSessionHandlerImpl.java index c2b61e31..be8c91cf 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/server/LimboSessionHandlerImpl.java +++ b/plugin/src/main/java/net/elytrium/limboapi/server/LimboSessionHandlerImpl.java @@ -97,7 +97,7 @@ public class LimboSessionHandlerImpl implements MinecraftSessionHandler { private boolean loaded; private boolean switching; private boolean disconnecting; - private boolean mitigateChatSessionDesync; + private boolean joinGameTriggered; public LimboSessionHandlerImpl(LimboAPI plugin, LimboImpl limbo, ConnectedPlayer player, LimboSessionHandler callback, StateRegistry originalState, MinecraftSessionHandler originalHandler, @@ -181,10 +181,8 @@ public void disconnectToConfig(Runnable runnable) { this.switching = true; this.loaded = false; - if (this.player.isOnlineMode() && this.mitigateChatSessionDesync) { - // As a client sends PlayerChatSessionPacket asynchronously, - // we should wait for it to ensure that it will not be sent - // while switching CONFIG to PLAY state, and so didn't break the connection + if (this.player.isOnlineMode() && this.player.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_21_2) && this.joinGameTriggered) { + // There is a race condition in the client then it reconnects too quickly (https://bugs.mojang.com/browse/MC-272506) if (!this.chatSession.isDone() && this.chatSessionTimeoutTask == null) { this.chatSessionTimeoutTask = this.player.getConnection().eventLoop() .schedule(() -> this.chatSession.complete(this), Settings.IMP.MAIN.CHAT_SESSION_PACKET_TIMEOUT, TimeUnit.MILLISECONDS); @@ -471,8 +469,8 @@ public int getPing() { return this.ping; } - public void setMitigateChatSessionDesync(boolean mitigateChatSessionDesync) { - this.mitigateChatSessionDesync = mitigateChatSessionDesync; + public void setJoinGameTriggered(boolean joinGameTriggered) { + this.joinGameTriggered = joinGameTriggered; } public void setRespawnTask(ScheduledFuture respawnTask) { diff --git a/plugin/src/main/java/net/elytrium/limboapi/utils/ProtocolTools.java b/plugin/src/main/java/net/elytrium/limboapi/utils/ProtocolTools.java new file mode 100644 index 00000000..4add52f2 --- /dev/null +++ b/plugin/src/main/java/net/elytrium/limboapi/utils/ProtocolTools.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 - 2024 Elytrium + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package net.elytrium.limboapi.utils; + +import com.velocitypowered.api.network.ProtocolVersion; +import com.velocitypowered.proxy.protocol.ProtocolUtils; +import io.netty.buffer.ByteBuf; + +public class ProtocolTools { + + public static void writeContainerId(ByteBuf buf, ProtocolVersion version, int id) { + if (version.noLessThan(ProtocolVersion.MINECRAFT_1_21_2)) { + ProtocolUtils.writeVarInt(buf, id); + } else { + buf.writeByte(id); + } + } + + public static int readContainerId(ByteBuf buf, ProtocolVersion version) { + if (version.noLessThan(ProtocolVersion.MINECRAFT_1_21_2)) { + return ProtocolUtils.readVarInt(buf); + } else { + return buf.readUnsignedByte(); + } + } +}