attempt to fix once again

This commit is contained in:
Paul Reilly 2023-04-13 14:37:55 -05:00
parent f4f60a7993
commit 9138d1856b
17 changed files with 237 additions and 108 deletions

View File

@ -1,5 +1,12 @@
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.List;
@ -29,8 +36,7 @@ public class FreedomServiceHandler
try
{
service.onStart();
}
catch (Exception e)
} catch (Exception e)
{
e.printStackTrace();
}
@ -44,8 +50,7 @@ public class FreedomServiceHandler
try
{
service.onStop();
}
catch (Exception e)
} catch (Exception e)
{
e.printStackTrace();
}

View File

@ -153,7 +153,7 @@ public class Admin
private void setActiveSplitWorkToReduceComplexity(TotalFreedomMod plugin)
{
if (getRank().isAtLeast(GroupProvider.ADMIN.getGroup()))
if (getRank().weightCheckAgainst(GroupProvider.ADMIN.getGroup()))
{
if (plugin.btb != null)
{

View File

@ -192,7 +192,7 @@ public class AdminList extends FreedomService
public boolean removeAdmin(Admin admin)
{
if (admin.getRank().isAtLeast(GroupProvider.ADMIN.getGroup()) && (plugin.btb != null))
if (admin.getRank().weightCheckAgainst(GroupProvider.ADMIN.getGroup()) && (plugin.btb != null))
{
plugin.btb.killTelnetSessions(admin.getName());
}
@ -270,7 +270,7 @@ public class AdminList extends FreedomService
public void deactivateOldEntries(boolean verbose)
{
allAdmins.stream()
.filter(admin -> admin.isActive() && !admin.getRank().isAtLeast(GroupProvider.SENIOR_ADMIN.getGroup()))
.filter(admin -> admin.isActive() && !admin.getRank().weightCheckAgainst(GroupProvider.SENIOR_ADMIN.getGroup()))
.forEach(admin ->
{
final Date lastLogin = admin.getLastLogin();

View File

@ -66,8 +66,7 @@ public enum ShopItem
try
{
return ShopItem.valueOf(string.toUpperCase());
}
catch (Exception ignored)
} catch (Exception ignored)
{
}

View File

@ -9,13 +9,13 @@ import org.jetbrains.annotations.NotNull;
public class AdminChatEvent extends Event
{
private static HandlerList handlerList = new HandlerList();
private static final HandlerList handlerList = new HandlerList();
//--
private Key identifier;
private final Key identifier;
private Component prefix = Component.empty();
private Component name;
private Displayable displayable;
private Component message;
private final Component name;
private final Displayable displayable;
private final Component message;
public AdminChatEvent(Key identifier, Component prefix, Component name, Displayable rank, Component message, boolean async)
{

View File

@ -7,6 +7,7 @@ import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.rank.DisplayableGroup;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.luckperms.api.context.ContextSatisfyMode;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -158,7 +159,8 @@ public class EssentialsBridge extends FreedomService
Player invOwner = (Player)inventoryHolder;
DisplayableGroup recieverRank = plugin.rm.getRank(player);
DisplayableGroup playerRank = plugin.rm.getRank(invOwner);
if (playerRank.getWeight() >= recieverRank.getWeight() || !invOwner.isOnline())
if (playerRank.getWeight().getWeight() >= recieverRank.getWeight().getWeight()
|| !invOwner.isOnline())
{
event.setCancelled(true);
refreshPlayer = player;

View File

@ -50,7 +50,7 @@ public class Command_deop extends FreedomCommand
return;
}
if (result == null || !result.wasSuccessful()) {
if (!result.wasSuccessful()) {
msgNew("<red><player> is already non-op.", Placeholder.unparsed("player", player.getName()));
return;
}

View File

@ -33,7 +33,7 @@ public class Command_deopall extends FreedomCommand
return;
}
if (result == null || !result.wasSuccessful()) {
if (!result.wasSuccessful()) {
msgNew("<red><player> is already non-OP.", Placeholder.unparsed("player", player.getName()));
return;
}

View File

@ -213,7 +213,7 @@ public class Command_saconfig extends FreedomCommand
return;
}
if (result == null || !result.wasSuccessful() || result.getGroupTo().isEmpty())
if (!result.wasSuccessful() || result.getGroupTo().isEmpty())
{
msgNew("<red>Failed to demote <player> to the next rank.", player(player));
return;
@ -244,7 +244,7 @@ public class Command_saconfig extends FreedomCommand
plugin.al.save(admin);
plugin.al.updateTables();
if (plugin.dc != null && plugin.dc.isEnabled() && ConfigEntry.DISCORD_ROLE_SYNC.getBoolean())
if (plugin.dc != null && plugin.dc.isEnabled() && Boolean.TRUE.equals(ConfigEntry.DISCORD_ROLE_SYNC.getBoolean()))
{
plugin.dc.syncRoles(admin, plugin.pl.getData(player).getDiscordID());
}

View File

@ -1,9 +1,12 @@
package me.totalfreedom.totalfreedommod.perms;
import me.totalfreedom.totalfreedommod.util.FLog;
import net.luckperms.api.model.group.Group;
import net.luckperms.api.model.group.GroupManager;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
public class GroupWrapper
{
@ -18,14 +21,39 @@ public class GroupWrapper
{
if (!manager.isLoaded(name) || !manager.getLoadedGroups().contains(manager.getGroup(name)))
{
return manager.createAndLoadGroup(name);
Optional<Group> group = manager.loadGroup(name).join();
return group
.map(CompletableFuture::completedFuture)
.orElseGet(() -> manager.createAndLoadGroup(name));
}
return CompletableFuture.supplyAsync(() -> manager.getGroup(name));
}
public void saveGroup(String name)
public void modifyGroup(String name, Function<Group, ? extends Group> function)
{
getGroup(name).thenAccept(manager::saveGroup);
getGroup(name)
.thenApplyAsync(function)
.thenAcceptAsync(manager::saveGroup)
.whenCompleteAsync((aVoid, throwable) ->
{
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

@ -99,21 +99,19 @@ public class UserWrapper
manager.modifyUser(user.getUniqueId(), c ->
{
if (!c.getNodes(NodeType.INHERITANCE)
.contains(GroupProvider.inheritanceNode(group)))
c.data().add(GroupProvider.inheritanceNode(group));
.contains(group.getInheritance()))
c.data().add(group.getInheritance());
}));
}
public void removeFromGroup(User user, Group group)
public void removeFromGroup(User user, DisplayableGroup group)
{
InheritanceNode groupNode = InheritanceNode.builder(group).build();
CompletableFuture.runAsync(() ->
manager.modifyUser(user.getUniqueId(), userConsumer ->
{
if (userConsumer.getNodes(NodeType.INHERITANCE)
.contains(groupNode))
userConsumer.data().remove(groupNode);
.contains(group.getInheritance()))
userConsumer.data().remove(group.getInheritance());
}));
}

View File

@ -100,7 +100,7 @@ public class PlayerList extends FreedomService
public boolean isTelnetMasterBuilder(PlayerData playerData)
{
Admin admin = plugin.al.getEntryByUuid(playerData.getUuid());
return admin != null && admin.getRank().isAtLeast(GroupProvider.ADMIN.getGroup()) && playerData.isMasterBuilder();
return admin != null && admin.getRank().weightCheckAgainst(GroupProvider.ADMIN.getGroup()) && playerData.isMasterBuilder();
}
// May not return null

View File

@ -1,19 +1,21 @@
package me.totalfreedom.totalfreedommod.rank;
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import net.luckperms.api.model.data.DataType;
import net.luckperms.api.context.ContextSatisfyMode;
import net.luckperms.api.model.group.Group;
import net.luckperms.api.node.NodeType;
import net.luckperms.api.node.types.InheritanceNode;
import net.luckperms.api.node.types.PermissionNode;
import net.luckperms.api.node.types.PrefixNode;
import net.luckperms.api.node.types.WeightNode;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CompletableFuture;
public class DisplayableGroup implements Displayable
{
@ -24,7 +26,7 @@ public class DisplayableGroup implements Displayable
private final Component abbr;
private final Component plural;
private final Component article;
private final int weight;
private final WeightNode weight;
private final Component tag;
@ -38,6 +40,12 @@ public class DisplayableGroup implements Displayable
private final boolean hasDefaultLoginMessage;
private final InheritanceNode inheritance;
private final PrefixNode prefix;
private final List<PermissionNode> permissions = new ArrayList<>();
public DisplayableGroup(String group,
Component plural,
Component tag,
@ -47,54 +55,80 @@ public class DisplayableGroup implements Displayable
boolean hasTeam,
boolean hasDefaultLoginMessage)
{
Group matched = TotalFreedomMod.getPlugin().lpb.getAPI().getGroupManager().getGroup(group);
WeightNode tempWeight;
PrefixNode tempPrefix;
Group matched = Hierarchy.getHierarchy().getGroup(group); // we don't need to null check because if there is no group this method will also create one.
if (matched == null)
{
CompletableFuture<Group> cfg = TotalFreedomMod.getPlugin()
.lpb
.getAPI()
.getGroupManager()
.createAndLoadGroup(group);
cfg.thenAcceptAsync(g ->
{
WeightNode weightNode = WeightNode.builder(weight).build();
PrefixNode prefixNode = PrefixNode.builder()
.prefix(FUtil.miniMessage(GroupProvider.OPEN.append(tag.color(color)).append(GroupProvider.CLOSE)))
.priority(1)
.build();
g.getData(DataType.NORMAL).add(prefixNode);
g.getData(DataType.NORMAL).add(weightNode);
}).join(); // Block until the group is created and loaded.
matched = TotalFreedomMod.getPlugin().lpb.getAPI().getGroupManager().getGroup(group);
if (matched == null)
throw new IllegalArgumentException("Group " + group + " does not exist and could not be created.");
}
this.group = matched;
this.name = (matched.getDisplayName() != null) ? FUtil.miniMessage(matched.getDisplayName()) : FUtil.miniMessage(matched.getName());
this.plural = plural;
this.article = StringUtils.startsWithAny(this.name.toString().toLowerCase(Locale.ROOT), new String[]{"a", "e", "i", "o", "u"}) ? Component.text("an") : Component.text("a");
this.abbr = tag;
this.weight = weight;
this.tag = GroupProvider.OPEN.append(tag).append(GroupProvider.CLOSE);
this.color = color;
this.teamColor = teamColor;
this.hasTeam = hasTeam;
this.coloredTag = tag.color(color);
this.tag = GroupProvider.OPEN.append(coloredTag).append(GroupProvider.CLOSE);
this.hasDefaultLoginMessage = hasDefaultLoginMessage;
tempWeight = WeightNode.builder(weight).build();
tempPrefix = PrefixNode.builder(FUtil.miniMessage(getTag()), weight).build();
permissions.addAll(matched.getNodes(NodeType.PERMISSION));
if (!matched.getNodes(NodeType.PREFIX).contains(tempPrefix)) matched.data().add(tempPrefix);
else tempPrefix = matched.getNodes(NodeType.PREFIX).iterator().next();
if (!matched.getNodes(NodeType.WEIGHT).contains(tempWeight)) matched.data().add(tempWeight);
else tempWeight = matched.getNodes(NodeType.WEIGHT).iterator().next();
this.prefix = tempPrefix;
this.weight = tempWeight;
this.group = matched;
this.inheritance = InheritanceNode.builder(this.group).build();
Hierarchy.getHierarchy().gw().saveGroupAsync(this.group.getName());
}
public boolean isAtLeast(@NotNull DisplayableGroup rank)
/**
* Checks the weight of this rank instance against the given rank.
*
* @param rank The rank to check against.
* @return True if the given rank is less than or equal to the weight of this specific rank instance.
*/
public boolean weightCheckAgainst(@NotNull DisplayableGroup rank)
{
return rank.getLuckPermsGroup().getWeight().orElse(0)
<= getLuckPermsGroup().getWeight().orElse(0);
return rank.getWeight().getWeight() <= getWeight().getWeight();
}
public int getWeight()
public void addPermission(String permission)
{
PermissionNode node = PermissionNode.builder(permission).build();
for (PermissionNode it : group.getNodes(NodeType.PERMISSION))
{
if (it.getContexts().isSatisfiedBy(node.getContexts())
|| it.getKey().equals(node.getKey()))
continue;
group.data().add(node);
permissions.add(node);
Hierarchy.getHierarchy().gw().saveGroupAsync(group.getName());
}
}
public void removePermission(String permission)
{
PermissionNode node = PermissionNode.builder(permission).build();
for (PermissionNode it : group.getNodes(NodeType.PERMISSION))
{
if (it.getContexts().isSatisfiedBy(node.getContexts(), ContextSatisfyMode.AT_LEAST_ONE_VALUE_PER_KEY)
|| it.getKey().equals(node.getKey()))
{
group.data().remove(node);
permissions.remove(node);
Hierarchy.getHierarchy().gw().saveGroupAsync(group.getName());
}
}
}
public WeightNode getWeight()
{
return weight;
}
@ -175,4 +209,19 @@ public class DisplayableGroup implements Displayable
{
return hasDefaultLoginMessage;
}
public InheritanceNode getInheritance()
{
return inheritance;
}
public PrefixNode getPrefix()
{
return prefix;
}
public List<PermissionNode> getPermissions()
{
return permissions;
}
}

View File

@ -10,7 +10,9 @@ import net.luckperms.api.node.types.InheritanceNode;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
@FunctionalInterface
public interface GroupProvider<T extends DisplayableGroup>
@ -34,6 +36,14 @@ public interface GroupProvider<T extends DisplayableGroup>
return NodeMatcher.key(inheritanceNode(group));
}
static DisplayableGroup LAMBDA$fromLuckPermsGroup(Group group)
{
return List.of(NON_OP.getGroup(), OP.getGroup(), MASTER_BUILDER.getGroup(), ADMIN.getGroup(), SENIOR_ADMIN.getGroup()).stream()
.filter(displayableGroup -> displayableGroup.getLuckPermsGroup().equals(group))
.findFirst()
.orElse(NON_OP.getGroup());
}
static User getUser(Player player)
{
return TotalFreedomMod.getPlugin()
@ -56,14 +66,10 @@ public interface GroupProvider<T extends DisplayableGroup>
static GroupProvider<DisplayableGroup> fromLuckPermsGroup(Group group)
{
return switch (group.getName().toLowerCase())
{
case "op" -> OP;
case "builder" -> MASTER_BUILDER;
case "admin" -> ADMIN;
case "senior" -> SENIOR_ADMIN;
default -> NON_OP;
};
return Stream.of(NON_OP, OP, MASTER_BUILDER, ADMIN, SENIOR_ADMIN)
.filter(displayableGroup -> displayableGroup.getGroup().getLuckPermsGroup().equals(group))
.findFirst()
.orElse(NON_OP);
}
static Set<GroupProvider<DisplayableGroup>> providerSet()

View File

@ -48,6 +48,21 @@ public class Hierarchy
return hierarchy;
}
public TrackWrapper tw()
{
return trackWrapper;
}
public GroupWrapper gw()
{
return groupWrapper;
}
public UserWrapper uw()
{
return userWrapper;
}
public PlayerAdapter<Player> getPlayerAdapter()
{
return playerAdapter;
@ -76,12 +91,30 @@ public class Hierarchy
return trackWrapper.getTrack("ADMIN").join();
}
public void addInheritance(DisplayableGroup previous, DisplayableGroup current)
@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)
{
CompletableFuture.runAsync(() ->
{
current.getLuckPermsGroup().data().add(InheritanceNode.builder(previous.getLuckPermsGroup()).build());
groupWrapper.saveGroup(current.getLuckPermsGroup().getName());
inheritor.getLuckPermsGroup().data().add(inherited.getInheritance());
groupWrapper.saveGroupAsync(inheritor.getLuckPermsGroup().getName());
}).whenComplete((a, b) ->
{
if (b != null)
@ -96,7 +129,7 @@ public class Hierarchy
return groupWrapper.getGroup(name).join();
}
public void addGroupToTrack(Track track, DisplayableGroup group)
public void asyncTrackGroup(Track track, DisplayableGroup group)
{
trackWrapper.getTrack(track.getName()).thenAccept(t ->
{
@ -111,7 +144,7 @@ public class Hierarchy
});
}
public void addUserData(Player player)
public void asyncAddUserData(Player player)
{
userWrapper.addUserData(player).whenComplete((a, b) ->
{
@ -122,7 +155,7 @@ public class Hierarchy
});
}
public void updateUserData(Player player)
public void asyncUpdateUserData(Player player)
{
userWrapper.updateUserData(player).whenComplete((a, b) ->
{
@ -133,7 +166,7 @@ public class Hierarchy
});
}
public void dropUserData(Player player)
public void asyncUserDrop(Player player)
{
userWrapper.removeUserData(player).whenComplete((a, b) ->
{
@ -185,7 +218,7 @@ public class Hierarchy
if (data.getUser().getNodes(NodeType.INHERITANCE)
.contains(InheritanceNode.builder(g).build()))
userWrapper.removeFromGroup(data.getUser(), g);
userWrapper.removeFromGroup(data.getUser(), GroupProvider.fromLuckPermsGroup(g).getGroup());
});
}
}).whenComplete((a, b) ->
@ -216,29 +249,39 @@ public class Hierarchy
private void onNodeAdd(NodeAddEvent event)
{
if (event.isUser())
if (event.getTarget() instanceof User user)
{
User user = (User) event.getTarget();
Player player = Bukkit.getPlayer(user.getUniqueId());
if (player != null)
{
TotalFreedomMod.getPlugin().rm.updateDisplay(player);
updateUserData(player);
asyncUpdateUserData(player);
uw().saveUser(user);
}
}
if (event.getTarget() instanceof Group group)
{
gw().saveGroupAsync(group.getName());
}
}
private void onNodeRemove(NodeRemoveEvent event)
{
if (event.isUser())
if (event.getTarget() instanceof User user)
{
User user = (User) event.getTarget();
Player player = Bukkit.getPlayer(user.getUniqueId());
if (player != null)
{
TotalFreedomMod.getPlugin().rm.updateDisplay(player);
updateUserData(player);
}
asyncUpdateUserData(player);
uw().saveUser(user);
}
}
if (event.getTarget() instanceof Group group)
{
gw().saveGroupAsync(group.getName());
}
}
}

View File

@ -7,7 +7,6 @@ import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.apache.commons.lang.StringUtils;
import org.bukkit.command.CommandSender;
@ -30,14 +29,14 @@ public class RankManager extends FreedomService
// Here, we are automatically creating new tracks if they don't exist, and then adding groups to them.
Hierarchy hierarchy = Hierarchy.getHierarchy();
hierarchy.addGroupToTrack(hierarchy.op(), GroupProvider.NON_OP.getGroup());
hierarchy.addGroupToTrack(hierarchy.op(), GroupProvider.OP.getGroup());
hierarchy.addGroupToTrack(hierarchy.builder(), GroupProvider.MASTER_BUILDER.getGroup());
hierarchy.addGroupToTrack(hierarchy.admin(), GroupProvider.ADMIN.getGroup());
hierarchy.addGroupToTrack(hierarchy.admin(), GroupProvider.SENIOR_ADMIN.getGroup());
hierarchy.asyncTrackGroup(hierarchy.op(), GroupProvider.NON_OP.getGroup());
hierarchy.asyncTrackGroup(hierarchy.op(), GroupProvider.OP.getGroup());
hierarchy.asyncTrackGroup(hierarchy.builder(), GroupProvider.MASTER_BUILDER.getGroup());
hierarchy.asyncTrackGroup(hierarchy.admin(), GroupProvider.ADMIN.getGroup());
hierarchy.asyncTrackGroup(hierarchy.admin(), GroupProvider.SENIOR_ADMIN.getGroup());
hierarchy.addInheritance(GroupProvider.NON_OP.getGroup(), GroupProvider.OP.getGroup());
hierarchy.addInheritance(GroupProvider.ADMIN.getGroup(), GroupProvider.SENIOR_ADMIN.getGroup());
hierarchy.asyncInheritFrom(GroupProvider.NON_OP.getGroup(), GroupProvider.OP.getGroup());
hierarchy.asyncInheritFrom(GroupProvider.ADMIN.getGroup(), GroupProvider.SENIOR_ADMIN.getGroup());
}
@Override
@ -192,7 +191,7 @@ public class RankManager extends FreedomService
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerLeave(PlayerQuitEvent event)
{
Hierarchy.getHierarchy().dropUserData(event.getPlayer());
Hierarchy.getHierarchy().asyncUserDrop(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR)
@ -200,7 +199,7 @@ public class RankManager extends FreedomService
{
final Player player = event.getPlayer();
Hierarchy.getHierarchy().addUserData(player);
Hierarchy.getHierarchy().asyncAddUserData(player);
PlayerData target = plugin.pl.getData(player);