Skip to content

Commit 07777bf

Browse files
committed
Updated reflection to include a possible LTS for 1.20+
1 parent a9751c6 commit 07777bf

File tree

1 file changed

+50
-20
lines changed

1 file changed

+50
-20
lines changed

bukkit-1.17/src/main/java/net/badlion/bukkitapi/BukkitPluginMessageSender.java

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,29 @@ public class BukkitPluginMessageSender extends AbstractBukkitPluginMessageSender
1313

1414
private final AbstractBukkitBadlionPlugin apiBukkit;
1515

16-
private final Method getHandleMethod;
17-
private final Field playerConnectionField;
18-
private final Method sendPacketMethod;
19-
2016
private String versionSuffix;
21-
private String versionName;
2217

23-
private Constructor<?> packetPlayOutCustomPayloadConstructor;
24-
private Constructor<?> packetPlayOutMinecraftKeyConstructor;
25-
private Constructor<?> discardedPayloadConstructor;
26-
private Method resourceLocationParseMethod;
18+
private Class<?> packetDataSerializerClass;
2719
private Class<?> minecraftKeyClass;
2820
private Class<?> customPacketPayloadClass;
29-
private boolean useMinecraftKey;
30-
private boolean usePacketPayload;
31-
private boolean useDiscardedPayload;
3221

33-
// Bukkit 1.8+ support
34-
private Class<?> packetDataSerializerClass;
35-
private Method packetDataSerializerWriteBytesMethod;
22+
private Constructor<?> packetPlayOutCustomPayloadConstructor;
3623
private Constructor<?> packetDataSerializerConstructor;
24+
private Constructor<?> packetPlayOutMinecraftKeyConstructor;
25+
private Constructor<?> discardedPayloadConstructor;
3726

27+
private Method sendCustomPayloadMethod;
3828
private Method wrappedBufferMethod;
29+
private Method packetDataSerializerWriteBytesMethod;
30+
private Method resourceLocationParseMethod;
31+
private Method getHandleMethod;
32+
private Method sendPacketMethod;
3933

34+
private Field playerConnectionField;
35+
36+
private boolean useMinecraftKey;
37+
private boolean usePacketPayload;
38+
private boolean useDiscardedPayload;
4039

4140
public BukkitPluginMessageSender(AbstractBukkitBadlionPlugin apiBukkit) {
4241
this.apiBukkit = apiBukkit;
@@ -49,7 +48,6 @@ public BukkitPluginMessageSender(AbstractBukkitBadlionPlugin apiBukkit) {
4948
String suffix = parts[parts.length - 1];
5049
if (!suffix.startsWith("v")) {
5150
// 1.20.5+ support
52-
// TODO: In 1.20.5+, the private method `CraftPlayer.sendCustomPayload(ResourceLocation, byte[])` should do the trick and handle all future versions
5351
if ("craftbukkit".equals(suffix)) {
5452
suffix = "";
5553
} else {
@@ -58,9 +56,10 @@ public BukkitPluginMessageSender(AbstractBukkitBadlionPlugin apiBukkit) {
5856
}
5957

6058
this.versionSuffix = suffix;
61-
this.versionName = this.apiBukkit.getServer().getVersion();
6259

63-
this.apiBukkit.getLogger().info("Found version " + this.versionSuffix + " (" + this.versionName + ")");
60+
String versionName = this.apiBukkit.getServer().getVersion();
61+
62+
this.apiBukkit.getLogger().info("Found version " + this.versionSuffix + " (" + versionName + ")");
6463
}
6564

6665
// We need to use reflection because Bukkit by default handles plugin messages in a really silly way
@@ -70,6 +69,26 @@ public BukkitPluginMessageSender(AbstractBukkitBadlionPlugin apiBukkit) {
7069
throw new RuntimeException("Failed to find CraftPlayer class");
7170
}
7271

72+
// Paper method added in 1.20.2+, hopefully should never change
73+
this.minecraftKeyClass = this.getClass("net.minecraft.resources.MinecraftKey");
74+
if (this.minecraftKeyClass != null) {
75+
this.sendCustomPayloadMethod = this.getMethod(craftPlayerClass, "sendCustomPayload", this.minecraftKeyClass, byte[].class);
76+
77+
if (this.sendCustomPayloadMethod != null) {
78+
this.packetPlayOutMinecraftKeyConstructor = this.getConstructor(this.minecraftKeyClass, String.class);
79+
80+
if (this.packetPlayOutMinecraftKeyConstructor == null) {
81+
this.resourceLocationParseMethod = this.getMethod(this.minecraftKeyClass, "parse", String.class);
82+
83+
if (this.resourceLocationParseMethod == null) {
84+
this.resourceLocationParseMethod = this.getMethod(this.minecraftKeyClass, "a", String.class);
85+
}
86+
}
87+
88+
return;
89+
}
90+
}
91+
7392
Class<?> nmsPlayerClass = this.getClass("net.minecraft.server.level.EntityPlayer");
7493
if (nmsPlayerClass == null) {
7594
throw new RuntimeException("Failed to find EntityPlayer class");
@@ -121,8 +140,6 @@ public BukkitPluginMessageSender(AbstractBukkitBadlionPlugin apiBukkit) {
121140
// If we made it this far in theory we are on at least 1.8
122141
this.packetPlayOutCustomPayloadConstructor = this.getConstructor(packetPlayOutCustomPayloadClass, String.class, this.packetDataSerializerClass);
123142
if (this.packetPlayOutCustomPayloadConstructor == null) {
124-
this.minecraftKeyClass = this.getClass("net.minecraft.resources.MinecraftKey");
125-
126143
// Fix for Paper in newer versions
127144
this.packetPlayOutCustomPayloadConstructor = this.getConstructor(packetPlayOutCustomPayloadClass, this.minecraftKeyClass, this.packetDataSerializerClass);
128145

@@ -218,6 +235,19 @@ public void sendPluginMessagePacket(Player player, String channel, Object data)
218235
try {
219236
Object packet;
220237

238+
if (this.sendCustomPayloadMethod != null) {
239+
Object key;
240+
241+
if (this.packetPlayOutMinecraftKeyConstructor == null) {
242+
key = this.resourceLocationParseMethod.invoke(null, channel);
243+
} else {
244+
key = this.packetPlayOutMinecraftKeyConstructor.newInstance(channel);
245+
}
246+
247+
this.sendCustomPayloadMethod.invoke(player, key, data);
248+
return;
249+
}
250+
221251
// Newer MC version, setup ByteBuf object
222252
if (this.packetDataSerializerClass != null) {
223253
if (this.usePacketPayload) {

0 commit comments

Comments
 (0)