|
38 | 38 | import com.github.games647.fastlogin.velocity.task.ForceLoginTask; |
39 | 39 | import com.google.common.cache.Cache; |
40 | 40 | import com.google.common.collect.ListMultimap; |
| 41 | +import com.velocitypowered.api.event.EventManager; |
41 | 42 | import com.velocitypowered.api.event.EventTask; |
42 | 43 | import com.velocitypowered.api.event.Subscribe; |
43 | 44 | import com.velocitypowered.api.event.connection.DisconnectEvent; |
|
51 | 52 | import com.velocitypowered.api.proxy.server.RegisteredServer; |
52 | 53 | import com.velocitypowered.api.util.GameProfile; |
53 | 54 | import com.velocitypowered.api.util.GameProfile.Property; |
54 | | - |
55 | 55 | import net.kyori.adventure.text.TextComponent; |
56 | 56 | import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; |
57 | 57 | import org.geysermc.floodgate.api.player.FloodgatePlayer; |
@@ -87,10 +87,9 @@ public EventTask onPreLogin(PreLoginEvent preLoginEvent) { |
87 | 87 | InetSocketAddress address = connection.getRemoteAddress(); |
88 | 88 | plugin.getLog().info("Incoming login request for {} from {}", username, address); |
89 | 89 |
|
90 | | - |
91 | 90 | // FloodgateVelocity only sets the correct username in GetProfileRequestEvent, but we need it here too. |
92 | 91 | if (plugin.getFloodgateService() != null) { |
93 | | - String floodgateUsername = getFloodgateUsername(preLoginEvent, connection); |
| 92 | + String floodgateUsername = getFloodgateUsername(connection); |
94 | 93 | if (floodgateUsername != null) { |
95 | 94 | plugin.getLog().info("Found player's Floodgate: {}", floodgateUsername); |
96 | 95 | username = floodgateUsername; |
@@ -197,65 +196,71 @@ public void onDisconnect(DisconnectEvent disconnectEvent) { |
197 | 196 |
|
198 | 197 | /** |
199 | 198 | * Get the Floodgate username from the Floodgate plugin's playerCache using lots of reflections |
200 | | - * @param preLoginEvent |
| 199 | + * |
201 | 200 | * @param connection |
202 | 201 | * @return the Floodgate username or null if not found |
203 | 202 | */ |
204 | | - private String getFloodgateUsername(PreLoginEvent preLoginEvent, InboundConnection connection) { |
| 203 | + private String getFloodgateUsername(InboundConnection connection) { |
205 | 204 | try { |
206 | | - // Get Velocity's event manager |
207 | | - Object eventManager = plugin.getServer().getEventManager(); |
208 | | - Field handlerField = eventManager.getClass().getDeclaredField("handlersByType"); |
209 | | - handlerField.setAccessible(true); |
210 | | - @SuppressWarnings("rawtypes") |
211 | | - ListMultimap handlersByType = (ListMultimap) handlerField.get(eventManager); |
212 | | - handlerField.setAccessible(false); |
213 | | - |
214 | | - // Get all registered PreLoginEvent handlers |
215 | | - @SuppressWarnings({ "rawtypes", "unchecked" }) |
216 | | - List preLoginEventHandlres = handlersByType.get(preLoginEvent.getClass()); |
217 | | - Field pluginField = preLoginEventHandlres.get(0).getClass().getDeclaredField("plugin"); |
218 | | - pluginField.setAccessible(true); |
219 | | - Object floodgateEventHandlerRegistration = null; |
220 | | - |
221 | | - // Find the Floodgate plugin's PreLoginEvent handler |
222 | | - for (Object handler : preLoginEventHandlres) { |
223 | | - PluginContainer eventHandlerPlugin = (PluginContainer) pluginField.get(handler); |
224 | | - String eventHandlerPluginName = eventHandlerPlugin.getInstance().get().getClass().getName(); |
225 | | - if (eventHandlerPluginName.equals(FLOODGATE_PLUGIN_NAME)) { |
226 | | - floodgateEventHandlerRegistration = handler; |
227 | | - break; |
228 | | - } |
229 | | - } |
230 | | - pluginField.setAccessible(false); |
231 | | - if (floodgateEventHandlerRegistration == null) { |
| 205 | + // get floodgate's event handler |
| 206 | + Object floodgateEventHandler = getFloodgateHandler(); |
| 207 | + if (floodgateEventHandler == null) { |
232 | 208 | return null; |
233 | 209 | } |
234 | 210 |
|
235 | | - // Extract the EventHandler instance from Velocity's internal registration handler storage |
236 | | - Field eventHandlerField = floodgateEventHandlerRegistration.getClass().getDeclaredField("instance"); |
237 | | - eventHandlerField.setAccessible(true); |
238 | | - Object floodgateEventHandler = eventHandlerField.get(floodgateEventHandlerRegistration); |
239 | | - eventHandlerField.setAccessible(false); |
240 | | - |
241 | 211 | // Get the Floodgate playerCache field |
242 | 212 | Field playerCacheField = floodgateEventHandler.getClass().getDeclaredField("playerCache"); |
243 | 213 | playerCacheField.setAccessible(true); |
244 | 214 | @SuppressWarnings("unchecked") |
245 | 215 | Cache<InboundConnection, FloodgatePlayer> playerCache = |
246 | | - (Cache<InboundConnection, FloodgatePlayer>) playerCacheField.get(floodgateEventHandler); |
247 | | - playerCacheField.setAccessible(false); |
| 216 | + (Cache<InboundConnection, FloodgatePlayer>) playerCacheField.get(floodgateEventHandler); |
248 | 217 |
|
249 | 218 | // Find the FloodgatePlayer instance in playerCache |
250 | 219 | FloodgatePlayer floodgatePlayer = playerCache.getIfPresent(connection); |
251 | 220 | if (floodgatePlayer == null) { |
252 | 221 | return null; |
253 | 222 | } |
254 | | - return floodgatePlayer.getCorrectUsername(); |
255 | 223 |
|
256 | | - } catch (Exception e) { |
257 | | - e.printStackTrace(); |
| 224 | + return floodgatePlayer.getCorrectUsername(); |
| 225 | + } catch (Exception ex) { |
| 226 | + plugin.getLog().error("Failed to fetch current floodgate username", ex); |
258 | 227 | } |
| 228 | + |
259 | 229 | return null; |
260 | 230 | } |
| 231 | + |
| 232 | + private Object getFloodgateHandler() |
| 233 | + throws NoSuchFieldException, IllegalAccessException { |
| 234 | + // Get Velocity's event manager |
| 235 | + EventManager eventManager = plugin.getServer().getEventManager(); |
| 236 | + Field handlerField = eventManager.getClass().getDeclaredField("handlersByType"); |
| 237 | + handlerField.setAccessible(true); |
| 238 | + @SuppressWarnings("unchecked") |
| 239 | + ListMultimap<Class<?>, ?> handlersByType = (ListMultimap<Class<?>, ?>) handlerField.get(eventManager); |
| 240 | + |
| 241 | + // Get all registered PreLoginEvent handlers |
| 242 | + List<?> loginEventRegistrations = handlersByType.get(PreLoginEvent.class); |
| 243 | + Field pluginField = loginEventRegistrations.get(0).getClass().getDeclaredField("plugin"); |
| 244 | + pluginField.setAccessible(true); |
| 245 | + |
| 246 | + // Find the Floodgate plugin's PreLoginEvent handler registration (Velocity implementation) |
| 247 | + Object floodgateRegistration = null; |
| 248 | + for (Object handler : loginEventRegistrations) { |
| 249 | + PluginContainer eventHandlerPlugin = (PluginContainer) pluginField.get(handler); |
| 250 | + String eventHandlerPluginName = eventHandlerPlugin.getInstance().get().getClass().getName(); |
| 251 | + if (eventHandlerPluginName.equals(FLOODGATE_PLUGIN_NAME)) { |
| 252 | + floodgateRegistration = handler; |
| 253 | + break; |
| 254 | + } |
| 255 | + } |
| 256 | + |
| 257 | + if (floodgateRegistration == null) { |
| 258 | + return null; |
| 259 | + } |
| 260 | + |
| 261 | + // Extract the EventHandler instance (floodgate impl) from Velocity's internal registration handler storage |
| 262 | + Field eventHandlerField = floodgateRegistration.getClass().getDeclaredField("instance"); |
| 263 | + eventHandlerField.setAccessible(true); |
| 264 | + return eventHandlerField.get(floodgateRegistration); |
| 265 | + } |
261 | 266 | } |
0 commit comments