Skip to content

Commit df804bf

Browse files
fix: adapt modern packet bridges for 1.21.11 and 26.x
Use string switches and Reflect helpers so modern shared sources compile across STAB enum drift, SetTime constructor changes, and private ChunkPos. Co-authored-by: OPmasterLEO <OPmasterLEO@users.noreply.github.com>
1 parent cd64114 commit df804bf

3 files changed

Lines changed: 105 additions & 32 deletions

File tree

‎nms-shared/Reflect.java‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package net.opmasterleo.packet.nms.shared;
22

3+
import java.lang.reflect.Constructor;
34
import java.lang.reflect.Field;
5+
import java.util.Map;
46

57
/**
68
* Reflection helpers for public Mojang-mapped members and mid/legacy private NMS fields.
@@ -80,4 +82,59 @@ static Object invoke(Object target, String... names) {
8082
}
8183
return null;
8284
}
85+
86+
static Object construct(Class<?> type, Class<?>[] paramTypes, Object... args) {
87+
if (type == null) {
88+
return null;
89+
}
90+
try {
91+
Constructor<?> ctor = type.getDeclaredConstructor(paramTypes);
92+
try {
93+
ctor.trySetAccessible();
94+
} catch (SecurityException ignored) {
95+
return null;
96+
}
97+
return ctor.newInstance(args);
98+
} catch (ReflectiveOperationException ignored) {
99+
return null;
100+
}
101+
}
102+
103+
/**
104+
* Best-effort ClientboundSetTimePacket construction across modern API drift:
105+
* pre-26 {@code (long, long, boolean)} vs 26.x {@code (long, Map)}.
106+
*/
107+
static Object constructSetTime(Class<?> type, long gameTime, long dayTime) {
108+
Object packet = construct(type, new Class<?>[]{long.class, long.class, boolean.class}, gameTime, dayTime, true);
109+
if (packet != null) {
110+
return packet;
111+
}
112+
for (Constructor<?> ctor : type.getDeclaredConstructors()) {
113+
Class<?>[] params = ctor.getParameterTypes();
114+
try {
115+
ctor.trySetAccessible();
116+
} catch (SecurityException ignored) {
117+
continue;
118+
}
119+
try {
120+
if (params.length == 2 && params[0] == long.class && Map.class.isAssignableFrom(params[1])) {
121+
return ctor.newInstance(gameTime, Map.of());
122+
}
123+
if (params.length == 3
124+
&& params[0] == long.class
125+
&& params[1] == long.class
126+
&& Map.class.isAssignableFrom(params[2])) {
127+
return ctor.newInstance(gameTime, dayTime, Map.of());
128+
}
129+
if (params.length == 3
130+
&& params[0] == long.class
131+
&& params[1] == long.class
132+
&& params[2] == boolean.class) {
133+
return ctor.newInstance(gameTime, dayTime, true);
134+
}
135+
} catch (ReflectiveOperationException ignored) {
136+
}
137+
}
138+
return null;
139+
}
83140
}

‎nms-shared/packet/modern/SharedPacketBridge.java‎

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
import net.opmasterleo.packet.nms.packet.PacketViews;
5858
import net.opmasterleo.packet.nms.packet.PlayerActionType;
5959

60+
import static net.opmasterleo.packet.nms.shared.Reflect.constructSetTime;
61+
import static net.opmasterleo.packet.nms.shared.Reflect.field;
62+
import static net.opmasterleo.packet.nms.shared.Reflect.get;
6063
import static net.opmasterleo.packet.nms.shared.Reflect.invoke;
6164

6265
public final class SharedPacketBridge implements PacketBridge {
@@ -78,23 +81,16 @@ public String classify(Object packet) {
7881

7982
@Override
8083
public int entityId(Object packet) {
81-
if (packet instanceof ClientboundAddEntityPacket add) {
82-
return add.getId();
83-
}
84-
if (packet instanceof ClientboundSetEntityDataPacket data) {
85-
return data.id();
86-
}
87-
if (packet instanceof ClientboundSetEquipmentPacket equipment) {
88-
return equipment.getEntity();
89-
}
90-
if (packet instanceof ClientboundSetEntityMotionPacket motion) {
91-
return motion.getId();
84+
if (packet == null) {
85+
return -1;
9286
}
93-
if (packet instanceof ServerboundInteractPacket interact) {
94-
return interact.getEntityId();
87+
// Method names drift across modern buckets (id/getId/getEntity/getEntityId).
88+
Object value = invoke(packet, "getEntityId", "getEntity", "getId", "id", "entityId");
89+
if (value instanceof Integer i) {
90+
return i;
9591
}
96-
Object value = invoke(packet, "getEntityId", "id", "entityId", "getId");
97-
return value instanceof Integer i ? i : -1;
92+
Object fieldValue = get(field(packet.getClass(), "id", "entityId", "entity"), packet);
93+
return fieldValue instanceof Integer i ? i : -1;
9894
}
9995

10096
@Override
@@ -254,7 +250,11 @@ public Object gameEvent(int eventId, float value) {
254250

255251
@Override
256252
public Object setTime(long gameTime, long dayTime) {
257-
return new ClientboundSetTimePacket(gameTime, dayTime, true);
253+
Object packet = constructSetTime(ClientboundSetTimePacket.class, gameTime, dayTime);
254+
if (packet == null) {
255+
throw new IllegalStateException("Unable to construct ClientboundSetTimePacket");
256+
}
257+
return packet;
258258
}
259259

260260
@Override
@@ -339,8 +339,9 @@ public PacketViews.InteractView interact(Object packet) {
339339
if (!(packet instanceof ServerboundInteractPacket interact)) {
340340
return PacketBridge.super.interact(packet);
341341
}
342-
InteractAction action = interact.isAttack() ? InteractAction.ATTACK : InteractAction.INTERACT;
343-
return new PacketViews.InteractView(interact.getEntityId(), action, Hand.MAIN_HAND);
342+
boolean attack = Boolean.TRUE.equals(invoke(interact, "isAttack"));
343+
InteractAction action = attack ? InteractAction.ATTACK : InteractAction.INTERACT;
344+
return new PacketViews.InteractView(entityId(interact), action, Hand.MAIN_HAND);
344345
}
345346

346347
@Override
@@ -353,14 +354,17 @@ public PacketViews.PlayerActionView playerAction(Object packet) {
353354
}
354355

355356
private static PlayerActionType playerActionType(ServerboundPlayerActionPacket.Action action) {
356-
return switch (action) {
357-
case START_DESTROY_BLOCK -> PlayerActionType.START_DESTROY_BLOCK;
358-
case ABORT_DESTROY_BLOCK -> PlayerActionType.ABORT_DESTROY_BLOCK;
359-
case STOP_DESTROY_BLOCK -> PlayerActionType.STOP_DESTROY_BLOCK;
360-
case DROP_ALL_ITEMS -> PlayerActionType.DROP_ALL_ITEMS;
361-
case DROP_ITEM -> PlayerActionType.DROP_ITEM;
362-
case RELEASE_USE_ITEM -> PlayerActionType.RELEASE_USE_ITEM;
363-
case SWAP_ITEM_WITH_OFFHAND -> PlayerActionType.SWAP_ITEM_WITH_OFFHAND;
357+
// String switch keeps older modern buckets compiling when newer enums add values (e.g. STAB).
358+
return switch (action.name()) {
359+
case "START_DESTROY_BLOCK" -> PlayerActionType.START_DESTROY_BLOCK;
360+
case "ABORT_DESTROY_BLOCK" -> PlayerActionType.ABORT_DESTROY_BLOCK;
361+
case "STOP_DESTROY_BLOCK" -> PlayerActionType.STOP_DESTROY_BLOCK;
362+
case "DROP_ALL_ITEMS" -> PlayerActionType.DROP_ALL_ITEMS;
363+
case "DROP_ITEM" -> PlayerActionType.DROP_ITEM;
364+
case "RELEASE_USE_ITEM" -> PlayerActionType.RELEASE_USE_ITEM;
365+
case "SWAP_ITEM_WITH_OFFHAND" -> PlayerActionType.SWAP_ITEM_WITH_OFFHAND;
366+
case "STAB" -> PlayerActionType.UNKNOWN;
367+
default -> PlayerActionType.UNKNOWN;
364368
};
365369
}
366370

‎nms-shared/world/modern/SharedWorldBridge.java‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,24 @@ public Stream<EntityHandle> entities(World world) {
3636
return Stream.empty();
3737
}
3838
return StreamSupport.stream(serverLevel.getAllEntities().spliterator(), false)
39-
.map(entity -> new EntityHandle(
40-
entity,
41-
entity.getId(),
42-
entity.chunkPosition().x,
43-
entity.chunkPosition().z
44-
));
39+
.map(entity -> {
40+
Object chunkPos = entity.chunkPosition();
41+
return new EntityHandle(
42+
entity,
43+
entity.getId(),
44+
chunkCoord(chunkPos, "x"),
45+
chunkCoord(chunkPos, "z")
46+
);
47+
});
48+
}
49+
50+
private static int chunkCoord(Object chunkPos, String name) {
51+
Object value = invoke(chunkPos, name, "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1));
52+
if (value instanceof Integer i) {
53+
return i;
54+
}
55+
Object fieldValue = get(field(chunkPos.getClass(), name), chunkPos);
56+
return fieldValue instanceof Integer i ? i : 0;
4557
}
4658

4759
@Override

0 commit comments

Comments
 (0)