1
0
mirror of https://github.com/lucko/LuckPerms.git synced 2025-09-25 05:21:29 +02:00

Implement special handling in the LP Vault implementation for NPC players (#1470)

This commit is contained in:
Luck
2019-04-01 15:09:58 +01:00
parent c7a0d7026c
commit 62ca2d9c79
4 changed files with 84 additions and 23 deletions

View File

@@ -38,7 +38,6 @@ import me.lucko.luckperms.common.command.CommandManager;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.factory.NodeFactory; import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.node.model.NodeTypes; import me.lucko.luckperms.common.node.model.NodeTypes;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
@@ -85,8 +84,8 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
public String getUserChatPrefix(String world, UUID uuid) { public String getUserChatPrefix(String world, UUID uuid) {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
User user = this.vaultPermission.lookupUser(uuid); PermissionHolder user = this.vaultPermission.lookupUser(uuid);
Contexts contexts = this.vaultPermission.contextForLookup(user, world); Contexts contexts = this.vaultPermission.contextForLookup(uuid, world);
MetaCache metaData = user.getCachedData().getMetaData(contexts); MetaCache metaData = user.getCachedData().getMetaData(contexts);
String ret = metaData.getPrefix(MetaCheckEvent.Origin.THIRD_PARTY_API); String ret = metaData.getPrefix(MetaCheckEvent.Origin.THIRD_PARTY_API);
if (log()) { if (log()) {
@@ -99,8 +98,8 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
public String getUserChatSuffix(String world, UUID uuid) { public String getUserChatSuffix(String world, UUID uuid) {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
User user = this.vaultPermission.lookupUser(uuid); PermissionHolder user = this.vaultPermission.lookupUser(uuid);
Contexts contexts = this.vaultPermission.contextForLookup(user, world); Contexts contexts = this.vaultPermission.contextForLookup(uuid, world);
MetaCache metaData = user.getCachedData().getMetaData(contexts); MetaCache metaData = user.getCachedData().getMetaData(contexts);
String ret = metaData.getSuffix(MetaCheckEvent.Origin.THIRD_PARTY_API); String ret = metaData.getSuffix(MetaCheckEvent.Origin.THIRD_PARTY_API);
if (log()) { if (log()) {
@@ -113,7 +112,10 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
public void setUserChatPrefix(String world, UUID uuid, String prefix) { public void setUserChatPrefix(String world, UUID uuid, String prefix) {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
User user = this.vaultPermission.lookupUser(uuid); PermissionHolder user = this.vaultPermission.lookupUser(uuid);
if (user instanceof Group) {
throw new UnsupportedOperationException("Unable to modify the permissions of NPC players");
}
setChatMeta(user, ChatMetaType.PREFIX, prefix, world); setChatMeta(user, ChatMetaType.PREFIX, prefix, world);
} }
@@ -121,7 +123,10 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
public void setUserChatSuffix(String world, UUID uuid, String suffix) { public void setUserChatSuffix(String world, UUID uuid, String suffix) {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
User user = this.vaultPermission.lookupUser(uuid); PermissionHolder user = this.vaultPermission.lookupUser(uuid);
if (user instanceof Group) {
throw new UnsupportedOperationException("Unable to modify the permissions of NPC players");
}
setChatMeta(user, ChatMetaType.SUFFIX, suffix, world); setChatMeta(user, ChatMetaType.SUFFIX, suffix, world);
} }
@@ -130,8 +135,8 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
Objects.requireNonNull(key, "key"); Objects.requireNonNull(key, "key");
User user = this.vaultPermission.lookupUser(uuid); PermissionHolder user = this.vaultPermission.lookupUser(uuid);
Contexts contexts = this.vaultPermission.contextForLookup(user, world); Contexts contexts = this.vaultPermission.contextForLookup(uuid, world);
MetaCache metaData = user.getCachedData().getMetaData(contexts); MetaCache metaData = user.getCachedData().getMetaData(contexts);
String ret = metaData.getMeta(MetaCheckEvent.Origin.THIRD_PARTY_API).get(key); String ret = metaData.getMeta(MetaCheckEvent.Origin.THIRD_PARTY_API).get(key);
if (log()) { if (log()) {
@@ -145,7 +150,10 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
Objects.requireNonNull(key, "key"); Objects.requireNonNull(key, "key");
User user = this.vaultPermission.lookupUser(uuid); PermissionHolder user = this.vaultPermission.lookupUser(uuid);
if (user instanceof Group) {
throw new UnsupportedOperationException("Unable to modify the permissions of NPC players");
}
setMeta(user, key, value, world); setMeta(user, key, value, world);
} }

View File

@@ -52,7 +52,6 @@ import org.bukkit.entity.Player;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
@@ -130,7 +129,7 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
return uuid; return uuid;
} }
public User lookupUser(UUID uuid) { public PermissionHolder lookupUser(UUID uuid) {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
// loaded already? // loaded already?
@@ -139,6 +138,21 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
return user; return user;
} }
// if the uuid is version 2, assume it is an NPC
// see: https://github.com/lucko/LuckPerms/issues/1470
// and https://github.com/lucko/LuckPerms/issues/1470#issuecomment-475403162
if (uuid.version() == 2) {
String npcGroupName = this.plugin.getConfiguration().get(ConfigKeys.VAULT_NPC_GROUP);
Group npcGroup = this.plugin.getGroupManager().getIfLoaded(npcGroupName);
if (npcGroup == null) {
npcGroup = this.plugin.getGroupManager().getIfLoaded(NodeFactory.DEFAULT_GROUP_NAME);
if (npcGroup == null) {
throw new IllegalStateException("unable to get default group");
}
}
return npcGroup;
}
// are we on the main thread? // are we on the main thread?
if (!this.plugin.getBootstrap().isServerStarting() && Bukkit.isPrimaryThread() && !this.plugin.getConfiguration().get(ConfigKeys.VAULT_UNSAFE_LOOKUPS)) { if (!this.plugin.getBootstrap().isServerStarting() && Bukkit.isPrimaryThread() && !this.plugin.getConfiguration().get(ConfigKeys.VAULT_UNSAFE_LOOKUPS)) {
throw new RuntimeException( throw new RuntimeException(
@@ -167,8 +181,8 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
Objects.requireNonNull(permission, "permission"); Objects.requireNonNull(permission, "permission");
User user = lookupUser(uuid); PermissionHolder user = lookupUser(uuid);
Contexts contexts = contextForLookup(user, world); Contexts contexts = contextForLookup(uuid, world);
PermissionCache permissionData = user.getCachedData().getPermissionData(contexts); PermissionCache permissionData = user.getCachedData().getPermissionData(contexts);
Tristate result = permissionData.getPermissionValue(permission, PermissionCheckEvent.Origin.THIRD_PARTY_API).result(); Tristate result = permissionData.getPermissionValue(permission, PermissionCheckEvent.Origin.THIRD_PARTY_API).result();
@@ -183,7 +197,10 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
Objects.requireNonNull(permission, "permission"); Objects.requireNonNull(permission, "permission");
User user = lookupUser(uuid); PermissionHolder user = lookupUser(uuid);
if (user instanceof Group) {
throw new UnsupportedOperationException("Unable to modify the permissions of NPC players");
}
return holderAddPermission(user, permission, world); return holderAddPermission(user, permission, world);
} }
@@ -192,7 +209,10 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
Objects.requireNonNull(permission, "permission"); Objects.requireNonNull(permission, "permission");
User user = lookupUser(uuid); PermissionHolder user = lookupUser(uuid);
if (user instanceof Group) {
throw new UnsupportedOperationException("Unable to modify the permissions of NPC players");
}
return holderRemovePermission(user, permission, world); return holderRemovePermission(user, permission, world);
} }
@@ -221,8 +241,8 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
public String[] userGetGroups(String world, UUID uuid) { public String[] userGetGroups(String world, UUID uuid) {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
User user = lookupUser(uuid); PermissionHolder user = lookupUser(uuid);
ContextSet contexts = contextForLookup(user, world).getContexts(); ContextSet contexts = contextForLookup(uuid, world).getContexts();
String[] ret = user.enduringData().immutable().values().stream() String[] ret = user.enduringData().immutable().values().stream()
.filter(Node::isGroupNode) .filter(Node::isGroupNode)
@@ -247,8 +267,11 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
public String userGetPrimaryGroup(String world, UUID uuid) { public String userGetPrimaryGroup(String world, UUID uuid) {
Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(uuid, "uuid");
User user = lookupUser(uuid); PermissionHolder user = lookupUser(uuid);
String value = user.getPrimaryGroup().getValue(); if (user instanceof Group) { // npc
return this.plugin.getConfiguration().get(ConfigKeys.VAULT_NPC_GROUP);
}
String value = ((User) user).getPrimaryGroup().getValue();
Group group = getGroup(value); Group group = getGroup(value);
if (group != null) { if (group != null) {
value = group.getPlainDisplayName(); value = group.getPlainDisplayName();
@@ -339,10 +362,10 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
} }
// utility method for getting a contexts instance for a given vault lookup. // utility method for getting a contexts instance for a given vault lookup.
Contexts contextForLookup(User user, String world) { Contexts contextForLookup(UUID uuid, String world) {
MutableContextSet context; MutableContextSet context;
Player player = Optional.ofNullable(user).flatMap(u -> this.plugin.getBootstrap().getPlayer(u.getUuid())).orElse(null); Player player = this.plugin.getBootstrap().getPlayer(uuid).orElse(null);
if (player != null) { if (player != null) {
context = this.plugin.getContextManager().getApplicableContext(player).mutableCopy(); context = this.plugin.getContextManager().getApplicableContext(player).mutableCopy();
} else { } else {
@@ -371,7 +394,14 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
} }
} }
return Contexts.of(context, isIncludeGlobal(), true, true, true, true, false); boolean op = false;
if (player != null) {
op = player.isOp();
} else if (uuid.version() == 2) { // npc
op = this.plugin.getConfiguration().get(ConfigKeys.VAULT_NPC_OP_STATUS);
}
return Contexts.of(context, isIncludeGlobal(), true, true, true, true, op);
} }
// utility methods for modifying the state of PermissionHolders // utility methods for modifying the state of PermissionHolders

View File

@@ -501,6 +501,19 @@ commands-allow-op: true
# option to 'true. # option to 'true.
vault-unsafe-lookups: false vault-unsafe-lookups: false
# Controls which group LuckPerms should use for NPC players when handling Vault requests.
#
# - As NPCs aren't actually real players, LuckPerms does not load any user data for them. This
# becomes an issue when plugins want to check for their permissions using Vault.
# - As a solution, Vault checks for NPCs fallback to a group, which is defined below.
vault-npc-group: default
# Controls how LuckPerms should consider the OP status of NPC players when handing Vault requests.
#
# - If you want NPCs to have the same permissions as "normal" players, set this option to false.
# - If you want NPCs to have OP status, set this option to true.
vault-npc-op-status: false
# If the vault-server option below should be used. # If the vault-server option below should be used.
# #
# - When this option is set to false, the server value defined above under "server" is used. # - When this option is set to false, the server value defined above under "server" is used.

View File

@@ -358,6 +358,16 @@ public final class ConfigKeys {
*/ */
public static final ConfigKey<Boolean> VAULT_UNSAFE_LOOKUPS = booleanKey("vault-unsafe-lookups", false); public static final ConfigKey<Boolean> VAULT_UNSAFE_LOOKUPS = booleanKey("vault-unsafe-lookups", false);
/**
* Controls which group LuckPerms should use for NPC players when handling Vault requests
*/
public static final ConfigKey<String> VAULT_NPC_GROUP = stringKey("vault-npc-group", "default");
/**
* Controls how LuckPerms should consider the OP status of NPC players when handing Vault requests
*/
public static final ConfigKey<Boolean> VAULT_NPC_OP_STATUS = booleanKey("vault-npc-op-status", false);
/** /**
* If the vault server option should be used * If the vault server option should be used
*/ */