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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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.
|
||||||
|
@@ -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
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user