Skip to content

Commit c781693

Browse files
authored
Add native Mojmap support for the spigot module (#591)
* Add native Mojmap support for the spigot module * Don't remove spigot class name for CraftPlayer * Also include CraftServer and CraftOfflinePlayer
1 parent fa1e5fa commit c781693

File tree

2 files changed

+100
-11
lines changed

2 files changed

+100
-11
lines changed

core/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,39 @@ public static Class<?> getClassOrFallback(String className, String fallbackClass
135135
return clazz;
136136
}
137137

138+
public static Class<?> getClassOrFallback(String className, String fallbackClassName1, String fallbackClassName2) {
139+
Class<?> clazz = getClassSilently(className);
140+
141+
if (clazz != null) {
142+
if (Constants.DEBUG_MODE) {
143+
System.out.println("Found class (primary): " + clazz.getName());
144+
}
145+
return clazz;
146+
}
147+
148+
clazz = getClassSilently(fallbackClassName1);
149+
150+
if (clazz != null) {
151+
if (Constants.DEBUG_MODE) {
152+
System.out.println("Found class (fallback1): " + clazz.getName());
153+
}
154+
return clazz;
155+
}
156+
157+
// do throw an exception when both classes couldn't be found
158+
clazz = ReflectionUtils.getClassOrThrow(fallbackClassName2);
159+
if (Constants.DEBUG_MODE) {
160+
System.out.println("Found class (fallback2): " + clazz.getName());
161+
}
162+
return clazz;
163+
}
164+
165+
@Nullable
166+
@SuppressWarnings("unchecked")
167+
public static <T> Class<T> getCastedClassOrFallback(String className, String fallbackClassName) {
168+
return (Class<T>) getClassOrFallback(className, fallbackClassName);
169+
}
170+
138171
@Nullable
139172
public static <T> Constructor<T> getConstructor(Class<T> clazz, boolean declared, Class<?>... parameters) {
140173
try {
@@ -210,6 +243,28 @@ public static Field getField(Class<?> clazz, String fieldName) {
210243
return getField(clazz, fieldName, false);
211244
}
212245

246+
/**
247+
* Get a field from a class, it doesn't matter if the field is public or not. This method will
248+
* first try to get a declared field and if that failed it'll try to get a public field.
249+
*
250+
* @param clazz the class to get the field from
251+
* @param fieldName the name of the field
252+
* @param fallbackFieldName the fallback incase fieldName doesn't exist
253+
* @return the field if found from the name or fallback, otherwise null
254+
*/
255+
@Nullable
256+
public static Field getField(Class<?> clazz, String fieldName, String fallbackFieldName) {
257+
Field field = getField(clazz, fieldName, true);
258+
if (field != null) {
259+
return field;
260+
}
261+
field = getField(clazz, fieldName, false);
262+
if (field != null) {
263+
return field;
264+
}
265+
return getField(clazz, fallbackFieldName);
266+
}
267+
213268
/**
214269
* Get a field from a class without having to provide a field name.
215270
*
@@ -418,6 +473,29 @@ public static Method getMethod(Class<?> clazz, String methodName, Class<?>... ar
418473
return getMethod(clazz, methodName, false, arguments);
419474
}
420475

476+
/**
477+
* Get a method from a class, it doesn't matter if the method is public or not. This method will
478+
* first try to get a declared method and if that fails it'll try to get a public method.
479+
*
480+
* @param clazz the class to get the method from
481+
* @param methodName the name of the method to find
482+
* @param fallbackName the fallback instead methodName does not exist
483+
* @param arguments the classes of the method arguments
484+
* @return the requested method if it has been found, otherwise null
485+
*/
486+
@Nullable
487+
public static Method getMethod(Class<?> clazz, String methodName, String fallbackName, Class<?>... arguments) {
488+
Method method = getMethod(clazz, methodName, true, arguments);
489+
if (method != null) {
490+
return method;
491+
}
492+
method = getMethod(clazz, methodName, false, arguments);
493+
if (method != null) {
494+
return method;
495+
}
496+
return getMethod(clazz, fallbackName, arguments);
497+
}
498+
421499
/**
422500
* Get a method from a class, it doesn't matter if the method is public or not. This method will
423501
* first try to get a declared method and if that fails it'll try to get a public method.

spigot/src/main/java/org/geysermc/floodgate/util/ClassNames.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,10 @@ public class ClassNames {
114114

115115

116116
// SpigotSkinApplier
117-
Class<?> craftPlayerClass = ReflectionUtils.getClass(
118-
"org.bukkit.craftbukkit." + version + "entity.CraftPlayer");
117+
Class<?> craftPlayerClass = getClassOrFallback(
118+
"org.bukkit.craftbukkit.entity.CraftPlayer",
119+
"org.bukkit.craftbukkit." + version + "entity.CraftPlayer"
120+
);
119121
GET_PROFILE_METHOD = getMethod(craftPlayerClass, "getProfile");
120122
checkNotNull(GET_PROFILE_METHOD, "Get profile method");
121123

@@ -135,28 +137,35 @@ public class ClassNames {
135137
);
136138

137139
SERVER_CONNECTION = getClassOrFallback(
140+
"net.minecraft.server.network.ServerConnectionListener",
138141
"net.minecraft.server.network.ServerConnection",
139142
nmsPackage + "ServerConnection"
140143
);
141144

142145
// WhitelistUtils
143-
Class<?> craftServerClass = ReflectionUtils.getClass(
144-
"org.bukkit.craftbukkit." + version + "CraftServer");
145-
Class<OfflinePlayer> craftOfflinePlayerClass = ReflectionUtils.getCastedClass(
146-
"org.bukkit.craftbukkit." + version + "CraftOfflinePlayer");
146+
Class<?> craftServerClass = getClassOrFallback(
147+
"org.bukkit.craftbukkit.CraftServer",
148+
"org.bukkit.craftbukkit." + version + "CraftServer"
149+
);
150+
Class<OfflinePlayer> craftOfflinePlayerClass = ReflectionUtils.getCastedClassOrFallback(
151+
"org.bukkit.craftbukkit.CraftOfflinePlayer",
152+
"org.bukkit.craftbukkit." + version + "CraftOfflinePlayer"
153+
);
147154

148155
CRAFT_OFFLINE_PLAYER_CONSTRUCTOR = ReflectionUtils.getConstructor(
149156
craftOfflinePlayerClass, true, craftServerClass, GameProfile.class);
150157

151158
// SpigotDataHandler
152159
Class<?> networkManager = getClassOrFallback(
160+
"net.minecraft.network.Connection",
153161
"net.minecraft.network.NetworkManager",
154162
nmsPackage + "NetworkManager"
155163
);
156164

157165
SOCKET_ADDRESS = getFieldOfType(networkManager, SocketAddress.class, false);
158166

159167
HANDSHAKE_PACKET = getClassOrFallback(
168+
"net.minecraft.network.protocol.handshake.ClientIntentionPacket",
160169
"net.minecraft.network.protocol.handshake.PacketHandshakingInSetProtocol",
161170
nmsPackage + "PacketHandshakingInSetProtocol"
162171
);
@@ -165,11 +174,13 @@ public class ClassNames {
165174
checkNotNull(HANDSHAKE_HOST, "Handshake host");
166175

167176
LOGIN_START_PACKET = getClassOrFallback(
177+
"net.minecraft.network.protocol.login.ServerboundHelloPacket",
168178
"net.minecraft.network.protocol.login.PacketLoginInStart",
169179
nmsPackage + "PacketLoginInStart"
170180
);
171181

172182
LOGIN_LISTENER = getClassOrFallback(
183+
"net.minecraft.server.network.ServerLoginPacketListenerImpl",
173184
"net.minecraft.server.network.LoginListener",
174185
nmsPackage + "LoginListener"
175186
);
@@ -210,15 +221,15 @@ public class ClassNames {
210221
// We get the field by name on 1.20.2+ as there are now multiple fields of this type in network manager
211222

212223
// PacketListener packetListener of NetworkManager
213-
PACKET_LISTENER = getField(networkManager, "q");
224+
PACKET_LISTENER = getField(networkManager, "packetListener", "q");
214225
makeAccessible(PACKET_LISTENER);
215226
}
216227
checkNotNull(PACKET_LISTENER, "Packet listener");
217228

218229
if (IS_POST_LOGIN_HANDLER) {
219230
makeAccessible(CALL_PLAYER_PRE_LOGIN_EVENTS);
220231

221-
START_CLIENT_VERIFICATION = getMethod(LOGIN_LISTENER, "b", GameProfile.class);
232+
START_CLIENT_VERIFICATION = getMethod(LOGIN_LISTENER, "startClientVerification", "b", GameProfile.class);
222233
checkNotNull(START_CLIENT_VERIFICATION, "startClientVerification");
223234
makeAccessible(START_CLIENT_VERIFICATION);
224235

@@ -314,15 +325,15 @@ public class ClassNames {
314325
String.class, int.class, CLIENT_INTENT);
315326
checkNotNull(HANDSHAKE_PACKET_CONSTRUCTOR, "Handshake packet constructor");
316327

317-
Field a = getField(HANDSHAKE_PACKET, "a");
328+
Field a = getField(HANDSHAKE_PACKET, "STREAM_CODEC", "a");
318329
checkNotNull(a, "Handshake \"a\" field (protocol version, or stream codec)");
319330

320331
if (a.getType().isPrimitive()) { // 1.20.2 - 1.20.4: a is the protocol version (int)
321332
HANDSHAKE_PROTOCOL = a;
322333
HANDSHAKE_PORT = getField(HANDSHAKE_PACKET, "c");
323334
} else { // 1.20.5: a is the stream_codec thing, so everything is shifted
324-
HANDSHAKE_PROTOCOL = getField(HANDSHAKE_PACKET, "b");
325-
HANDSHAKE_PORT = getField(HANDSHAKE_PACKET, "d");
335+
HANDSHAKE_PROTOCOL = getField(HANDSHAKE_PACKET, "protocolVersion", "b");
336+
HANDSHAKE_PORT = getField(HANDSHAKE_PACKET, "port", "d");
326337
}
327338

328339
checkNotNull(HANDSHAKE_PROTOCOL, "Handshake protocol");

0 commit comments

Comments
 (0)