From 982aa768c51b1ceba72b1fe01ef2cdd2231de033 Mon Sep 17 00:00:00 2001 From: UserNugget Date: Mon, 30 Jun 2025 23:53:10 +0300 Subject: [PATCH 1/6] Throw proper exception then getting item id for an unsupported version --- .../net/elytrium/limboapi/server/world/SimpleItem.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugin/src/main/java/net/elytrium/limboapi/server/world/SimpleItem.java b/plugin/src/main/java/net/elytrium/limboapi/server/world/SimpleItem.java index a4ccb3b4..cb860b1f 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/server/world/SimpleItem.java +++ b/plugin/src/main/java/net/elytrium/limboapi/server/world/SimpleItem.java @@ -52,7 +52,12 @@ public short getID(ProtocolVersion version) { @Override public short getID(WorldVersion version) { - return this.versionIDs.get(version); + Short result = this.versionIDs.get(version); + if (result == null) { + throw new IllegalArgumentException("Item " + this.modernId + " does not exists on " + version); + } + + return result; } @Override From ad8610672eded23ef44924f34908b4ef7c175372 Mon Sep 17 00:00:00 2001 From: UserNugget Date: Tue, 30 Sep 2025 13:09:23 +0300 Subject: [PATCH 2/6] Initial 1.21.9 support --- .../api/chunk/BlockEntityVersion.java | 3 +- .../limboapi/api/material/WorldVersion.java | 3 +- .../api/protocol/packets/PacketFactory.java | 2 + plugin/build.gradle | 10 ++- plugin/mapping/fallbackdata.json | 64 +++++++++++++++++++ .../java/net/elytrium/limboapi/LimboAPI.java | 2 +- .../java/net/elytrium/limboapi/Settings.java | 2 +- .../limboapi/protocol/LimboProtocol.java | 33 ++++++---- .../protocol/packets/PacketFactoryImpl.java | 7 +- .../s2c/DefaultSpawnPositionPacket.java | 29 ++++++--- .../elytrium/limboapi/server/LimboImpl.java | 3 +- .../mapping/modern_block_id_remap.json | 3 +- 12 files changed, 131 insertions(+), 30 deletions(-) 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 f134e8e4..58d7dfcf 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 @@ -30,7 +30,8 @@ public enum BlockEntityVersion { MINECRAFT_1_21_4(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_4)), MINECRAFT_1_21_5(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_5)), MINECRAFT_1_21_6(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_6)), - MINECRAFT_1_21_7(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_7)); + MINECRAFT_1_21_7(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_7)), + MINECRAFT_1_21_9(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_9)); private static final EnumMap MC_VERSION_TO_ITEM_VERSIONS = new EnumMap<>(ProtocolVersion.class); private static final Map KEY_LOOKUP = Map.copyOf(EnumUniverse.createProtocolLookup(values())); 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 b87c8947..dbfab3ca 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 @@ -34,7 +34,8 @@ public enum WorldVersion { MINECRAFT_1_21_4(ProtocolVersion.MINECRAFT_1_21_4), MINECRAFT_1_21_5(ProtocolVersion.MINECRAFT_1_21_5), MINECRAFT_1_21_6(ProtocolVersion.MINECRAFT_1_21_6), - MINECRAFT_1_21_7(EnumSet.range(ProtocolVersion.MINECRAFT_1_21_7, ProtocolVersion.MAXIMUM_VERSION)); + MINECRAFT_1_21_7(ProtocolVersion.MINECRAFT_1_21_7), + MINECRAFT_1_21_9(EnumSet.range(ProtocolVersion.MINECRAFT_1_21_9, ProtocolVersion.MAXIMUM_VERSION)); private static final EnumMap MC_VERSION_TO_ITEM_VERSIONS = new EnumMap<>(ProtocolVersion.class); private static final Map KEY_LOOKUP = Map.copyOf(EnumUniverse.createProtocolLookup(values())); diff --git a/api/src/main/java/net/elytrium/limboapi/api/protocol/packets/PacketFactory.java b/api/src/main/java/net/elytrium/limboapi/api/protocol/packets/PacketFactory.java index bc0529d0..a7851720 100644 --- a/api/src/main/java/net/elytrium/limboapi/api/protocol/packets/PacketFactory.java +++ b/api/src/main/java/net/elytrium/limboapi/api/protocol/packets/PacketFactory.java @@ -32,6 +32,8 @@ public interface PacketFactory { Object createDefaultSpawnPositionPacket(int posX, int posY, int posZ, float angle); + Object createDefaultSpawnPositionPacket(String dimension, int posX, int posY, int posZ, float yaw, float pitch); + Object createMapDataPacket(int mapID, byte scale, MapData mapData); /** diff --git a/plugin/build.gradle b/plugin/build.gradle index fad45c8c..ddd091a5 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -133,7 +133,8 @@ enum MinecraftVersion { MINECRAFT_1_21_4(769), MINECRAFT_1_21_5(770), MINECRAFT_1_21_6(771), - MINECRAFT_1_21_7(772) + MINECRAFT_1_21_7(772), + MINECRAFT_1_21_9(773) public static final List WORLD_VERSIONS = List.of( MINECRAFT_1_13, @@ -153,7 +154,8 @@ enum MinecraftVersion { MINECRAFT_1_21_4, MINECRAFT_1_21_5, MINECRAFT_1_21_6, - MINECRAFT_1_21_7 + MINECRAFT_1_21_7, + MINECRAFT_1_21_9 ) public static final MinecraftVersion MINIMUM_VERSION = MINECRAFT_1_7_2 @@ -212,7 +214,9 @@ File downloadVersionManifest(String version) { this.println("> Downloading ${version} manifest...") Object manifest = new JsonSlurper().parse(versionManifestFile) - def optional = manifest.versions.stream().filter({ it.id == version }).findFirst() + + // TODO: remove + def optional = manifest.versions.stream().filter({ version == "1.21.9" ? it.id == version + "-rc1" : it.id == version }).findFirst() if (optional.empty()) { throw new RuntimeException("Couldn't find version: ${version}") } diff --git a/plugin/mapping/fallbackdata.json b/plugin/mapping/fallbackdata.json index 6748259d..0a57e4f9 100755 --- a/plugin/mapping/fallbackdata.json +++ b/plugin/mapping/fallbackdata.json @@ -1,4 +1,68 @@ { + "MINECRAFT_1_21_7": { + "minecraft:acacia_shelf": "minecraft:acacia_planks", + "minecraft:bamboo_shelf": "minecraft:bamboo_planks", + "minecraft:birch_shelf": "minecraft:birch_planks", + "minecraft:cherry_shelf": "minecraft:cherry_planks", + "minecraft:crimson_shelf": "minecraft:crimson_planks", + "minecraft:dark_oak_shelf": "minecraft:dark_oak_planks", + "minecraft:jungle_shelf": "minecraft:jungle_planks", + "minecraft:mangrove_shelf": "minecraft:mangrove_planks", + "minecraft:oak_shelf": "minecraft:oak_planks", + "minecraft:pale_oak_shelf": "minecraft:oak_planks", + "minecraft:spruce_shelf": "minecraft:spruce_planks", + "minecraft:warped_shelf": "minecraft:warped_planks", + "minecraft:copper_chest": "minecraft:chest", + "minecraft:exposed_copper_chest": "minecraft:chest", + "minecraft:weathered_copper_chest": "minecraft:chest", + "minecraft:oxidized_copper_chest": "minecraft:chest", + "minecraft:waxed_copper_chest": "minecraft:chest", + "minecraft:waxed_exposed_copper_chest": "minecraft:chest", + "minecraft:waxed_weathered_copper_chest": "minecraft:chest", + "minecraft:waxed_oxidized_copper_chest": "minecraft:chest", + "minecraft:copper_golem_statue": "minecraft:copper_block", + "minecraft:exposed_copper_golem_statue": "minecraft:copper_block", + "minecraft:weathered_copper_golem_statue": "minecraft:copper_block", + "minecraft:oxidized_copper_golem_statue": "minecraft:copper_block", + "minecraft:waxed_copper_golem_statue": "minecraft:copper_block", + "minecraft:waxed_exposed_copper_golem_statue": "minecraft:copper_block", + "minecraft:waxed_weathered_copper_golem_statue": "minecraft:copper_block", + "minecraft:waxed_oxidized_copper_golem_statue": "minecraft:copper_block", + "minecraft:exposed_lightning_rod": "minecraft:lightning_rod", + "minecraft:weathered_lightning_rod": "minecraft:lightning_rod", + "minecraft:oxidized_lightning_rod": "minecraft:lightning_rod", + "minecraft:waxed_lightning_rod": "minecraft:lightning_rod", + "minecraft:waxed_exposed_lightning_rod": "minecraft:lightning_rod", + "minecraft:waxed_weathered_lightning_rod": "minecraft:lightning_rod", + "minecraft:waxed_oxidized_lightning_rod": "minecraft:lightning_rod", + "minecraft:copper_torch": "minecraft:soul_torch", + "minecraft:copper_wall_torch": "minecraft:soul_wall_torch", + "minecraft:copper_bars": "minecraft:iron_bars", + "minecraft:exposed_copper_bars": "minecraft:iron_bars", + "minecraft:weathered_copper_bars": "minecraft:iron_bars", + "minecraft:oxidized_copper_bars": "minecraft:iron_bars", + "minecraft:waxed_copper_bars": "minecraft:iron_bars", + "minecraft:waxed_exposed_copper_bars": "minecraft:iron_bars", + "minecraft:waxed_weathered_copper_bars": "minecraft:iron_bars", + "minecraft:waxed_oxidized_copper_bars": "minecraft:iron_bars", + "minecraft:copper_chain": "minecraft:chain", + "minecraft:exposed_copper_chain": "minecraft:chain", + "minecraft:weathered_copper_chain": "minecraft:chain", + "minecraft:oxidized_copper_chain": "minecraft:chain", + "minecraft:waxed_copper_chain": "minecraft:chain", + "minecraft:waxed_exposed_copper_chain": "minecraft:chain", + "minecraft:waxed_weathered_copper_chain": "minecraft:chain", + "minecraft:waxed_oxidized_copper_chain": "minecraft:chain", + "minecraft:copper_lantern": "minecraft:soul_lantern", + "minecraft:exposed_copper_lantern": "minecraft:soul_lantern", + "minecraft:weathered_copper_lantern": "minecraft:soul_lantern", + "minecraft:oxidized_copper_lantern": "minecraft:soul_lantern", + "minecraft:waxed_copper_lantern": "minecraft:soul_lantern", + "minecraft:waxed_exposed_copper_lantern": "minecraft:soul_lantern", + "minecraft:waxed_weathered_copper_lantern": "minecraft:soul_lantern", + "minecraft:waxed_oxidized_copper_lantern": "minecraft:soul_lantern", + "minecraft:iron_chain": "minecraft:chain" + }, "MINECRAFT_1_21_5": { "minecraft:dried_ghast": "minecraft:chorus_plant" }, diff --git a/plugin/src/main/java/net/elytrium/limboapi/LimboAPI.java b/plugin/src/main/java/net/elytrium/limboapi/LimboAPI.java index 9df390e9..d7b219b0 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 = 772; + private static final int SUPPORTED_MAXIMUM_PROTOCOL_VERSION_NUMBER = 773; @MonotonicNonNull private static Logger LOGGER; diff --git a/plugin/src/main/java/net/elytrium/limboapi/Settings.java b/plugin/src/main/java/net/elytrium/limboapi/Settings.java index e486d881..a36ce09f 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/Settings.java +++ b/plugin/src/main/java/net/elytrium/limboapi/Settings.java @@ -87,7 +87,7 @@ public static class MAIN { "1_7_2, 1_7_6, 1_8, 1_9, 1_9_1, 1_9_2, 1_9_4, 1_10, 1_11, 1_11_1, 1_12, 1_12_1, 1_12_2,", "1_13, 1_13_1, 1_13_2, 1_14, 1_14_1, 1_14_2, 1_14_3, 1_14_4, 1_15, 1_15_1, 1_15_2,", "1_16, 1_16_1, 1_16_2, 1_16_3, 1_16_4, 1_17, 1_17_1, 1_18, 1_18_2, 1_19, 1_19_1, 1_19_3,", - "1_20, 1_20_2, 1_20_3, 1_20_5, 1_21, 1_21_2, 1_21_4, 1_21_5, 1_21_6, 1_21_7, LATEST" + "1_20, 1_20_2, 1_20_3, 1_20_5, 1_21, 1_21_2, 1_21_4, 1_21_5, 1_21_6, 1_21_7, 1_21_9, LATEST" }) public String PREPARE_MIN_VERSION = "1_7_2"; public String PREPARE_MAX_VERSION = "LATEST"; 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 c4666ceb..824defc8 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/LimboProtocol.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/LimboProtocol.java @@ -197,7 +197,8 @@ public static void init() throws Throwable { createMapping(0x20, ProtocolVersion.MINECRAFT_1_20_2, true), createMapping(0x22, ProtocolVersion.MINECRAFT_1_20_5, true), createMapping(0x23, ProtocolVersion.MINECRAFT_1_21_2, true), - createMapping(0x22, ProtocolVersion.MINECRAFT_1_21_5, true) + createMapping(0x22, ProtocolVersion.MINECRAFT_1_21_5, true), + createMapping(0x26, ProtocolVersion.MINECRAFT_1_21_9, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, ChunkDataPacket.class, ChunkDataPacket::new, @@ -216,7 +217,8 @@ public static void init() throws Throwable { createMapping(0x25, ProtocolVersion.MINECRAFT_1_20_2, true), createMapping(0x27, ProtocolVersion.MINECRAFT_1_20_5, true), createMapping(0x28, ProtocolVersion.MINECRAFT_1_21_2, true), - createMapping(0x27, ProtocolVersion.MINECRAFT_1_21_5, true) + createMapping(0x27, ProtocolVersion.MINECRAFT_1_21_5, true), + createMapping(0x2C, ProtocolVersion.MINECRAFT_1_21_9, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, ChunkUnloadPacket.class, ChunkUnloadPacket::new, @@ -236,7 +238,8 @@ public static void init() throws Throwable { createMapping(0x1F, ProtocolVersion.MINECRAFT_1_20_2, true), createMapping(0x21, ProtocolVersion.MINECRAFT_1_20_5, true), createMapping(0x22, ProtocolVersion.MINECRAFT_1_21_2, true), - createMapping(0x21, ProtocolVersion.MINECRAFT_1_21_5, true) + createMapping(0x21, ProtocolVersion.MINECRAFT_1_21_5, true), + createMapping(0x25, ProtocolVersion.MINECRAFT_1_21_9, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, DefaultSpawnPositionPacket.class, DefaultSpawnPositionPacket::new, @@ -257,7 +260,8 @@ public static void init() throws Throwable { createMapping(0x54, ProtocolVersion.MINECRAFT_1_20_3, true), createMapping(0x56, ProtocolVersion.MINECRAFT_1_20_5, true), createMapping(0x5B, ProtocolVersion.MINECRAFT_1_21_2, true), - createMapping(0x5A, ProtocolVersion.MINECRAFT_1_21_5, true) + createMapping(0x5A, ProtocolVersion.MINECRAFT_1_21_5, true), + createMapping(0x5F, ProtocolVersion.MINECRAFT_1_21_9, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, MapDataPacket.class, MapDataPacket::new, @@ -275,7 +279,8 @@ public static void init() throws Throwable { createMapping(0x2A, ProtocolVersion.MINECRAFT_1_20_2, true), createMapping(0x2C, ProtocolVersion.MINECRAFT_1_20_5, true), createMapping(0x2D, ProtocolVersion.MINECRAFT_1_21_2, true), - createMapping(0x2C, ProtocolVersion.MINECRAFT_1_21_5, true) + createMapping(0x2C, ProtocolVersion.MINECRAFT_1_21_5, true), + createMapping(0x31, ProtocolVersion.MINECRAFT_1_21_9, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, PlayerAbilitiesPacket.class, PlayerAbilitiesPacket::new, @@ -295,7 +300,8 @@ public static void init() throws Throwable { createMapping(0x36, ProtocolVersion.MINECRAFT_1_20_2, true), createMapping(0x38, ProtocolVersion.MINECRAFT_1_20_5, true), createMapping(0x3A, ProtocolVersion.MINECRAFT_1_21_2, true), - createMapping(0x39, ProtocolVersion.MINECRAFT_1_21_5, true) + createMapping(0x39, ProtocolVersion.MINECRAFT_1_21_5, true), + createMapping(0x3E, ProtocolVersion.MINECRAFT_1_21_9, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, PositionRotationPacket.class, PositionRotationPacket::new, @@ -315,7 +321,8 @@ public static void init() throws Throwable { createMapping(0x3E, ProtocolVersion.MINECRAFT_1_20_2, true), createMapping(0x40, ProtocolVersion.MINECRAFT_1_20_5, true), createMapping(0x42, ProtocolVersion.MINECRAFT_1_21_2, true), - createMapping(0x41, ProtocolVersion.MINECRAFT_1_21_5, true) + createMapping(0x41, ProtocolVersion.MINECRAFT_1_21_5, true), + createMapping(0x46, ProtocolVersion.MINECRAFT_1_21_9, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, SetExperiencePacket.class, SetExperiencePacket::new, @@ -334,7 +341,8 @@ public static void init() throws Throwable { createMapping(0x5A, ProtocolVersion.MINECRAFT_1_20_3, true), createMapping(0x5C, ProtocolVersion.MINECRAFT_1_20_5, true), createMapping(0x61, ProtocolVersion.MINECRAFT_1_21_2, true), - createMapping(0x60, ProtocolVersion.MINECRAFT_1_21_5, true) + createMapping(0x60, ProtocolVersion.MINECRAFT_1_21_5, true), + createMapping(0x65, ProtocolVersion.MINECRAFT_1_21_9, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, SetSlotPacket.class, SetSlotPacket::new, @@ -371,7 +379,8 @@ public static void init() throws Throwable { createMapping(0x62, ProtocolVersion.MINECRAFT_1_20_3, true), createMapping(0x64, ProtocolVersion.MINECRAFT_1_20_5, true), createMapping(0x6B, ProtocolVersion.MINECRAFT_1_21_2, true), - createMapping(0x6A, ProtocolVersion.MINECRAFT_1_21_5, true) + createMapping(0x6A, ProtocolVersion.MINECRAFT_1_21_5, true), + createMapping(0x6F, ProtocolVersion.MINECRAFT_1_21_9, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, UpdateViewPositionPacket.class, UpdateViewPositionPacket::new, // ViewCentre, ChunkRenderDistanceCenter @@ -387,7 +396,8 @@ public static void init() throws Throwable { createMapping(0x52, ProtocolVersion.MINECRAFT_1_20_3, true), createMapping(0x54, ProtocolVersion.MINECRAFT_1_20_5, true), createMapping(0x58, ProtocolVersion.MINECRAFT_1_21_2, true), - createMapping(0x57, ProtocolVersion.MINECRAFT_1_21_5, true) + createMapping(0x57, ProtocolVersion.MINECRAFT_1_21_5, true), + createMapping(0x5C, ProtocolVersion.MINECRAFT_1_21_9, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.CLIENTBOUND, UpdateTagsPacket.class, UpdateTagsPacket::new, @@ -404,7 +414,8 @@ public static void init() throws Throwable { 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(0x7F, ProtocolVersion.MINECRAFT_1_21_2, true) + createMapping(0x7F, ProtocolVersion.MINECRAFT_1_21_2, true), + createMapping(0x84, ProtocolVersion.MINECRAFT_1_21_9, true) ); register(LIMBO_STATE_REGISTRY, PacketDirection.SERVERBOUND, diff --git a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/PacketFactoryImpl.java b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/PacketFactoryImpl.java index c161d8db..ffff7b38 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/PacketFactoryImpl.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/PacketFactoryImpl.java @@ -67,7 +67,12 @@ public Object createChunkUnloadPacket(int posX, int posZ) { @Override public Object createDefaultSpawnPositionPacket(int posX, int posY, int posZ, float angle) { - return new DefaultSpawnPositionPacket(posX, posY, posZ, angle); + return new DefaultSpawnPositionPacket(Dimension.OVERWORLD.getKey(), posX, posY, posZ, angle, 0); + } + + @Override + public Object createDefaultSpawnPositionPacket(String dimension, int posX, int posY, int posZ, float yaw, float pitch) { + return new DefaultSpawnPositionPacket(dimension, posX, posY, posZ, yaw, pitch); } @Override diff --git a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/DefaultSpawnPositionPacket.java b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/DefaultSpawnPositionPacket.java index 21c574ea..c97dcb72 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/DefaultSpawnPositionPacket.java +++ b/plugin/src/main/java/net/elytrium/limboapi/protocol/packets/s2c/DefaultSpawnPositionPacket.java @@ -25,16 +25,20 @@ public class DefaultSpawnPositionPacket implements MinecraftPacket { + private final String dimension; private final int posX; private final int posY; private final int posZ; - private final float angle; + private final float yaw; + private final float pitch; - public DefaultSpawnPositionPacket(int posX, int posY, int posZ, float angle) { + public DefaultSpawnPositionPacket(String dimension, int posX, int posY, int posZ, float yaw, float pitch) { + this.dimension = dimension; this.posX = posX; this.posY = posY; this.posZ = posZ; - this.angle = angle; + this.yaw = yaw; + this.pitch = pitch; } public DefaultSpawnPositionPacket() { @@ -48,7 +52,12 @@ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi @Override public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) { - if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_8) < 0) { + if (protocolVersion.noLessThan(ProtocolVersion.MINECRAFT_1_21_9)) { + ProtocolUtils.writeString(buf, this.dimension); + buf.writeLong(((this.posX & 0x3FFFFFFL) << 38) | ((this.posZ & 0x3FFFFFFL) << 12) | (this.posY & 0xFFFL)); + buf.writeFloat(this.yaw); + buf.writeFloat(this.pitch); + } else if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_8) < 0) { buf.writeInt(this.posX); buf.writeInt(this.posY); buf.writeInt(this.posZ); @@ -63,7 +72,7 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi buf.writeLong(location); if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) { - buf.writeFloat(this.angle); + buf.writeFloat(this.yaw); } } } @@ -75,11 +84,13 @@ public boolean handle(MinecraftSessionHandler handler) { @Override public String toString() { - return "DefaultSpawnPosition{" - + "posX=" + this.posX + return "DefaultSpawnPositionPacket{" + + "dimension='" + this.dimension + '\'' + + ", posX=" + this.posX + ", posY=" + this.posY + ", posZ=" + this.posZ - + ", angle=" + this.angle - + "}"; + + ", yaw=" + this.yaw + + ", pitch=" + this.pitch + + '}'; } } 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 53ffad05..784e263c 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java +++ b/plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java @@ -1095,7 +1095,8 @@ private JoinGamePacket createLegacyJoinGamePacket() { } private DefaultSpawnPositionPacket createDefaultSpawnPositionPacket() { - return new DefaultSpawnPositionPacket((int) this.world.getSpawnX(), (int) this.world.getSpawnY(), (int) this.world.getSpawnZ(), 0.0F); + return new DefaultSpawnPositionPacket(this.world.getDimension().getKey(), + (int) this.world.getSpawnX(), (int) this.world.getSpawnY(), (int) this.world.getSpawnZ(), 0.0F, 0.0f); } private TimeUpdatePacket createWorldTicksPacket() { diff --git a/plugin/src/main/resources/mapping/modern_block_id_remap.json b/plugin/src/main/resources/mapping/modern_block_id_remap.json index b281fc06..a29bcb74 100644 --- a/plugin/src/main/resources/mapping/modern_block_id_remap.json +++ b/plugin/src/main/resources/mapping/modern_block_id_remap.json @@ -1,3 +1,4 @@ { - "minecraft:grass": "minecraft:short_grass" + "minecraft:grass": "minecraft:short_grass", + "minecraft:chain": "minecraft:iron_chain" } \ No newline at end of file From 6178739f1efb9c75f0ab73e75a50590a4179a245 Mon Sep 17 00:00:00 2001 From: UserNugget Date: Thu, 27 Nov 2025 12:06:33 +0300 Subject: [PATCH 3/6] Remove release candidate workaround --- plugin/build.gradle | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugin/build.gradle b/plugin/build.gradle index ddd091a5..b8ea6415 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -214,9 +214,7 @@ File downloadVersionManifest(String version) { this.println("> Downloading ${version} manifest...") Object manifest = new JsonSlurper().parse(versionManifestFile) - - // TODO: remove - def optional = manifest.versions.stream().filter({ version == "1.21.9" ? it.id == version + "-rc1" : it.id == version }).findFirst() + def optional = manifest.versions.stream().filter({ it.id == version }).findFirst() if (optional.empty()) { throw new RuntimeException("Couldn't find version: ${version}") } From dae7f3558c4881c503e37a5eaf82b3733f95da7c Mon Sep 17 00:00:00 2001 From: UserNugget Date: Tue, 9 Dec 2025 19:36:49 +0300 Subject: [PATCH 4/6] Initial 1.21.11 support --- .../limboapi/api/chunk/BlockEntityVersion.java | 3 ++- .../limboapi/api/material/WorldVersion.java | 3 ++- plugin/build.gradle | 10 +++++++--- .../main/java/net/elytrium/limboapi/LimboAPI.java | 2 +- .../main/java/net/elytrium/limboapi/Settings.java | 2 +- .../net/elytrium/limboapi/server/LimboImpl.java | 13 ++++++++++++- 6 files changed, 25 insertions(+), 8 deletions(-) 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 58d7dfcf..98a47778 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 @@ -31,7 +31,8 @@ public enum BlockEntityVersion { MINECRAFT_1_21_5(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_5)), MINECRAFT_1_21_6(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_6)), MINECRAFT_1_21_7(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_7)), - MINECRAFT_1_21_9(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_9)); + MINECRAFT_1_21_9(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_9)), + MINECRAFT_1_21_11(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_11)); private static final EnumMap MC_VERSION_TO_ITEM_VERSIONS = new EnumMap<>(ProtocolVersion.class); private static final Map KEY_LOOKUP = Map.copyOf(EnumUniverse.createProtocolLookup(values())); 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 dbfab3ca..29c83483 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 @@ -35,7 +35,8 @@ public enum WorldVersion { MINECRAFT_1_21_5(ProtocolVersion.MINECRAFT_1_21_5), MINECRAFT_1_21_6(ProtocolVersion.MINECRAFT_1_21_6), MINECRAFT_1_21_7(ProtocolVersion.MINECRAFT_1_21_7), - MINECRAFT_1_21_9(EnumSet.range(ProtocolVersion.MINECRAFT_1_21_9, ProtocolVersion.MAXIMUM_VERSION)); + MINECRAFT_1_21_9(ProtocolVersion.MINECRAFT_1_21_9), + MINECRAFT_1_21_11(EnumSet.range(ProtocolVersion.MINECRAFT_1_21_11, ProtocolVersion.MAXIMUM_VERSION)); private static final EnumMap MC_VERSION_TO_ITEM_VERSIONS = new EnumMap<>(ProtocolVersion.class); private static final Map KEY_LOOKUP = Map.copyOf(EnumUniverse.createProtocolLookup(values())); diff --git a/plugin/build.gradle b/plugin/build.gradle index b8ea6415..a73ca7a9 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -134,7 +134,8 @@ enum MinecraftVersion { MINECRAFT_1_21_5(770), MINECRAFT_1_21_6(771), MINECRAFT_1_21_7(772), - MINECRAFT_1_21_9(773) + MINECRAFT_1_21_9(773), + MINECRAFT_1_21_11(774) public static final List WORLD_VERSIONS = List.of( MINECRAFT_1_13, @@ -155,7 +156,8 @@ enum MinecraftVersion { MINECRAFT_1_21_5, MINECRAFT_1_21_6, MINECRAFT_1_21_7, - MINECRAFT_1_21_9 + MINECRAFT_1_21_9, + MINECRAFT_1_21_11 ) public static final MinecraftVersion MINIMUM_VERSION = MINECRAFT_1_7_2 @@ -214,7 +216,9 @@ File downloadVersionManifest(String version) { this.println("> Downloading ${version} manifest...") Object manifest = new JsonSlurper().parse(versionManifestFile) - def optional = manifest.versions.stream().filter({ it.id == version }).findFirst() + + // TODO: remove + def optional = manifest.versions.stream().filter({ version == "1.21.11" ? it.id == version + "-rc3" : it.id == version }).findFirst() if (optional.empty()) { throw new RuntimeException("Couldn't find version: ${version}") } diff --git a/plugin/src/main/java/net/elytrium/limboapi/LimboAPI.java b/plugin/src/main/java/net/elytrium/limboapi/LimboAPI.java index d7b219b0..3da3e35e 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 = 773; + private static final int SUPPORTED_MAXIMUM_PROTOCOL_VERSION_NUMBER = 774; @MonotonicNonNull private static Logger LOGGER; diff --git a/plugin/src/main/java/net/elytrium/limboapi/Settings.java b/plugin/src/main/java/net/elytrium/limboapi/Settings.java index a36ce09f..f2c58a23 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/Settings.java +++ b/plugin/src/main/java/net/elytrium/limboapi/Settings.java @@ -87,7 +87,7 @@ public static class MAIN { "1_7_2, 1_7_6, 1_8, 1_9, 1_9_1, 1_9_2, 1_9_4, 1_10, 1_11, 1_11_1, 1_12, 1_12_1, 1_12_2,", "1_13, 1_13_1, 1_13_2, 1_14, 1_14_1, 1_14_2, 1_14_3, 1_14_4, 1_15, 1_15_1, 1_15_2,", "1_16, 1_16_1, 1_16_2, 1_16_3, 1_16_4, 1_17, 1_17_1, 1_18, 1_18_2, 1_19, 1_19_1, 1_19_3,", - "1_20, 1_20_2, 1_20_3, 1_20_5, 1_21, 1_21_2, 1_21_4, 1_21_5, 1_21_6, 1_21_7, 1_21_9, LATEST" + "1_20, 1_20_2, 1_20_3, 1_20_5, 1_21, 1_21_2, 1_21_4, 1_21_5, 1_21_6, 1_21_7, 1_21_9, 1_21_11, LATEST" }) public String PREPARE_MIN_VERSION = "1_7_2"; public String PREPARE_MAX_VERSION = "LATEST"; 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 784e263c..5f5d07b5 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java +++ b/plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java @@ -246,7 +246,8 @@ protected void refresh() { this.createRegistrySyncModern(configPackets, ProtocolVersion.MINECRAFT_1_20_5, ProtocolVersion.MINECRAFT_1_20_5); this.createRegistrySyncModern(configPackets, ProtocolVersion.MINECRAFT_1_21, ProtocolVersion.MINECRAFT_1_21); this.createRegistrySyncModern(configPackets, ProtocolVersion.MINECRAFT_1_21_2, ProtocolVersion.MINECRAFT_1_21_4); - this.createRegistrySyncModern(configPackets, ProtocolVersion.MINECRAFT_1_21_5, ProtocolVersion.MAXIMUM_VERSION); + this.createRegistrySyncModern(configPackets, ProtocolVersion.MINECRAFT_1_21_5, ProtocolVersion.MINECRAFT_1_21_9); + this.createRegistrySyncModern(configPackets, ProtocolVersion.MINECRAFT_1_21_11, ProtocolVersion.MAXIMUM_VERSION); if (this.shouldUpdateTags) { configPackets.prepare(this::createTagsUpdate, ProtocolVersion.MINECRAFT_1_20_2); } @@ -1055,6 +1056,16 @@ private JoinGamePacket createJoinGamePacket(ProtocolVersion version) { registryContainer.put("minecraft:wolf_variant", this.createRegistry("minecraft:wolf_variant", Map.of("minecraft:ashen", wolfVariant.build()))); + + if (version.compareTo(ProtocolVersion.MINECRAFT_1_21_11) >= 0) { + // Zombie nautilus variant + CompoundBinaryTag zombieVariant = CompoundBinaryTag.builder() + .putString("asset_id", "minecraft:entity/nautilus/zombie_nautilus") + .put("spawn_conditions", ListBinaryTag.empty()).build(); + + registryContainer.put("minecraft:zombie_nautilus_variant", this.createRegistry("minecraft:zombie_nautilus_variant", + Map.of("minecraft:temperate", zombieVariant))); + } } else { CompoundBinaryTag.Builder wolfVariant = CompoundBinaryTag.builder() .putString("wild_texture", "minecraft:entity/wolf/wolf_ashen") From 9d834e0a9d438409208be127e5afb365decb552a Mon Sep 17 00:00:00 2001 From: UserNugget Date: Tue, 9 Dec 2025 20:10:07 +0300 Subject: [PATCH 5/6] Remove RC workaround --- plugin/build.gradle | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugin/build.gradle b/plugin/build.gradle index a73ca7a9..7a79f6dc 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -216,9 +216,7 @@ File downloadVersionManifest(String version) { this.println("> Downloading ${version} manifest...") Object manifest = new JsonSlurper().parse(versionManifestFile) - - // TODO: remove - def optional = manifest.versions.stream().filter({ version == "1.21.11" ? it.id == version + "-rc3" : it.id == version }).findFirst() + def optional = manifest.versions.stream().filter({ it.id == version }).findFirst() if (optional.empty()) { throw new RuntimeException("Couldn't find version: ${version}") } From 10bcd3c853d5f3a5166a1059bc20a365620ba284 Mon Sep 17 00:00:00 2001 From: UserNugget Date: Wed, 10 Dec 2025 19:31:34 +0300 Subject: [PATCH 6/6] Use new default settings for built-in dimensions --- .../elytrium/limboapi/server/LimboImpl.java | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) 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 5f5d07b5..9c516b1e 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java +++ b/plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java @@ -868,7 +868,7 @@ private CompoundBinaryTag createRegistry(String registryName, ListBinaryTag tags } private CompoundBinaryTag createDimensionData(Dimension dimension, ProtocolVersion version) { - CompoundBinaryTag details = CompoundBinaryTag.builder() + CompoundBinaryTag.Builder details = CompoundBinaryTag.builder() .putBoolean("natural", false) .putFloat("ambient_light", 0.0F) .putBoolean("shrunk", false) @@ -886,17 +886,49 @@ private CompoundBinaryTag createDimensionData(Dimension dimension, ProtocolVersi .putInt("min_y", 0) .putInt("height", 256) .putInt("monster_spawn_block_light_limit", 0) - .putInt("monster_spawn_light_level", 0) - .build(); + .putInt("monster_spawn_light_level", 0); + + if (version.compareTo(ProtocolVersion.MINECRAFT_1_21_11) >= 0) { + // TODO: use timelines? + switch (dimension) { + case OVERWORLD -> { + details.put("attributes", CompoundBinaryTag.builder() + .putString("minecraft:visual/cloud_color", "#ccffffff") + .putFloat("minecraft:visual/cloud_height", 192.33f) + .putString("minecraft:visual/fog_color", "#c0d8ff") + .putString("minecraft:visual/sky_color", "#78a7ff") + .build()); + } + case NETHER -> { + details.putString("cardinal_light", "nether"); + details.putString("skybox", "none"); + details.put("attributes", CompoundBinaryTag.builder() + .putFloat("minecraft:gameplay/sky_light_level", 4.0f) + .putFloat("minecraft:visual/fog_end_distance", 96.0f) + .putFloat("minecraft:visual/fog_start_distance", 10.0f) + .putString("minecraft:visual/sky_light_color", "#7a7aff") + .build()); + } + case THE_END -> { + details.putString("skybox", "end"); + details.put("attributes", CompoundBinaryTag.builder() + .putString("minecraft:visual/fog_color", "#181318") + .putString("minecraft:visual/sky_color", "#000000") + .putString("minecraft:visual/sky_light_color", "#e580ff") + .build()); + } + default -> throw new IllegalStateException("Unknown dimension: " + dimension); // Checkstyle madness + } + } if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) { return CompoundBinaryTag.builder() .putString("name", dimension.getKey()) .putInt("id", dimension.getModernID()) - .put("element", details) + .put("element", details.build()) .build(); } else { - return details.putString("name", dimension.getKey()); + return details.build().putString("name", dimension.getKey()); } }