Skip to content

Commit a432fae

Browse files
authored
1.21.6 update (#3475)
1 parent 8a5e59d commit a432fae

16 files changed

+200
-129
lines changed

build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ plugins {
1212
group = "com.comphenix.protocol"
1313
description = "Provides access to the Minecraft protocol"
1414

15-
val mcVersion = "1.21.5"
15+
val mcVersion = "1.21.6"
1616
val isSnapshot = version.toString().endsWith("-SNAPSHOT")
1717
val buildNumber = System.getenv("BUILD_NUMBER") ?: ""
1818
val isJenkins = buildNumber.isNotEmpty()
@@ -205,4 +205,4 @@ publishing {
205205
}
206206
}
207207
}
208-
}
208+
}

src/main/java/com/comphenix/protocol/PacketType.java

Lines changed: 68 additions & 60 deletions
Large diffs are not rendered by default.

src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,8 @@ public static Class<?> getChatComponentTextClass() {
685685
* @throws IllegalStateException If the class could not be found or deduced.
686686
*/
687687
public static Class<?> getChatSerializerClass() {
688-
return getMinecraftClass("network.chat.IChatBaseComponent$ChatSerializer", "network.chat.Component$Serializer", "IChatBaseComponent$ChatSerializer");
688+
return getMinecraftClass("network.chat.ComponentSerialization",
689+
"network.chat.IChatBaseComponent$ChatSerializer", "network.chat.Component$Serializer", "IChatBaseComponent$ChatSerializer");
689690
}
690691

691692
/**

src/main/java/com/comphenix/protocol/utility/MinecraftVersion.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
* @author Kristian
3737
*/
3838
public final class MinecraftVersion implements Comparable<MinecraftVersion>, Serializable {
39+
/**
40+
* Version 1.21.6 - chase the skies
41+
*/
42+
public static final MinecraftVersion v1_21_6 = new MinecraftVersion("1.21.6");
3943

4044
/**
4145
* Version 1.21.5 - spring to life drop
@@ -165,7 +169,7 @@ public final class MinecraftVersion implements Comparable<MinecraftVersion>, Ser
165169
/**
166170
* The latest release version of minecraft.
167171
*/
168-
public static final MinecraftVersion LATEST = v1_21_5;
172+
public static final MinecraftVersion LATEST = v1_21_6;
169173

170174
// used when serializing
171175
private static final long serialVersionUID = -8695133558996459770L;

src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.util.Set;
1212
import java.util.concurrent.ConcurrentHashMap;
1313

14+
import net.minecraft.world.entity.Interaction;
1415
import org.apache.commons.lang.Validate;
1516
import org.bukkit.ChatColor;
1617
import org.bukkit.GameMode;
@@ -193,8 +194,18 @@ public String[] getAliases() {
193194
}
194195

195196
public enum PlayerAction implements AliasedEnum {
197+
/**
198+
* @deprecated Removed in 1.21.6
199+
*/
200+
@Deprecated
196201
START_SNEAKING("PRESS_SHIFT_KEY"),
202+
203+
/**
204+
* @deprecated Removed in 1.21.6
205+
*/
206+
@Deprecated
197207
STOP_SNEAKING("RELEASE_SHIFT_KEY"),
208+
198209
STOP_SLEEPING,
199210
START_SPRINTING,
200211
STOP_SPRINTING,
@@ -334,7 +345,8 @@ public enum SoundCategory {
334345
NEUTRAL("neutral"),
335346
PLAYERS("player"),
336347
AMBIENT("ambient"),
337-
VOICE("voice");
348+
VOICE("voice"),
349+
UI("ui");
338350

339351
private static final Map<String, SoundCategory> LOOKUP;
340352
static {

src/main/java/com/comphenix/protocol/wrappers/WrappedChatComponent.java

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package com.comphenix.protocol.wrappers;
22

33
import java.io.StringReader;
4+
import java.lang.reflect.Field;
45
import java.util.Optional;
56

7+
import com.comphenix.protocol.wrappers.codecs.WrappedCodec;
8+
import com.comphenix.protocol.wrappers.codecs.WrappedDynamicOps;
9+
import com.google.gson.JsonElement;
10+
import com.google.gson.JsonParseException;
11+
import com.google.gson.JsonParser;
612
import org.bukkit.ChatColor;
713

814
import com.comphenix.protocol.reflect.FuzzyReflection;
@@ -35,41 +41,49 @@ public class WrappedChatComponent extends AbstractWrapper implements ClonableWra
3541

3642
private static ConstructorAccessor CONSTRUCT_TEXT_COMPONENT = null;
3743

44+
private static WrappedCodec CODEC;
45+
3846
static {
39-
FuzzyReflection reflection = FuzzyReflection.fromClass(SERIALIZER, true);
47+
FuzzyReflection fuzzy = FuzzyReflection.fromClass(SERIALIZER, true);
4048

41-
// Retrieve the correct methods
42-
if (MinecraftVersion.v1_20_5.atOrAbove()) {
43-
SERIALIZE_COMPONENT = Accessors.getMethodAccessor(reflection.getMethod(FuzzyMethodContract.newBuilder()
49+
if (MinecraftVersion.v1_21_6.atOrAbove()) {
50+
Field codecField = fuzzy.getFieldByType("CODEC", MinecraftReflection.getCodecClass());
51+
CODEC = WrappedCodec.fromHandle(Accessors.getFieldAccessor(codecField).get(null));
52+
} else if (MinecraftVersion.v1_20_5.atOrAbove()) {
53+
SERIALIZE_COMPONENT = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract.newBuilder()
4454
.returnTypeExact(String.class)
4555
.parameterDerivedOf(COMPONENT)
4656
.parameterDerivedOf(MinecraftReflection.getHolderLookupProviderClass())
4757
.build()));
4858
} else {
49-
SERIALIZE_COMPONENT = Accessors.getMethodAccessor(reflection.getMethodByReturnTypeAndParameters("serialize", /* a */
59+
SERIALIZE_COMPONENT = Accessors.getMethodAccessor(fuzzy.getMethodByReturnTypeAndParameters("serialize", /* a */
5060
String.class, new Class<?>[] { COMPONENT }));
5161
}
5262

53-
GSON = Accessors.getFieldAccessor(reflection.getFieldByType("gson", GSON_CLASS)).get(null);
63+
if (!MinecraftVersion.v1_20_4.atOrAbove()) {
64+
GSON = Accessors.getFieldAccessor(fuzzy.getFieldByType("gson", GSON_CLASS)).get(null);
65+
}
5466

55-
if (MinecraftVersion.v1_20_5.atOrAbove()) {
56-
DESERIALIZE = Accessors.getMethodAccessor(reflection.getMethod(FuzzyMethodContract.newBuilder()
57-
.returnDerivedOf(COMPONENT)
58-
.parameterExactType(String.class)
59-
.parameterDerivedOf(MinecraftReflection.getHolderLookupProviderClass())
60-
.build()));
61-
} else if (MinecraftVersion.v1_20_4.atOrAbove()) {
62-
DESERIALIZE = Accessors.getMethodAccessor(reflection
63-
.getMethodByReturnTypeAndParameters("fromJson", MUTABLE_COMPONENT_CLASS.get(), new Class[] { String.class }));
64-
} else {
65-
try {
66-
DESERIALIZE = Accessors.getMethodAccessor(FuzzyReflection.fromClass(MinecraftReflection.getChatDeserializer(), true)
67-
.getMethodByReturnTypeAndParameters("deserialize", Object.class, new Class<?>[] { GSON_CLASS, String.class, Class.class, boolean.class }));
68-
} catch (IllegalArgumentException ex) {
69-
// We'll handle it in the ComponentParser
70-
DESERIALIZE = null;
71-
}
72-
}
67+
if (!MinecraftVersion.v1_21_6.atOrAbove()) {
68+
if (MinecraftVersion.v1_20_5.atOrAbove()) {
69+
DESERIALIZE = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract.newBuilder()
70+
.returnDerivedOf(COMPONENT)
71+
.parameterExactType(String.class)
72+
.parameterDerivedOf(MinecraftReflection.getHolderLookupProviderClass())
73+
.build()));
74+
} else if (MinecraftVersion.v1_20_4.atOrAbove()) {
75+
DESERIALIZE = Accessors.getMethodAccessor(fuzzy
76+
.getMethodByReturnTypeAndParameters("fromJson", MUTABLE_COMPONENT_CLASS.get(), new Class[]{String.class}));
77+
} else {
78+
try {
79+
DESERIALIZE = Accessors.getMethodAccessor(FuzzyReflection.fromClass(MinecraftReflection.getChatDeserializer(), true)
80+
.getMethodByReturnTypeAndParameters("deserialize", Object.class, new Class<?>[]{GSON_CLASS, String.class, Class.class, boolean.class}));
81+
} catch (IllegalArgumentException ex) {
82+
// We'll handle it in the ComponentParser
83+
DESERIALIZE = null;
84+
}
85+
}
86+
}
7387

7488
// Get a component from a standard Minecraft message
7589
CONSTRUCT_COMPONENT = Accessors.getMethodAccessor(MinecraftReflection.getCraftChatMessage(), "fromString", String.class, boolean.class);
@@ -83,6 +97,11 @@ public class WrappedChatComponent extends AbstractWrapper implements ClonableWra
8397
}
8498

8599
private static Object serialize(Object handle) {
100+
if (CODEC != null) {
101+
Object jobj = CODEC.encode(handle, WrappedDynamicOps.json(false)).getOrThrow(JsonParseException::new);
102+
return jobj.toString();
103+
}
104+
86105
if (MinecraftVersion.v1_20_5.atOrAbove()) {
87106
return SERIALIZE_COMPONENT.invoke(null, handle, MinecraftRegistryAccess.get());
88107
}
@@ -91,6 +110,10 @@ private static Object serialize(Object handle) {
91110
}
92111

93112
private static Object deserialize(String json) {
113+
if (CODEC != null) {
114+
return CODEC.parse(JsonParser.parseString(json), WrappedDynamicOps.json(false)).getOrThrow(JsonParseException::new);
115+
}
116+
94117
if (MinecraftVersion.v1_20_5.atOrAbove()) {
95118
return DESERIALIZE.invoke(null, json, MinecraftRegistryAccess.get());
96119
}

src/main/java/com/comphenix/protocol/wrappers/nbt/TileEntityAccessor.java

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.comphenix.protocol.wrappers.nbt;
22

33
import java.io.IOException;
4-
import java.lang.reflect.Constructor;
54
import java.lang.reflect.Modifier;
65
import java.util.HashMap;
76
import java.util.Map;
@@ -34,6 +33,9 @@ class TileEntityAccessor<T extends BlockState> {
3433
private static final boolean BLOCK_DATA_INCL = MinecraftVersion.NETHER_UPDATE.atOrAbove()
3534
&& !MinecraftVersion.CAVES_CLIFFS_1.atOrAbove();
3635
private static final boolean USE_HOLDER_LOOKUP = MinecraftVersion.v1_21_5.atOrAbove();
36+
private static final boolean USE_TAG_VALUE_INPUT = MinecraftVersion.v1_21_6.atOrAbove();
37+
38+
private static final Class<?> TAG_VALUE_INPUT = MinecraftReflection.getNullableNMS("world.level.storage.TagValueInput");
3739

3840
/**
3941
* Token indicating that the given block state doesn't contain any tile entities.
@@ -45,7 +47,7 @@ class TileEntityAccessor<T extends BlockState> {
4547
*/
4648
private static final Map<Class<?>, TileEntityAccessor<?>> cachedAccessors = new HashMap<>();
4749

48-
private static Constructor<?> nbtCompoundParserConstructor;
50+
private MethodAccessor createInputWrapper;
4951

5052
private FieldAccessor tileEntityField;
5153
private MethodAccessor readCompound;
@@ -120,14 +122,31 @@ void findMethods(Class<?> type, T state) {
120122
.parameterExactArray(holderLookup)
121123
.build()));
122124

123-
// should be equiv. to `void loadWithComponents(CompoundTag, HolderLookup.Provider)`
124-
readCompound = Accessors.getMethodAccessor(fuzzy.getMethod(
125-
FuzzyMethodContract.newBuilder()
126-
.banModifier(Modifier.STATIC)
127-
.requireModifier(Modifier.FINAL)
128-
.returnTypeVoid()
129-
.parameterExactArray(nbtCompound, holderLookup)
130-
.build()));
125+
if (USE_TAG_VALUE_INPUT) {
126+
createInputWrapper = Accessors.getMethodAccessor(FuzzyReflection.fromClass(TAG_VALUE_INPUT).getMethod(
127+
FuzzyMethodContract.newBuilder()
128+
.requireModifier(Modifier.STATIC)
129+
.parameterExactArray(MinecraftReflection.getMinecraftClass("util.ProblemReporter"), holderLookup, nbtCompound)
130+
.build()));
131+
132+
// should be equiv. to `void loadWithComponents(ValueInput)`
133+
readCompound = Accessors.getMethodAccessor(fuzzy.getMethod(
134+
FuzzyMethodContract.newBuilder()
135+
.banModifier(Modifier.STATIC)
136+
.requireModifier(Modifier.FINAL)
137+
.returnTypeVoid()
138+
.parameterSuperOf(TAG_VALUE_INPUT)
139+
.build()));
140+
} else {
141+
// should be equiv. to `void loadWithComponents(CompoundTag, HolderLookup.Provider)`
142+
readCompound = Accessors.getMethodAccessor(fuzzy.getMethod(
143+
FuzzyMethodContract.newBuilder()
144+
.banModifier(Modifier.STATIC)
145+
.requireModifier(Modifier.FINAL)
146+
.returnTypeVoid()
147+
.parameterExactArray(nbtCompound, holderLookup)
148+
.build()));
149+
}
131150
} else if (BLOCK_DATA_INCL) {
132151
Class<?> iBlockData = MinecraftReflection.getIBlockDataClass();
133152

@@ -260,7 +279,12 @@ public void writeBlockState(T state, NbtCompound compound) {
260279

261280
// Ensure the block state is set to the compound
262281
if (USE_HOLDER_LOOKUP) {
263-
readCompound.invoke(tileEntity, NbtFactory.fromBase(compound).getHandle(), MinecraftRegistryAccess.get());
282+
if (USE_TAG_VALUE_INPUT) {
283+
Object tagValueInput = createInputWrapper.invoke(null, null, MinecraftRegistryAccess.get(), NbtFactory.fromBase(compound).getHandle());
284+
readCompound.invoke(tileEntity, tagValueInput);
285+
} else {
286+
readCompound.invoke(tileEntity, NbtFactory.fromBase(compound).getHandle(), MinecraftRegistryAccess.get());
287+
}
264288
} else if (BLOCK_DATA_INCL) {
265289
Object blockData = BukkitUnwrapper.getInstance().unwrapItem(state);
266290
readCompound.invoke(tileEntity, blockData, NbtFactory.fromBase(compound).getHandle());

src/test/java/com/comphenix/protocol/BukkitInitialization.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,18 @@
4646
import org.bukkit.NamespacedKey;
4747
import org.bukkit.Registry;
4848
import org.bukkit.World;
49-
import org.bukkit.craftbukkit.v1_21_R4.CraftLootTable;
50-
import org.bukkit.craftbukkit.v1_21_R4.CraftRegistry;
51-
import org.bukkit.craftbukkit.v1_21_R4.CraftServer;
52-
import org.bukkit.craftbukkit.v1_21_R4.CraftWorld;
53-
import org.bukkit.craftbukkit.v1_21_R4.inventory.CraftItemFactory;
54-
import org.bukkit.craftbukkit.v1_21_R4.tag.CraftBlockTag;
55-
import org.bukkit.craftbukkit.v1_21_R4.tag.CraftEntityTag;
56-
import org.bukkit.craftbukkit.v1_21_R4.tag.CraftFluidTag;
57-
import org.bukkit.craftbukkit.v1_21_R4.tag.CraftItemTag;
58-
import org.bukkit.craftbukkit.v1_21_R4.util.CraftMagicNumbers;
59-
import org.bukkit.craftbukkit.v1_21_R4.util.CraftNamespacedKey;
60-
import org.bukkit.craftbukkit.v1_21_R4.util.Versioning;
49+
import org.bukkit.craftbukkit.v1_21_R5.CraftLootTable;
50+
import org.bukkit.craftbukkit.v1_21_R5.CraftRegistry;
51+
import org.bukkit.craftbukkit.v1_21_R5.CraftServer;
52+
import org.bukkit.craftbukkit.v1_21_R5.CraftWorld;
53+
import org.bukkit.craftbukkit.v1_21_R5.inventory.CraftItemFactory;
54+
import org.bukkit.craftbukkit.v1_21_R5.tag.CraftBlockTag;
55+
import org.bukkit.craftbukkit.v1_21_R5.tag.CraftEntityTag;
56+
import org.bukkit.craftbukkit.v1_21_R5.tag.CraftFluidTag;
57+
import org.bukkit.craftbukkit.v1_21_R5.tag.CraftItemTag;
58+
import org.bukkit.craftbukkit.v1_21_R5.util.CraftMagicNumbers;
59+
import org.bukkit.craftbukkit.v1_21_R5.util.CraftNamespacedKey;
60+
import org.bukkit.craftbukkit.v1_21_R5.util.Versioning;
6161
import org.jetbrains.annotations.NotNull;
6262
import org.spigotmc.SpigotWorldConfig;
6363

src/test/java/com/comphenix/protocol/events/PacketContainerTest.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import java.util.UUID;
4242
import java.util.concurrent.ThreadLocalRandom;
4343

44+
import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
45+
import net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket;
4446
import org.apache.commons.lang.SerializationUtils;
4547
import org.bukkit.ChatColor;
4648
import org.bukkit.Material;
@@ -625,10 +627,6 @@ public void testPlayerAction() {
625627
// no change across nms versions
626628
container.getPlayerActions().write(0, EnumWrappers.PlayerAction.OPEN_INVENTORY);
627629
assertEquals(container.getPlayerActions().read(0), EnumWrappers.PlayerAction.OPEN_INVENTORY);
628-
629-
// changed in 1.15
630-
container.getPlayerActions().write(0, EnumWrappers.PlayerAction.START_SNEAKING);
631-
assertEquals(container.getPlayerActions().read(0), EnumWrappers.PlayerAction.START_SNEAKING);
632630
}
633631

634632
@Test

src/test/java/com/comphenix/protocol/injector/EntityUtilitiesTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
import java.lang.reflect.Field;
88

9-
import org.bukkit.craftbukkit.v1_21_R4.CraftWorld;
10-
import org.bukkit.craftbukkit.v1_21_R4.entity.CraftEntity;
9+
import org.bukkit.craftbukkit.v1_21_R5.CraftWorld;
10+
import org.bukkit.craftbukkit.v1_21_R5.entity.CraftEntity;
1111
import org.junit.jupiter.api.BeforeAll;
1212
import org.junit.jupiter.api.Test;
1313

0 commit comments

Comments
 (0)