Halfway fixed... need to figure out why the group save is getting spammed...

This commit is contained in:
Paul Reilly 2023-05-03 15:57:45 -05:00
parent 9138d1856b
commit 618eb669b2
16 changed files with 284 additions and 607 deletions

View File

@ -1,12 +1,5 @@
package me.totalfreedom.totalfreedommod; package me.totalfreedom.totalfreedommod;
import me.totalfreedom.totalfreedommod.api.Callback;
import me.totalfreedom.totalfreedommod.api.event.EventBus;
import me.totalfreedom.totalfreedommod.api.event.MethodEvent;
import me.totalfreedom.totalfreedommod.rank.DisplayableGroup;
import me.totalfreedom.totalfreedommod.rank.Hierarchy;
import me.totalfreedom.totalfreedommod.util.FLog;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -2,16 +2,14 @@ package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.command.handling.*; import me.totalfreedom.totalfreedommod.command.handling.*;
import me.totalfreedom.totalfreedommod.rank.Hierarchy; import me.totalfreedom.totalfreedommod.rank.Hierarchy;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.luckperms.api.track.DemotionResult;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.concurrent.atomic.AtomicBoolean;
@Intercept("deop") @Intercept("deop")
@CommandPermissions(permission = "deop", source = SourceType.BOTH) @CommandPermissions(permission = "deop", source = SourceType.BOTH)
@CommandParameters(description = "Deop a player", usage = "/<command> <partialname>") @CommandParameters(description = "Deop a player", usage = "/<command> <partialname>")
@ -39,30 +37,22 @@ public class Command_deop extends FreedomCommand
return true; return true;
} }
AtomicBoolean atomicBoolean = new AtomicBoolean(silent); boolean b = silent;
Hierarchy.getHierarchy().demoteUser(Hierarchy.getHierarchy().op(), player).whenComplete((result, throwable) -> DemotionResult result = Hierarchy.getHierarchy()
{ .demoteUser(Hierarchy.getHierarchy().op(), player);
if (throwable != null)
{
msgNew("<red>Could not demote <player> to non-OP. Check the logs for more details.", player(player));
FLog.severe("Error while demoting " + player.getName() + " to non-OP:");
FLog.severe(throwable);
return;
}
if (!result.wasSuccessful()) { if (!result.wasSuccessful())
{
msgNew("<red><player> is already non-op.", Placeholder.unparsed("player", player.getName())); msgNew("<red><player> is already non-op.", Placeholder.unparsed("player", player.getName()));
return; return true;
} }
msg(player, YOU_ARE_NOT_OP); msg(player, YOU_ARE_NOT_OP);
if (!atomicBoolean.get()) if (!b)
{ {
FUtil.adminAction(sender.getName(), "De-opping " + player.getName(), false); FUtil.adminAction(sender.getName(), "De-opping " + player.getName(), false);
} }
});
return true; return true;
} }
} }

View File

@ -5,9 +5,9 @@ import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand; import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
import me.totalfreedom.totalfreedommod.command.handling.SourceType; import me.totalfreedom.totalfreedommod.command.handling.SourceType;
import me.totalfreedom.totalfreedommod.rank.Hierarchy; import me.totalfreedom.totalfreedommod.rank.Hierarchy;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.luckperms.api.track.DemotionResult;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -23,23 +23,18 @@ public class Command_deopall extends FreedomCommand
FUtil.adminAction(sender.getName(), "De-opping all players on the server", true); FUtil.adminAction(sender.getName(), "De-opping all players on the server", true);
server.getOnlinePlayers().forEach(player -> server.getOnlinePlayers().forEach(player ->
Hierarchy.getHierarchy().demoteUser(Hierarchy.getHierarchy().op(), player).whenComplete((result, ex) ->
{ {
if (ex != null) DemotionResult result = Hierarchy.getHierarchy()
{ .demoteUser(Hierarchy.getHierarchy().op(), player);
msgNew("<red>Could not demote <player> to non-OP. Check the logs for more details.", player(player));
FLog.severe("Failed to demote " + player.getName() + " to non-OP:");
FLog.severe(ex);
return;
}
if (!result.wasSuccessful()) { if (!result.wasSuccessful())
{
msgNew("<red><player> is already non-OP.", Placeholder.unparsed("player", player.getName())); msgNew("<red><player> is already non-OP.", Placeholder.unparsed("player", player.getName()));
return; return;
} }
msg(player, YOU_ARE_NOT_OP); msg(player, YOU_ARE_NOT_OP);
})); });
return true; return true;
} }

View File

@ -158,7 +158,7 @@ public class Command_mbconfig extends FreedomCommand
FUtil.adminAction(sender.getName(), "Removing " + data.getName() + " from the Master Builder list", true); FUtil.adminAction(sender.getName(), "Removing " + data.getName() + " from the Master Builder list", true);
Hierarchy.getHierarchy() Hierarchy.getHierarchy()
.dropUserFromAll(Hierarchy.getHierarchy().builder(), player); .dropUser(Hierarchy.getHierarchy().builder(), player);
data.setMasterBuilder(false); data.setMasterBuilder(false);
plugin.pl.save(data); plugin.pl.save(data);

View File

@ -2,15 +2,13 @@ package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.command.handling.*; import me.totalfreedom.totalfreedommod.command.handling.*;
import me.totalfreedom.totalfreedommod.rank.Hierarchy; import me.totalfreedom.totalfreedommod.rank.Hierarchy;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.luckperms.api.track.PromotionResult;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.concurrent.atomic.AtomicBoolean;
@Intercept("op") @Intercept("op")
@CommandPermissions(permission = "op", source = SourceType.BOTH, cooldown = 5) @CommandPermissions(permission = "op", source = SourceType.BOTH, cooldown = 5)
@CommandParameters(description = "OP a player", usage = "/<command> <partialname>") @CommandParameters(description = "OP a player", usage = "/<command> <partialname>")
@ -39,33 +37,22 @@ public class Command_op extends FreedomCommand
return true; return true;
} }
AtomicBoolean atomicBoolean = new AtomicBoolean(silent); boolean b = silent;
Hierarchy.getHierarchy().promoteUser(Hierarchy.getHierarchy().op(), player).whenComplete((result, throwable) -> PromotionResult result = Hierarchy.getHierarchy()
{ .promoteUser(Hierarchy.getHierarchy().op(), player);
if (throwable != null)
{
msgNew("<red>Failed to promote <player> to OP. Check logs for more details.", player(player));
FLog.severe("Failed to promote " + player.getName() + " to OP:");
FLog.severe(throwable);
return;
}
if (result == null) { if (!result.wasSuccessful())
msgNew("<red><player> was not on the track! Added.", player(player));
}
else if (!result.wasSuccessful())
{ {
msgNew("<red><player> is already OP!", player(player)); msgNew("<red><player> is already OP!", player(player));
return; return true;
} }
msg(player, YOU_ARE_OP); msg(player, YOU_ARE_OP);
if (!atomicBoolean.get()) if (!b)
{ {
FUtil.adminAction(sender.getName(), "Opping " + player.getName(), false); FUtil.adminAction(sender.getName(), "Opping " + player.getName(), false);
} }
});
return true; return true;

View File

@ -5,8 +5,8 @@ import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand; import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
import me.totalfreedom.totalfreedommod.command.handling.SourceType; import me.totalfreedom.totalfreedommod.command.handling.SourceType;
import me.totalfreedom.totalfreedommod.rank.Hierarchy; import me.totalfreedom.totalfreedommod.rank.Hierarchy;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.luckperms.api.track.PromotionResult;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -21,25 +21,18 @@ public class Command_opall extends FreedomCommand
FUtil.adminAction(sender.getName(), "Opping all players on the server", true); FUtil.adminAction(sender.getName(), "Opping all players on the server", true);
server.getOnlinePlayers().forEach(player -> server.getOnlinePlayers().forEach(player ->
Hierarchy.getHierarchy().promoteUser(Hierarchy.getHierarchy().op(), player).whenComplete((result, throwable) ->
{ {
if (throwable != null) PromotionResult result = Hierarchy.getHierarchy()
{ .promoteUser(Hierarchy.getHierarchy().op(), player);
msgNew("<red>Failed to promote <player> to OP. Check the logs for more details.", player(player));
FLog.severe("Failed to promote " + player.getName());
FLog.severe(throwable);
return;
}
if (result == null) { if (!result.wasSuccessful())
msgNew("<red><player> was not present on the track! Added.", player(player)); {
} else if (!result.wasSuccessful()) {
msgNew("<red>Player is already OP!", player(player)); msgNew("<red>Player is already OP!", player(player));
return; return;
} }
msg(player, YOU_ARE_OP); msg(player, YOU_ARE_OP);
})); });
return true; return true;
} }

View File

@ -5,8 +5,8 @@ import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand; import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
import me.totalfreedom.totalfreedommod.command.handling.SourceType; import me.totalfreedom.totalfreedommod.command.handling.SourceType;
import me.totalfreedom.totalfreedommod.rank.Hierarchy; import me.totalfreedom.totalfreedommod.rank.Hierarchy;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.luckperms.api.track.PromotionResult;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -20,22 +20,17 @@ public class Command_opme extends FreedomCommand
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{ {
FUtil.adminAction(sender.getName(), "Opping " + sender.getName(), false); FUtil.adminAction(sender.getName(), "Opping " + sender.getName(), false);
Hierarchy.getHierarchy().promoteUser(Hierarchy.getHierarchy().op(), playerSender) PromotionResult result = Hierarchy.getHierarchy()
.whenComplete((result, error) -> .promoteUser(Hierarchy.getHierarchy().op(), playerSender);
{
if (error != null)
{
FLog.severe("Error while promoting " + playerSender.getName() + " to OP: " + error.getMessage());
return;
}
if (result != null && !result.wasSuccessful()) { if (!result.wasSuccessful())
{
msgNew("<red>You are already op!"); msgNew("<red>You are already op!");
return; return true;
} }
msg(YOU_ARE_OP); msg(YOU_ARE_OP);
});
return true; return true;
} }
} }

View File

@ -10,11 +10,12 @@ import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.rank.DisplayableGroup; import me.totalfreedom.totalfreedommod.rank.DisplayableGroup;
import me.totalfreedom.totalfreedommod.rank.GroupProvider; import me.totalfreedom.totalfreedommod.rank.GroupProvider;
import me.totalfreedom.totalfreedommod.rank.Hierarchy; import me.totalfreedom.totalfreedommod.rank.Hierarchy;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import me.totalfreedom.totalfreedommod.util.PermissibleCompletion; import me.totalfreedom.totalfreedommod.util.PermissibleCompletion;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.luckperms.api.model.group.Group; import net.luckperms.api.model.group.Group;
import net.luckperms.api.track.DemotionResult;
import net.luckperms.api.track.PromotionResult;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -26,7 +27,8 @@ import java.util.Date;
import java.util.List; import java.util.List;
@CommandPermissions(permission = "saconfig", source = SourceType.BOTH) @CommandPermissions(permission = "saconfig", source = SourceType.BOTH)
@CommandParameters(description = "List, add, remove, or set the rank of admins, clean or reload the admin list, or view admin information.", usage = "/<command> <list | clean | reload | | setrank <username> <rank> | <add | remove | info> <username>>", aliases = "slconfig") @CommandParameters(description = "List, add, remove, or set the rank of admins, clean or reload the admin list, or view admin information.",
usage = "/<command> <list | clean | reload | | setrank <username> <rank> | <promote | demote | info | remove> <username>>", aliases = "slconfig")
public class Command_saconfig extends FreedomCommand public class Command_saconfig extends FreedomCommand
{ {
@ -82,26 +84,14 @@ public class Command_saconfig extends FreedomCommand
return true; return true;
} }
Hierarchy.getHierarchy() PromotionResult result = Hierarchy.getHierarchy()
.promoteUser(Hierarchy.getHierarchy().admin(), player) .promoteUser(Hierarchy.getHierarchy().admin(), player);
.whenComplete((result, ex) ->
{
if (ex != null)
{
FLog.severe("Failed to promote "
+ player.getName()
+ " to the next rank");
return;
}
if (result == null) { if (!result.wasSuccessful() || result.getGroupTo().isEmpty())
msgNew("<green>Added <player> to the ADMIN group.", player(player));
}
else if (!result.wasSuccessful() || result.getGroupTo().isEmpty())
{ {
msgNew("<red>Failed to promote <player> to the next rank.", player(player)); msgNew("<red>Failed to promote <player> to the next rank.", player(player));
return; } else
} else { {
result.getGroupTo().ifPresentOrElse(group -> result.getGroupTo().ifPresentOrElse(group ->
{ {
Admin admin = plugin.al.getAdmin(player); Admin admin = plugin.al.getAdmin(player);
@ -113,7 +103,7 @@ public class Command_saconfig extends FreedomCommand
} }
Group actual = Hierarchy.getHierarchy().getGroup(group); Group actual = Hierarchy.getHierarchy().getGroup(group);
DisplayableGroup rank = GroupProvider.fromLuckPermsGroup(actual).getGroup(); DisplayableGroup rank = GroupProvider.wrappedFromLPG(actual).getGroup();
if (rank == null) if (rank == null)
{ {
@ -148,7 +138,6 @@ public class Command_saconfig extends FreedomCommand
Placeholder.unparsed("rank", group)); Placeholder.unparsed("rank", group));
}, () -> msgNew("<red>Failed to promote <player> to the next rank.", player(player))); }, () -> msgNew("<red>Failed to promote <player> to the next rank.", player(player)));
} }
});
return true; return true;
} }
@ -201,22 +190,13 @@ public class Command_saconfig extends FreedomCommand
return true; return true;
} }
Hierarchy.getHierarchy() DemotionResult result = Hierarchy.getHierarchy()
.demoteUser(Hierarchy.getHierarchy().admin(), player) .demoteUser(Hierarchy.getHierarchy().admin(), player);
.whenComplete((result, ex) ->
{
if (ex != null)
{
FLog.severe("Failed to demote "
+ player.getName()
+ " to the next rank");
return;
}
if (!result.wasSuccessful() || result.getGroupTo().isEmpty()) if (!result.wasSuccessful() || result.getGroupTo().isEmpty())
{ {
msgNew("<red>Failed to demote <player> to the next rank.", player(player)); msgNew("<red>Failed to demote <player> to the next rank.", player(player));
return; return true;
} }
result.getGroupTo().ifPresentOrElse(group -> result.getGroupTo().ifPresentOrElse(group ->
@ -230,7 +210,7 @@ public class Command_saconfig extends FreedomCommand
} }
Group actual = Hierarchy.getHierarchy().getGroup(group); Group actual = Hierarchy.getHierarchy().getGroup(group);
DisplayableGroup rank = GroupProvider.fromLuckPermsGroup(actual).getGroup(); DisplayableGroup rank = GroupProvider.wrappedFromLPG(actual).getGroup();
if (rank == null) if (rank == null)
{ {
@ -262,7 +242,8 @@ public class Command_saconfig extends FreedomCommand
Placeholder.unparsed("player", player.getName()), Placeholder.unparsed("player", player.getName()),
Placeholder.unparsed("rank", group)); Placeholder.unparsed("rank", group));
}, () -> msgNew("<red>Failed to demote <player> to the next rank.", Placeholder.unparsed("player", player.getName()))); }, () -> msgNew("<red>Failed to demote <player> to the next rank.", Placeholder.unparsed("player", player.getName())));
});
return true;
} }
case "remove" -> case "remove" ->
{ {
@ -278,7 +259,7 @@ public class Command_saconfig extends FreedomCommand
Admin admin = plugin.al.getAdmin(player); Admin admin = plugin.al.getAdmin(player);
plugin.al.removeAdmin(admin); plugin.al.removeAdmin(admin);
Hierarchy.getHierarchy().dropUserFromAll(Hierarchy.getHierarchy().admin(), player); Hierarchy.getHierarchy().dropUser(Hierarchy.getHierarchy().admin(), player);
FUtil.adminAction(sender.getName(), "Removing " + admin.getName() + " from the admin list", true); FUtil.adminAction(sender.getName(), "Removing " + admin.getName() + " from the admin list", true);
admin.setActive(false); admin.setActive(false);
@ -299,7 +280,6 @@ public class Command_saconfig extends FreedomCommand
return false; return false;
} }
} }
return false;
} }
@Override @Override
@ -315,11 +295,17 @@ public class Command_saconfig extends FreedomCommand
PermissibleCompletion.of("tfm.saconfig.clean", "clean"), PermissibleCompletion.of("tfm.saconfig.clean", "clean"),
PermissibleCompletion.of("tfm.saconfig.promote", "promote")); PermissibleCompletion.of("tfm.saconfig.promote", "promote"));
} }
if (args.length == 2 && (args[0].equals("add") || args[0].equals("remove") || args[0].equals("setrank") || args[0].equals("info"))) if (args.length == 2 && (args[0].equals("promote")
|| args[0].equals("demote")
|| args[0].equals("remove")
|| args[0].equals("setrank")
|| args[0].equals("info")))
{ {
return playerCompletions(args[1]); return playerCompletions(args[1]);
} }
if (args.length == 3 && args[0].equals("setrank") && sender.hasPermission("tfm.saconfig.setrank")) if (args.length == 3
&& args[0].equals("setrank")
&& sender.hasPermission("tfm.saconfig.setrank"))
{ {
return Arrays.asList("ADMIN", "SENIOR_ADMIN"); return Arrays.asList("ADMIN", "SENIOR_ADMIN");
} }

View File

@ -4,9 +4,7 @@ import me.totalfreedom.totalfreedommod.util.FLog;
import net.luckperms.api.model.group.Group; import net.luckperms.api.model.group.Group;
import net.luckperms.api.model.group.GroupManager; import net.luckperms.api.model.group.GroupManager;
import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
public class GroupWrapper public class GroupWrapper
{ {
@ -17,43 +15,21 @@ public class GroupWrapper
this.manager = manager; this.manager = manager;
} }
public CompletableFuture<Group> getGroup(String name) public Group getGroup(String name)
{ {
if (!manager.isLoaded(name) || !manager.getLoadedGroups().contains(manager.getGroup(name))) if (!manager.isLoaded(name))
{ {
Optional<Group> group = manager.loadGroup(name).join(); return manager.createAndLoadGroup(name).join();
return group
.map(CompletableFuture::completedFuture)
.orElseGet(() -> manager.createAndLoadGroup(name));
} }
return CompletableFuture.supplyAsync(() -> manager.getGroup(name)); return manager.getGroup(name);
} }
public void modifyGroup(String name, Function<Group, ? extends Group> function) public void saveGroup(String name)
{ {
getGroup(name) Group group = getGroup(name);
.thenApplyAsync(function) manager.saveGroup(group)
.thenAcceptAsync(manager::saveGroup) .thenRun(() ->
.whenCompleteAsync((aVoid, throwable) -> FLog.info("Saved group " + name + " to LuckPerms."));
{
if (throwable != null)
{
FLog.severe(throwable);
}
});
}
public void saveGroupAsync(String name)
{
getGroup(name)
.thenAcceptAsync(manager::saveGroup)
.whenCompleteAsync((aVoid, throwable) ->
{
if (throwable != null)
{
FLog.severe(throwable);
}
});
} }
} }

View File

@ -1,39 +1,35 @@
package me.totalfreedom.totalfreedommod.perms; package me.totalfreedom.totalfreedommod.perms;
import me.totalfreedom.totalfreedommod.util.FLog;
import net.luckperms.api.track.Track; import net.luckperms.api.track.Track;
import net.luckperms.api.track.TrackManager; import net.luckperms.api.track.TrackManager;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class TrackWrapper public class TrackWrapper
{ {
private final TrackManager manager; private final TrackManager manager;
private final Set<Track> trackSet;
public TrackWrapper(TrackManager manager) public TrackWrapper(TrackManager manager)
{ {
this.manager = manager; this.manager = manager;
this.trackSet = new HashSet<>();
trackSet.addAll(manager.getLoadedTracks());
} }
public CompletableFuture<Track> getTrack(String name) public Track getTrack(String name)
{ {
if (!manager.isLoaded(name) || !trackSet.contains(manager.getTrack(name))) if (!manager.isLoaded(name))
{ {
return manager.createAndLoadTrack(name).thenApplyAsync(a -> { return manager.createAndLoadTrack(name).join();
trackSet.add(a);
return a;
});
} }
return CompletableFuture.supplyAsync(() -> manager.getTrack(name)); return manager.getTrack(name);
} }
public void saveTrack(String name) public void saveTrack(String name)
{ {
getTrack(name).thenAccept(manager::saveTrack); Track t = getTrack(name);
manager.saveTrack(t)
.thenRun(() ->
FLog.info("Saved track " + name + " successfully."));
} }
} }

View File

@ -1,84 +1,46 @@
package me.totalfreedom.totalfreedommod.perms; package me.totalfreedom.totalfreedommod.perms;
import net.luckperms.api.LuckPermsProvider;
import net.luckperms.api.cacheddata.CachedData;
import net.luckperms.api.cacheddata.CachedDataManager;
import net.luckperms.api.cacheddata.CachedMetaData; import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.cacheddata.CachedPermissionData; import net.luckperms.api.cacheddata.CachedPermissionData;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.model.user.User; import net.luckperms.api.model.user.User;
import net.luckperms.api.platform.PlayerAdapter;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import org.bukkit.entity.Player;
/**
* This class is a utility class that can be used to retrieve
* numerous contextual options related to LuckPerms users.
*/
public class UserData public class UserData
{ {
private User user; public static User fromPlayer(Player player) {
private CachedMetaData metaData; PlayerAdapter<Player> adapter = LuckPermsProvider
private CachedPermissionData permissionData; .get()
private ImmutableContextSet contextSet; .getPlayerAdapter(Player.class);
private QueryOptions queryOptions; return adapter.getUser(player);
public UserData(User user, CachedMetaData metaData, CachedPermissionData permissionData, ImmutableContextSet contextSet, QueryOptions queryOptions)
{
this.user = user;
this.metaData = metaData;
this.permissionData = permissionData;
this.contextSet = contextSet;
this.queryOptions = queryOptions;
} }
public User getUser() public static QueryOptions getQueryOptions(User user) {
{ return user.getQueryOptions();
return user;
} }
public void setUser(User user) public static CachedDataManager getDataManager(User user) {
{ return user.getCachedData();
this.user = user;
} }
public CachedMetaData getMetaData() public static ImmutableContextSet getContextSet(User user) {
{ return getQueryOptions(user).context();
return metaData;
} }
public void setMetaData(CachedMetaData metaData) public static CachedMetaData getMetaData(User user) {
{ return getDataManager(user).getMetaData();
this.metaData = metaData;
} }
public CachedPermissionData getPermissionData() public static CachedPermissionData getPermissionData(User user) {
{ return getDataManager(user).getPermissionData();
return permissionData;
}
public void setPermissionData(CachedPermissionData permissionData)
{
this.permissionData = permissionData;
}
public ImmutableContextSet getContextSet()
{
return contextSet;
}
public void setContextSet(ImmutableContextSet contextSet)
{
this.contextSet = contextSet;
}
public QueryOptions getQueryOptions()
{
return queryOptions;
}
public void setQueryOptions(QueryOptions queryOptions)
{
this.queryOptions = queryOptions;
}
public UserData copy()
{
return new UserData(getUser(),
getMetaData(),
getPermissionData(),
getContextSet(),
getQueryOptions());
} }
} }

View File

@ -1,122 +1,70 @@
package me.totalfreedom.totalfreedommod.perms; package me.totalfreedom.totalfreedommod.perms;
import me.totalfreedom.totalfreedommod.rank.DisplayableGroup; import me.totalfreedom.totalfreedommod.rank.DisplayableGroup;
import me.totalfreedom.totalfreedommod.rank.GroupProvider; import me.totalfreedom.totalfreedommod.util.FLog;
import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.cacheddata.CachedPermissionData;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.model.group.Group;
import net.luckperms.api.model.user.User; import net.luckperms.api.model.user.User;
import net.luckperms.api.model.user.UserManager; import net.luckperms.api.model.user.UserManager;
import net.luckperms.api.node.NodeType; import net.luckperms.api.node.NodeType;
import net.luckperms.api.node.types.InheritanceNode;
import net.luckperms.api.platform.PlayerAdapter; import net.luckperms.api.platform.PlayerAdapter;
import net.luckperms.api.query.QueryOptions;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class UserWrapper public class UserWrapper
{ {
private final UserManager manager; private final UserManager manager;
private final PlayerAdapter<Player> playerAdapter; private final PlayerAdapter<Player> playerAdapter;
private final Set<UserData> userDataSet;
public UserWrapper(UserManager manager, PlayerAdapter<Player> adapter) public UserWrapper(UserManager manager, PlayerAdapter<Player> adapter)
{ {
this.manager = manager; this.manager = manager;
this.playerAdapter = adapter; this.playerAdapter = adapter;
this.userDataSet = new HashSet<>();
} }
public CompletableFuture<Void> addUserData(Player player) public User getUser(Player player)
{
User user = playerAdapter.getUser(player);
CachedPermissionData permissionData = playerAdapter.getPermissionData(player);
ImmutableContextSet contextSet = playerAdapter.getContext(player);
QueryOptions queryOptions = playerAdapter.getQueryOptions(player);
CachedMetaData metaData = playerAdapter.getMetaData(player);
UserData userData = new UserData(user, metaData, permissionData, contextSet, queryOptions);
return CompletableFuture.runAsync(() -> userDataSet.add(userData));
}
public CompletableFuture<User> getUser(Player player)
{ {
if (!manager.isLoaded(player.getUniqueId()) || !manager.getLoadedUsers().contains(manager.getUser(player.getUniqueId()))) if (!manager.isLoaded(player.getUniqueId()) || !manager.getLoadedUsers().contains(manager.getUser(player.getUniqueId())))
{ {
return manager.loadUser(player.getUniqueId()); return manager.loadUser(player.getUniqueId()).join();
} }
return CompletableFuture.supplyAsync(() -> manager.getUser(player.getUniqueId())); return manager.getUser(player.getUniqueId());
}
public CompletableFuture<UserData> getUserData(Player player)
{
return getUser(player).thenApply(user ->
{
for (UserData userData : userDataSet)
{
if (userData.getUser().getUniqueId().equals(user.getUniqueId()))
{
return userData;
}
}
return null;
});
}
public CompletableFuture<Void> removeUserData(Player player)
{
return getUserData(player).thenAccept(userDataSet::remove);
}
public CompletableFuture<Void> updateUserData(Player player)
{
return getUserData(player).thenApply(userData ->
{
UserData newData = userData.copy();
CachedPermissionData permissionData = playerAdapter.getPermissionData(player);
ImmutableContextSet contextSet = playerAdapter.getContext(player);
QueryOptions queryOptions = playerAdapter.getQueryOptions(player);
CachedMetaData metaData = playerAdapter.getMetaData(player);
newData.setPermissionData(permissionData);
newData.setContextSet(contextSet);
newData.setQueryOptions(queryOptions);
newData.setMetaData(metaData);
userDataSet.remove(userData);
return newData;
}).thenAccept(userDataSet::add);
} }
public void addToGroup(User user, DisplayableGroup group) public void addToGroup(User user, DisplayableGroup group)
{ {
CompletableFuture.runAsync(() ->
manager.modifyUser(user.getUniqueId(), c -> manager.modifyUser(user.getUniqueId(), c ->
{ {
if (!c.getNodes(NodeType.INHERITANCE) if (!c.getNodes(NodeType.INHERITANCE)
.contains(group.getInheritance())) .contains(group.getInheritance()))
c.data().add(group.getInheritance()); c.data().add(group.getInheritance());
})); })
.thenRun(() ->
FLog.info("Successfully saved user "
+ user.getUsername()
+ " to group "
+ group.getName()));
} }
public void removeFromGroup(User user, DisplayableGroup group) public void removeFromGroup(User user, DisplayableGroup group)
{ {
CompletableFuture.runAsync(() ->
manager.modifyUser(user.getUniqueId(), userConsumer -> manager.modifyUser(user.getUniqueId(), userConsumer ->
{ {
if (userConsumer.getNodes(NodeType.INHERITANCE) if (userConsumer.getNodes(NodeType.INHERITANCE)
.contains(group.getInheritance())) .contains(group.getInheritance()))
userConsumer.data().remove(group.getInheritance()); userConsumer.data().remove(group.getInheritance());
})); }).thenRun(() ->
FLog.info("Successfully removed user "
+ user.getUsername()
+ " from group "
+ group.getName()));
} }
public void saveUser(User user) public void saveUser(User user)
{ {
CompletableFuture.runAsync(() -> manager.saveUser(user)); manager.saveUser(user).thenRun(() ->
FLog.info("Successfully saved user "
+ user.getUsername()));
} }
} }

View File

@ -84,7 +84,7 @@ public class DisplayableGroup implements Displayable
this.weight = tempWeight; this.weight = tempWeight;
this.group = matched; this.group = matched;
this.inheritance = InheritanceNode.builder(this.group).build(); this.inheritance = InheritanceNode.builder(this.group).build();
Hierarchy.getHierarchy().gw().saveGroupAsync(this.group.getName()); this.save();
} }
/** /**
@ -109,7 +109,7 @@ public class DisplayableGroup implements Displayable
group.data().add(node); group.data().add(node);
permissions.add(node); permissions.add(node);
Hierarchy.getHierarchy().gw().saveGroupAsync(group.getName()); save();
} }
} }
@ -123,7 +123,7 @@ public class DisplayableGroup implements Displayable
{ {
group.data().remove(node); group.data().remove(node);
permissions.remove(node); permissions.remove(node);
Hierarchy.getHierarchy().gw().saveGroupAsync(group.getName()); save();
} }
} }
} }
@ -224,4 +224,9 @@ public class DisplayableGroup implements Displayable
{ {
return permissions; return permissions;
} }
public void save()
{
Hierarchy.getHierarchy().gw().saveGroup(group.getName());
}
} }

View File

@ -36,7 +36,7 @@ public interface GroupProvider<T extends DisplayableGroup>
return NodeMatcher.key(inheritanceNode(group)); return NodeMatcher.key(inheritanceNode(group));
} }
static DisplayableGroup LAMBDA$fromLuckPermsGroup(Group group) static DisplayableGroup directFromLPG(Group group)
{ {
return List.of(NON_OP.getGroup(), OP.getGroup(), MASTER_BUILDER.getGroup(), ADMIN.getGroup(), SENIOR_ADMIN.getGroup()).stream() return List.of(NON_OP.getGroup(), OP.getGroup(), MASTER_BUILDER.getGroup(), ADMIN.getGroup(), SENIOR_ADMIN.getGroup()).stream()
.filter(displayableGroup -> displayableGroup.getLuckPermsGroup().equals(group)) .filter(displayableGroup -> displayableGroup.getLuckPermsGroup().equals(group))
@ -64,7 +64,7 @@ public interface GroupProvider<T extends DisplayableGroup>
}; };
} }
static GroupProvider<DisplayableGroup> fromLuckPermsGroup(Group group) static GroupProvider<DisplayableGroup> wrappedFromLPG(Group group)
{ {
return Stream.of(NON_OP, OP, MASTER_BUILDER, ADMIN, SENIOR_ADMIN) return Stream.of(NON_OP, OP, MASTER_BUILDER, ADMIN, SENIOR_ADMIN)
.filter(displayableGroup -> displayableGroup.getGroup().getLuckPermsGroup().equals(group)) .filter(displayableGroup -> displayableGroup.getGroup().getLuckPermsGroup().equals(group))

View File

@ -3,12 +3,9 @@ package me.totalfreedom.totalfreedommod.rank;
import me.totalfreedom.totalfreedommod.TotalFreedomMod; import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.perms.GroupWrapper; import me.totalfreedom.totalfreedommod.perms.GroupWrapper;
import me.totalfreedom.totalfreedommod.perms.TrackWrapper; import me.totalfreedom.totalfreedommod.perms.TrackWrapper;
import me.totalfreedom.totalfreedommod.perms.UserData;
import me.totalfreedom.totalfreedommod.perms.UserWrapper; import me.totalfreedom.totalfreedommod.perms.UserWrapper;
import me.totalfreedom.totalfreedommod.util.FLog; 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.model.group.Group;
import net.luckperms.api.model.user.User; import net.luckperms.api.model.user.User;
import net.luckperms.api.node.NodeType; import net.luckperms.api.node.NodeType;
@ -17,14 +14,8 @@ import net.luckperms.api.platform.PlayerAdapter;
import net.luckperms.api.track.DemotionResult; import net.luckperms.api.track.DemotionResult;
import net.luckperms.api.track.PromotionResult; import net.luckperms.api.track.PromotionResult;
import net.luckperms.api.track.Track; import net.luckperms.api.track.Track;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
public class Hierarchy public class Hierarchy
{ {
private static final Hierarchy hierarchy = new Hierarchy(); // static singleton for global state. private static final Hierarchy hierarchy = new Hierarchy(); // static singleton for global state.
@ -38,9 +29,7 @@ public class Hierarchy
this.playerAdapter = TotalFreedomMod.getPlugin().lpb.getAPI().getPlayerAdapter(Player.class); this.playerAdapter = TotalFreedomMod.getPlugin().lpb.getAPI().getPlayerAdapter(Player.class);
this.groupWrapper = new GroupWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getGroupManager()); this.groupWrapper = new GroupWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getGroupManager());
this.trackWrapper = new TrackWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getTrackManager()); this.trackWrapper = new TrackWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getTrackManager());
this.userWrapper = new UserWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getUserManager(), this.userWrapper = new UserWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getUserManager(), getPlayerAdapter());
getPlayerAdapter());
new LuckPermsUserDataListener().register();
} }
public static Hierarchy getHierarchy() public static Hierarchy getHierarchy()
@ -70,219 +59,89 @@ public class Hierarchy
public boolean isUserOnAdminTrack(Player player) public boolean isUserOnAdminTrack(Player player)
{ {
return userWrapper.getUser(player) User user = uw().getUser(player);
.thenApply(user -> user.getNodes(NodeType.INHERITANCE) return user
.contains(GroupProvider.inheritanceNode(GroupProvider.ADMIN.getGroup()))) .getNodes(NodeType.INHERITANCE)
.join(); .contains(GroupProvider
.inheritanceNode(
GroupProvider
.ADMIN
.getGroup()));
} }
public Track op() public Track op()
{ {
return trackWrapper.getTrack("OP").join(); return tw().getTrack("OP");
} }
public Track builder() public Track builder()
{ {
return trackWrapper.getTrack("BUILDER").join(); return tw().getTrack("BUILDER");
} }
public Track admin() public Track admin()
{ {
return trackWrapper.getTrack("ADMIN").join(); return tw().getTrack("ADMIN");
}
@SuppressWarnings("unchecked")
public <T> T getWrapper(Class<T> clazz)
{
if (clazz == GroupWrapper.class)
{
return (T) groupWrapper;
} else if (clazz == TrackWrapper.class)
{
return clazz.cast(trackWrapper);
} else if (clazz == UserWrapper.class)
{
return clazz.cast(userWrapper);
} else
{
throw new IllegalArgumentException("Invalid class type");
}
} }
public void asyncInheritFrom(DisplayableGroup inherited, DisplayableGroup inheritor) public void asyncInheritFrom(DisplayableGroup inherited, DisplayableGroup inheritor)
{ {
CompletableFuture.runAsync(() -> inheritor
{ .getLuckPermsGroup()
inheritor.getLuckPermsGroup().data().add(inherited.getInheritance()); .data()
groupWrapper.saveGroupAsync(inheritor.getLuckPermsGroup().getName()); .add(inherited.getInheritance());
}).whenComplete((a, b) ->
{ gw().saveGroup(inheritor
if (b != null) .getLuckPermsGroup()
{ .getName());
FLog.severe(b);
} FLog.info("Inherited " + inherited.getName() + " to " + inheritor.getName());
});
} }
public Group getGroup(String name) public Group getGroup(String name)
{ {
return groupWrapper.getGroup(name).join(); return gw().getGroup(name);
} }
public void asyncTrackGroup(Track track, DisplayableGroup group) public void asyncTrackGroup(Track track, DisplayableGroup group)
{ {
trackWrapper.getTrack(track.getName()).thenAccept(t -> Track t = tw().getTrack(track.getName());
{
t.appendGroup(group.getLuckPermsGroup()); t.appendGroup(group.getLuckPermsGroup());
trackWrapper.saveTrack(t.getName()); tw().saveTrack(t.getName());
}).whenComplete((a, b) -> gw().saveGroup(group.getLuckPermsGroup().getName());
{ FLog.info("Added " + group.getName() + " to track " + track.getName());
if (b != null)
{
FLog.severe(b);
}
});
} }
public void asyncAddUserData(Player player) public PromotionResult promoteUser(Track track, Player player)
{ {
userWrapper.addUserData(player).whenComplete((a, b) -> User user = UserData.fromPlayer(player);
{ return track.promote(user, UserData.getContextSet(user));
if (b != null)
{
FLog.severe(b);
}
});
} }
public void asyncUpdateUserData(Player player) public DemotionResult demoteUser(Track track, Player player)
{ {
userWrapper.updateUserData(player).whenComplete((a, b) -> User user = UserData.fromPlayer(player);
{ return track.demote(user, UserData.getContextSet(user));
if (b != null)
{
FLog.severe(b);
}
});
}
public void asyncUserDrop(Player player)
{
userWrapper.removeUserData(player).whenComplete((a, b) ->
{
if (b != null)
{
FLog.severe(b);
}
});
}
public CompletableFuture<PromotionResult> promoteUser(Track track, Player player)
{
return userWrapper.getUserData(player)
.thenApply(data -> track.promote(data.getUser(), data.getContextSet()));
}
public CompletableFuture<DemotionResult> demoteUser(Track track, Player player)
{
return userWrapper.getUserData(player)
.thenApply(data -> track.demote(data.getUser(), data.getContextSet()));
} }
public void addUserToGroup(DisplayableGroup group, Player player) public void addUserToGroup(DisplayableGroup group, Player player)
{ {
userWrapper.getUserData(player).thenAccept(user -> User user = UserData.fromPlayer(player);
userWrapper.addToGroup(user.getUser(), group)) uw().addToGroup(user, group);
.whenComplete((a, b) -> FLog.info("Successfully added " + player.getName() + " to " + group.getName());
{
if (b != null)
{
FLog.severe(b);
}
});
} }
public void dropUserFromAll(Track track, Player player) public void dropUser(Track track, Player player)
{
userWrapper.getUserData(player).thenAccept(data ->
{ {
User user = UserData.fromPlayer(player);
for (String group : track.getGroups()) for (String group : track.getGroups())
{ {
groupWrapper.getGroup(group).whenComplete((g, b) -> Group g = gw().getGroup(group);
{ InheritanceNode node = GroupProvider.directFromLPG(g).getInheritance();
if (b != null)
{
FLog.severe(b);
return;
}
if (data.getUser().getNodes(NodeType.INHERITANCE) if (user.getNodes(NodeType.INHERITANCE).contains(node))
.contains(InheritanceNode.builder(g).build())) uw().removeFromGroup(user, GroupProvider.wrappedFromLPG(g).getGroup());
userWrapper.removeFromGroup(data.getUser(), GroupProvider.fromLuckPermsGroup(g).getGroup());
});
}
}).whenComplete((a, b) ->
{
if (b != null)
{
FLog.severe(b);
}
});
}
private class LuckPermsUserDataListener
{
private final Map<NamespacedKey, EventSubscription<?>> 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));
}
public void unregister()
{
subscriptions.forEach((key, subscription) -> subscription.close());
subscriptions.clear();
}
private void onNodeAdd(NodeAddEvent event)
{
if (event.getTarget() instanceof User user)
{
Player player = Bukkit.getPlayer(user.getUniqueId());
if (player != null)
{
TotalFreedomMod.getPlugin().rm.updateDisplay(player);
asyncUpdateUserData(player);
uw().saveUser(user);
}
}
if (event.getTarget() instanceof Group group)
{
gw().saveGroupAsync(group.getName());
}
}
private void onNodeRemove(NodeRemoveEvent event)
{
if (event.getTarget() instanceof User user)
{
Player player = Bukkit.getPlayer(user.getUniqueId());
if (player != null)
{
TotalFreedomMod.getPlugin().rm.updateDisplay(player);
asyncUpdateUserData(player);
uw().saveUser(user);
}
}
if (event.getTarget() instanceof Group group)
{
gw().saveGroupAsync(group.getName());
}
} }
} }
} }

View File

@ -188,19 +188,11 @@ public class RankManager extends FreedomService
updatePlayerTeam(player); updatePlayerTeam(player);
} }
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerLeave(PlayerQuitEvent event)
{
Hierarchy.getHierarchy().asyncUserDrop(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) public void onPlayerJoin(PlayerJoinEvent event)
{ {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
Hierarchy.getHierarchy().asyncAddUserData(player);
PlayerData target = plugin.pl.getData(player); PlayerData target = plugin.pl.getData(player);
boolean isAdmin = plugin.al.isAdmin(player); boolean isAdmin = plugin.al.isAdmin(player);