From ebdf927a382dfefd64bf392d51dcbb0711273431 Mon Sep 17 00:00:00 2001 From: gbpii Date: Fri, 27 Mar 2026 17:28:11 +0300 Subject: [PATCH] Fix LimboAPI login injection on Velocity-CTD (DEFAULT_PERMISSION_RESOLVER fallback) Velocity-CTD does not expose ConnectedPlayer.DEFAULT_PERMISSIONS (it uses DEFAULT_PERMISSION_RESOLVER instead), which caused LoginTasksQueue static initialization to fail with NoSuchFieldException during player connect. Update LoginTasksQueue to prefer DEFAULT_PERMISSIONS when present (standard Velocity), and when absent, reflect DEFAULT_PERMISSION_RESOLVER and wrap it into a PermissionProvider so PermissionsSetupEvent can still run. This restores LimboAPI login injection compatibility with Velocity-CTD. --- .../injection/login/LoginTasksQueue.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/plugin/src/main/java/net/elytrium/limboapi/injection/login/LoginTasksQueue.java b/plugin/src/main/java/net/elytrium/limboapi/injection/login/LoginTasksQueue.java index c312718f..e850670c 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/injection/login/LoginTasksQueue.java +++ b/plugin/src/main/java/net/elytrium/limboapi/injection/login/LoginTasksQueue.java @@ -292,9 +292,19 @@ private void connectToServer(Logger logger, ConnectedPlayer player, MinecraftCon PROFILE_FIELD = MethodHandles.privateLookupIn(ConnectedPlayer.class, MethodHandles.lookup()) .findSetter(ConnectedPlayer.class, "profile", GameProfile.class); - Field defaultPermissionsField = ConnectedPlayer.class.getDeclaredField("DEFAULT_PERMISSIONS"); - defaultPermissionsField.setAccessible(true); - DEFAULT_PERMISSIONS = (PermissionProvider) defaultPermissionsField.get(null); + PermissionProvider defaultPermissions; + try { + Field defaultPermissionsField = ConnectedPlayer.class.getDeclaredField("DEFAULT_PERMISSIONS"); + defaultPermissionsField.setAccessible(true); + defaultPermissions = (PermissionProvider) defaultPermissionsField.get(null); + } catch (NoSuchFieldException e) { + Field defaultPermissionResolverField = ConnectedPlayer.class.getDeclaredField("DEFAULT_PERMISSION_RESOLVER"); + defaultPermissionResolverField.setAccessible(true); + PermissionFunction defaultResolver = (PermissionFunction) defaultPermissionResolverField.get(null); + // Velocity-CTD does not expose DEFAULT_PERMISSIONS; adapt its resolver to the PermissionProvider contract. + defaultPermissions = subject -> (PermissionFunction) defaultResolver; + } + DEFAULT_PERMISSIONS = defaultPermissions; SET_PERMISSION_FUNCTION_METHOD = MethodHandles.privateLookupIn(ConnectedPlayer.class, MethodHandles.lookup()) .findVirtual(ConnectedPlayer.class, "setPermissionFunction", MethodType.methodType(void.class, PermissionFunction.class));