From 948a0d673e8f9a50c989f7972c70ee50f2501a27 Mon Sep 17 00:00:00 2001 From: Angelillo15 Date: Sun, 8 Dec 2024 21:01:06 +0100 Subject: [PATCH] feat: add LuckPermsPermissionInterceptor to create StaffPlayers when the plugins detects a permission change --- .../com/nookure/staff/paper/NookureStaff.java | 28 +++++- .../LuckPermsPermissionInterceptor.java | 92 +++++++++++++++++++ 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 NookureStaff-Paper/src/main/java/com/nookure/staff/paper/permission/LuckPermsPermissionInterceptor.java diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/NookureStaff.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/NookureStaff.java index 5b71f6b3..daec3205 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/NookureStaff.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/NookureStaff.java @@ -56,6 +56,7 @@ import com.nookure.staff.paper.messaging.BackendMessageMessenger; import com.nookure.staff.paper.note.command.ParentNoteCommand; import com.nookure.staff.paper.note.listener.OnPlayerNoteJoin; +import com.nookure.staff.paper.permission.LuckPermsPermissionInterceptor; import com.nookure.staff.paper.pin.command.ChangePin; import com.nookure.staff.paper.pin.command.DeletePinCommand; import com.nookure.staff.paper.pin.command.SetPinCommand; @@ -70,6 +71,7 @@ import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; +import java.io.Closeable; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; @@ -77,6 +79,8 @@ @Singleton public class NookureStaff { private final ArrayList listeners = new ArrayList<>(); + private final ArrayList closeablesListeners = new ArrayList<>(); + private final List> loadersClass; private final List loaders = new ArrayList<>(); @@ -218,6 +222,15 @@ private void loadBukkitListeners() { if (config.get().modules.isPinCode()) { registerListener(OnInventoryClose.class); } + + if (config.get().permission.watchLuckPermsPermissions) { + try { + Class.forName("net.luckperms.api.LuckPerms"); + closeablesListeners.add(injector.getInstance(LuckPermsPermissionInterceptor.class)); + } catch (ClassNotFoundException e) { + logger.warning("LuckPerms is not installed on the server, disabling LuckPerms permission interceptor"); + } + } } public void registerListener(Class listener) { @@ -229,9 +242,22 @@ public void registerListener(Class listener) { } public void unregisterListeners() { + logger.debug("Unregistering Bukkit listeners..."); HandlerList.getHandlerLists().forEach(listener -> listeners.forEach(listener::unregister)); - listeners.clear(); + + logger.debug("Closing closeables listeners..."); + closeablesListeners.forEach(closeable -> { + try { + closeable.close(); + } catch (Exception e) { + logger.severe("An error occurred while closing listener %s, %s", closeable.getClass().getName(), e); + } + }); + + closeablesListeners.clear(); + + logger.debug("Listeners unregistered"); } private void loadLoaders() { diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/permission/LuckPermsPermissionInterceptor.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/permission/LuckPermsPermissionInterceptor.java new file mode 100644 index 00000000..366d836b --- /dev/null +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/permission/LuckPermsPermissionInterceptor.java @@ -0,0 +1,92 @@ +package com.nookure.staff.paper.permission; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import com.nookure.staff.api.util.PlayerTransformer; +import com.nookure.staff.paper.bootstrap.StaffBootstrapper; +import net.luckperms.api.LuckPerms; +import net.luckperms.api.event.EventSubscription; +import net.luckperms.api.event.node.NodeAddEvent; +import net.luckperms.api.model.group.Group; +import net.luckperms.api.model.user.User; +import org.bukkit.Bukkit; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.jetbrains.annotations.NotNull; + +import java.io.Closeable; +import java.util.Optional; + +@Singleton +public final class LuckPermsPermissionInterceptor implements Closeable { + private final EventSubscription nodeAddEventEventSubscription; + private final PlayerTransformer playerTransformer; + + private static final String BASE_PERMISSION = "nookure.staff"; + private static final String GROUP_PERMISSION = "group."; + + @Inject + public LuckPermsPermissionInterceptor( + @NotNull final StaffBootstrapper bootstrapper, + @NotNull final PlayerTransformer playerTransformer + ) { + RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); + + if (provider == null) { + throw new IllegalStateException("LuckPerms is not installed on the server."); + } + + LuckPerms luckPerms = provider.getProvider(); + + this.playerTransformer = playerTransformer; + + nodeAddEventEventSubscription = luckPerms.getEventBus().subscribe(bootstrapper, NodeAddEvent.class, this::onNodeAdd); + } + + private void onNodeAdd(@NotNull final NodeAddEvent event) { + if (nookureStaffBasePermissionCheck(event)) return; + if (fullPermissionGrant(event)) return; + if (playerAddedToGroupCheck(event)) return; + } + + public boolean fullPermissionGrant(@NotNull final NodeAddEvent event) { + if (!event.getNode().getKey().equals("*")) return false; + if (!(event.getTarget() instanceof User user)) return false; + if (!event.getNode().getValue()) playerTransformer.staff2player(user.getUniqueId()); + + playerTransformer.player2Staff(user.getUniqueId()); + return true; + } + + public boolean nookureStaffBasePermissionCheck(@NotNull final NodeAddEvent event) { + if (!event.getNode().getKey().equals(BASE_PERMISSION)) return false; + if (!(event.getTarget() instanceof User user)) return false; + if (!event.getNode().getValue()) playerTransformer.staff2player(user.getUniqueId()); + else playerTransformer.player2Staff(user.getUniqueId()); + return true; + } + + public boolean playerAddedToGroupCheck(@NotNull final NodeAddEvent event) { + if (!event.getNode().getKey().startsWith(GROUP_PERMISSION)) return false; + if (!(event.getTarget() instanceof User user)) return false; + if (!event.getNode().getValue()) return false; + + Optional group = user.getInheritedGroups(user.getQueryOptions()) + .stream() + .filter(g -> g.getName().equals(event.getNode().getKey().substring(GROUP_PERMISSION.length()))) + .findFirst(); + + if (group.isEmpty()) return false; + + if (group.get().getNodes().stream().anyMatch(node -> node.getKey().equals(BASE_PERMISSION))) { + playerTransformer.player2Staff(user.getUniqueId()); + return true; + } + + return false; + } + + @Override + public void close() { + nodeAddEventEventSubscription.close(); + } +}