Add group setdisplayname command (#493)

This commit is contained in:
Luck 2017-10-22 16:58:53 +01:00
parent 26c813c07b
commit ca8cc91f37
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
33 changed files with 301 additions and 206 deletions

View File

@ -108,25 +108,25 @@ public class VaultChatHook extends Chat {
@Override
public String getGroupPrefix(String world, @NonNull String group) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
return getGroupChatMeta(g, ChatMetaType.PREFIX, world);
}
@Override
public void setGroupPrefix(String world, @NonNull String group, @NonNull String prefix) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
setChatMeta(g, ChatMetaType.PREFIX, prefix, world);
}
@Override
public String getGroupSuffix(String world, @NonNull String group) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
return getGroupChatMeta(g, ChatMetaType.SUFFIX, world);
}
@Override
public void setGroupSuffix(String world, @NonNull String group, @NonNull String suffix) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
setChatMeta(g, ChatMetaType.SUFFIX, suffix, world);
}
@ -148,7 +148,7 @@ public class VaultChatHook extends Chat {
@Override
public int getGroupInfoInteger(String world, @NonNull String group, @NonNull String node, int defaultValue) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
try {
return Integer.parseInt(getGroupMeta(g, node, world, String.valueOf(defaultValue)));
} catch (NumberFormatException e) {
@ -158,7 +158,7 @@ public class VaultChatHook extends Chat {
@Override
public void setGroupInfoInteger(String world, @NonNull String group, @NonNull String node, int value) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
setMeta(g, node, String.valueOf(value), world);
}
@ -180,7 +180,7 @@ public class VaultChatHook extends Chat {
@Override
public double getGroupInfoDouble(String world, @NonNull String group, @NonNull String node, double defaultValue) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
try {
return Double.parseDouble(getGroupMeta(g, node, world, String.valueOf(defaultValue)));
} catch (NumberFormatException e) {
@ -190,7 +190,7 @@ public class VaultChatHook extends Chat {
@Override
public void setGroupInfoDouble(String world, @NonNull String group, @NonNull String node, double value) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
setMeta(g, node, String.valueOf(value), world);
}
@ -212,7 +212,7 @@ public class VaultChatHook extends Chat {
@Override
public boolean getGroupInfoBoolean(String world, @NonNull String group, @NonNull String node, boolean defaultValue) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
String s = getGroupMeta(g, node, world, String.valueOf(defaultValue));
if (!s.equalsIgnoreCase("true") && !s.equalsIgnoreCase("false")) {
return defaultValue;
@ -222,7 +222,7 @@ public class VaultChatHook extends Chat {
@Override
public void setGroupInfoBoolean(String world, @NonNull String group, @NonNull String node, boolean value) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
setMeta(g, node, String.valueOf(value), world);
}
@ -240,13 +240,13 @@ public class VaultChatHook extends Chat {
@Override
public String getGroupInfoString(String world, @NonNull String group, @NonNull String node, String defaultValue) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
return getGroupMeta(g, node, world, defaultValue);
}
@Override
public void setGroupInfoString(String world, @NonNull String group, @NonNull String node, String value) {
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
final Group g = perms.getPlugin().getGroupManager().getByDisplayName(group);
setMeta(g, node, value, world);
}

View File

@ -31,11 +31,9 @@ import lombok.NonNull;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.caching.PermissionCache;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
@ -52,9 +50,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* An implementation of the Vault {@link Permission} API using LuckPerms.
@ -110,7 +106,7 @@ public class VaultPermissionHook extends Permission {
@Override
public String[] getGroups() {
return plugin.getGroupManager().getAll().keySet().toArray(new String[0]);
return plugin.getGroupManager().getAll().values().stream().map(g -> g.getDisplayName().orElse(g.getName())).toArray(String[]::new);
}
@Override
@ -221,7 +217,7 @@ public class VaultPermissionHook extends Permission {
world = correctWorld(world);
log("Checking if group " + groupName + " has permission: " + permission + " on world " + world + ", server " + getServer());
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
final Group group = plugin.getGroupManager().getByDisplayName(groupName);
if (group == null) return false;
// This is a nasty call. Groups aren't cached. :(
@ -234,7 +230,7 @@ public class VaultPermissionHook extends Permission {
world = correctWorld(world);
log("Adding permission to group " + groupName + ": '" + permission + "' on world " + world + ", server " + getServer());
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
final Group group = plugin.getGroupManager().getByDisplayName(groupName);
if (group == null) return false;
holderAddPermission(group, permission, world);
@ -246,7 +242,7 @@ public class VaultPermissionHook extends Permission {
world = correctWorld(world);
log("Removing permission from group " + groupName + ": '" + permission + "' on world " + world + ", server " + getServer());
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
final Group group = plugin.getGroupManager().getByDisplayName(groupName);
if (group == null) return false;
holderRemovePermission(group, permission, world);
@ -255,69 +251,77 @@ public class VaultPermissionHook extends Permission {
@Override
public boolean playerInGroup(String world, String player, @NonNull String group) {
return playerHas(world, player, "group." + group);
return playerHas(world, player, "group." + rewriteGroupName(group));
}
@SuppressWarnings("deprecation")
@Override
public boolean playerInGroup(World world, String player, @NonNull String group) {
return playerHas(world, player, "group." + group);
return playerHas(world, player, "group." + rewriteGroupName(group));
}
@Override
public boolean playerInGroup(String world, OfflinePlayer player, @NonNull String group) {
return playerHas(world, player, "group." + group);
return playerHas(world, player, "group." + rewriteGroupName(group));
}
@Override
public boolean playerInGroup(Player player, @NonNull String group) {
return playerHas(player, "group." + group);
return playerHas(player, "group." + rewriteGroupName(group));
}
private boolean checkGroupExists(String group) {
return plugin.getGroupManager().isLoaded(group);
return plugin.getGroupManager().getByDisplayName(group) != null;
}
private String rewriteGroupName(String name) {
Group group = plugin.getGroupManager().getByDisplayName(name);
if (group != null) {
return group.getName();
}
return name;
}
@Override
public boolean playerAddGroup(String world, String player, @NonNull String group) {
return checkGroupExists(group) && playerAdd(world, player, "group." + group);
return checkGroupExists(group) && playerAdd(world, player, "group." + rewriteGroupName(group));
}
@SuppressWarnings("deprecation")
@Override
public boolean playerAddGroup(World world, String player, @NonNull String group) {
return checkGroupExists(group) && playerAdd(world, player, "group." + group);
return checkGroupExists(group) && playerAdd(world, player, "group." + rewriteGroupName(group));
}
@Override
public boolean playerAddGroup(String world, OfflinePlayer player, @NonNull String group) {
return checkGroupExists(group) && playerAdd(world, player, "group." + group);
return checkGroupExists(group) && playerAdd(world, player, "group." + rewriteGroupName(group));
}
@Override
public boolean playerAddGroup(Player player, @NonNull String group) {
return checkGroupExists(group) && playerAdd(player, "group." + group);
return checkGroupExists(group) && playerAdd(player, "group." + rewriteGroupName(group));
}
@Override
public boolean playerRemoveGroup(String world, String player, @NonNull String group) {
return checkGroupExists(group) && playerRemove(world, player, "group." + group);
return checkGroupExists(group) && playerRemove(world, player, "group." + rewriteGroupName(group));
}
@SuppressWarnings("deprecation")
@Override
public boolean playerRemoveGroup(World world, String player, @NonNull String group) {
return checkGroupExists(group) && playerRemove(world, player, "group." + group);
return checkGroupExists(group) && playerRemove(world, player, "group." + rewriteGroupName(group));
}
@Override
public boolean playerRemoveGroup(String world, OfflinePlayer player, @NonNull String group) {
return checkGroupExists(group) && playerRemove(world, player, "group." + group);
return checkGroupExists(group) && playerRemove(world, player, "group." + rewriteGroupName(group));
}
@Override
public boolean playerRemoveGroup(Player player, @NonNull String group) {
return checkGroupExists(group) && playerRemove(player, "group." + group);
return checkGroupExists(group) && playerRemove(player, "group." + rewriteGroupName(group));
}
@Override
@ -353,28 +357,34 @@ public class VaultPermissionHook extends Permission {
return user.getEnduringNodes().values().stream()
.filter(Node::isGroupNode)
.filter(n -> n.shouldApplyWithContext(createContextForWorldLookup(player, w).getContexts()))
.map(Node::getGroupName)
.map(n -> {
Group group = plugin.getGroupManager().getIfLoaded(n.getGroupName());
if (group != null) {
return group.getDisplayName().orElse(group.getName());
}
return n.getGroupName();
})
.toArray(String[]::new);
}
@Override
public String getPrimaryGroup(String world, @NonNull String player) {
return getPrimaryGroup(world, Bukkit.getPlayerExact(player));
return getPrimaryGroup(Bukkit.getPlayerExact(player));
}
@SuppressWarnings("deprecation")
@Override
public String getPrimaryGroup(World world, @NonNull String player) {
return getPrimaryGroup(world == null ? null : world.getName(), Bukkit.getPlayerExact(player));
return getPrimaryGroup(Bukkit.getPlayerExact(player));
}
@Override
public String getPrimaryGroup(String world, @NonNull OfflinePlayer player) {
return getPrimaryGroup(world, player.getPlayer());
return getPrimaryGroup(player.getPlayer());
}
private String getPrimaryGroup(String world, Player player) {
world = correctWorld(world);
@Override
public String getPrimaryGroup(Player player) {
log("Getting primary group of player: " + player);
if (player == null) {
@ -387,71 +397,13 @@ public class VaultPermissionHook extends Permission {
return null;
}
// nothing special, just return the value.
if (!isPgo()) {
String g = user.getPrimaryGroup().getValue();
return plugin.getConfiguration().get(ConfigKeys.GROUP_NAME_REWRITES).getOrDefault(g, g);
}
// we need to do the complex PGO checking. (it's been enabled in the config.)
if (isPgoCheckInherited()) {
// we can just check the cached data
PermissionCache data = user.getUserData().getPermissionData(createContextForWorldLookup(plugin.getPlayer(user), world));
for (Map.Entry<String, Boolean> e : data.getImmutableBacking().entrySet()) {
if (!e.getValue()) continue;
if (!e.getKey().toLowerCase().startsWith("vault.primarygroup.")) continue;
String group = e.getKey().substring("vault.primarygroup.".length());
if (isPgoCheckExists()) {
if (!plugin.getGroupManager().isLoaded(group)) {
continue;
}
}
if (isPgoCheckMemberOf()) {
if (data.getPermissionValue("group." + group, CheckOrigin.INTERNAL) != Tristate.TRUE) {
continue;
}
}
return group;
}
} else {
// we need to check the users permissions only
for (Node node : user.getOwnNodes()) {
if (!node.getValuePrimitive()) continue;
if (!node.getPermission().toLowerCase().startsWith("vault.primarygroup.")) continue;
if (!node.shouldApplyOnServer(getServer(), isIncludeGlobal(), false)) continue;
if (!node.shouldApplyOnWorld(world, true, false)) continue;
String group = node.getPermission().substring("vault.primarygroup.".length());
if (isPgoCheckExists()) {
if (!plugin.getGroupManager().isLoaded(group)) {
continue;
}
}
if (isPgoCheckMemberOf()) {
String finalWorld = world;
List<String> localGroups = user.getOwnNodes().stream()
.filter(Node::isGroupNode)
.filter(n -> n.shouldApplyOnWorld(finalWorld, isIncludeGlobal(), true))
.filter(n -> n.shouldApplyOnServer(getServer(), isIncludeGlobal(), true))
.map(Node::getGroupName)
.collect(Collectors.toList());
if (!localGroups.contains(group.toLowerCase())) {
continue;
}
}
return group;
}
}
// Fallback
String g = user.getPrimaryGroup().getValue();
return plugin.getConfiguration().get(ConfigKeys.GROUP_NAME_REWRITES).getOrDefault(g, g);
Group group = plugin.getGroupManager().getByDisplayName(g);
if (group != null) {
return group.getDisplayName().orElse(group.getName());
}
return g;
}
public void log(String s) {
@ -561,20 +513,4 @@ public class VaultPermissionHook extends Permission {
boolean isIgnoreWorld() {
return plugin.getConfiguration().get(ConfigKeys.VAULT_IGNORE_WORLD);
}
private boolean isPgo() {
return plugin.getConfiguration().get(ConfigKeys.VAULT_PRIMARY_GROUP_OVERRIDES);
}
private boolean isPgoCheckInherited() {
return plugin.getConfiguration().get(ConfigKeys.VAULT_PRIMARY_GROUP_OVERRIDES_CHECK_INHERITED);
}
private boolean isPgoCheckExists() {
return plugin.getConfiguration().get(ConfigKeys.VAULT_PRIMARY_GROUP_OVERRIDES_CHECK_EXISTS);
}
private boolean isPgoCheckMemberOf() {
return plugin.getConfiguration().get(ConfigKeys.VAULT_PRIMARY_GROUP_OVERRIDES_CHECK_MEMBER_OF);
}
}

View File

@ -89,11 +89,6 @@ world-rewrite:
# world_nether: world
# world_the_end: world
# Rewrites group names. The underlying name of the group does not change, just the output in
# commands / placeholders / Vault.
group-name-rewrite:
# default: Member
# Controls how temporary permissions/parents/meta should be accumulated
#
# The default behaviour is "deny"

View File

@ -92,11 +92,6 @@ world-rewrite:
# world_nether: world
# world_the_end: world
# Rewrites group names. The underlying name of the group does not change, just the output in
# commands / placeholders / Vault.
group-name-rewrite:
# default: Member
# Controls how temporary permissions/parents/meta should be accumulated
#
# The default behaviour is "deny"

View File

@ -41,6 +41,7 @@ import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.MetaType;
import me.lucko.luckperms.common.node.NodeFactory;
@ -72,6 +73,10 @@ public class PermissionHolderDelegate implements PermissionHolder {
@Override
public String getFriendlyName() {
if (handle instanceof Group) {
Group group = (Group) this.handle;
return group.getDisplayName().orElse(group.getName());
}
return handle.getFriendlyName();
}

View File

@ -88,7 +88,7 @@ public class ParentAdd extends SharedSubCommand {
DataMutateResult result = holder.setInheritGroup(group, context);
if (result.asBoolean()) {
Message.SET_INHERIT_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName(), Util.contextSetToString(context));
Message.SET_INHERIT_SUCCESS.send(sender, holder.getFriendlyName(), group.getFriendlyName(), Util.contextSetToString(context));
ExtendedLogEntry.build().actor(sender).acted(holder)
.action("parent add " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
@ -97,7 +97,7 @@ public class ParentAdd extends SharedSubCommand {
save(holder, sender, plugin);
return CommandResult.SUCCESS;
} else {
Message.ALREADY_INHERITS.send(sender, holder.getFriendlyName(), group.getDisplayName(), Util.contextSetToString(context));
Message.ALREADY_INHERITS.send(sender, holder.getFriendlyName(), group.getFriendlyName(), Util.contextSetToString(context));
return CommandResult.STATE_ERROR;
}
}

View File

@ -94,7 +94,7 @@ public class ParentAddTemp extends SharedSubCommand {
}
if (group.getName().equalsIgnoreCase(holder.getObjectName())) {
Message.ALREADY_TEMP_INHERITS.send(sender, holder.getFriendlyName(), group.getDisplayName(), Util.contextSetToString(context));
Message.ALREADY_TEMP_INHERITS.send(sender, holder.getFriendlyName(), group.getFriendlyName(), Util.contextSetToString(context));
return CommandResult.STATE_ERROR;
}
@ -102,7 +102,7 @@ public class ParentAddTemp extends SharedSubCommand {
if (ret.getKey().asBoolean()) {
duration = ret.getValue().getExpiryUnixTime();
Message.SET_TEMP_INHERIT_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName(), DateUtil.formatDateDiff(duration), Util.contextSetToString(context));
Message.SET_TEMP_INHERIT_SUCCESS.send(sender, holder.getFriendlyName(), group.getFriendlyName(), DateUtil.formatDateDiff(duration), Util.contextSetToString(context));
ExtendedLogEntry.build().actor(sender).acted(holder)
.action("parent addtemp " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
@ -111,7 +111,7 @@ public class ParentAddTemp extends SharedSubCommand {
save(holder, sender, plugin);
return CommandResult.SUCCESS;
} else {
Message.ALREADY_TEMP_INHERITS.send(sender, holder.getFriendlyName(), group.getDisplayName(), Util.contextSetToString(context));
Message.ALREADY_TEMP_INHERITS.send(sender, holder.getFriendlyName(), group.getFriendlyName(), Util.contextSetToString(context));
return CommandResult.STATE_ERROR;
}
}

View File

@ -91,7 +91,7 @@ public class ParentSet extends SharedSubCommand {
((User) holder).getPrimaryGroup().setStoredValue(group.getName());
}
Message.SET_PARENT_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName(), Util.contextSetToString(context));
Message.SET_PARENT_SUCCESS.send(sender, holder.getFriendlyName(), group.getFriendlyName(), Util.contextSetToString(context));
ExtendedLogEntry.build().actor(sender).acted(holder)
.action("parent set " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))

View File

@ -128,7 +128,7 @@ public class ParentSetTrack extends SharedSubCommand {
holder.removeIf(node -> node.isGroupNode() && node.getFullContexts().equals(context) && track.containsGroup(node.getGroupName()));
holder.setInheritGroup(group, context);
Message.SET_TRACK_PARENT_SUCCESS.send(sender, holder.getFriendlyName(), track.getName(), group.getDisplayName(), Util.contextSetToString(context));
Message.SET_TRACK_PARENT_SUCCESS.send(sender, holder.getFriendlyName(), track.getName(), group.getFriendlyName(), Util.contextSetToString(context));
ExtendedLogEntry.build().actor(sender).acted(holder)
.action("parent settrack " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))

View File

@ -78,7 +78,7 @@ public class DeleteGroup extends SingleCommand {
return CommandResult.FAILURE;
}
Message.DELETE_SUCCESS.send(sender, group.getDisplayName());
Message.DELETE_SUCCESS.send(sender, group.getFriendlyName());
ExtendedLogEntry.build().actor(sender).actedName(groupName).entryType(LogEntry.Type.GROUP).action("delete").build().submit(plugin, sender);
plugin.getUpdateTaskBuffer().request();
return CommandResult.SUCCESS;

View File

@ -58,8 +58,8 @@ public class GroupInfo extends SubCommand<Group> {
}
Message.GROUP_INFO_GENERAL.send(sender,
group.getId(),
group.getDisplayName(),
group.getName(),
group.getDisplayName().orElse(group.getName()),
group.getWeight().isPresent() ? group.getWeight().getAsInt() : "None",
group.getOwnNodes().size(),
group.getOwnNodes().stream().filter(n -> !(n.isGroupNode() || n.isPrefix() || n.isSuffix() || n.isMeta())).mapToInt(n -> 1).sum(),

View File

@ -68,6 +68,7 @@ public class GroupMainCommand extends MainCommand<Group, String> {
.add(new HolderEditor<>(locale, false))
.add(new GroupListMembers(locale))
.add(new GroupSetWeight(locale))
.add(new GroupSetDisplayName(locale))
.add(new HolderShowTracks<>(locale, false))
.add(new HolderClear<>(locale, false))
.add(new GroupRename(locale))
@ -84,11 +85,16 @@ public class GroupMainCommand extends MainCommand<Group, String> {
@Override
protected Group getTarget(String target, LuckPermsPlugin plugin, Sender sender) {
if (!plugin.getStorage().loadGroup(target).join()) {
Message.GROUP_NOT_FOUND.send(sender, target);
return null;
// failed to load, but it might be a display name.
// nope, not a display name
if (plugin.getGroupManager().getByDisplayName(target) == null) {
Message.GROUP_NOT_FOUND.send(sender, target);
return null;
}
}
Group group = plugin.getGroupManager().getIfLoaded(target);
Group group = plugin.getGroupManager().getByDisplayName(target);
if (group == null) {
Message.GROUP_NOT_FOUND.send(sender, target);
return null;

View File

@ -0,0 +1,90 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.impl.group;
import me.lucko.luckperms.common.commands.ArgumentPermissions;
import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.abstraction.SubCommand;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
import me.lucko.luckperms.common.constants.CommandPermission;
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.Group;
import me.lucko.luckperms.common.node.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.Predicates;
import java.util.List;
public class GroupSetDisplayName extends SubCommand<Group> {
public GroupSetDisplayName(LocaleManager locale) {
super(CommandSpec.GROUP_SET_DISPLAY_NAME.spec(locale), "setdisplayname", CommandPermission.GROUP_SET_DISPLAY_NAME, Predicates.not(1));
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) throws CommandException {
if (ArgumentPermissions.checkModifyPerms(plugin, sender, getPermission().get(), group)) {
Message.COMMAND_NO_PERMISSION.send(sender);
return CommandResult.NO_PERMISSION;
}
String name = ArgumentUtils.handleString(0, args);
String previousName = group.getDisplayName().orElse(null);
if (previousName == null && name.equals(group.getName())) {
Message.GROUP_SET_DISPLAY_NAME_DOESNT_HAVE.send(sender, group.getName());
return CommandResult.STATE_ERROR;
}
if (name.equals(previousName)) {
Message.GROUP_SET_DISPLAY_NAME_ALREADY_HAS.send(sender, group.getName(), name);
return CommandResult.STATE_ERROR;
}
Group existing = plugin.getGroupManager().getByDisplayName(name);
if (existing != null && !group.equals(existing)) {
Message.GROUP_SET_DISPLAY_NAME_ALREADY_IN_USE.send(sender, name, existing.getName());
return CommandResult.STATE_ERROR;
}
group.removeIf(n -> n.getPermission().startsWith("displayname."));
if (name.equals(group.getName())) {
save(group, sender, plugin);
Message.GROUP_SET_DISPLAY_NAME_REMOVED.send(sender, group.getName());
return CommandResult.SUCCESS;
}
group.setPermission(NodeFactory.newBuilder("displayname." + name).build());
save(group, sender, plugin);
Message.GROUP_SET_DISPLAY_NAME.send(sender, name, group.getName());
return CommandResult.SUCCESS;
}
}

View File

@ -60,7 +60,7 @@ public class GroupSetWeight extends SubCommand<Group> {
group.setPermission(NodeFactory.newBuilder("weight." + weight).build());
save(group, sender, plugin);
Message.GROUP_SET_WEIGHT.send(sender, weight, group.getDisplayName());
Message.GROUP_SET_WEIGHT.send(sender, weight, group.getFriendlyName());
return CommandResult.SUCCESS;
}
}

View File

@ -71,12 +71,12 @@ public class ListGroups extends SingleCommand {
if (tracks.isEmpty()) {
component = TextUtils.fromLegacy(Message.GROUPS_LIST_ENTRY.asString(plugin.getLocaleManager(),
group.getDisplayName(),
group.getFriendlyName(),
group.getWeight().orElse(0)
), Constants.COLOR_CHAR);
} else {
component = TextUtils.fromLegacy(Message.GROUPS_LIST_ENTRY_WITH_TRACKS.asString(plugin.getLocaleManager(),
group.getDisplayName(),
group.getFriendlyName(),
group.getWeight().orElse(0),
Util.toCommaSep(tracks)
), Constants.COLOR_CHAR);

View File

@ -160,9 +160,9 @@ public class UserDemote extends SubCommand<User> {
user.getPrimaryGroup().setStoredValue(previousGroup.getName());
}
Message.USER_DEMOTE_SUCCESS.send(sender, track.getName(), old, previousGroup.getDisplayName(), Util.contextSetToString(context));
Message.USER_DEMOTE_SUCCESS.send(sender, track.getName(), old, previousGroup.getFriendlyName(), Util.contextSetToString(context));
if (!silent) {
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups(), previousGroup.getDisplayName(), old, true));
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups(), previousGroup.getFriendlyName(), old, true));
}
ExtendedLogEntry.build().actor(sender).acted(user)

View File

@ -171,9 +171,9 @@ public class UserPromote extends SubCommand<User> {
user.getPrimaryGroup().setStoredValue(nextGroup.getName());
}
Message.USER_PROMOTE_SUCCESS.send(sender, user.getFriendlyName(), track.getName(), old, nextGroup.getDisplayName(), Util.contextSetToString(context));
Message.USER_PROMOTE_SUCCESS.send(sender, user.getFriendlyName(), track.getName(), old, nextGroup.getFriendlyName(), Util.contextSetToString(context));
if (!silent) {
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups(), old, nextGroup.getDisplayName(), false));
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups(), old, nextGroup.getFriendlyName(), false));
}
ExtendedLogEntry.build().actor(sender).acted(user)

View File

@ -78,7 +78,7 @@ public class UserSwitchPrimaryGroup extends SubCommand<User> {
}
user.getPrimaryGroup().setStoredValue(group.getName());
Message.USER_PRIMARYGROUP_SUCCESS.send(sender, user.getFriendlyName(), group.getDisplayName());
Message.USER_PRIMARYGROUP_SUCCESS.send(sender, user.getFriendlyName(), group.getFriendlyName());
ExtendedLogEntry.build().actor(sender).acted(user)
.action("setprimarygroup " + group.getName())
.build().submit(plugin, sender);

View File

@ -320,12 +320,6 @@ public class ConfigKeys {
*/
public static final ConfigKey<Boolean> VAULT_IGNORE_WORLD = BooleanKey.of("vault-ignore-world", false);
/* controls the settings for Vault primary group overrides. Likely to be removed in later versions */
public static final ConfigKey<Boolean> VAULT_PRIMARY_GROUP_OVERRIDES = BooleanKey.of("vault-primary-groups-overrides.enabled", false);
public static final ConfigKey<Boolean> VAULT_PRIMARY_GROUP_OVERRIDES_CHECK_INHERITED = BooleanKey.of("vault-primary-groups-overrides.check-inherited-permissions", false);
public static final ConfigKey<Boolean> VAULT_PRIMARY_GROUP_OVERRIDES_CHECK_EXISTS = BooleanKey.of("vault-primary-groups-overrides.check-group-exists", true);
public static final ConfigKey<Boolean> VAULT_PRIMARY_GROUP_OVERRIDES_CHECK_MEMBER_OF = BooleanKey.of("vault-primary-groups-overrides.check-user-member-of", true);
/**
* If Vault debug mode is enabled
*/

View File

@ -136,6 +136,7 @@ public enum CommandPermission {
GROUP_LISTMEMBERS("listmembers", GROUP),
GROUP_SHOWTRACKS("showtracks", GROUP),
GROUP_SETWEIGHT("setweight", GROUP),
GROUP_SET_DISPLAY_NAME("setdisplayname", GROUP),
GROUP_CLEAR("clear", GROUP),
GROUP_RENAME("rename", GROUP),
GROUP_CLONE("clone", GROUP),

View File

@ -163,6 +163,11 @@ public enum CommandSpec {
Arg.create("weight", true, "the weight to set")
)
),
GROUP_SET_DISPLAY_NAME("Set the groups display name",
Arg.list(
Arg.create("name", true, "the name to set")
)
),
GROUP_RENAME("Rename the group",
Arg.list(
Arg.create("name", true, "the new name")

View File

@ -359,6 +359,12 @@ public enum Message {
),
GROUP_SET_WEIGHT("&aSet weight to &b{}&a for group &b{}&a.", true),
GROUP_SET_DISPLAY_NAME_DOESNT_HAVE("&b{}&a doesn't have a display name set.", true),
GROUP_SET_DISPLAY_NAME_ALREADY_HAS("&b{}&a already has a display name of &b{}&a.", true),
GROUP_SET_DISPLAY_NAME_ALREADY_IN_USE("&aThe display name &b{}&a is already being used by &b{}&a.", true),
GROUP_SET_DISPLAY_NAME("&aSet display name to &b{}&a for group &b{}&a.", true),
GROUP_SET_DISPLAY_NAME_REMOVED("&aRemoved display name for group &b{}&a.", true),
TRACK_INFO(
"{PREFIX}&b&l> &bShowing Track: &f{}" + "\n" +
"{PREFIX}&f- &7Path: &f{}",

View File

@ -39,4 +39,28 @@ public class GenericGroupManager extends AbstractManager<String, Group> implemen
return new Group(name, plugin);
}
@Override
public Group getByDisplayName(String name) {
// try to get an exact match first
Group g = getIfLoaded(name);
if (g != null) {
return g;
}
// then try exact display name matches
for (Group group : getAll().values()) {
if (group.getDisplayName().isPresent() && group.getDisplayName().get().equals(name)) {
return group;
}
}
// then try case insensitive name matches
for (Group group : getAll().values()) {
if (group.getDisplayName().isPresent() && group.getDisplayName().get().equalsIgnoreCase(name)) {
return group;
}
}
return null;
}
}

View File

@ -29,4 +29,12 @@ import me.lucko.luckperms.common.model.Group;
public interface GroupManager extends Manager<String, Group> {
/**
* Get a group object by display name
*
* @param name The name to search by
* @return a {@link Group} object if the group is loaded, returns null if the group is not loaded
*/
Group getByDisplayName(String name);
}

View File

@ -29,12 +29,16 @@ import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.common.api.delegates.GroupDelegate;
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.Identifiable;
import java.util.Optional;
@ToString(of = {"name"})
@EqualsAndHashCode(of = {"name"}, callSuper = false)
public class Group extends PermissionHolder implements Identifiable<String> {
@ -58,18 +62,29 @@ public class Group extends PermissionHolder implements Identifiable<String> {
return name;
}
public String getRawDisplayName() {
return getPlugin().getConfiguration().get(ConfigKeys.GROUP_NAME_REWRITES).getOrDefault(name, name);
}
public Optional<String> getDisplayName() {
String name = null;
for (Node n : getEnduringNodes().get(ImmutableContextSet.empty())) {
if (!n.getPermission().startsWith("displayname.")) {
continue;
}
public String getDisplayName() {
String dn = getRawDisplayName();
return dn.equals(name) ? name : name + " (" + dn + ")";
name = n.getPermission().substring("displayname.".length());
break;
}
if (name != null) {
return Optional.of(name);
}
name = getPlugin().getConfiguration().get(ConfigKeys.GROUP_NAME_REWRITES).get(getObjectName());
return name == null || name.equals(getObjectName()) ? Optional.empty() : Optional.of(name);
}
@Override
public String getFriendlyName() {
return getDisplayName();
Optional<String> dn = getDisplayName();
return dn.map(s -> name + " (" + s + ")").orElse(name);
}
@Override

View File

@ -1494,7 +1494,7 @@ public abstract class PermissionHolder {
boolean seen = false;
int best = 0;
for (Node n : getOwnNodes()) {
for (Node n : getEnduringNodes().get(ImmutableContextSet.empty())) {
if (!n.getPermission().startsWith("weight.")) {
continue;
}

View File

@ -25,7 +25,6 @@
package me.lucko.luckperms.common.storage.backing.sql.provider.file;
import me.lucko.luckperms.common.storage.backing.sql.NonClosableConnection;
import me.lucko.luckperms.common.storage.backing.sql.provider.AbstractConnectionFactory;
import java.io.File;

View File

@ -23,7 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.storage.backing.sql;
package me.lucko.luckperms.common.storage.backing.sql.provider.file;
import lombok.AllArgsConstructor;
import lombok.experimental.Delegate;
@ -32,7 +32,7 @@ import java.sql.Connection;
import java.sql.SQLException;
@AllArgsConstructor
public class NonClosableConnection implements Connection {
public final class NonClosableConnection implements Connection {
@Delegate(excludes = Exclude.class)
private Connection delegate;

View File

@ -26,7 +26,6 @@
package me.lucko.luckperms.common.storage.wrappings;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Delegate;
@ -44,15 +43,14 @@ public class BufferedOutputStorage implements Storage, Runnable {
return new BufferedOutputStorage(storage, flushTime);
}
@Getter
@Delegate(excludes = Exclude.class)
private final Storage backing;
private final Storage delegate;
private final long flushTime;
private final Buffer<User, Boolean> userOutputBuffer = Buffer.of(user -> BufferedOutputStorage.this.backing.saveUser(user).join());
private final Buffer<Group, Boolean> groupOutputBuffer = Buffer.of(group -> BufferedOutputStorage.this.backing.saveGroup(group).join());
private final Buffer<Track, Boolean> trackOutputBuffer = Buffer.of(track -> BufferedOutputStorage.this.backing.saveTrack(track).join());
private final Buffer<User, Boolean> userOutputBuffer = Buffer.of(user -> BufferedOutputStorage.this.delegate.saveUser(user).join());
private final Buffer<Group, Boolean> groupOutputBuffer = Buffer.of(group -> BufferedOutputStorage.this.delegate.saveGroup(group).join());
private final Buffer<Track, Boolean> trackOutputBuffer = Buffer.of(track -> BufferedOutputStorage.this.delegate.saveTrack(track).join());
@Override
public void run() {
@ -71,13 +69,13 @@ public class BufferedOutputStorage implements Storage, Runnable {
@Override
public Storage noBuffer() {
return backing;
return delegate;
}
@Override
public void shutdown() {
forceFlush();
backing.shutdown();
delegate.shutdown();
}
@Override

View File

@ -60,7 +60,7 @@ public class PhasedStorage implements Storage {
}
@Delegate(types = Delegated.class)
private final Storage backing;
private final Storage delegate;
private final Phaser phaser = new Phaser();
@ -78,14 +78,14 @@ public class PhasedStorage implements Storage {
e.printStackTrace();
}
backing.shutdown();
delegate.shutdown();
}
@Override
public CompletableFuture<Boolean> logAction(LogEntry entry) {
phaser.register();
try {
return backing.logAction(entry);
return delegate.logAction(entry);
} finally {
phaser.arriveAndDeregister();
}
@ -95,7 +95,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Log> getLog() {
phaser.register();
try {
return backing.getLog();
return delegate.getLog();
} finally {
phaser.arriveAndDeregister();
}
@ -105,7 +105,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> applyBulkUpdate(BulkUpdate bulkUpdate) {
phaser.register();
try {
return backing.applyBulkUpdate(bulkUpdate);
return delegate.applyBulkUpdate(bulkUpdate);
} finally {
phaser.arriveAndDeregister();
}
@ -115,7 +115,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> loadUser(UUID uuid, String username) {
phaser.register();
try {
return backing.loadUser(uuid, username);
return delegate.loadUser(uuid, username);
} finally {
phaser.arriveAndDeregister();
}
@ -125,7 +125,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> saveUser(User user) {
phaser.register();
try {
return backing.saveUser(user);
return delegate.saveUser(user);
} finally {
phaser.arriveAndDeregister();
}
@ -135,7 +135,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Set<UUID>> getUniqueUsers() {
phaser.register();
try {
return backing.getUniqueUsers();
return delegate.getUniqueUsers();
} finally {
phaser.arriveAndDeregister();
}
@ -145,7 +145,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<List<HeldPermission<UUID>>> getUsersWithPermission(String permission) {
phaser.register();
try {
return backing.getUsersWithPermission(permission);
return delegate.getUsersWithPermission(permission);
} finally {
phaser.arriveAndDeregister();
}
@ -155,7 +155,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> createAndLoadGroup(String name, CreationCause cause) {
phaser.register();
try {
return backing.createAndLoadGroup(name, cause);
return delegate.createAndLoadGroup(name, cause);
} finally {
phaser.arriveAndDeregister();
}
@ -165,7 +165,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> loadGroup(String name) {
phaser.register();
try {
return backing.loadGroup(name);
return delegate.loadGroup(name);
} finally {
phaser.arriveAndDeregister();
}
@ -175,7 +175,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> loadAllGroups() {
phaser.register();
try {
return backing.loadAllGroups();
return delegate.loadAllGroups();
} finally {
phaser.arriveAndDeregister();
}
@ -185,7 +185,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> saveGroup(Group group) {
phaser.register();
try {
return backing.saveGroup(group);
return delegate.saveGroup(group);
} finally {
phaser.arriveAndDeregister();
}
@ -195,7 +195,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> deleteGroup(Group group, DeletionCause cause) {
phaser.register();
try {
return backing.deleteGroup(group, cause);
return delegate.deleteGroup(group, cause);
} finally {
phaser.arriveAndDeregister();
}
@ -205,7 +205,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<List<HeldPermission<String>>> getGroupsWithPermission(String permission) {
phaser.register();
try {
return backing.getGroupsWithPermission(permission);
return delegate.getGroupsWithPermission(permission);
} finally {
phaser.arriveAndDeregister();
}
@ -215,7 +215,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> createAndLoadTrack(String name, CreationCause cause) {
phaser.register();
try {
return backing.createAndLoadTrack(name, cause);
return delegate.createAndLoadTrack(name, cause);
} finally {
phaser.arriveAndDeregister();
}
@ -225,7 +225,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> loadTrack(String name) {
phaser.register();
try {
return backing.loadTrack(name);
return delegate.loadTrack(name);
} finally {
phaser.arriveAndDeregister();
}
@ -235,7 +235,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> loadAllTracks() {
phaser.register();
try {
return backing.loadAllTracks();
return delegate.loadAllTracks();
} finally {
phaser.arriveAndDeregister();
}
@ -245,7 +245,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> saveTrack(Track track) {
phaser.register();
try {
return backing.saveTrack(track);
return delegate.saveTrack(track);
} finally {
phaser.arriveAndDeregister();
}
@ -255,7 +255,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> deleteTrack(Track track, DeletionCause cause) {
phaser.register();
try {
return backing.deleteTrack(track, cause);
return delegate.deleteTrack(track, cause);
} finally {
phaser.arriveAndDeregister();
}
@ -265,7 +265,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<Boolean> saveUUIDData(UUID uuid, String username) {
phaser.register();
try {
return backing.saveUUIDData(uuid, username);
return delegate.saveUUIDData(uuid, username);
} finally {
phaser.arriveAndDeregister();
}
@ -275,7 +275,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<UUID> getUUID(String username) {
phaser.register();
try {
return backing.getUUID(username);
return delegate.getUUID(username);
} finally {
phaser.arriveAndDeregister();
}
@ -285,7 +285,7 @@ public class PhasedStorage implements Storage {
public CompletableFuture<String> getName(UUID uuid) {
phaser.register();
try {
return backing.getName(uuid);
return delegate.getName(uuid);
} finally {
phaser.arriveAndDeregister();
}

View File

@ -288,4 +288,29 @@ public class SpongeGroupManager implements GroupManager, LPSubjectCollection {
public void suggestUnload(String identifier) {
// noop
}
@Override
public Group getByDisplayName(String name) {
// try to get an exact match first
Group g = getIfLoaded(name);
if (g != null) {
return g;
}
// then try exact display name matches
for (Group group : getAll().values()) {
if (group.getDisplayName().isPresent() && group.getDisplayName().get().equals(name)) {
return group;
}
}
// then try case insensitive name matches
for (Group group : getAll().values()) {
if (group.getDisplayName().isPresent() && group.getDisplayName().get().equalsIgnoreCase(name)) {
return group;
}
}
return null;
}
}

View File

@ -151,8 +151,7 @@ public class SpongeGroup extends Group {
@Override
public Optional<String> getFriendlyIdentifier() {
String rawDisplayName = parent.getRawDisplayName();
return rawDisplayName.equals(getIdentifier()) ? Optional.empty() : Optional.of(rawDisplayName);
return parent.getDisplayName();
}
@Override

View File

@ -89,12 +89,6 @@ world-rewrite {
# world_the_end="world"
}
# Rewrites group names. The underlying name of the group does not change, just the output in
# commands / placeholders / Vault.
group-name-rewrite {
# default="Member"
}
# Controls how temporary permissions/parents/meta should be accumulated
#
# The default behaviour is "deny"