From 921d706c1ebdcfbe93803187c98ec5532667536f Mon Sep 17 00:00:00 2001 From: Tim203 Date: Sat, 30 Dec 2023 21:19:29 +0100 Subject: [PATCH] Made Floodgate compatible with latest Spigot changes --- .../addon/data/SpigotDataHandler.java | 26 +++++---- .../geysermc/floodgate/util/ClassNames.java | 54 ++++++++++++++----- 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java b/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java index 55dfc36e..75e7057c 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java +++ b/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java @@ -167,31 +167,35 @@ public final class SpigotDataHandler extends CommonDataHandler { } } - // set the player his GameProfile, we can't change the username without this GameProfile gameProfile = new GameProfile( player.getCorrectUniqueId(), player.getCorrectUsername() ); - setValue(packetListener, ClassNames.LOGIN_PROFILE, gameProfile); // we have to fake the offline player (login) cycle - // just like on Spigot: - - Object loginHandler = ClassNames.LOGIN_HANDLER_CONSTRUCTOR.newInstance(packetListener); if (ClassNames.IS_PRE_1_20_2) { // 1.20.1 and below - - // LoginListener#initUUID - // new LoginHandler().fireEvents(); - + // - set profile, otherwise the username doesn't change + // - LoginListener#initUUID + // - new LoginHandler().fireEvents(); // and the tick of LoginListener will do the rest + Object loginHandler = ClassNames.LOGIN_HANDLER_CONSTRUCTOR.newInstance(packetListener); + setValue(packetListener, ClassNames.LOGIN_PROFILE, gameProfile); ClassNames.INIT_UUID.invoke(packetListener); ClassNames.FIRE_LOGIN_EVENTS.invoke(loginHandler); - } else { - // 1.20.2 and above we directly register the profile + } else if (!ClassNames.IS_POST_LOGIN_HANDLER) { + // 1.20.2 until somewhere in 1.20.4 we can directly register the profile + Object loginHandler = ClassNames.LOGIN_HANDLER_CONSTRUCTOR.newInstance(packetListener); ClassNames.FIRE_LOGIN_EVENTS_GAME_PROFILE.invoke(loginHandler, gameProfile); + } else { + // somewhere during 1.20.4 md_5 moved stuff to CraftBukkit + + // LoginListener#callPlayerPreLoginEvents(GameProfile) + // LoginListener#startClientVerification(GameProfile) + ClassNames.CALL_PLAYER_PRE_LOGIN_EVENTS.invoke(packetListener, gameProfile); + ClassNames.START_CLIENT_VERIFICATION.invoke(packetListener, gameProfile); } ctx.pipeline().remove(this); diff --git a/spigot/src/main/java/org/geysermc/floodgate/util/ClassNames.java b/spigot/src/main/java/org/geysermc/floodgate/util/ClassNames.java index 77e00cc7..b0eee8f0 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/util/ClassNames.java +++ b/spigot/src/main/java/org/geysermc/floodgate/util/ClassNames.java @@ -59,11 +59,10 @@ public class ClassNames { public static final Class HANDSHAKE_PACKET; public static final Class LOGIN_START_PACKET; public static final Class LOGIN_LISTENER; - public static final Class LOGIN_HANDLER; @Nullable public static final Class CLIENT_INTENT; public static final Constructor CRAFT_OFFLINE_PLAYER_CONSTRUCTOR; - public static final Constructor LOGIN_HANDLER_CONSTRUCTOR; + @Nullable public static final Constructor LOGIN_HANDLER_CONSTRUCTOR; @Nullable public static final Constructor HANDSHAKE_PACKET_CONSTRUCTOR; public static final Field SOCKET_ADDRESS; @@ -84,13 +83,17 @@ public class ClassNames { @Nullable public static final Method INIT_UUID; @Nullable public static final Method FIRE_LOGIN_EVENTS; @Nullable public static final Method FIRE_LOGIN_EVENTS_GAME_PROFILE; + @Nullable public static final Method CALL_PLAYER_PRE_LOGIN_EVENTS; + @Nullable public static final Method START_CLIENT_VERIFICATION; public static final Field BUNGEE; public static final boolean IS_FOLIA; public static final boolean IS_PRE_1_20_2; + public static final boolean IS_POST_LOGIN_HANDLER; static { + // ahhhhhhh, this class should really be reworked at this point String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; SPIGOT_MAPPING_PREFIX = "net.minecraft.server." + version; @@ -167,6 +170,14 @@ public class ClassNames { INIT_UUID = getMethod(LOGIN_LISTENER, "initUUID"); IS_PRE_1_20_2 = INIT_UUID != null; + // somewhere during 1.20.4 md_5 moved PreLogin logic to CraftBukkit + CALL_PLAYER_PRE_LOGIN_EVENTS = getMethod( + LOGIN_LISTENER, + "callPlayerPreLoginEvents", + GameProfile.class + ); + IS_POST_LOGIN_HANDLER = CALL_PLAYER_PRE_LOGIN_EVENTS != null; + if (IS_PRE_1_20_2) { Class packetListenerClass = getClassOrFallback( "net.minecraft.network.PacketListener", @@ -183,21 +194,36 @@ public class ClassNames { } checkNotNull(PACKET_LISTENER, "Packet listener"); - LOGIN_HANDLER = getClassOrFallback( - "net.minecraft.server.network.LoginListener$LoginHandler", - nmsPackage + "LoginListener$LoginHandler" - ); + if (IS_POST_LOGIN_HANDLER) { + makeAccessible(CALL_PLAYER_PRE_LOGIN_EVENTS); - LOGIN_HANDLER_CONSTRUCTOR = - ReflectionUtils.getConstructor(LOGIN_HANDLER, true, LOGIN_LISTENER); - checkNotNull(LOGIN_HANDLER_CONSTRUCTOR, "LoginHandler constructor"); + START_CLIENT_VERIFICATION = getMethod(LOGIN_LISTENER, "b", GameProfile.class); + checkNotNull(START_CLIENT_VERIFICATION, "startClientVerification"); + makeAccessible(START_CLIENT_VERIFICATION); - FIRE_LOGIN_EVENTS = getMethod(LOGIN_HANDLER, "fireEvents"); + LOGIN_HANDLER_CONSTRUCTOR = null; + FIRE_LOGIN_EVENTS = null; + FIRE_LOGIN_EVENTS_GAME_PROFILE = null; + } else { + Class loginHandler = getClassOrFallback( + "net.minecraft.server.network.LoginListener$LoginHandler", + nmsPackage + "LoginListener$LoginHandler" + ); - // LoginHandler().fireEvents(GameProfile) - FIRE_LOGIN_EVENTS_GAME_PROFILE = getMethod(LOGIN_HANDLER, "fireEvents", GameProfile.class); - checkNotNull(FIRE_LOGIN_EVENTS, FIRE_LOGIN_EVENTS_GAME_PROFILE, - "fireEvents from LoginHandler", "fireEvents(GameProfile) from LoginHandler"); + LOGIN_HANDLER_CONSTRUCTOR = + ReflectionUtils.getConstructor(loginHandler, true, LOGIN_LISTENER); + checkNotNull(LOGIN_HANDLER_CONSTRUCTOR, "LoginHandler constructor"); + + FIRE_LOGIN_EVENTS = getMethod(loginHandler, "fireEvents"); + + // LoginHandler().fireEvents(GameProfile) + FIRE_LOGIN_EVENTS_GAME_PROFILE = getMethod(loginHandler, "fireEvents", + GameProfile.class); + checkNotNull(FIRE_LOGIN_EVENTS, FIRE_LOGIN_EVENTS_GAME_PROFILE, + "fireEvents from LoginHandler", "fireEvents(GameProfile) from LoginHandler"); + + START_CLIENT_VERIFICATION = null; + } PAPER_DISABLE_USERNAME_VALIDATION = getField(LOGIN_LISTENER, "iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation");