Minor code styling

* Use logging instead of raw exception printing
* Extract method
* Shorter var names
* More precise generics if possible
* Don't restore accessible state could be in conflict with other plugins
if we don't restore the exact value
This commit is contained in:
games647
2024-07-08 10:46:48 +02:00
parent 9a40cf0afb
commit 7f488498cf

View File

@ -38,6 +38,7 @@ import com.github.games647.fastlogin.velocity.task.FloodgateAuthTask;
import com.github.games647.fastlogin.velocity.task.ForceLoginTask; import com.github.games647.fastlogin.velocity.task.ForceLoginTask;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.collect.ListMultimap; import com.google.common.collect.ListMultimap;
import com.velocitypowered.api.event.EventManager;
import com.velocitypowered.api.event.EventTask; import com.velocitypowered.api.event.EventTask;
import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.DisconnectEvent; import com.velocitypowered.api.event.connection.DisconnectEvent;
@ -51,7 +52,6 @@ import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.api.util.GameProfile.Property; import com.velocitypowered.api.util.GameProfile.Property;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.api.player.FloodgatePlayer;
@ -87,10 +87,9 @@ public class ConnectListener {
InetSocketAddress address = connection.getRemoteAddress(); InetSocketAddress address = connection.getRemoteAddress();
plugin.getLog().info("Incoming login request for {} from {}", username, address); plugin.getLog().info("Incoming login request for {} from {}", username, address);
// FloodgateVelocity only sets the correct username in GetProfileRequestEvent, but we need it here too. // FloodgateVelocity only sets the correct username in GetProfileRequestEvent, but we need it here too.
if (plugin.getFloodgateService() != null) { if (plugin.getFloodgateService() != null) {
String floodgateUsername = getFloodgateUsername(preLoginEvent, connection); String floodgateUsername = getFloodgateUsername(connection);
if (floodgateUsername != null) { if (floodgateUsername != null) {
plugin.getLog().info("Found player's Floodgate: {}", floodgateUsername); plugin.getLog().info("Found player's Floodgate: {}", floodgateUsername);
username = floodgateUsername; username = floodgateUsername;
@ -197,65 +196,71 @@ public class ConnectListener {
/** /**
* Get the Floodgate username from the Floodgate plugin's playerCache using lots of reflections * Get the Floodgate username from the Floodgate plugin's playerCache using lots of reflections
* @param preLoginEvent *
* @param connection * @param connection
* @return the Floodgate username or null if not found * @return the Floodgate username or null if not found
*/ */
private String getFloodgateUsername(PreLoginEvent preLoginEvent, InboundConnection connection) { private String getFloodgateUsername(InboundConnection connection) {
try { try {
// Get Velocity's event manager // get floodgate's event handler
Object eventManager = plugin.getServer().getEventManager(); Object floodgateEventHandler = getFloodgateHandler();
Field handlerField = eventManager.getClass().getDeclaredField("handlersByType"); if (floodgateEventHandler == null) {
handlerField.setAccessible(true);
@SuppressWarnings("rawtypes")
ListMultimap handlersByType = (ListMultimap) handlerField.get(eventManager);
handlerField.setAccessible(false);
// Get all registered PreLoginEvent handlers
@SuppressWarnings({ "rawtypes", "unchecked" })
List preLoginEventHandlres = handlersByType.get(preLoginEvent.getClass());
Field pluginField = preLoginEventHandlres.get(0).getClass().getDeclaredField("plugin");
pluginField.setAccessible(true);
Object floodgateEventHandlerRegistration = null;
// Find the Floodgate plugin's PreLoginEvent handler
for (Object handler : preLoginEventHandlres) {
PluginContainer eventHandlerPlugin = (PluginContainer) pluginField.get(handler);
String eventHandlerPluginName = eventHandlerPlugin.getInstance().get().getClass().getName();
if (eventHandlerPluginName.equals(FLOODGATE_PLUGIN_NAME)) {
floodgateEventHandlerRegistration = handler;
break;
}
}
pluginField.setAccessible(false);
if (floodgateEventHandlerRegistration == null) {
return null; return null;
} }
// Extract the EventHandler instance from Velocity's internal registration handler storage
Field eventHandlerField = floodgateEventHandlerRegistration.getClass().getDeclaredField("instance");
eventHandlerField.setAccessible(true);
Object floodgateEventHandler = eventHandlerField.get(floodgateEventHandlerRegistration);
eventHandlerField.setAccessible(false);
// Get the Floodgate playerCache field // Get the Floodgate playerCache field
Field playerCacheField = floodgateEventHandler.getClass().getDeclaredField("playerCache"); Field playerCacheField = floodgateEventHandler.getClass().getDeclaredField("playerCache");
playerCacheField.setAccessible(true); playerCacheField.setAccessible(true);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Cache<InboundConnection, FloodgatePlayer> playerCache = Cache<InboundConnection, FloodgatePlayer> playerCache =
(Cache<InboundConnection, FloodgatePlayer>) playerCacheField.get(floodgateEventHandler); (Cache<InboundConnection, FloodgatePlayer>) playerCacheField.get(floodgateEventHandler);
playerCacheField.setAccessible(false);
// Find the FloodgatePlayer instance in playerCache // Find the FloodgatePlayer instance in playerCache
FloodgatePlayer floodgatePlayer = playerCache.getIfPresent(connection); FloodgatePlayer floodgatePlayer = playerCache.getIfPresent(connection);
if (floodgatePlayer == null) { if (floodgatePlayer == null) {
return null; return null;
} }
return floodgatePlayer.getCorrectUsername();
} catch (Exception e) { return floodgatePlayer.getCorrectUsername();
e.printStackTrace(); } catch (Exception ex) {
plugin.getLog().error("Failed to fetch current floodgate username", ex);
} }
return null; return null;
} }
private Object getFloodgateHandler()
throws NoSuchFieldException, IllegalAccessException {
// Get Velocity's event manager
EventManager eventManager = plugin.getServer().getEventManager();
Field handlerField = eventManager.getClass().getDeclaredField("handlersByType");
handlerField.setAccessible(true);
@SuppressWarnings("unchecked")
ListMultimap<Class<?>, ?> handlersByType = (ListMultimap<Class<?>, ?>) handlerField.get(eventManager);
// Get all registered PreLoginEvent handlers
List<?> loginEventRegistrations = handlersByType.get(PreLoginEvent.class);
Field pluginField = loginEventRegistrations.get(0).getClass().getDeclaredField("plugin");
pluginField.setAccessible(true);
// Find the Floodgate plugin's PreLoginEvent handler registration (Velocity implementation)
Object floodgateRegistration = null;
for (Object handler : loginEventRegistrations) {
PluginContainer eventHandlerPlugin = (PluginContainer) pluginField.get(handler);
String eventHandlerPluginName = eventHandlerPlugin.getInstance().get().getClass().getName();
if (eventHandlerPluginName.equals(FLOODGATE_PLUGIN_NAME)) {
floodgateRegistration = handler;
break;
}
}
if (floodgateRegistration == null) {
return null;
}
// Extract the EventHandler instance (floodgate impl) from Velocity's internal registration handler storage
Field eventHandlerField = floodgateRegistration.getClass().getDeclaredField("instance");
eventHandlerField.setAccessible(true);
return eventHandlerField.get(floodgateRegistration);
}
} }