1
0
mirror of https://github.com/GeyserMC/Floodgate.git synced 2026-01-04 15:31:48 +00:00

Add native Mojmap support for the spigot module

This commit is contained in:
Aurora
2025-06-20 18:52:13 +01:00
committed by Aurora
parent fa1e5fa571
commit 5c426b471d
2 changed files with 85 additions and 8 deletions

View File

@@ -135,6 +135,33 @@ public final class ReflectionUtils {
return clazz;
}
public static Class<?> getClassOrFallback(String className, String fallbackClassName1, String fallbackClassName2) {
Class<?> clazz = getClassSilently(className);
if (clazz != null) {
if (Constants.DEBUG_MODE) {
System.out.println("Found class (primary): " + clazz.getName());
}
return clazz;
}
clazz = getClassSilently(fallbackClassName1);
if (clazz != null) {
if (Constants.DEBUG_MODE) {
System.out.println("Found class (fallback1): " + clazz.getName());
}
return clazz;
}
// do throw an exception when both classes couldn't be found
clazz = ReflectionUtils.getClassOrThrow(fallbackClassName2);
if (Constants.DEBUG_MODE) {
System.out.println("Found class (fallback2): " + clazz.getName());
}
return clazz;
}
@Nullable
public static <T> Constructor<T> getConstructor(Class<T> clazz, boolean declared, Class<?>... parameters) {
try {
@@ -210,6 +237,28 @@ public final class ReflectionUtils {
return getField(clazz, fieldName, false);
}
/**
* Get a field from a class, it doesn't matter if the field is public or not. This method will
* first try to get a declared field and if that failed it'll try to get a public field.
*
* @param clazz the class to get the field from
* @param fieldName the name of the field
* @param fallbackFieldName the fallback incase fieldName doesn't exist
* @return the field if found from the name or fallback, otherwise null
*/
@Nullable
public static Field getField(Class<?> clazz, String fieldName, String fallbackFieldName) {
Field field = getField(clazz, fieldName, true);
if (field != null) {
return field;
}
field = getField(clazz, fieldName, false);
if (field != null) {
return field;
}
return getField(clazz, fallbackFieldName);
}
/**
* Get a field from a class without having to provide a field name.
*
@@ -418,6 +467,29 @@ public final class ReflectionUtils {
return getMethod(clazz, methodName, false, arguments);
}
/**
* Get a method from a class, it doesn't matter if the method is public or not. This method will
* first try to get a declared method and if that fails it'll try to get a public method.
*
* @param clazz the class to get the method from
* @param methodName the name of the method to find
* @param fallbackName the fallback instead methodName does not exist
* @param arguments the classes of the method arguments
* @return the requested method if it has been found, otherwise null
*/
@Nullable
public static Method getMethod(Class<?> clazz, String methodName, String fallbackName, Class<?>... arguments) {
Method method = getMethod(clazz, methodName, true, arguments);
if (method != null) {
return method;
}
method = getMethod(clazz, methodName, false, arguments);
if (method != null) {
return method;
}
return getMethod(clazz, fallbackName, arguments);
}
/**
* Get a method from a class, it doesn't matter if the method is public or not. This method will
* first try to get a declared method and if that fails it'll try to get a public method.

View File

@@ -115,7 +115,7 @@ public class ClassNames {
// SpigotSkinApplier
Class<?> craftPlayerClass = ReflectionUtils.getClass(
"org.bukkit.craftbukkit." + version + "entity.CraftPlayer");
"org.bukkit.craftbukkit.entity.CraftPlayer");
GET_PROFILE_METHOD = getMethod(craftPlayerClass, "getProfile");
checkNotNull(GET_PROFILE_METHOD, "Get profile method");
@@ -135,21 +135,23 @@ public class ClassNames {
);
SERVER_CONNECTION = getClassOrFallback(
"net.minecraft.server.network.ServerConnectionListener",
"net.minecraft.server.network.ServerConnection",
nmsPackage + "ServerConnection"
);
// WhitelistUtils
Class<?> craftServerClass = ReflectionUtils.getClass(
"org.bukkit.craftbukkit." + version + "CraftServer");
"org.bukkit.craftbukkit.CraftServer");
Class<OfflinePlayer> craftOfflinePlayerClass = ReflectionUtils.getCastedClass(
"org.bukkit.craftbukkit." + version + "CraftOfflinePlayer");
"org.bukkit.craftbukkit.CraftOfflinePlayer");
CRAFT_OFFLINE_PLAYER_CONSTRUCTOR = ReflectionUtils.getConstructor(
craftOfflinePlayerClass, true, craftServerClass, GameProfile.class);
// SpigotDataHandler
Class<?> networkManager = getClassOrFallback(
"net.minecraft.network.Connection",
"net.minecraft.network.NetworkManager",
nmsPackage + "NetworkManager"
);
@@ -157,6 +159,7 @@ public class ClassNames {
SOCKET_ADDRESS = getFieldOfType(networkManager, SocketAddress.class, false);
HANDSHAKE_PACKET = getClassOrFallback(
"net.minecraft.network.protocol.handshake.ClientIntentionPacket",
"net.minecraft.network.protocol.handshake.PacketHandshakingInSetProtocol",
nmsPackage + "PacketHandshakingInSetProtocol"
);
@@ -165,11 +168,13 @@ public class ClassNames {
checkNotNull(HANDSHAKE_HOST, "Handshake host");
LOGIN_START_PACKET = getClassOrFallback(
"net.minecraft.network.protocol.login.ServerboundHelloPacket",
"net.minecraft.network.protocol.login.PacketLoginInStart",
nmsPackage + "PacketLoginInStart"
);
LOGIN_LISTENER = getClassOrFallback(
"net.minecraft.server.network.ServerLoginPacketListenerImpl",
"net.minecraft.server.network.LoginListener",
nmsPackage + "LoginListener"
);
@@ -210,7 +215,7 @@ public class ClassNames {
// We get the field by name on 1.20.2+ as there are now multiple fields of this type in network manager
// PacketListener packetListener of NetworkManager
PACKET_LISTENER = getField(networkManager, "q");
PACKET_LISTENER = getField(networkManager, "packetListener", "q");
makeAccessible(PACKET_LISTENER);
}
checkNotNull(PACKET_LISTENER, "Packet listener");
@@ -218,7 +223,7 @@ public class ClassNames {
if (IS_POST_LOGIN_HANDLER) {
makeAccessible(CALL_PLAYER_PRE_LOGIN_EVENTS);
START_CLIENT_VERIFICATION = getMethod(LOGIN_LISTENER, "b", GameProfile.class);
START_CLIENT_VERIFICATION = getMethod(LOGIN_LISTENER, "startClientVerification", "b", GameProfile.class);
checkNotNull(START_CLIENT_VERIFICATION, "startClientVerification");
makeAccessible(START_CLIENT_VERIFICATION);
@@ -314,15 +319,15 @@ public class ClassNames {
String.class, int.class, CLIENT_INTENT);
checkNotNull(HANDSHAKE_PACKET_CONSTRUCTOR, "Handshake packet constructor");
Field a = getField(HANDSHAKE_PACKET, "a");
Field a = getField(HANDSHAKE_PACKET, "STREAM_CODEC", "a");
checkNotNull(a, "Handshake \"a\" field (protocol version, or stream codec)");
if (a.getType().isPrimitive()) { // 1.20.2 - 1.20.4: a is the protocol version (int)
HANDSHAKE_PROTOCOL = a;
HANDSHAKE_PORT = getField(HANDSHAKE_PACKET, "c");
} else { // 1.20.5: a is the stream_codec thing, so everything is shifted
HANDSHAKE_PROTOCOL = getField(HANDSHAKE_PACKET, "b");
HANDSHAKE_PORT = getField(HANDSHAKE_PACKET, "d");
HANDSHAKE_PROTOCOL = getField(HANDSHAKE_PACKET, "protocolVersion", "b");
HANDSHAKE_PORT = getField(HANDSHAKE_PACKET, "port", "d");
}
checkNotNull(HANDSHAKE_PROTOCOL, "Handshake protocol");