diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deop.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deop.java index 01ff2952..717bf45b 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deop.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deop.java @@ -54,13 +54,11 @@ public class Command_deop extends FreedomCommand } msg(player, YOU_ARE_NOT_OP); - plugin.rm.updateDisplay(player); if (!atomicBoolean.get()) { FUtil.adminAction(sender.getName(), "De-opping " + player.getName(), false); } - Hierarchy.getHierarchy().updateUserData(player); }); return true; diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deopall.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deopall.java index 31114e85..16aa6129 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deopall.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deopall.java @@ -35,8 +35,6 @@ public class Command_deopall extends FreedomCommand } msg(player, YOU_ARE_NOT_OP); - plugin.rm.updateDisplay(player); - Hierarchy.getHierarchy().updateUserData(player); })); return true; diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java index 2e3b9fa4..4ca3d72e 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java @@ -122,12 +122,9 @@ public class Command_mbconfig extends FreedomCommand { FUtil.adminAction(sender.getName(), "Adding " + data.getName() + " to the Master Builder list", true); data.setMasterBuilder(true); - Hierarchy.getHierarchy().addUserToGroup(GroupProvider.MASTER_BUILDER.getGroup(), player); + Hierarchy.getHierarchy() + .addUserToGroup(GroupProvider.MASTER_BUILDER.getGroup(), player); plugin.pl.save(data); - if (player != null) - { - plugin.rm.updateDisplay(player); - } } else { msg("That player is already on the Master Builder list."); @@ -156,10 +153,10 @@ public class Command_mbconfig extends FreedomCommand } FUtil.adminAction(sender.getName(), "Removing " + data.getName() + " from the Master Builder list", true); - Hierarchy.getHierarchy().dropUserFromAll(Hierarchy.getHierarchy().builder(), player); + Hierarchy.getHierarchy() + .dropUserFromAll(Hierarchy.getHierarchy().builder(), player); data.setMasterBuilder(false); plugin.pl.save(data); - plugin.rm.updateDisplay(player); return true; } diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_op.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_op.java index 6861bbb2..07f4a320 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_op.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_op.java @@ -58,8 +58,7 @@ public class Command_op extends FreedomCommand } msg(player, YOU_ARE_OP); - plugin.rm.updateDisplay(player); - Hierarchy.getHierarchy().updateUserData(player); + if (!atomicBoolean.get()) { FUtil.adminAction(sender.getName(), "Opping " + player.getName(), false); diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opall.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opall.java index ee1f0280..457687db 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opall.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opall.java @@ -35,8 +35,6 @@ public class Command_opall extends FreedomCommand } msg(player, YOU_ARE_OP); - plugin.rm.updateDisplay(player); - Hierarchy.getHierarchy().updateUserData(player); })); return true; diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opme.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opme.java index c037366e..9e755371 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opme.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opme.java @@ -16,7 +16,8 @@ public class Command_opme extends FreedomCommand public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) { FUtil.adminAction(sender.getName(), "Opping " + sender.getName(), false); - Hierarchy.getHierarchy().promoteUser(Hierarchy.getHierarchy().op(), playerSender).whenComplete((result, error) -> + Hierarchy.getHierarchy().promoteUser(Hierarchy.getHierarchy().op(), playerSender) + .whenComplete((result, error) -> { if (error != null) { @@ -30,8 +31,6 @@ public class Command_opme extends FreedomCommand } msg(YOU_ARE_OP); - plugin.rm.updateDisplay(playerSender); - Hierarchy.getHierarchy().updateUserData(playerSender); }); return true; } diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java index abe3923f..447b8946 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java @@ -124,7 +124,6 @@ public class Command_saconfig extends FreedomCommand plugin.al.save(admin); plugin.al.updateTables(); - plugin.rm.updateDisplay(player); if (plugin.dc != null && plugin.dc.isEnabled() && ConfigEntry.DISCORD_ROLE_SYNC.getBoolean()) { @@ -140,8 +139,6 @@ public class Command_saconfig extends FreedomCommand msgNew(player, "You have been unfrozen."); } - Hierarchy.getHierarchy().updateUserData(player); - msgNew("Admin has been promoted to ", player(player), Placeholder.unparsed("rank", group)); @@ -242,7 +239,6 @@ public class Command_saconfig extends FreedomCommand plugin.al.save(admin); plugin.al.updateTables(); - plugin.rm.updateDisplay(player); if (plugin.dc != null && plugin.dc.isEnabled() && ConfigEntry.DISCORD_ROLE_SYNC.getBoolean()) { @@ -258,8 +254,6 @@ public class Command_saconfig extends FreedomCommand msgNew(player, "You have been unfrozen."); } - Hierarchy.getHierarchy().updateUserData(player); - msgNew("Admin has been demoted to ", Placeholder.unparsed("player", player.getName()), Placeholder.unparsed("rank", group)); @@ -288,11 +282,6 @@ public class Command_saconfig extends FreedomCommand plugin.al.save(admin); plugin.al.updateTables(); - if (player != null) - { - plugin.rm.updateDisplay(player); - } - if (plugin.dc != null && plugin.dc.isEnabled() && ConfigEntry.DISCORD_ROLE_SYNC.getBoolean()) { plugin.dc.syncRoles(admin, plugin.pl.getData(admin.getName()) diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/perms/UserData.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/perms/UserData.java index 3ba2e5b5..7e70985c 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/perms/UserData.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/perms/UserData.java @@ -73,8 +73,12 @@ public class UserData this.queryOptions = queryOptions; } - public UserData clone() + public UserData copy() { - return new UserData(user, metaData, permissionData, contextSet, queryOptions); + return new UserData(getUser(), + getMetaData(), + getPermissionData(), + getContextSet(), + getQueryOptions()); } } diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/perms/UserWrapper.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/perms/UserWrapper.java index 95579d34..ba5d4d41 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/perms/UserWrapper.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/perms/UserWrapper.java @@ -1,5 +1,7 @@ package me.totalfreedom.totalfreedommod.perms; +import me.totalfreedom.totalfreedommod.rank.DisplayableGroup; +import me.totalfreedom.totalfreedommod.rank.GroupProvider; import net.luckperms.api.cacheddata.CachedMetaData; import net.luckperms.api.cacheddata.CachedPermissionData; import net.luckperms.api.context.ImmutableContextSet; @@ -7,6 +9,7 @@ import net.luckperms.api.model.group.Group; import net.luckperms.api.model.user.User; import net.luckperms.api.model.user.UserManager; import net.luckperms.api.node.NodeType; +import net.luckperms.api.node.types.InheritanceNode; import net.luckperms.api.platform.PlayerAdapter; import net.luckperms.api.query.QueryOptions; import org.bukkit.entity.Player; @@ -74,7 +77,7 @@ public class UserWrapper { return getUserData(player).thenApply(userData -> { - UserData newData = userData.clone(); + UserData newData = userData.copy(); CachedPermissionData permissionData = playerAdapter.getPermissionData(player); ImmutableContextSet contextSet = playerAdapter.getContext(player); QueryOptions queryOptions = playerAdapter.getQueryOptions(player); @@ -90,18 +93,28 @@ public class UserWrapper }).thenAccept(userDataSet::add); } - public void addToGroup(User user, Group group) { + public void addToGroup(User user, DisplayableGroup group) + { CompletableFuture.runAsync(() -> manager.modifyUser(user.getUniqueId(), c -> - group.getNodes(NodeType.INHERITANCE).forEach(node -> - c.data().add(node)))); + { + if (!c.getNodes(NodeType.INHERITANCE) + .contains(GroupProvider.inheritanceNode(group))) + c.data().add(GroupProvider.inheritanceNode(group)); + })); } - public void removeFromGroup(User user, Group group) { + public void removeFromGroup(User user, Group group) + { + InheritanceNode groupNode = InheritanceNode.builder(group).build(); + CompletableFuture.runAsync(() -> - manager.modifyUser(user.getUniqueId(), c -> - group.getNodes(NodeType.INHERITANCE).forEach(node -> - c.data().remove(node)))); + manager.modifyUser(user.getUniqueId(), userConsumer -> + { + if (userConsumer.getNodes(NodeType.INHERITANCE) + .contains(groupNode)) + userConsumer.data().remove(groupNode); + })); } public void saveUser(User user) diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/GroupProvider.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/GroupProvider.java index 40f39a70..9a77d025 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/GroupProvider.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/GroupProvider.java @@ -5,6 +5,8 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.luckperms.api.model.group.Group; import net.luckperms.api.model.user.User; +import net.luckperms.api.node.matcher.NodeMatcher; +import net.luckperms.api.node.types.InheritanceNode; import org.bukkit.ChatColor; import org.bukkit.entity.Player; @@ -22,6 +24,16 @@ public interface GroupProvider GroupProvider ADMIN = () -> new DisplayableGroup("admin", Component.text("Administrators"), Component.text("Admin"), 3, NamedTextColor.DARK_GREEN, ChatColor.DARK_GREEN, true, true); GroupProvider SENIOR_ADMIN = () -> new DisplayableGroup("senior", Component.text("Senior Administrators"), Component.text("SrA"), 4, NamedTextColor.GOLD, ChatColor.GOLD, true, true); + static InheritanceNode inheritanceNode(DisplayableGroup group) + { + return InheritanceNode.builder(group.getLuckPermsGroup()).build(); + } + + static NodeMatcher nodeMatcher(DisplayableGroup group) + { + return NodeMatcher.key(inheritanceNode(group)); + } + static User getUser(Player player) { return TotalFreedomMod.getPlugin() @@ -42,8 +54,10 @@ public interface GroupProvider }; } - static GroupProvider fromLuckPermsGroup(Group group) { - return switch (group.getName().toLowerCase()) { + static GroupProvider fromLuckPermsGroup(Group group) + { + return switch (group.getName().toLowerCase()) + { case "op" -> OP; case "builder" -> MASTER_BUILDER; case "admin" -> ADMIN; diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/Hierarchy.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/Hierarchy.java index cfe51c68..495fab62 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/Hierarchy.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/Hierarchy.java @@ -5,17 +5,25 @@ import me.totalfreedom.totalfreedommod.perms.GroupWrapper; import me.totalfreedom.totalfreedommod.perms.TrackWrapper; import me.totalfreedom.totalfreedommod.perms.UserWrapper; import me.totalfreedom.totalfreedommod.util.FLog; +import net.luckperms.api.event.EventBus; +import net.luckperms.api.event.EventSubscription; +import net.luckperms.api.event.node.NodeAddEvent; +import net.luckperms.api.event.node.NodeRemoveEvent; import net.luckperms.api.model.group.Group; -import net.luckperms.api.node.NodeEqualityPredicate; +import net.luckperms.api.model.user.User; import net.luckperms.api.node.NodeType; import net.luckperms.api.node.types.InheritanceNode; +import net.luckperms.api.platform.PlayerAdapter; import net.luckperms.api.track.DemotionResult; import net.luckperms.api.track.PromotionResult; import net.luckperms.api.track.Track; +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicBoolean; public class Hierarchy { @@ -23,13 +31,16 @@ public class Hierarchy private final GroupWrapper groupWrapper; private final TrackWrapper trackWrapper; private final UserWrapper userWrapper; + private final PlayerAdapter playerAdapter; private Hierarchy() { + this.playerAdapter = TotalFreedomMod.getPlugin().lpb.getAPI().getPlayerAdapter(Player.class); this.groupWrapper = new GroupWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getGroupManager()); this.trackWrapper = new TrackWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getTrackManager()); this.userWrapper = new UserWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getUserManager(), - TotalFreedomMod.getPlugin().lpb.getAPI().getPlayerAdapter(Player.class)); + getPlayerAdapter()); + new LuckPermsUserDataListener().register(); } public static Hierarchy getHierarchy() @@ -37,32 +48,17 @@ public class Hierarchy return hierarchy; } + public PlayerAdapter getPlayerAdapter() + { + return playerAdapter; + } + public boolean isUserOnAdminTrack(Player player) { - AtomicBoolean isOnAdminTrack = new AtomicBoolean(false); - userWrapper.getUser(player).thenAccept(user -> - user.data().toCollection().stream() - .filter(NodeType.INHERITANCE::matches) - .map(NodeType.INHERITANCE::cast) - .filter(NodeEqualityPredicate.ONLY_KEY - .equalTo(InheritanceNode - .builder(GroupProvider.ADMIN.getGroup().getLuckPermsGroup().getName()) - .build())) - .forEach(node -> - { - if (node.getGroupName().startsWith("admin")) - { - isOnAdminTrack.set(true); - } - })).whenComplete((a, b) -> - { - if (b != null) - { - FLog.severe(b); - } - }); - - return isOnAdminTrack.get(); + return userWrapper.getUser(player) + .thenApply(user -> user.getNodes(NodeType.INHERITANCE) + .contains(GroupProvider.inheritanceNode(GroupProvider.ADMIN.getGroup()))) + .join(); } public Track op() @@ -115,7 +111,8 @@ public class Hierarchy }); } - public void addUserData(Player player) { + public void addUserData(Player player) + { userWrapper.addUserData(player).whenComplete((a, b) -> { if (b != null) @@ -125,7 +122,8 @@ public class Hierarchy }); } - public void updateUserData(Player player) { + public void updateUserData(Player player) + { userWrapper.updateUserData(player).whenComplete((a, b) -> { if (b != null) @@ -135,7 +133,8 @@ public class Hierarchy }); } - public void dropUserData(Player player) { + public void dropUserData(Player player) + { userWrapper.removeUserData(player).whenComplete((a, b) -> { if (b != null) @@ -147,71 +146,26 @@ public class Hierarchy public CompletableFuture promoteUser(Track track, Player player) { - return userWrapper.getUserData(player).thenApply(data -> - { - boolean isOnTrack = false; - for (String trackGroup : track.getGroups()) - { - for (Group userGroup : data.getUser().getInheritedGroups(data.getQueryOptions())) - { - if (userGroup.getName().equals(trackGroup)) - { - isOnTrack = true; - } - } - } - - if (isOnTrack) - { - return track.promote(data.getUser(), data.getContextSet()); - } else - { - addUserToGroup(GroupProvider.fromString(track.getGroups().get(0)).getGroup(), player); - return null; - } - }); + return userWrapper.getUserData(player) + .thenApply(data -> track.promote(data.getUser(), data.getContextSet())); } public CompletableFuture demoteUser(Track track, Player player) { - return userWrapper.getUserData(player).thenApply(data -> - { - boolean isOnTrack = false; - for (String trackGroup : track.getGroups()) - { - for (Group userGroup : data.getUser().getInheritedGroups(data.getQueryOptions())) - { - if (userGroup.getName().equals(trackGroup)) - { - isOnTrack = true; - } - } - } - - if (isOnTrack) - { - return track.demote(data.getUser(), data.getContextSet()); - } else - { - return null; - } - }); + return userWrapper.getUserData(player) + .thenApply(data -> track.demote(data.getUser(), data.getContextSet())); } public void addUserToGroup(DisplayableGroup group, Player player) { userWrapper.getUserData(player).thenAccept(user -> - { - userWrapper.addToGroup(user.getUser(), group.getLuckPermsGroup()); - userWrapper.saveUser(user.getUser()); - }).whenComplete((a, b) -> + userWrapper.addToGroup(user.getUser(), group)) + .whenComplete((a, b) -> { if (b != null) { FLog.severe(b); } - - updateUserData(player); }); } @@ -229,18 +183,56 @@ public class Hierarchy return; } - userWrapper.removeFromGroup(data.getUser(), g); + if (data.getUser().getNodes(NodeType.INHERITANCE) + .contains(InheritanceNode.builder(g).build())) + userWrapper.removeFromGroup(data.getUser(), g); }); } - userWrapper.saveUser(data.getUser()); }).whenComplete((a, b) -> { if (b != null) { FLog.severe(b); } - - updateUserData(player); }); } + + private class LuckPermsUserDataListener + { + private final Map> subscriptions = new HashMap<>(); + + public void register() + { + EventBus eventBus = TotalFreedomMod.getPlugin().lpb.getAPI().getEventBus(); + subscriptions.put(new NamespacedKey(TotalFreedomMod.getPlugin(), "node_add"), eventBus.subscribe(TotalFreedomMod.getPlugin(), NodeAddEvent.class, this::onNodeAdd)); + subscriptions.put(new NamespacedKey(TotalFreedomMod.getPlugin(), "node_remove"), eventBus.subscribe(TotalFreedomMod.getPlugin(), NodeRemoveEvent.class, this::onNodeRemove)); + } + + private void onNodeAdd(NodeAddEvent event) + { + if (event.isUser()) + { + User user = (User) event.getTarget(); + Player player = Bukkit.getPlayer(user.getUniqueId()); + if (player != null) + { + updateUserData(player); + } + } + } + + private void onNodeRemove(NodeRemoveEvent event) + { + if (event.isUser()) + { + User user = (User) event.getTarget(); + Player player = Bukkit.getPlayer(user.getUniqueId()); + if (player != null) + { + TotalFreedomMod.getPlugin().rm.updateDisplay(player); + updateUserData(player); + } + } + } + } } diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java index 5fee4967..3cf3a09c 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java @@ -181,7 +181,7 @@ public class RankManager extends FreedomService } else { fPlayer.setTag(null); - player.setPlayerListName(null); + player.playerListName(Component.empty()); } fPlayer.setTag(getTag(player, display.getColoredTag()));