diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java index b6996c900..bf364c378 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java @@ -52,6 +52,7 @@ import me.lucko.luckperms.common.runnables.UpdateTask; import me.lucko.luckperms.common.storage.Storage; import me.lucko.luckperms.common.storage.StorageFactory; import me.lucko.luckperms.common.tracks.TrackManager; +import me.lucko.luckperms.common.users.User; import me.lucko.luckperms.common.users.UserManager; import me.lucko.luckperms.common.utils.BufferedRequest; import me.lucko.luckperms.common.utils.DebugHandler; @@ -307,6 +308,28 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { return getDataFolder(); } + @Override + public Player getPlayer(User user) { + return getServer().getPlayer(uuidCache.getExternalUUID(user.getUuid())); + } + + @Override + public Contexts getContextForUser(User user) { + Player player = getPlayer(user); + if (player == null) { + return null; + } + return new Contexts( + getContextManager().getApplicableContext(player), + getConfiguration().isIncludingGlobalPerms(), + getConfiguration().isIncludingGlobalWorldPerms(), + true, + getConfiguration().isApplyingGlobalGroups(), + getConfiguration().isApplyingGlobalWorldGroups(), + player.isOp() + ); + } + @Override public int getPlayerCount() { return getServer().getOnlinePlayers().size(); diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java b/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java index 58beb55c1..f7d5b7464 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java @@ -47,6 +47,7 @@ import me.lucko.luckperms.common.runnables.UpdateTask; import me.lucko.luckperms.common.storage.Storage; import me.lucko.luckperms.common.storage.StorageFactory; import me.lucko.luckperms.common.tracks.TrackManager; +import me.lucko.luckperms.common.users.User; import me.lucko.luckperms.common.users.UserManager; import me.lucko.luckperms.common.utils.BufferedRequest; import me.lucko.luckperms.common.utils.DebugHandler; @@ -213,6 +214,28 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin { return getDataFolder(); } + @Override + public ProxiedPlayer getPlayer(User user) { + return getProxy().getPlayer(uuidCache.getExternalUUID(user.getUuid())); + } + + @Override + public Contexts getContextForUser(User user) { + ProxiedPlayer player = getPlayer(user); + if (player == null) { + return null; + } + return new Contexts( + getContextManager().getApplicableContext(player), + getConfiguration().isIncludingGlobalPerms(), + getConfiguration().isIncludingGlobalWorldPerms(), + true, + getConfiguration().isApplyingGlobalGroups(), + getConfiguration().isApplyingGlobalWorldGroups(), + false + ); + } + @Override public int getPlayerCount() { return getProxy().getOnlineCount(); diff --git a/common/src/main/java/me/lucko/luckperms/common/LuckPermsPlugin.java b/common/src/main/java/me/lucko/luckperms/common/LuckPermsPlugin.java index 39fc4962d..4b57124fd 100644 --- a/common/src/main/java/me/lucko/luckperms/common/LuckPermsPlugin.java +++ b/common/src/main/java/me/lucko/luckperms/common/LuckPermsPlugin.java @@ -39,6 +39,7 @@ import me.lucko.luckperms.common.groups.GroupManager; import me.lucko.luckperms.common.messaging.RedisMessaging; import me.lucko.luckperms.common.storage.Storage; import me.lucko.luckperms.common.tracks.TrackManager; +import me.lucko.luckperms.common.users.User; import me.lucko.luckperms.common.users.UserManager; import me.lucko.luckperms.common.utils.BufferedRequest; import me.lucko.luckperms.common.utils.DebugHandler; @@ -205,6 +206,22 @@ public interface LuckPermsPlugin { return isOnline(external) ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE; } + + /** + * Gets a player object linked to this User. The returned object must be the same type + * as the instance used in the platforms {@link ContextManager} + * @param user the user instance + * @return a player object, or null, if one couldn't be found. + */ + Object getPlayer(User user); + + /** + * Gets a calculated context instance for the user using the rules of the platform. + * @param user the user instance + * @return a contexts object, or null if one couldn't be generated + */ + Contexts getContextForUser(User user); + /** * Gets the number of users online on the platform * @return the number of users diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java index c3ce8b9da..9b7638998 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java @@ -22,35 +22,93 @@ package me.lucko.luckperms.common.commands.user; +import me.lucko.luckperms.api.Contexts; +import me.lucko.luckperms.api.Node; +import me.lucko.luckperms.api.caching.MetaData; +import me.lucko.luckperms.api.caching.UserData; import me.lucko.luckperms.common.LuckPermsPlugin; import me.lucko.luckperms.common.commands.CommandException; import me.lucko.luckperms.common.commands.CommandResult; import me.lucko.luckperms.common.commands.SubCommand; import me.lucko.luckperms.common.commands.sender.Sender; +import me.lucko.luckperms.common.commands.utils.Util; import me.lucko.luckperms.common.constants.Message; import me.lucko.luckperms.common.constants.Permission; import me.lucko.luckperms.common.users.User; +import me.lucko.luckperms.common.utils.DateUtil; import me.lucko.luckperms.common.utils.Predicates; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; public class UserInfo extends SubCommand { public UserInfo() { super("info", "Shows info about the user", Permission.USER_INFO, Predicates.alwaysFalse(), null); } + @SuppressWarnings("unchecked") @Override public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) throws CommandException { - Message.USER_INFO.send(sender, + Message.USER_INFO_GENERAL.send(sender, user.getName(), user.getUuid(), plugin.getPlayerStatus(user.getUuid()), user.getPrimaryGroup(), user.getPermanentNodes().size(), user.getTemporaryNodes().size(), - label, - user.getName() + user.getPrefixNodes().size(), + user.getSuffixNodes().size(), + user.getMetaNodes().size() ); + + Set parents = user.getPermissions(false).stream() + .filter(Node::isGroupNode) + .filter(Node::isPermanent) + .collect(Collectors.toSet()); + + Set tempParents = user.getPermissions(false).stream() + .filter(Node::isGroupNode) + .filter(Node::isTemporary) + .collect(Collectors.toSet()); + + if (!parents.isEmpty()) { + Message.USER_INFO_PARENT_HEADER.send(sender); + for (Node node : parents) { + Message.EMPTY.send(sender, "&f- &3> &f" + node.getGroupName() + Util.getNodeContextDescription(node)); + } + } + + if (!tempParents.isEmpty()) { + Message.USER_INFO_TEMP_PARENT_HEADER.send(sender); + for (Node node : tempParents) { + Message.EMPTY.send(sender, "&f- &3> &f" + node.getGroupName() + Util.getNodeContextDescription(node)); + Message.EMPTY.send(sender, "&f- &2- expires in " + DateUtil.formatDateDiff(node.getExpiryUnixTime())); + } + } + + UserData data = user.getUserData(); + String context = "&bNone"; + String prefix = "&bNone"; + String suffix = "&bNone"; + if (data != null) { + Contexts contexts = plugin.getContextForUser(user); + if (contexts != null) { + context = contexts.getContexts().toSet().stream() + .map(e -> Util.contextToString(e.getKey(), e.getValue())) + .collect(Collectors.joining(" ")); + + MetaData meta = data.getMetaData(contexts); + if (meta.getPrefix() != null) { + prefix = "&f\"" + meta.getPrefix() + "&f\""; + } + if (meta.getSuffix() != null) { + suffix = "&f\"" + meta.getSuffix() + "&f\""; + } + } + } + + Message.USER_INFO_DATA.send(sender, Util.formatBoolean(data != null), context, prefix, suffix); return CommandResult.SUCCESS; } } diff --git a/common/src/main/java/me/lucko/luckperms/common/constants/Message.java b/common/src/main/java/me/lucko/luckperms/common/constants/Message.java index f32b1d491..1e3e44e0d 100644 --- a/common/src/main/java/me/lucko/luckperms/common/constants/Message.java +++ b/common/src/main/java/me/lucko/luckperms/common/constants/Message.java @@ -260,16 +260,31 @@ public enum Message { BULK_CHANGE_TYPE_ERROR("Invalid type. Was expecting 'server' or 'world'.", true), BULK_CHANGE_SUCCESS("&aApplied bulk change successfully. {0} records were changed.", true), - USER_INFO( + USER_INFO_GENERAL( "{PREFIX}&b&l> &bUser Info: &f{0}" + "\n" + "{PREFIX}&f- &3UUID: &f{1}" + "\n" + "{PREFIX}&f- &3Status: {2}" + "\n" + "{PREFIX}&f- &3Primary Group: &f{3}" + "\n" + - "{PREFIX}&f- &3Permissions: &f{4}" + "\n" + - "{PREFIX}&f- &3Temporary Permissions: &f{5}" + "\n" + - "{PREFIX}&f- &3Use &b/{6} user {7} permission info &3to see all permissions.", + "{PREFIX}&f- &aCounts:" + "\n" + + "{PREFIX}&f- &3Permissions: &a{4}" + "\n" + + "{PREFIX}&f- &3Temporary Permissions: &a{5}" + "\n" + + "{PREFIX}&f- &3Prefixes: &a{6}" + "\n" + + "{PREFIX}&f- &3Suffixes: &a{7}" + "\n" + + "{PREFIX}&f- &3Meta: &a{8}", false ), + + USER_INFO_DATA( + "{PREFIX}&f- &aCached Data:" + "\n" + + "{PREFIX}&f- &3Is Loaded: {0}" + "\n" + + "{PREFIX}&f- &3Current Contexts: {1}" + "\n" + + "{PREFIX}&f- &3Current Prefix: {2}" + "\n" + + "{PREFIX}&f- &3Current Suffix: {3}", + false + ), + + USER_INFO_PARENT_HEADER("&f- &aParent Groups:", true), + USER_INFO_TEMP_PARENT_HEADER("&f- &aTemporary Parent Groups:", true), USER_GETUUID("&bThe UUID of &b{0}&b is &b{1}&b.", true), USER_REMOVEGROUP_ERROR_PRIMARY("You cannot remove a user from their primary group.", true), USER_PRIMARYGROUP_SUCCESS("&b{0}&a's primary group was set to &b{1}&a.", true), diff --git a/common/src/main/java/me/lucko/luckperms/common/core/PermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/core/PermissionHolder.java index 5d92488ee..97980129c 100644 --- a/common/src/main/java/me/lucko/luckperms/common/core/PermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/core/PermissionHolder.java @@ -916,6 +916,18 @@ public abstract class PermissionHolder { return getPermissions(false).stream().filter(Node::isPermanent).collect(Collectors.toSet()); } + public Set getPrefixNodes() { + return getPermissions(false).stream().filter(Node::isPrefix).collect(Collectors.toSet()); + } + + public Set getSuffixNodes() { + return getPermissions(false).stream().filter(Node::isSuffix).collect(Collectors.toSet()); + } + + public Set getMetaNodes() { + return getPermissions(false).stream().filter(Node::isMeta).collect(Collectors.toSet()); + } + /** * Get a {@link List} of all of the groups the holder inherits, on all servers * @return a {@link List} of group names diff --git a/default-lang.yml b/default-lang.yml index 717294903..8c1cff786 100644 --- a/default-lang.yml +++ b/default-lang.yml @@ -214,14 +214,25 @@ unset-meta-temp-server-world-success: "&aUnset temporary meta value with key &f\ bulk-change-type-error: "Invalid type. Was expecting 'server' or 'world'." bulk-change-success: "&aApplied bulk change successfully. {0} records were changed." -user-info: > +user-info-general: > {PREFIX}&b&l> &bUser Info: &f{0}\n {PREFIX}&f- &3UUID: &f{1}\n {PREFIX}&f- &3Status: {2}\n {PREFIX}&f- &3Primary Group: &f{3}\n - {PREFIX}&f- &3Permissions: &f{4}\n - {PREFIX}&f- &3Temporary Permissions: &f{5}\n - {PREFIX}&f- &3Use &b/{6} user {7} permission info &3to see all permissions. + {PREFIX}&f- &aCounts:\n + {PREFIX}&f- &3Permissions: &a{4}\n + {PREFIX}&f- &3Temporary Permissions: &a{5}\n + {PREFIX}&f- &3Prefixes: &a{6}\n + {PREFIX}&f- &3Suffixes: &a{7}\n + {PREFIX}&f- &3Meta: &a{8} +user-info-data: > + {PREFIX}&f- &aCached Data:\n + {PREFIX}&f- &3Is Loaded: {0}\n + {PREFIX}&f- &3Current Contexts: {1}\n + {PREFIX}&f- &3Current Prefix: {2}\n + {PREFIX}&f- &3Current Suffix: {3} +user-info-parent-header: "&f- &aParent Groups:" +user-info-temp-parent-header: "&f- &aTemporary Parent Groups:" user-getuuid: "&bThe UUID of &b{0}&b is &b{1}&b." user-removegroup-error-primary: "You cannot remove a user from their primary group." user-primarygroup-success: "&b{0}&a's primary group was set to &b{1}&a." diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java index df431a9b3..a9697bd23 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java @@ -47,6 +47,7 @@ import me.lucko.luckperms.common.runnables.UpdateTask; import me.lucko.luckperms.common.storage.Storage; import me.lucko.luckperms.common.storage.StorageFactory; import me.lucko.luckperms.common.tracks.TrackManager; +import me.lucko.luckperms.common.users.User; import me.lucko.luckperms.common.users.UserManager; import me.lucko.luckperms.common.utils.BufferedRequest; import me.lucko.luckperms.common.utils.DebugHandler; @@ -291,6 +292,28 @@ public class LPSpongePlugin implements LuckPermsPlugin { return getMainDir(); } + @Override + public Player getPlayer(User user) { + return game.getServer().getPlayer(uuidCache.getExternalUUID(user.getUuid())).orElse(null); + } + + @Override + public Contexts getContextForUser(User user) { + Player player = getPlayer(user); + if (player == null) { + return null; + } + return new Contexts( + getContextManager().getApplicableContext(player), + getConfiguration().isIncludingGlobalPerms(), + getConfiguration().isIncludingGlobalWorldPerms(), + true, + getConfiguration().isApplyingGlobalGroups(), + getConfiguration().isApplyingGlobalWorldGroups(), + false + ); + } + @Override public String getVersion() { return VersionData.VERSION;