mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-28 20:17:55 +01:00
Refactor paginated command output, add flags for ordering 'permission info' entries, fix crashes caused by long messages (#591)
This commit is contained in:
parent
2e7a08c006
commit
904bb90385
@ -302,7 +302,7 @@ public class VaultChatHook extends Chat {
|
||||
world = perms.correctWorld(world);
|
||||
|
||||
Contexts contexts;
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
contexts = perms.createContextForWorldLookup(perms.getPlugin().getPlayer((User) holder), world);
|
||||
} else {
|
||||
contexts = perms.createContextForWorldLookup(world);
|
||||
@ -322,7 +322,7 @@ public class VaultChatHook extends Chat {
|
||||
world = perms.correctWorld(world);
|
||||
|
||||
Contexts contexts;
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
contexts = perms.createContextForWorldLookup(perms.getPlugin().getPlayer((User) holder), world);
|
||||
} else {
|
||||
contexts = perms.createContextForWorldLookup(world);
|
||||
|
@ -444,11 +444,11 @@ public class VaultPermissionHook extends Permission {
|
||||
}
|
||||
|
||||
void holderSave(PermissionHolder holder) {
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
User u = (User) holder;
|
||||
plugin.getStorage().saveUser(u).thenRunAsync(() -> u.getRefreshBuffer().request(), plugin.getScheduler().async());
|
||||
}
|
||||
if (holder instanceof Group) {
|
||||
if (holder.getType().isGroup()) {
|
||||
Group g = (Group) holder;
|
||||
plugin.getStorage().saveGroup(g).thenRunAsync(() -> plugin.getUpdateTaskBuffer().request(), plugin.getScheduler().async());
|
||||
}
|
||||
|
@ -283,11 +283,11 @@ public class ExtendedLogEntry implements LogEntry {
|
||||
}
|
||||
|
||||
public ExtendedLogEntryBuilder acted(PermissionHolder acted) {
|
||||
if (acted instanceof User) {
|
||||
if (acted.getType().isUser()) {
|
||||
actedName(((User) acted).getName().orElse("null"));
|
||||
acted(((User) acted).getUuid());
|
||||
type(Type.USER);
|
||||
} else if (acted instanceof Group) {
|
||||
} else if (acted.getType().isGroup()) {
|
||||
actedName(((Group) acted).getName());
|
||||
type(Type.GROUP);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public class ApiPermissionHolder implements PermissionHolder {
|
||||
|
||||
@Override
|
||||
public String getFriendlyName() {
|
||||
if (handle instanceof Group) {
|
||||
if (handle.getType().isGroup()) {
|
||||
Group group = (Group) this.handle;
|
||||
return group.getDisplayName().orElse(group.getName());
|
||||
}
|
||||
@ -181,7 +181,7 @@ public class ApiPermissionHolder implements PermissionHolder {
|
||||
@Override
|
||||
public void clearMatching(Predicate<Node> test) {
|
||||
handle.removeIf(test);
|
||||
if (handle instanceof User) {
|
||||
if (handle.getType().isUser()) {
|
||||
handle.getPlugin().getUserManager().giveDefaultIfNeeded((User) handle, false);
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.node.NodeFactory;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.references.HolderType;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
import me.lucko.luckperms.common.utils.Cycle;
|
||||
|
||||
@ -124,7 +125,7 @@ public class Exporter implements Runnable {
|
||||
|
||||
write(writer, "# Export group: " + group.getName());
|
||||
for (Node node : group.getEnduringNodes().values()) {
|
||||
write(writer, "/lp " + NodeFactory.nodeAsCommand(node, group.getName(), true, true));
|
||||
write(writer, "/lp " + NodeFactory.nodeAsCommand(node, group.getName(), HolderType.GROUP, true));
|
||||
}
|
||||
write(writer, "");
|
||||
log.logAllProgress("Exported {} groups so far.", groupCount.incrementAndGet());
|
||||
@ -230,7 +231,7 @@ public class Exporter implements Runnable {
|
||||
continue;
|
||||
}
|
||||
|
||||
output.add("/lp " + NodeFactory.nodeAsCommand(node, user.getUuid().toString(), false, true));
|
||||
output.add("/lp " + NodeFactory.nodeAsCommand(node, user.getUuid().toString(), HolderType.USER, true));
|
||||
}
|
||||
|
||||
if (!user.getPrimaryGroup().getStoredValue().orElse("default").equalsIgnoreCase("default")) {
|
||||
|
@ -118,13 +118,13 @@ public abstract class SharedSubCommand {
|
||||
}
|
||||
|
||||
public static void save(PermissionHolder holder, Sender sender, LuckPermsPlugin plugin) {
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
User user = ((User) holder);
|
||||
SubCommand.save(user, sender, plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
if (holder instanceof Group) {
|
||||
if (holder.getType().isGroup()) {
|
||||
Group group = ((Group) holder);
|
||||
SubCommand.save(group, sender, plugin);
|
||||
return;
|
||||
|
@ -43,7 +43,6 @@ import me.lucko.luckperms.common.locale.LocaleManager;
|
||||
import me.lucko.luckperms.common.locale.Message;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.node.NodeFactory;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
@ -168,12 +167,12 @@ public class MetaInfo extends SharedSubCommand {
|
||||
"¥7Click to remove this " + type.name().toLowerCase() + " from " + holder.getFriendlyName()
|
||||
), '¥'));
|
||||
|
||||
boolean group = !(holder instanceof User);
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(node, group ? holder.getObjectName() : holder.getFriendlyName(), group, false);
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(node, holder.getType().isGroup() ? holder.getObjectName() : holder.getFriendlyName(), holder.getType(), false);
|
||||
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command);
|
||||
|
||||
return component -> {
|
||||
component.hoverEvent(hoverEvent);
|
||||
component.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
|
||||
component.clickEvent(clickEvent);
|
||||
};
|
||||
}
|
||||
|
||||
@ -192,12 +191,12 @@ public class MetaInfo extends SharedSubCommand {
|
||||
"¥7Click to remove this meta pair from " + holder.getFriendlyName()
|
||||
), '¥'));
|
||||
|
||||
boolean group = !(holder instanceof User);
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(node, group ? holder.getObjectName() : holder.getFriendlyName(), group, false);
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(node, holder.getType().isGroup() ? holder.getObjectName() : holder.getFriendlyName(), holder.getType(), false);
|
||||
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command);
|
||||
|
||||
return component -> {
|
||||
component.hoverEvent(hoverEvent);
|
||||
component.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
|
||||
component.clickEvent(clickEvent);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public class HolderEditor<T extends PermissionHolder> extends SubCommand<T> {
|
||||
JsonObject payload = new JsonObject();
|
||||
payload.addProperty("who", WebEditorUtils.getHolderIdentifier(holder));
|
||||
payload.addProperty("whoFriendly", holder.getFriendlyName());
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
payload.addProperty("whoUuid", ((User) holder).getUuid().toString());
|
||||
}
|
||||
payload.addProperty("cmdAlias", label);
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands.impl.generic.other;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.commands.ArgumentPermissions;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
@ -37,10 +39,13 @@ import me.lucko.luckperms.common.locale.CommandSpec;
|
||||
import me.lucko.luckperms.common.locale.LocaleManager;
|
||||
import me.lucko.luckperms.common.locale.Message;
|
||||
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -63,32 +68,32 @@ public class HolderShowTracks<T extends PermissionHolder> extends SubCommand<T>
|
||||
|
||||
Set<Node> nodes = holder.getEnduringNodes().values().stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.filter(Node::getValuePrimitive)
|
||||
.filter(Node::isPermanent)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<Map.Entry<Track, String>> lines = new ArrayList<>();
|
||||
|
||||
for (Node node : nodes) {
|
||||
String name = node.getGroupName();
|
||||
|
||||
plugin.getTrackManager().getAll().values().stream()
|
||||
List<Track> tracks = plugin.getTrackManager().getAll().values().stream()
|
||||
.filter(t -> t.containsGroup(name))
|
||||
.forEach(t -> sb.append("&a")
|
||||
.append(t.getName())
|
||||
.append(": ")
|
||||
.append(CommandUtils.listToArrowSep(t.getGroups(), name))
|
||||
.append(CommandUtils.getAppendableNodeContextString(node))
|
||||
.append("\n")
|
||||
);
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (Track t : tracks) {
|
||||
lines.add(Maps.immutableEntry(t, CommandUtils.listToArrowSep(t.getGroups(), name) + CommandUtils.getAppendableNodeContextString(node)));
|
||||
}
|
||||
}
|
||||
|
||||
if (sb.length() == 0) {
|
||||
if (lines.isEmpty()) {
|
||||
Message.LIST_TRACKS_EMPTY.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.SUCCESS;
|
||||
} else {
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
Message.LIST_TRACKS.send(sender, holder.getFriendlyName(), sb.toString());
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
Message.LIST_TRACKS.send(sender, holder.getFriendlyName());
|
||||
for (Map.Entry<Track, String> line : lines) {
|
||||
Message.LIST_TRACKS_ENTRY.send(sender, line.getKey().getName(), line.getValue());
|
||||
}
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ public class ParentClearTrack extends SharedSubCommand {
|
||||
holder.removeIf(node -> node.isGroupNode() && node.getFullContexts().equals(context) && track.containsGroup(node.getGroupName()));
|
||||
}
|
||||
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
plugin.getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
|
||||
|
@ -32,35 +32,38 @@ import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.abstraction.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.CommandUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.SortMode;
|
||||
import me.lucko.luckperms.common.commands.utils.SortType;
|
||||
import me.lucko.luckperms.common.constants.CommandPermission;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
import me.lucko.luckperms.common.locale.CommandSpec;
|
||||
import me.lucko.luckperms.common.locale.LocaleManager;
|
||||
import me.lucko.luckperms.common.locale.Message;
|
||||
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.node.NodeFactory;
|
||||
import me.lucko.luckperms.common.node.NodeWithContextComparator;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.utils.CollationKeyCache;
|
||||
import me.lucko.luckperms.common.utils.DateUtil;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.common.utils.TextUtils;
|
||||
|
||||
import net.kyori.text.BuildableComponent;
|
||||
import net.kyori.text.Component;
|
||||
import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.event.ClickEvent;
|
||||
import net.kyori.text.event.HoverEvent;
|
||||
import net.kyori.text.format.TextColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ParentInfo extends SharedSubCommand {
|
||||
public ParentInfo(LocaleManager locale) {
|
||||
super(CommandSpec.PARENT_INFO.spec(locale), "info", CommandPermission.USER_PARENT_INFO, CommandPermission.GROUP_PARENT_INFO, Predicates.alwaysFalse());
|
||||
super(CommandSpec.PARENT_INFO.spec(locale), "info", CommandPermission.USER_PARENT_INFO, CommandPermission.GROUP_PARENT_INFO, Predicates.notInRange(0, 2));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -70,58 +73,67 @@ public class ParentInfo extends SharedSubCommand {
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
Component ent = permGroupsToMessage(holder.getOwnNodesSorted(), holder, label);
|
||||
Message.LISTPARENTS.send(sender, holder.getFriendlyName());
|
||||
sender.sendMessage(ent);
|
||||
int page = ArgumentUtils.handleIntOrElse(0, args, 1);
|
||||
SortMode sortMode = SortMode.determine(args);
|
||||
|
||||
Component tempEnt = tempGroupsToMessage(holder.getOwnNodesSorted(), holder, label);
|
||||
Message.LISTPARENTS_TEMP.send(sender, holder.getFriendlyName());
|
||||
sender.sendMessage(tempEnt);
|
||||
// get the holders nodes
|
||||
List<LocalizedNode> nodes = new ArrayList<>(holder.getOwnNodesSorted());
|
||||
|
||||
// remove irrelevant types (these are displayed in the other info commands)
|
||||
nodes.removeIf(node -> !node.isGroupNode() || !node.getValuePrimitive());
|
||||
|
||||
// handle empty
|
||||
if (nodes.isEmpty()) {
|
||||
Message.PARENT_INFO_NO_DATA.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
// sort the list alphabetically instead
|
||||
if (sortMode.getType() == SortType.ALPHABETICALLY) {
|
||||
nodes.sort(ALPHABETICAL_NODE_COMPARATOR);
|
||||
}
|
||||
|
||||
// reverse the order if necessary
|
||||
if (!sortMode.isAscending()) {
|
||||
Collections.reverse(nodes);
|
||||
}
|
||||
|
||||
int pageIndex = page - 1;
|
||||
List<List<LocalizedNode>> pages = CommandUtils.divideList(nodes, 19);
|
||||
|
||||
if (pageIndex < 0 || pageIndex >= pages.size()) {
|
||||
page = 1;
|
||||
pageIndex = 0;
|
||||
}
|
||||
|
||||
List<LocalizedNode> content = pages.get(pageIndex);
|
||||
|
||||
// send header
|
||||
Message.PARENT_INFO.send(sender, holder.getFriendlyName(), page, pages.size(), nodes.size());
|
||||
|
||||
// send content
|
||||
for (LocalizedNode node : content) {
|
||||
String s = "&3> &a" + node.getGroupName() + CommandUtils.getAppendableNodeContextString(node);
|
||||
if (node.isTemporary()) {
|
||||
s += "\n&2 expires in " + DateUtil.formatDateDiff(node.getExpiryUnixTime());
|
||||
}
|
||||
|
||||
TextComponent message = TextUtils.fromLegacy(s, Constants.FORMAT_CHAR).toBuilder().applyDeep(makeFancy(holder, label, node)).build();
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private static Component permGroupsToMessage(SortedSet<LocalizedNode> nodes, PermissionHolder holder, String label) {
|
||||
List<Node> page = new ArrayList<>();
|
||||
for (Node node : nodes) {
|
||||
if (!node.isGroupNode()) continue;
|
||||
if (!node.getValuePrimitive()) continue;
|
||||
if (node.isTemporary()) continue;
|
||||
page.add(node);
|
||||
private static final Comparator<LocalizedNode> ALPHABETICAL_NODE_COMPARATOR = (o1, o2) -> {
|
||||
int i = CollationKeyCache.compareStrings(o1.getGroupName(), o2.getGroupName());
|
||||
if (i != 0) {
|
||||
return i;
|
||||
}
|
||||
|
||||
if (page.isEmpty()) {
|
||||
return TextComponent.builder("None").color(TextColor.DARK_AQUA).build();
|
||||
}
|
||||
|
||||
TextComponent.Builder message = TextComponent.builder("");
|
||||
for (Node node : page) {
|
||||
String s = "&3> &a" + node.getGroupName() + CommandUtils.getAppendableNodeContextString(node) + "\n";
|
||||
message.append(TextUtils.fromLegacy(s, Constants.FORMAT_CHAR).toBuilder().applyDeep(makeFancy(holder, label, node)).build());
|
||||
}
|
||||
return message.build();
|
||||
}
|
||||
|
||||
private static Component tempGroupsToMessage(SortedSet<LocalizedNode> nodes, PermissionHolder holder, String label) {
|
||||
List<Node> page = new ArrayList<>();
|
||||
for (Node node : nodes) {
|
||||
if (!node.isGroupNode()) continue;
|
||||
if (!node.getValuePrimitive()) continue;
|
||||
if (node.isPermanent()) continue;
|
||||
page.add(node);
|
||||
}
|
||||
|
||||
if (page.isEmpty()) {
|
||||
return TextComponent.builder("None").color(TextColor.DARK_AQUA).build();
|
||||
}
|
||||
|
||||
TextComponent.Builder message = TextComponent.builder("");
|
||||
for (Node node : page) {
|
||||
String s = "&3> &a" + node.getGroupName() + CommandUtils.getAppendableNodeContextString(node) + "\n&2- expires in " + DateUtil.formatDateDiff(node.getExpiryUnixTime()) + "\n";
|
||||
message.append(TextUtils.fromLegacy(s, Constants.FORMAT_CHAR).toBuilder().applyDeep(makeFancy(holder, label, node)).build());
|
||||
}
|
||||
return message.build();
|
||||
}
|
||||
// fallback to priority
|
||||
return NodeWithContextComparator.reverse().compare(o1, o2);
|
||||
};
|
||||
|
||||
private static Consumer<BuildableComponent.Builder<? ,?>> makeFancy(PermissionHolder holder, String label, Node node) {
|
||||
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextUtils.fromLegacy(TextUtils.joinNewline(
|
||||
@ -130,12 +142,12 @@ public class ParentInfo extends SharedSubCommand {
|
||||
"&7Click to remove this parent from " + holder.getFriendlyName()
|
||||
), Constants.FORMAT_CHAR));
|
||||
|
||||
boolean group = !(holder instanceof User);
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(node, group ? holder.getObjectName() : holder.getFriendlyName(), group, false);
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(node, holder.getType().isGroup() ? holder.getObjectName() : holder.getFriendlyName(), holder.getType(), false);
|
||||
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command);
|
||||
|
||||
return component -> {
|
||||
component.hoverEvent(hoverEvent);
|
||||
component.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
|
||||
component.clickEvent(clickEvent);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public class ParentRemove extends SharedSubCommand {
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
User user = (User) holder;
|
||||
|
||||
boolean shouldPrevent = plugin.getConfiguration().get(ConfigKeys.PREVENT_PRIMARY_GROUP_REMOVAL) &&
|
||||
@ -97,7 +97,7 @@ public class ParentRemove extends SharedSubCommand {
|
||||
.action("parent", "remove", groupName, context)
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
plugin.getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ public class ParentSet extends SharedSubCommand {
|
||||
|
||||
holder.clearParents(context, false);
|
||||
holder.setInheritGroup(group, context);
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
((User) holder).getPrimaryGroup().setStoredValue(group.getName());
|
||||
}
|
||||
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands.impl.generic.permission;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.commands.ArgumentPermissions;
|
||||
@ -36,30 +34,31 @@ import me.lucko.luckperms.common.commands.abstraction.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.CommandUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.SortMode;
|
||||
import me.lucko.luckperms.common.commands.utils.SortType;
|
||||
import me.lucko.luckperms.common.constants.CommandPermission;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
import me.lucko.luckperms.common.locale.CommandSpec;
|
||||
import me.lucko.luckperms.common.locale.LocaleManager;
|
||||
import me.lucko.luckperms.common.locale.Message;
|
||||
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.node.NodeFactory;
|
||||
import me.lucko.luckperms.common.node.NodeWithContextComparator;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.utils.CollationKeyCache;
|
||||
import me.lucko.luckperms.common.utils.DateUtil;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.common.utils.TextUtils;
|
||||
|
||||
import net.kyori.text.BuildableComponent;
|
||||
import net.kyori.text.Component;
|
||||
import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.event.ClickEvent;
|
||||
import net.kyori.text.event.HoverEvent;
|
||||
import net.kyori.text.format.TextColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class PermissionInfo extends SharedSubCommand {
|
||||
@ -74,111 +73,72 @@ public class PermissionInfo extends SharedSubCommand {
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
String filter = null;
|
||||
if (args.size() == 1) {
|
||||
// it might be a filter, if it's a number, then it relates to a page.
|
||||
try {
|
||||
Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
// it's not a number, so assume it's the filter.
|
||||
filter = args.get(0);
|
||||
}
|
||||
} else if (args.size() == 2) {
|
||||
filter = args.get(1);
|
||||
}
|
||||
|
||||
int page = ArgumentUtils.handleIntOrElse(0, args, 1);
|
||||
SortMode sortMode = SortMode.determine(args);
|
||||
|
||||
Map.Entry<Component, String> ent = nodesToMessage(false, filter, holder.getOwnNodesSorted(), holder, label, page, sender.isConsole());
|
||||
if (ent.getValue() != null) {
|
||||
Message.LISTNODES_WITH_PAGE.send(sender, holder.getFriendlyName(), ent.getValue());
|
||||
sender.sendMessage(ent.getKey());
|
||||
} else {
|
||||
Message.LISTNODES.send(sender, holder.getFriendlyName());
|
||||
sender.sendMessage(ent.getKey());
|
||||
// get the holders nodes
|
||||
List<LocalizedNode> nodes = new ArrayList<>(holder.getOwnNodesSorted());
|
||||
|
||||
// remove irrelevant types (these are displayed in the other info commands)
|
||||
nodes.removeIf(node ->
|
||||
// remove if the node is a group node, and if the value isn't false and if the group actually exists
|
||||
(node.isGroupNode() && node.getValuePrimitive() && plugin.getGroupManager().isLoaded(node.getGroupName())) ||
|
||||
// remove if the node is a meta node
|
||||
node.isPrefix() || node.isSuffix() || node.isMeta()
|
||||
);
|
||||
|
||||
// handle empty
|
||||
if (nodes.isEmpty()) {
|
||||
Message.PERMISSION_INFO_NO_DATA.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
Map.Entry<Component, String> tempEnt = nodesToMessage(true, filter, holder.getOwnNodesSorted(), holder, label, page, sender.isConsole());
|
||||
if (tempEnt.getValue() != null) {
|
||||
Message.LISTNODES_TEMP_WITH_PAGE.send(sender, holder.getFriendlyName(), tempEnt.getValue());
|
||||
sender.sendMessage(tempEnt.getKey());
|
||||
} else {
|
||||
Message.LISTNODES_TEMP.send(sender, holder.getFriendlyName());
|
||||
sender.sendMessage(tempEnt.getKey());
|
||||
// sort the list alphabetically instead
|
||||
if (sortMode.getType() == SortType.ALPHABETICALLY) {
|
||||
nodes.sort(ALPHABETICAL_NODE_COMPARATOR);
|
||||
}
|
||||
|
||||
// reverse the order if necessary
|
||||
if (!sortMode.isAscending()) {
|
||||
Collections.reverse(nodes);
|
||||
}
|
||||
|
||||
int pageIndex = page - 1;
|
||||
List<List<LocalizedNode>> pages = CommandUtils.divideList(nodes, 19);
|
||||
|
||||
if (pageIndex < 0 || pageIndex >= pages.size()) {
|
||||
page = 1;
|
||||
pageIndex = 0;
|
||||
}
|
||||
|
||||
List<LocalizedNode> content = pages.get(pageIndex);
|
||||
|
||||
// send header
|
||||
Message.PERMISSION_INFO.send(sender, holder.getFriendlyName(), page, pages.size(), nodes.size());
|
||||
|
||||
// send content
|
||||
for (LocalizedNode node : content) {
|
||||
String s = "&3> " + (node.getValuePrimitive() ? "&a" : "&c") + node.getPermission() + (sender.isConsole() ? " &7(" + node.getValuePrimitive() + "&7)" : "") + CommandUtils.getAppendableNodeContextString(node);
|
||||
if (node.isTemporary()) {
|
||||
s += "\n&2- expires in " + DateUtil.formatDateDiff(node.getExpiryUnixTime());
|
||||
}
|
||||
|
||||
TextComponent message = TextUtils.fromLegacy(s, Constants.FORMAT_CHAR).toBuilder().applyDeep(makeFancy(holder, label, node)).build();
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private static Map.Entry<Component, String> nodesToMessage(boolean temp, String filter, SortedSet<LocalizedNode> nodes, PermissionHolder holder, String label, int pageNumber, boolean console) {
|
||||
// parse the filter
|
||||
String nodeFilter = null;
|
||||
Map.Entry<String, String> contextFilter = null;
|
||||
|
||||
if (filter != null) {
|
||||
int index = filter.indexOf('=');
|
||||
|
||||
context:
|
||||
if (index != -1) {
|
||||
String key = filter.substring(0, index);
|
||||
if (key.equals("")) break context;
|
||||
|
||||
String value = filter.substring(index + 1);
|
||||
if (value.equals("")) break context;
|
||||
|
||||
contextFilter = Maps.immutableEntry(key, value);
|
||||
}
|
||||
|
||||
if (contextFilter == null) {
|
||||
nodeFilter = filter;
|
||||
}
|
||||
private static final Comparator<LocalizedNode> ALPHABETICAL_NODE_COMPARATOR = (o1, o2) -> {
|
||||
int i = CollationKeyCache.compareStrings(o1.getPermission(), o2.getPermission());
|
||||
if (i != 0) {
|
||||
return i;
|
||||
}
|
||||
|
||||
List<Node> l = new ArrayList<>();
|
||||
for (Node node : nodes) {
|
||||
if ((node.isGroupNode() && node.getValuePrimitive()) || node.isPrefix() || node.isSuffix() || node.isMeta()) continue;
|
||||
|
||||
// check against filters
|
||||
if (nodeFilter != null && !node.getPermission().startsWith(nodeFilter)) continue;
|
||||
if (contextFilter != null && !node.getFullContexts().hasIgnoreCase(contextFilter.getKey(), contextFilter.getValue())) continue;
|
||||
if (temp != node.isTemporary()) continue;
|
||||
|
||||
l.add(node);
|
||||
}
|
||||
|
||||
if (l.isEmpty()) {
|
||||
return Maps.immutableEntry(TextComponent.builder("None").color(TextColor.DARK_AQUA).build(), null);
|
||||
}
|
||||
|
||||
int index = pageNumber - 1;
|
||||
List<List<Node>> pages = CommandUtils.divideList(l, 15);
|
||||
|
||||
if (index < 0 || index >= pages.size()) {
|
||||
pageNumber = 1;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
List<Node> page = pages.get(index);
|
||||
|
||||
TextComponent.Builder message = TextComponent.builder("");
|
||||
String title = "&7(showing page &f" + pageNumber + "&7 of &f" + pages.size() + "&7 - &f" + l.size() + "&7 entries";
|
||||
if (filter != null) {
|
||||
title += " - filtered by &f\"" + filter + "\"&7)";
|
||||
} else {
|
||||
title += ")";
|
||||
}
|
||||
|
||||
for (Node node : page) {
|
||||
String s = "&3> " + (node.getValuePrimitive() ? "&a" : "&c") + node.getPermission() + (console ? " &7(" + node.getValuePrimitive() + "&7)" : "") + CommandUtils.getAppendableNodeContextString(node) + "\n";
|
||||
if (temp) {
|
||||
s += "&2- expires in " + DateUtil.formatDateDiff(node.getExpiryUnixTime()) + "\n";
|
||||
}
|
||||
|
||||
message.append(TextUtils.fromLegacy(s, Constants.FORMAT_CHAR).toBuilder().applyDeep(makeFancy(holder, label, node)).build());
|
||||
}
|
||||
|
||||
return Maps.immutableEntry(message.build(), title);
|
||||
}
|
||||
// fallback to priority
|
||||
return NodeWithContextComparator.reverse().compare(o1, o2);
|
||||
};
|
||||
|
||||
private static Consumer<BuildableComponent.Builder<?, ?>> makeFancy(PermissionHolder holder, String label, Node node) {
|
||||
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextUtils.fromLegacy(TextUtils.joinNewline(
|
||||
@ -187,12 +147,12 @@ public class PermissionInfo extends SharedSubCommand {
|
||||
"¥7Click to remove this node from " + holder.getFriendlyName()
|
||||
), '¥'));
|
||||
|
||||
boolean group = !(holder instanceof User);
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(node, group ? holder.getObjectName() : holder.getFriendlyName(), group, false);
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(node, holder.getType().isGroup() ? holder.getObjectName() : holder.getFriendlyName(), holder.getType(), false);
|
||||
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command);
|
||||
|
||||
return component -> {
|
||||
component.hoverEvent(hoverEvent);
|
||||
component.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
|
||||
component.clickEvent(clickEvent);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands.impl.group;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import me.lucko.luckperms.api.HeldPermission;
|
||||
@ -44,20 +46,17 @@ import me.lucko.luckperms.common.locale.Message;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.node.NodeFactory;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.references.HolderType;
|
||||
import me.lucko.luckperms.common.utils.DateUtil;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.common.utils.TextUtils;
|
||||
|
||||
import net.kyori.text.BuildableComponent;
|
||||
import net.kyori.text.Component;
|
||||
import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.event.ClickEvent;
|
||||
import net.kyori.text.event.HoverEvent;
|
||||
import net.kyori.text.format.TextColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -90,96 +89,60 @@ public class GroupListMembers extends SubCommand<Group> {
|
||||
|
||||
Message.SEARCH_RESULT.send(sender, users + groups, users, groups);
|
||||
|
||||
Map<UUID, String> uuidLookups = new HashMap<>();
|
||||
Function<UUID, String> lookupFunc = uuid -> uuidLookups.computeIfAbsent(uuid, u -> {
|
||||
String s = plugin.getStorage().getName(u).join();
|
||||
if (s == null || s.isEmpty() || s.equals("null")) {
|
||||
s = u.toString();
|
||||
}
|
||||
return s;
|
||||
});
|
||||
|
||||
Map.Entry<Component, String> msgUsers = searchUserResultToMessage(matchedUsers, lookupFunc, label, page);
|
||||
Map.Entry<Component, String> msgGroups = searchGroupResultToMessage(matchedGroups, label, page);
|
||||
|
||||
if (msgUsers.getValue() != null) {
|
||||
Message.SEARCH_SHOWING_USERS_WITH_PAGE.send(sender, msgUsers.getValue());
|
||||
sender.sendMessage(msgUsers.getKey());
|
||||
} else {
|
||||
Message.SEARCH_SHOWING_USERS.send(sender);
|
||||
sender.sendMessage(msgUsers.getKey());
|
||||
if (!matchedUsers.isEmpty()) {
|
||||
LoadingCache<UUID, String> uuidLookups = Caffeine.newBuilder()
|
||||
.build(u -> {
|
||||
String s = plugin.getStorage().getName(u).join();
|
||||
if (s == null || s.isEmpty() || s.equals("null")) {
|
||||
s = u.toString();
|
||||
}
|
||||
return s;
|
||||
});
|
||||
sendResult(sender, matchedUsers, uuidLookups::get, Message.SEARCH_SHOWING_USERS, HolderType.USER, label, page);
|
||||
}
|
||||
|
||||
if (msgGroups.getValue() != null) {
|
||||
Message.SEARCH_SHOWING_GROUPS_WITH_PAGE.send(sender, msgGroups.getValue());
|
||||
sender.sendMessage(msgGroups.getKey());
|
||||
} else {
|
||||
Message.SEARCH_SHOWING_GROUPS.send(sender);
|
||||
sender.sendMessage(msgGroups.getKey());
|
||||
if (!matchedGroups.isEmpty()) {
|
||||
sendResult(sender, matchedGroups, Function.identity(), Message.SEARCH_SHOWING_GROUPS, HolderType.GROUP, label, page);
|
||||
}
|
||||
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private static Map.Entry<Component, String> searchUserResultToMessage(List<HeldPermission<UUID>> results, Function<UUID, String> uuidLookup, String label, int pageNumber) {
|
||||
if (results.isEmpty()) {
|
||||
return Maps.immutableEntry(TextComponent.builder("None").color(TextColor.DARK_AQUA).build(), null);
|
||||
private static <T> void sendResult(Sender sender, List<HeldPermission<T>> results, Function<T, String> lookupFunction, Message headerMessage, HolderType holderType, String label, int page) {
|
||||
results = new ArrayList<>(results);
|
||||
|
||||
// we need a deterministic sort order
|
||||
// even though we're comparing uuids here in some cases - it doesn't matter
|
||||
// the import thing is that the order is the same each time the command is executed
|
||||
results.sort((o1, o2) -> {
|
||||
Comparable h1 = (Comparable) o1.getHolder();
|
||||
Comparable h2 = (Comparable) o2.getHolder();
|
||||
//noinspection unchecked
|
||||
return h1.compareTo(h2);
|
||||
});
|
||||
|
||||
int pageIndex = page - 1;
|
||||
List<List<HeldPermission<T>>> pages = CommandUtils.divideList(results, 15);
|
||||
|
||||
if (pageIndex < 0 || pageIndex >= pages.size()) {
|
||||
page = 1;
|
||||
pageIndex = 0;
|
||||
}
|
||||
|
||||
List<HeldPermission<UUID>> sorted = new ArrayList<>(results);
|
||||
sorted.sort(Comparator.comparing(HeldPermission::getHolder));
|
||||
List<HeldPermission<T>> content = pages.get(pageIndex);
|
||||
|
||||
int index = pageNumber - 1;
|
||||
List<List<HeldPermission<UUID>>> pages = CommandUtils.divideList(sorted, 15);
|
||||
|
||||
if (index < 0 || index >= pages.size()) {
|
||||
pageNumber = 1;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
List<HeldPermission<UUID>> page = pages.get(index);
|
||||
List<Map.Entry<String, HeldPermission<UUID>>> uuidMappedPage = page.stream()
|
||||
.map(hp -> Maps.immutableEntry(uuidLookup.apply(hp.getHolder()), hp))
|
||||
List<Map.Entry<String, HeldPermission<T>>> mappedContent = content.stream()
|
||||
.map(hp -> Maps.immutableEntry(lookupFunction.apply(hp.getHolder()), hp))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
TextComponent.Builder message = TextComponent.builder("");
|
||||
String title = "&7(page &f" + pageNumber + "&7 of &f" + pages.size() + "&7 - &f" + sorted.size() + "&7 entries)";
|
||||
// send header
|
||||
headerMessage.send(sender, page, pages.size(), results.size());
|
||||
|
||||
for (Map.Entry<String, HeldPermission<UUID>> ent : uuidMappedPage) {
|
||||
String s = "&3> &b" + ent.getKey() + " " + getNodeExpiryString(ent.getValue().asNode()) + CommandUtils.getAppendableNodeContextString(ent.getValue().asNode()) + "\n";
|
||||
message.append(TextUtils.fromLegacy(s, Constants.FORMAT_CHAR).toBuilder().applyDeep(makeFancy(ent.getKey(), false, label, ent.getValue())).build());
|
||||
for (Map.Entry<String, HeldPermission<T>> ent : mappedContent) {
|
||||
String s = "&3> &b" + ent.getKey() + " " + getNodeExpiryString(ent.getValue().asNode()) + CommandUtils.getAppendableNodeContextString(ent.getValue().asNode());
|
||||
TextComponent message = TextUtils.fromLegacy(s, Constants.FORMAT_CHAR).toBuilder().applyDeep(makeFancy(ent.getKey(), holderType, label, ent.getValue())).build();
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
|
||||
return Maps.immutableEntry(message.build(), title);
|
||||
}
|
||||
|
||||
private static Map.Entry<Component, String> searchGroupResultToMessage(List<HeldPermission<String>> results, String label, int pageNumber) {
|
||||
if (results.isEmpty()) {
|
||||
return Maps.immutableEntry(TextComponent.builder("None").color(TextColor.DARK_AQUA).build(), null);
|
||||
}
|
||||
|
||||
List<HeldPermission<String>> sorted = new ArrayList<>(results);
|
||||
sorted.sort(Comparator.comparing(HeldPermission::getHolder));
|
||||
|
||||
int index = pageNumber - 1;
|
||||
List<List<HeldPermission<String>>> pages = CommandUtils.divideList(sorted, 15);
|
||||
|
||||
if (index < 0 || index >= pages.size()) {
|
||||
pageNumber = 1;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
List<HeldPermission<String>> page = pages.get(index);
|
||||
|
||||
TextComponent.Builder message = TextComponent.builder("");
|
||||
String title = "&7(page &f" + pageNumber + "&7 of &f" + pages.size() + "&7 - &f" + sorted.size() + "&7 entries)";
|
||||
|
||||
for (HeldPermission<String> ent : page) {
|
||||
String s = "&3> &b" + ent.getHolder() + " " + getNodeExpiryString(ent.asNode()) + CommandUtils.getAppendableNodeContextString(ent.asNode()) + "\n";
|
||||
message.append(TextUtils.fromLegacy(s, Constants.FORMAT_CHAR).toBuilder().applyDeep(makeFancy(ent.getHolder(), true, label, ent)).build());
|
||||
}
|
||||
|
||||
return Maps.immutableEntry(message.build(), title);
|
||||
}
|
||||
|
||||
private static String getNodeExpiryString(Node node) {
|
||||
@ -190,18 +153,19 @@ public class GroupListMembers extends SubCommand<Group> {
|
||||
return " &8(&7expires in " + DateUtil.formatDateDiff(node.getExpiryUnixTime()) + "&8)";
|
||||
}
|
||||
|
||||
private static Consumer<BuildableComponent.Builder<? ,?>> makeFancy(String holderName, boolean group, String label, HeldPermission<?> perm) {
|
||||
private static Consumer<BuildableComponent.Builder<? ,?>> makeFancy(String holderName, HolderType holderType, String label, HeldPermission<?> perm) {
|
||||
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextUtils.fromLegacy(TextUtils.joinNewline(
|
||||
"&3> " + (perm.asNode().getValuePrimitive() ? "&a" : "&c") + perm.asNode().getGroupName(),
|
||||
"&3> &b" + perm.asNode().getGroupName(),
|
||||
" ",
|
||||
"&7Click to remove this parent from " + holderName
|
||||
), Constants.FORMAT_CHAR));
|
||||
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(perm.asNode(), holderName, group, false);
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(perm.asNode(), holderName, holderType, false);
|
||||
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command);
|
||||
|
||||
return component -> {
|
||||
component.hoverEvent(hoverEvent);
|
||||
component.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
|
||||
component.clickEvent(clickEvent);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands.impl.misc;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import me.lucko.luckperms.api.HeldPermission;
|
||||
@ -43,20 +45,17 @@ import me.lucko.luckperms.common.locale.LocaleManager;
|
||||
import me.lucko.luckperms.common.locale.Message;
|
||||
import me.lucko.luckperms.common.node.NodeFactory;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.references.HolderType;
|
||||
import me.lucko.luckperms.common.utils.DateUtil;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.common.utils.TextUtils;
|
||||
|
||||
import net.kyori.text.BuildableComponent;
|
||||
import net.kyori.text.Component;
|
||||
import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.event.ClickEvent;
|
||||
import net.kyori.text.event.HoverEvent;
|
||||
import net.kyori.text.format.TextColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -84,32 +83,20 @@ public class SearchCommand extends SingleCommand {
|
||||
|
||||
Message.SEARCH_RESULT.send(sender, users + groups, users, groups);
|
||||
|
||||
Map<UUID, String> uuidLookups = new HashMap<>();
|
||||
Function<UUID, String> lookupFunc = uuid -> uuidLookups.computeIfAbsent(uuid, u -> {
|
||||
String s = plugin.getStorage().getName(u).join();
|
||||
if (s == null || s.isEmpty() || s.equals("null")) {
|
||||
s = u.toString();
|
||||
}
|
||||
return s;
|
||||
});
|
||||
|
||||
Map.Entry<Component, String> msgUsers = searchUserResultToMessage(matchedUsers, lookupFunc, label, page);
|
||||
Map.Entry<Component, String> msgGroups = searchGroupResultToMessage(matchedGroups, label, page);
|
||||
|
||||
if (msgUsers.getValue() != null) {
|
||||
Message.SEARCH_SHOWING_USERS_WITH_PAGE.send(sender, msgUsers.getValue());
|
||||
sender.sendMessage(msgUsers.getKey());
|
||||
} else {
|
||||
Message.SEARCH_SHOWING_USERS.send(sender);
|
||||
sender.sendMessage(msgUsers.getKey());
|
||||
if (!matchedUsers.isEmpty()) {
|
||||
LoadingCache<UUID, String> uuidLookups = Caffeine.newBuilder()
|
||||
.build(u -> {
|
||||
String s = plugin.getStorage().getName(u).join();
|
||||
if (s == null || s.isEmpty() || s.equals("null")) {
|
||||
s = u.toString();
|
||||
}
|
||||
return s;
|
||||
});
|
||||
sendResult(sender, matchedUsers, uuidLookups::get, Message.SEARCH_SHOWING_USERS, HolderType.USER, label, page);
|
||||
}
|
||||
|
||||
if (msgGroups.getValue() != null) {
|
||||
Message.SEARCH_SHOWING_GROUPS_WITH_PAGE.send(sender, msgGroups.getValue());
|
||||
sender.sendMessage(msgGroups.getKey());
|
||||
} else {
|
||||
Message.SEARCH_SHOWING_GROUPS.send(sender);
|
||||
sender.sendMessage(msgGroups.getKey());
|
||||
if (!matchedGroups.isEmpty()) {
|
||||
sendResult(sender, matchedGroups, Function.identity(), Message.SEARCH_SHOWING_GROUPS, HolderType.GROUP, label, page);
|
||||
}
|
||||
|
||||
return CommandResult.SUCCESS;
|
||||
@ -120,65 +107,41 @@ public class SearchCommand extends SingleCommand {
|
||||
return SubCommand.getPermissionTabComplete(args, plugin.getPermissionVault());
|
||||
}
|
||||
|
||||
private static Map.Entry<Component, String> searchUserResultToMessage(List<HeldPermission<UUID>> results, Function<UUID, String> uuidLookup, String label, int pageNumber) {
|
||||
if (results.isEmpty()) {
|
||||
return Maps.immutableEntry(TextComponent.builder("None").color(TextColor.DARK_AQUA).build(), null);
|
||||
private static <T> void sendResult(Sender sender, List<HeldPermission<T>> results, Function<T, String> lookupFunction, Message headerMessage, HolderType holderType, String label, int page) {
|
||||
results = new ArrayList<>(results);
|
||||
|
||||
// we need a deterministic sort order
|
||||
// even though we're comparing uuids here in some cases - it doesn't matter
|
||||
// the import thing is that the order is the same each time the command is executed
|
||||
results.sort((o1, o2) -> {
|
||||
Comparable h1 = (Comparable) o1.getHolder();
|
||||
Comparable h2 = (Comparable) o2.getHolder();
|
||||
//noinspection unchecked
|
||||
return h1.compareTo(h2);
|
||||
});
|
||||
|
||||
int pageIndex = page - 1;
|
||||
List<List<HeldPermission<T>>> pages = CommandUtils.divideList(results, 15);
|
||||
|
||||
if (pageIndex < 0 || pageIndex >= pages.size()) {
|
||||
page = 1;
|
||||
pageIndex = 0;
|
||||
}
|
||||
|
||||
List<HeldPermission<UUID>> sorted = new ArrayList<>(results);
|
||||
sorted.sort(Comparator.comparing(HeldPermission::getHolder));
|
||||
List<HeldPermission<T>> content = pages.get(pageIndex);
|
||||
|
||||
int index = pageNumber - 1;
|
||||
List<List<HeldPermission<UUID>>> pages = CommandUtils.divideList(sorted, 15);
|
||||
|
||||
if (index < 0 || index >= pages.size()) {
|
||||
pageNumber = 1;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
List<HeldPermission<UUID>> page = pages.get(index);
|
||||
List<Map.Entry<String, HeldPermission<UUID>>> uuidMappedPage = page.stream()
|
||||
.map(hp -> Maps.immutableEntry(uuidLookup.apply(hp.getHolder()), hp))
|
||||
List<Map.Entry<String, HeldPermission<T>>> mappedContent = content.stream()
|
||||
.map(hp -> Maps.immutableEntry(lookupFunction.apply(hp.getHolder()), hp))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
TextComponent.Builder message = TextComponent.builder("");
|
||||
String title = "&7(page &f" + pageNumber + "&7 of &f" + pages.size() + "&7 - &f" + sorted.size() + "&7 entries)";
|
||||
// send header
|
||||
headerMessage.send(sender, page, pages.size(), results.size());
|
||||
|
||||
for (Map.Entry<String, HeldPermission<UUID>> ent : uuidMappedPage) {
|
||||
String s = "&3> &b" + ent.getKey() + " &7- " + (ent.getValue().getValue() ? "&a" : "&c") + ent.getValue().getValue() + getNodeExpiryString(ent.getValue().asNode()) + CommandUtils.getAppendableNodeContextString(ent.getValue().asNode()) + "\n";
|
||||
message.append(TextUtils.fromLegacy(s, Constants.FORMAT_CHAR).toBuilder().applyDeep(makeFancy(ent.getKey(), false, label, ent.getValue())).build());
|
||||
for (Map.Entry<String, HeldPermission<T>> ent : mappedContent) {
|
||||
String s = "&3> &b" + ent.getKey() + " &7- " + (ent.getValue().getValue() ? "&a" : "&c") + ent.getValue().getValue() + getNodeExpiryString(ent.getValue().asNode()) + CommandUtils.getAppendableNodeContextString(ent.getValue().asNode());
|
||||
TextComponent message = TextUtils.fromLegacy(s, Constants.FORMAT_CHAR).toBuilder().applyDeep(makeFancy(ent.getKey(), holderType, label, ent.getValue())).build();
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
|
||||
return Maps.immutableEntry(message.build(), title);
|
||||
}
|
||||
|
||||
private static Map.Entry<Component, String> searchGroupResultToMessage(List<HeldPermission<String>> results, String label, int pageNumber) {
|
||||
if (results.isEmpty()) {
|
||||
return Maps.immutableEntry(TextComponent.builder("None").color(TextColor.DARK_AQUA).build(), null);
|
||||
}
|
||||
|
||||
List<HeldPermission<String>> sorted = new ArrayList<>(results);
|
||||
sorted.sort(Comparator.comparing(HeldPermission::getHolder));
|
||||
|
||||
int index = pageNumber - 1;
|
||||
List<List<HeldPermission<String>>> pages = CommandUtils.divideList(sorted, 15);
|
||||
|
||||
if (index < 0 || index >= pages.size()) {
|
||||
pageNumber = 1;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
List<HeldPermission<String>> page = pages.get(index);
|
||||
|
||||
TextComponent.Builder message = TextComponent.builder("");
|
||||
String title = "&7(page &f" + pageNumber + "&7 of &f" + pages.size() + "&7 - &f" + sorted.size() + "&7 entries)";
|
||||
|
||||
for (HeldPermission<String> ent : page) {
|
||||
String s = "&3> &b" + ent.getHolder() + " &7- " + (ent.getValue() ? "&a" : "&c") + ent.getValue() + getNodeExpiryString(ent.asNode()) + CommandUtils.getAppendableNodeContextString(ent.asNode()) + "\n";
|
||||
message.append(TextUtils.fromLegacy(s, Constants.FORMAT_CHAR).toBuilder().applyDeep(makeFancy(ent.getHolder(), true, label, ent)).build());
|
||||
}
|
||||
|
||||
return Maps.immutableEntry(message.build(), title);
|
||||
}
|
||||
|
||||
private static String getNodeExpiryString(Node node) {
|
||||
@ -189,18 +152,19 @@ public class SearchCommand extends SingleCommand {
|
||||
return " &8(&7expires in " + DateUtil.formatDateDiff(node.getExpiryUnixTime()) + "&8)";
|
||||
}
|
||||
|
||||
private static Consumer<BuildableComponent.Builder<?, ?>> makeFancy(String holderName, boolean group, String label, HeldPermission<?> perm) {
|
||||
private static Consumer<BuildableComponent.Builder<?, ?>> makeFancy(String holderName, HolderType holderType, String label, HeldPermission<?> perm) {
|
||||
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextUtils.fromLegacy(TextUtils.joinNewline(
|
||||
"&3> " + (perm.asNode().getValuePrimitive() ? "&a" : "&c") + perm.asNode().getPermission(),
|
||||
" ",
|
||||
"&7Click to remove this node from " + holderName
|
||||
), Constants.FORMAT_CHAR));
|
||||
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(perm.asNode(), holderName, group, false);
|
||||
String command = "/" + label + " " + NodeFactory.nodeAsCommand(perm.asNode(), holderName, holderType, false);
|
||||
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command);
|
||||
|
||||
return component -> {
|
||||
component.hoverEvent(hoverEvent);
|
||||
component.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
|
||||
component.clickEvent(clickEvent);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.utils;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class SortMode {
|
||||
|
||||
public static SortMode determine(List<String> args) {
|
||||
SortType type = SortType.PRIORITY;
|
||||
boolean ascending = true;
|
||||
for (String arg : args) {
|
||||
if (arg.equals("!") || arg.equalsIgnoreCase("reverse") || arg.equalsIgnoreCase("reversed")) {
|
||||
ascending = false;
|
||||
} else if (arg.equalsIgnoreCase("priority")) {
|
||||
type = SortType.PRIORITY;
|
||||
ascending = true;
|
||||
} else if (arg.equalsIgnoreCase("!priority")) {
|
||||
type = SortType.PRIORITY;
|
||||
ascending = false;
|
||||
} else if (arg.equalsIgnoreCase("alphabetically") || arg.equalsIgnoreCase("abc")) {
|
||||
type = SortType.ALPHABETICALLY;
|
||||
ascending = true;
|
||||
} else if (arg.equalsIgnoreCase("!alphabetically") || arg.equalsIgnoreCase("!abc")) {
|
||||
type = SortType.ALPHABETICALLY;
|
||||
ascending = false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return new SortMode(type, ascending);
|
||||
}
|
||||
|
||||
private final SortType type;
|
||||
private final boolean ascending;
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.utils;
|
||||
|
||||
public enum SortType {
|
||||
|
||||
PRIORITY,
|
||||
ALPHABETICALLY;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
}
|
@ -191,7 +191,7 @@ public enum CommandSpec {
|
||||
PERMISSION_INFO("Lists the permission nodes the object has",
|
||||
Arg.list(
|
||||
Arg.create("page", false, "the page to view"),
|
||||
Arg.create("filter", false, "the string to filter by")
|
||||
Arg.create("sort mode", false, "how to sort the entries")
|
||||
)
|
||||
),
|
||||
PERMISSION_SET("Sets a permission for the object",
|
||||
@ -234,7 +234,12 @@ public enum CommandSpec {
|
||||
)
|
||||
),
|
||||
|
||||
PARENT_INFO("Lists the groups that this object inherits from"),
|
||||
PARENT_INFO("Lists the groups that this object inherits from",
|
||||
Arg.list(
|
||||
Arg.create("page", false, "the page to view"),
|
||||
Arg.create("sort mode", false, "how to sort the entries")
|
||||
)
|
||||
),
|
||||
PARENT_SET("Removes all other groups the object inherits already and adds them to the one given",
|
||||
Arg.list(
|
||||
Arg.create("group", true, "the group to set to"),
|
||||
|
@ -113,10 +113,9 @@ public enum Message {
|
||||
SEARCH_SEARCHING("&aSearching for users and groups with &b{}&a...", true),
|
||||
SEARCH_SEARCHING_MEMBERS("&aSearching for users and groups who inherit from &b{}&a...", true),
|
||||
SEARCH_RESULT("&aFound &b{}&a entries from &b{}&a users and &b{}&a groups.", true),
|
||||
SEARCH_SHOWING_USERS("&bShowing user entries:", true),
|
||||
SEARCH_SHOWING_GROUPS("&bShowing group entries:", true),
|
||||
SEARCH_SHOWING_USERS_WITH_PAGE("&bShowing user entries: {}", true),
|
||||
SEARCH_SHOWING_GROUPS_WITH_PAGE("&bShowing group entries: {}", true),
|
||||
|
||||
SEARCH_SHOWING_USERS("&bShowing user entries: &7(showing page &f{}&7 of &f{}&7 - &f{}&7 entries)", true),
|
||||
SEARCH_SHOWING_GROUPS("&bShowing group entries: &7(showing page &f{}&7 of &f{}&7 - &f{}&7 entries)", true),
|
||||
|
||||
APPLY_EDITS_INVALID_CODE("&cInvalid code. &7({})", true),
|
||||
APPLY_EDITS_UNABLE_TO_READ("&cUnable to read data using the given code. &7({})", true),
|
||||
@ -198,14 +197,14 @@ public enum Message {
|
||||
|
||||
TRACKS_LIST("&aTracks: {}", true),
|
||||
|
||||
LISTNODES("&b{}'s Permissions:", true),
|
||||
LISTNODES_WITH_PAGE("&b{}'s Permissions: {}", true),
|
||||
LISTNODES_TEMP("&b{}'s Temporary Permissions:", true),
|
||||
LISTNODES_TEMP_WITH_PAGE("&b{}'s Temporary Permissions: {}", true),
|
||||
PERMISSION_INFO("&b{}'s Permissions: &7(showing page &f{}&7 of &f{}&7 - &f{}&7 entries)", true),
|
||||
PERMISSION_INFO_NO_DATA("&b{}&a does not have any permissions set.", true),
|
||||
|
||||
LISTPARENTS("&b{}'s Parent Groups:", true),
|
||||
LISTPARENTS_TEMP("&b{}'s Temporary Parent Groups:", true),
|
||||
LIST_TRACKS("&b{}'s Tracks:" + "\n" + "{}", true),
|
||||
PARENT_INFO("&b{}'s Parents: &7(showing page &f{}&7 of &f{}&7 - &f{}&7 entries)", true),
|
||||
PARENT_INFO_NO_DATA("&b{}&a does not have any parents defined.", true),
|
||||
|
||||
LIST_TRACKS("&b{}'s Tracks:", true),
|
||||
LIST_TRACKS_ENTRY("&a{}: {}", false),
|
||||
LIST_TRACKS_EMPTY("&b{}&a is not on any tracks.", true),
|
||||
|
||||
CONTEXT_PAIR_INLINE("&3{}=&b{}", false),
|
||||
|
@ -37,6 +37,7 @@ import me.lucko.luckperms.common.caching.GroupCachedData;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.references.GroupReference;
|
||||
import me.lucko.luckperms.common.references.HolderType;
|
||||
import me.lucko.luckperms.common.references.Identifiable;
|
||||
|
||||
import java.util.Optional;
|
||||
@ -111,6 +112,11 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
||||
return GroupReference.of(getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolderType getType() {
|
||||
return HolderType.GROUP;
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> reloadCachedData() {
|
||||
return CompletableFuture.allOf(cachedData.reloadPermissions(), cachedData.reloadMeta()).thenAccept(n -> {
|
||||
getPlugin().getApiProvider().getEventFactory().handleGroupDataRecalculate(this, cachedData);
|
||||
|
@ -64,6 +64,7 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.primarygroup.GroupInheritanceComparator;
|
||||
import me.lucko.luckperms.common.references.GroupReference;
|
||||
import me.lucko.luckperms.common.references.HolderReference;
|
||||
import me.lucko.luckperms.common.references.HolderType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -240,7 +241,7 @@ public abstract class PermissionHolder {
|
||||
protected void declareState() {
|
||||
/* only declare state of groups. the state manager isn't really being used now the caches in this class
|
||||
are gone, but it's useful for command output. */
|
||||
if (this instanceof Group) {
|
||||
if (this.getType().isGroup()) {
|
||||
plugin.getCachedStateManager().putAll(toReference(), getGroupReferences());
|
||||
}
|
||||
}
|
||||
@ -268,6 +269,13 @@ public abstract class PermissionHolder {
|
||||
*/
|
||||
public abstract HolderReference<?, ?> toReference();
|
||||
|
||||
/**
|
||||
* Returns the type of this PermissionHolder.
|
||||
*
|
||||
* @return this holders type
|
||||
*/
|
||||
public abstract HolderType getType();
|
||||
|
||||
/**
|
||||
* Gets the API delegate for this instance
|
||||
*
|
||||
@ -543,7 +551,7 @@ public abstract class PermissionHolder {
|
||||
excludedGroups = new HashSet<>();
|
||||
}
|
||||
|
||||
if (this instanceof Group) {
|
||||
if (this.getType().isGroup()) {
|
||||
excludedGroups.add(getObjectName().toLowerCase());
|
||||
}
|
||||
|
||||
@ -619,7 +627,7 @@ public abstract class PermissionHolder {
|
||||
excludedGroups = new HashSet<>();
|
||||
}
|
||||
|
||||
if (this instanceof Group) {
|
||||
if (this.getType().isGroup()) {
|
||||
excludedGroups.add(getObjectName().toLowerCase());
|
||||
}
|
||||
|
||||
@ -768,7 +776,7 @@ public abstract class PermissionHolder {
|
||||
excludedGroups = new HashSet<>();
|
||||
}
|
||||
|
||||
if (this instanceof Group) {
|
||||
if (this.getType().isGroup()) {
|
||||
excludedGroups.add(getObjectName().toLowerCase());
|
||||
}
|
||||
|
||||
@ -830,7 +838,7 @@ public abstract class PermissionHolder {
|
||||
excludedGroups = new HashSet<>();
|
||||
}
|
||||
|
||||
if (this instanceof Group) {
|
||||
if (this.getType().isGroup()) {
|
||||
excludedGroups.add(getObjectName().toLowerCase());
|
||||
}
|
||||
|
||||
@ -956,7 +964,7 @@ public abstract class PermissionHolder {
|
||||
* @return a tristate
|
||||
*/
|
||||
public Tristate hasPermission(Node node, boolean checkTransient) {
|
||||
if (this instanceof Group && node.isGroupNode() && node.getGroupName().equalsIgnoreCase(getObjectName())) {
|
||||
if (this.getType().isGroup() && node.isGroupNode() && node.getGroupName().equalsIgnoreCase(getObjectName())) {
|
||||
return Tristate.TRUE;
|
||||
}
|
||||
|
||||
@ -1327,7 +1335,7 @@ public abstract class PermissionHolder {
|
||||
nodesLock.unlock();
|
||||
}
|
||||
|
||||
if (this instanceof User && giveDefault) {
|
||||
if (this.getType().isUser() && giveDefault) {
|
||||
plugin.getUserManager().giveDefaultIfNeeded((User) this, false);
|
||||
}
|
||||
|
||||
@ -1355,7 +1363,7 @@ public abstract class PermissionHolder {
|
||||
nodesLock.unlock();
|
||||
}
|
||||
|
||||
if (this instanceof User && giveDefault) {
|
||||
if (this.getType().isUser() && giveDefault) {
|
||||
plugin.getUserManager().giveDefaultIfNeeded((User) this, false);
|
||||
}
|
||||
invalidateCache();
|
||||
@ -1501,7 +1509,7 @@ public abstract class PermissionHolder {
|
||||
}
|
||||
|
||||
private OptionalInt calculateWeight() {
|
||||
if (this instanceof User) return OptionalInt.empty();
|
||||
if (this.getType().isUser()) return OptionalInt.empty();
|
||||
|
||||
boolean seen = false;
|
||||
int best = 0;
|
||||
|
@ -36,6 +36,7 @@ import me.lucko.luckperms.common.caching.UserCachedData;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.primarygroup.PrimaryGroupHolder;
|
||||
import me.lucko.luckperms.common.references.HolderType;
|
||||
import me.lucko.luckperms.common.references.Identifiable;
|
||||
import me.lucko.luckperms.common.references.UserIdentifier;
|
||||
import me.lucko.luckperms.common.references.UserReference;
|
||||
@ -168,6 +169,11 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
||||
return UserReference.of(getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolderType getType() {
|
||||
return HolderType.USER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the UserData cache
|
||||
* Blocking call.
|
||||
|
@ -34,6 +34,7 @@ import me.lucko.luckperms.api.ChatMetaType;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.references.HolderType;
|
||||
import me.lucko.luckperms.common.utils.PatternCache;
|
||||
|
||||
import java.util.Iterator;
|
||||
@ -79,9 +80,9 @@ public class NodeFactory {
|
||||
return new NodeBuilder("suffix." + priority + "." + LegacyNodeFactory.escapeCharacters(suffix));
|
||||
}
|
||||
|
||||
public static String nodeAsCommand(Node node, String id, boolean group, boolean set) {
|
||||
public static String nodeAsCommand(Node node, String id, HolderType type, boolean set) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(group ? "group " : "user ").append(id).append(" ");
|
||||
sb.append(type.toString()).append(" ").append(id).append(" ");
|
||||
|
||||
if (node.isGroupNode()) {
|
||||
sb.append(node.isTemporary() ? (set ? "parent addtemp " : "parent removetemp ") : (set ? "parent add " : "parent remove "));
|
||||
@ -95,16 +96,16 @@ public class NodeFactory {
|
||||
}
|
||||
|
||||
if (node.getValuePrimitive() && (node.isPrefix() || node.isSuffix())) {
|
||||
ChatMetaType type = node.isPrefix() ? ChatMetaType.PREFIX : ChatMetaType.SUFFIX;
|
||||
ChatMetaType nodeType = node.isPrefix() ? ChatMetaType.PREFIX : ChatMetaType.SUFFIX;
|
||||
String typeName = type.name().toLowerCase();
|
||||
|
||||
sb.append(node.isTemporary() ? (set ? "meta addtemp" + typeName + " " : "meta removetemp" + typeName + " ") : (set ? "meta add" + typeName + " " : "meta remove" + typeName + " "));
|
||||
sb.append(type.getEntry(node).getKey()).append(" ");
|
||||
sb.append(nodeType.getEntry(node).getKey()).append(" ");
|
||||
|
||||
if (type.getEntry(node).getValue().contains(" ")) {
|
||||
sb.append("\"").append(type.getEntry(node).getValue()).append("\"");
|
||||
if (nodeType.getEntry(node).getValue().contains(" ")) {
|
||||
sb.append("\"").append(nodeType.getEntry(node).getValue()).append("\"");
|
||||
} else {
|
||||
sb.append(type.getEntry(node).getValue());
|
||||
sb.append(nodeType.getEntry(node).getValue());
|
||||
}
|
||||
if (set && node.isTemporary()) {
|
||||
sb.append(" ").append(node.getExpiryUnixTime());
|
||||
|
@ -42,7 +42,7 @@ public class GroupInheritanceComparator implements Comparator<Group> {
|
||||
private static final Comparator<Group> NULL_ORIGIN = new GroupInheritanceComparator(null);
|
||||
|
||||
public static Comparator<Group> getFor(PermissionHolder origin) {
|
||||
if (origin instanceof User) {
|
||||
if (origin.getType().isUser()) {
|
||||
return new GroupInheritanceComparator(((User) origin));
|
||||
}
|
||||
return NULL_ORIGIN;
|
||||
|
@ -25,9 +25,27 @@
|
||||
|
||||
package me.lucko.luckperms.common.references;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum HolderType {
|
||||
|
||||
USER,
|
||||
GROUP
|
||||
USER(true, false),
|
||||
GROUP(false, true);
|
||||
|
||||
private final boolean user;
|
||||
private final boolean group;
|
||||
|
||||
public boolean matches(PermissionHolder holder) {
|
||||
return holder.getType() == this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ public class WebEditorUtils {
|
||||
private static final String GROUP_ID_PATTERN = "group/";
|
||||
|
||||
public static String getHolderIdentifier(PermissionHolder holder) {
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
User user = ((User) holder);
|
||||
return USER_ID_PATTERN + user.getUuid().toString();
|
||||
} else {
|
||||
|
@ -48,7 +48,7 @@ import java.util.Set;
|
||||
public class SpongeMigrationUtils {
|
||||
|
||||
public static void migrateSubject(Subject from, PermissionHolder to, int priority) {
|
||||
if (to instanceof Group) {
|
||||
if (to.getType().isGroup()) {
|
||||
MigrationUtils.setGroupWeight((Group) to, priority);
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
|
||||
@ -158,7 +158,7 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
if (holder instanceof User) {
|
||||
if (holder.getType().isUser()) {
|
||||
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
|
||||
@ -251,7 +251,7 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
||||
toRemove.forEach(makeUnsetConsumer(false));
|
||||
ret = !toRemove.isEmpty();
|
||||
|
||||
if (ret && holder instanceof User) {
|
||||
if (ret && holder.getType().isUser()) {
|
||||
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
}
|
||||
@ -277,7 +277,7 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
||||
toRemove.forEach(makeUnsetConsumer(false));
|
||||
ret = !toRemove.isEmpty();
|
||||
|
||||
if (ret && holder instanceof User) {
|
||||
if (ret && holder.getType().isUser()) {
|
||||
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
}
|
||||
@ -441,14 +441,14 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
||||
private CompletableFuture<Void> objectSave(PermissionHolder t) {
|
||||
if (!enduring) {
|
||||
// don't bother saving to primary storage. just refresh
|
||||
if (t instanceof User) {
|
||||
if (t.getType().isUser()) {
|
||||
User user = ((User) t);
|
||||
return user.getRefreshBuffer().request();
|
||||
} else {
|
||||
return service.getPlugin().getUpdateTaskBuffer().request();
|
||||
}
|
||||
} else {
|
||||
if (t instanceof User) {
|
||||
if (t.getType().isUser()) {
|
||||
User user = ((User) t);
|
||||
return service.getPlugin().getStorage().saveUser(user).thenComposeAsync(success -> {
|
||||
if (!success) {
|
||||
|
Loading…
Reference in New Issue
Block a user