Skip to content

Commit f3f8959

Browse files
fix: initialization error of ChunkData wrapper on MC 1.21.5+ (#3495)
1 parent 67e7375 commit f3f8959

File tree

2 files changed

+88
-3
lines changed

2 files changed

+88
-3
lines changed

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,15 @@ public String toString() {
708708
}
709709
}
710710

711+
public enum HeightmapType {
712+
WORLD_SURFACE_WG,
713+
WORLD_SURFACE,
714+
OCEAN_FLOOR_WG,
715+
OCEAN_FLOOR,
716+
MOTION_BLOCKING,
717+
MOTION_BLOCKING_NO_LEAVES,
718+
}
719+
711720
private static Class<?> PROTOCOL_CLASS = null;
712721
private static Class<?> CLIENT_COMMAND_CLASS = null;
713722
private static Class<?> CHAT_VISIBILITY_CLASS = null;
@@ -735,6 +744,7 @@ public String toString() {
735744
private static Class<?> CLIENT_INTENT_CLASS = null;
736745
private static Class<?> TEAM_COLLISION_RULE_CLASS = null;
737746
private static Class<?> TEAM_VISIBILITY_CLASS = null;
747+
private static Class<?> HEIGHTMAP_TYPE_CLASS = null;
738748

739749
private static boolean INITIALIZING = false;
740750
private static boolean INITIALIZED = false;
@@ -849,6 +859,10 @@ private static void initialize() {
849859
"world.scores.ScoreboardTeamBase$EnumNameTagVisibility" /* Spigot Mapping */,
850860
"world.scores.Team$Visibility" /* Mojang Mapping */);
851861

862+
HEIGHTMAP_TYPE_CLASS = MinecraftReflection.getNullableNMS(
863+
"world.level.levelgen.HeightMap$Type" /* Spigot Mapping */,
864+
"world.level.levelgen.Heightmap$Types" /* Mojang Mapping */);
865+
852866
associate(PROTOCOL_CLASS, Protocol.class, getProtocolConverter());
853867
associate(CLIENT_COMMAND_CLASS, ClientCommand.class, getClientCommandConverter());
854868
associate(CHAT_VISIBILITY_CLASS, ChatVisibility.class, getChatVisibilityConverter());
@@ -875,6 +889,7 @@ private static void initialize() {
875889
associate(CLIENT_INTENT_CLASS, ClientIntent.class, getClientIntentConverter());
876890
associate(TEAM_COLLISION_RULE_CLASS, TeamCollisionRule.class, getTeamCollisionRuleConverter());
877891
associate(TEAM_VISIBILITY_CLASS, TeamVisibility.class, getTeamVisibilityConverter());
892+
associate(HEIGHTMAP_TYPE_CLASS, HeightmapType.class, getHeightmapTypeConverter());
878893

879894
if (ENTITY_POSE_CLASS != null) {
880895
associate(ENTITY_POSE_CLASS, EntityPose.class, getEntityPoseConverter());
@@ -1059,6 +1074,11 @@ public static Class<?> getTeamVisibilityClass() {
10591074
return TEAM_VISIBILITY_CLASS;
10601075
}
10611076

1077+
public static Class<?> getHeightmapTypeClass() {
1078+
initialize();
1079+
return HEIGHTMAP_TYPE_CLASS;
1080+
}
1081+
10621082
// Get the converters
10631083
public static EquivalentConverter<Protocol> getProtocolConverter() {
10641084
return new EnumConverter<>(getProtocolClass(), Protocol.class);
@@ -1164,6 +1184,10 @@ public static EquivalentConverter<TeamVisibility> getTeamVisibilityConverter() {
11641184
return new EnumConverter<>(getTeamVisibilityClass(), TeamVisibility.class);
11651185
}
11661186

1187+
public static EquivalentConverter<HeightmapType> getHeightmapTypeConverter() {
1188+
return new EnumConverter<>(getHeightmapTypeClass(), HeightmapType.class);
1189+
}
1190+
11671191
/**
11681192
* @since 1.13+
11691193
* @return {@link EnumConverter} or null (if bellow 1.13 / nms EnumPose class cannot be found)

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

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
import java.util.ArrayList;
55
import java.util.BitSet;
66
import java.util.List;
7+
import java.util.Map;
78

9+
import com.comphenix.protocol.reflect.EquivalentConverter;
810
import org.jetbrains.annotations.Nullable;
911

1012
import com.comphenix.protocol.injector.StructureCache;
@@ -41,6 +43,7 @@ public static final class ChunkData extends AbstractWrapper {
4143

4244
private static final FieldAccessor BLOCK_ENTITIES_DATA_ACCESSOR;
4345
private static final FieldAccessor HEIGHTMAPS_ACCESSOR;
46+
private static final EquivalentConverter<Map<EnumWrappers.HeightmapType, long[]>> HEIGHTMAPS_CONVERTER;
4447
private static final FieldAccessor BUFFER_ACCESSOR;
4548

4649
static {
@@ -54,9 +57,17 @@ public static final class ChunkData extends AbstractWrapper {
5457
BLOCK_ENTITIES_DATA_ACCESSOR = Accessors.getFieldAccessor(reflection.getField(FuzzyFieldContract.newBuilder()
5558
.typeExact(List.class)
5659
.build()));
57-
HEIGHTMAPS_ACCESSOR = Accessors.getFieldAccessor(reflection.getField(FuzzyFieldContract.newBuilder()
58-
.typeExact(MinecraftReflection.getNBTCompoundClass())
59-
.build()));
60+
if (MinecraftVersion.v1_21_5.atOrAbove()) {
61+
HEIGHTMAPS_ACCESSOR = Accessors.getFieldAccessor(reflection.getField(FuzzyFieldContract.newBuilder()
62+
.typeExact(Map.class)
63+
.build()));
64+
HEIGHTMAPS_CONVERTER = BukkitConverters.getMapConverter(EnumWrappers.getHeightmapTypeConverter(), Converters.passthrough(long[].class));
65+
} else {
66+
HEIGHTMAPS_ACCESSOR = Accessors.getFieldAccessor(reflection.getField(FuzzyFieldContract.newBuilder()
67+
.typeExact(MinecraftReflection.getNBTCompoundClass())
68+
.build()));
69+
HEIGHTMAPS_CONVERTER = null;
70+
}
6071
BUFFER_ACCESSOR = Accessors.getFieldAccessor(reflection.getField(FuzzyFieldContract.newBuilder().typeExact(byte[].class).build()));
6172
}
6273

@@ -68,22 +79,50 @@ public ChunkData(Object handle) {
6879

6980
/**
7081
* The heightmap of this chunk.
82+
* <p>
83+
* Removed in Minecraft 1.21.5.
7184
*
7285
* @return an NBT-Tag
86+
* @deprecated Use {@link ChunkData#getHeightmaps()} instead.
7387
*/
88+
@Deprecated
7489
public NbtCompound getHeightmapsTag() {
7590
return NbtFactory.fromNMSCompound(HEIGHTMAPS_ACCESSOR.get(handle));
7691
}
7792

7893
/**
7994
* Sets the heightmap tag of this chunk.
95+
* <p>
96+
* Removed in Minecraft 1.21.5.
8097
*
8198
* @param heightmapsTag the new heightmaps tag.
99+
* @deprecated Use {@link ChunkData#setHeightmaps(Map)} instead.
82100
*/
101+
@Deprecated
83102
public void setHeightmapsTag(NbtCompound heightmapsTag) {
84103
HEIGHTMAPS_ACCESSOR.set(handle, NbtFactory.fromBase(heightmapsTag).getHandle());
85104
}
86105

106+
/**
107+
* The heightmap of this chunk.
108+
*
109+
* @return a map containing the heightmaps
110+
*/
111+
public Map<EnumWrappers.HeightmapType, long[]> getHeightmaps() {
112+
return HEIGHTMAPS_CONVERTER.getSpecific(HEIGHTMAPS_ACCESSOR.get(handle));
113+
}
114+
115+
/**
116+
* Sets the heightmap tag of this chunk.
117+
* <p>
118+
* Removed in Minecraft 1.21.5.
119+
*
120+
* @param heightmaps the new heightmaps.
121+
*/
122+
public void setHeightmaps(Map<EnumWrappers.HeightmapType, long[]> heightmaps) {
123+
HEIGHTMAPS_ACCESSOR.set(handle, HEIGHTMAPS_CONVERTER.getGeneric(heightmaps));
124+
}
125+
87126
/**
88127
* The actual structural data of this chunk as bytes.
89128
*
@@ -130,12 +169,16 @@ public void setBlockEntityInfo(List<BlockEntityInfo> blockEntityInfo) {
130169

131170
/**
132171
* Creates a new wrapper using predefined values.
172+
* <p>
173+
* Removed in Minecraft 1.21.5.
133174
*
134175
* @param heightmapsTag the heightmaps tag
135176
* @param buffer the buffer
136177
* @param blockEntityInfo a list of wrapped block entities
137178
* @return a newly created wrapper
179+
* @deprecated Use {@link ChunkData#fromValues(Map, byte[], List)} instead.
138180
*/
181+
@Deprecated
139182
public static ChunkData fromValues(NbtCompound heightmapsTag, byte[] buffer, List<BlockEntityInfo> blockEntityInfo) {
140183
ChunkData data = new ChunkData(LEVEL_CHUNK_PACKET_DATA_CONSTRUCTOR.invoke(StructureCache.newNullDataSerializer(), 0, 0));
141184

@@ -145,6 +188,24 @@ public static ChunkData fromValues(NbtCompound heightmapsTag, byte[] buffer, Lis
145188

146189
return new ChunkData(data);
147190
}
191+
192+
/**
193+
* Creates a new wrapper using predefined values.
194+
*
195+
* @param heightmaps the heightmaps
196+
* @param buffer the buffer
197+
* @param blockEntityInfo a list of wrapped block entities
198+
* @return a newly created wrapper
199+
*/
200+
public static ChunkData fromValues(Map<EnumWrappers.HeightmapType, long[]> heightmaps, byte[] buffer, List<BlockEntityInfo> blockEntityInfo) {
201+
ChunkData data = new ChunkData(LEVEL_CHUNK_PACKET_DATA_CONSTRUCTOR.invoke(StructureCache.newNullDataSerializer(), 0, 0));
202+
203+
data.setHeightmaps(heightmaps);
204+
data.setBuffer(buffer);
205+
data.setBlockEntityInfo(blockEntityInfo);
206+
207+
return new ChunkData(data);
208+
}
148209
}
149210

150211
/**

0 commit comments

Comments
 (0)