Retain cause node information for cached permission/meta data (#3250)

This commit is contained in:
lucko 2021-12-31 16:03:00 +00:00 committed by GitHub
parent ae93c9768b
commit 2d662cbab9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
88 changed files with 1809 additions and 1082 deletions

View File

@ -54,6 +54,6 @@ public interface MetaValueSelector {
* @param values the values, in the order in which they were accumulated.
* @return the selected value
*/
@NonNull String selectValue(@NonNull String key, @NonNull List<String> values);
@NonNull MetaNode selectValue(@NonNull String key, @NonNull List<MetaNode> values);
}

View File

@ -52,7 +52,7 @@ public class BukkitCalculatorFactory implements CalculatorFactory {
@Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
List<PermissionProcessor> processors = new ArrayList<>(7);
List<PermissionProcessor> processors = new ArrayList<>(8);
processors.add(new DirectProcessor());
@ -75,7 +75,8 @@ public class BukkitCalculatorFactory implements CalculatorFactory {
boolean op = queryOptions.option(BukkitContextManager.OP_OPTION).orElse(false);
if (metadata.getHolderType() == HolderType.USER && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) {
boolean overrideWildcards = this.plugin.getConfiguration().get(ConfigKeys.APPLY_DEFAULT_NEGATIONS_BEFORE_WILDCARDS);
processors.add(new DefaultsProcessor(this.plugin, overrideWildcards, op));
processors.add(new DefaultPermissionMapProcessor(this.plugin, op));
processors.add(new PermissionMapProcessor(this.plugin, overrideWildcards, op));
}
if (op) {

View File

@ -26,9 +26,9 @@
package me.lucko.luckperms.bukkit.calculator;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.AbstractSourceBasedProcessor;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import net.luckperms.api.util.Tristate;
@ -40,7 +40,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* Permission Processor for Bukkits "child" permission system.
*/
public class ChildProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
public class ChildProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(ChildProcessor.class);
private final LPBukkitPlugin plugin;
@ -62,10 +62,10 @@ public class ChildProcessor extends AbstractPermissionProcessor implements Permi
@Override
public void refresh() {
Map<String, TristateResult> childPermissions = new HashMap<>();
this.sourceMap.forEach((key, value) -> {
Map<String, Boolean> children = this.plugin.getPermissionMap().getChildPermissions(key, value);
this.sourceMap.forEach((key, node) -> {
Map<String, Boolean> children = this.plugin.getPermissionMap().getChildPermissions(key, node.getValue());
children.forEach((childKey, childValue) -> {
childPermissions.put(childKey, RESULT_FACTORY.result(Tristate.of(childValue), "parent: " + key));
childPermissions.put(childKey, RESULT_FACTORY.resultWithOverride(node, Tristate.of(childValue)));
});
});
this.childPermissions = childPermissions;

View File

@ -0,0 +1,58 @@
/*
* 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.bukkit.calculator;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import net.luckperms.api.util.Tristate;
/**
* Permission Processor for Bukkits "default" permission system.
*/
public class DefaultPermissionMapProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(DefaultPermissionMapProcessor.class);
private final LPBukkitPlugin plugin;
private final boolean isOp;
public DefaultPermissionMapProcessor(LPBukkitPlugin plugin, boolean isOp) {
this.plugin = plugin;
this.isOp = isOp;
}
@Override
public TristateResult hasPermission(String permission) {
Tristate t = this.plugin.getDefaultPermissionMap().lookupDefaultPermission(permission, this.isOp);
if (t != Tristate.UNDEFINED) {
return RESULT_FACTORY.result(t);
}
return TristateResult.UNDEFINED;
}
}

View File

@ -1,90 +0,0 @@
/*
* 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.bukkit.calculator;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.processor.SpongeWildcardProcessor;
import me.lucko.luckperms.common.calculator.processor.WildcardProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import net.luckperms.api.util.Tristate;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
/**
* Permission Processor for Bukkits "default" permission system.
*/
public class DefaultsProcessor implements PermissionProcessor {
private static final TristateResult.Factory DEFAULT_PERMISSION_MAP_RESULT_FACTORY = new TristateResult.Factory(DefaultsProcessor.class, "default permission map");
private static final TristateResult.Factory PERMISSION_MAP_RESULT_FACTORY = new TristateResult.Factory(DefaultsProcessor.class, "permission map");
private final LPBukkitPlugin plugin;
private final boolean overrideWildcards;
private final boolean isOp;
public DefaultsProcessor(LPBukkitPlugin plugin, boolean overrideWildcards, boolean isOp) {
this.plugin = plugin;
this.overrideWildcards = overrideWildcards;
this.isOp = isOp;
}
private boolean canOverrideWildcard(TristateResult prev) {
return this.overrideWildcards &&
(prev.processorClass() == WildcardProcessor.class || prev.processorClass() == SpongeWildcardProcessor.class) &&
prev.result() == Tristate.TRUE;
}
@Override
public TristateResult hasPermission(TristateResult prev, String permission) {
if (prev != TristateResult.UNDEFINED) {
// Check to see if the result should be overridden
if (canOverrideWildcard(prev)) {
Permission defPerm = this.plugin.getPermissionMap().get(permission);
if (defPerm != null) {
PermissionDefault def = defPerm.getDefault();
if (def == PermissionDefault.FALSE || this.isOp && def == PermissionDefault.NOT_OP) {
return PERMISSION_MAP_RESULT_FACTORY.result(Tristate.FALSE, "permission map (overriding wildcard): " + prev.cause());
}
}
}
return prev;
}
Tristate t = this.plugin.getDefaultPermissionMap().lookupDefaultPermission(permission, this.isOp);
if (t != Tristate.UNDEFINED) {
return DEFAULT_PERMISSION_MAP_RESULT_FACTORY.result(t);
}
Permission defPerm = this.plugin.getPermissionMap().get(permission);
if (defPerm == null) {
return TristateResult.UNDEFINED;
}
return PERMISSION_MAP_RESULT_FACTORY.result(Tristate.of(defPerm.getDefault().getValue(this.isOp)));
}
}

View File

@ -25,8 +25,9 @@
package me.lucko.luckperms.bukkit.calculator;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import net.luckperms.api.util.Tristate;
@ -34,7 +35,7 @@ import net.luckperms.api.util.Tristate;
* Permission Processor which is added for opped users, to simply return true if
* no other processors match.
*/
public final class OpProcessor implements PermissionProcessor {
public final class OpProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
private static final TristateResult TRUE_RESULT = new TristateResult.Factory(OpProcessor.class).result(Tristate.TRUE);
public static final OpProcessor INSTANCE = new OpProcessor();
@ -44,10 +45,7 @@ public final class OpProcessor implements PermissionProcessor {
}
@Override
public TristateResult hasPermission(TristateResult prev, String permission) {
if (prev != TristateResult.UNDEFINED) {
return prev;
}
public TristateResult hasPermission(String permission) {
return TRUE_RESULT;
}
}

View File

@ -0,0 +1,60 @@
/*
* 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.bukkit.calculator;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.AbstractOverrideWildcardProcessor;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import net.luckperms.api.util.Tristate;
import org.bukkit.permissions.Permission;
/**
* Permission Processor for Bukkits "default" permission system.
*/
public class PermissionMapProcessor extends AbstractOverrideWildcardProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(PermissionMapProcessor.class);
private final LPBukkitPlugin plugin;
private final boolean isOp;
public PermissionMapProcessor(LPBukkitPlugin plugin, boolean overrideWildcards, boolean isOp) {
super(overrideWildcards);
this.plugin = plugin;
this.isOp = isOp;
}
@Override
public TristateResult hasPermission(String permission) {
Permission defPerm = this.plugin.getPermissionMap().get(permission);
if (defPerm == null) {
return TristateResult.UNDEFINED;
}
return RESULT_FACTORY.result(Tristate.of(defPerm.getDefault().getValue(this.isOp)));
}
}

View File

@ -29,13 +29,13 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.bukkit.calculator.DefaultsProcessor;
import me.lucko.luckperms.bukkit.calculator.OpProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.bukkit.calculator.PermissionMapProcessor;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
@ -143,13 +143,13 @@ public class LuckPermsPermissible extends PermissibleBase {
}
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions();
TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK);
TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET);
if (result.result() == Tristate.UNDEFINED) {
return false;
}
// ignore matches made from looking up in the permission map (replicate bukkit behaviour)
if (result.processorClass() == DefaultsProcessor.class && "permission map".equals(result.cause())) {
if (result.processorClass() == PermissionMapProcessor.class) {
return false;
}
@ -173,7 +173,7 @@ public class LuckPermsPermissible extends PermissibleBase {
}
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions();
return this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK).result().asBoolean();
return this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result().asBoolean();
}
@Override
@ -183,7 +183,7 @@ public class LuckPermsPermissible extends PermissibleBase {
}
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions();
TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission.getName(), PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK);
TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission.getName(), CheckOrigin.PLATFORM_API_HAS_PERMISSION);
// override default op handling using the Permission class we have
if (result.processorClass() == OpProcessor.class && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) {

View File

@ -25,12 +25,12 @@
package me.lucko.luckperms.bukkit.inject.permissible;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.util.Tristate;
@ -69,8 +69,8 @@ public class MonitoredPermissibleBase extends PermissibleBase {
this.initialised = true;
}
private void logCheck(PermissionCheckEvent.Origin origin, String permission, boolean result) {
this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(Tristate.of(result)));
private void logCheck(CheckOrigin origin, String permission, boolean result) {
this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(Tristate.of(result)));
this.plugin.getPermissionRegistry().offer(permission);
}
@ -85,7 +85,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
}
final boolean result = this.delegate.isPermissionSet(permission);
logCheck(PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK, permission, result);
logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, permission, result);
return result;
}
@ -96,7 +96,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
}
final boolean result = this.delegate.isPermissionSet(permission);
logCheck(PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK, permission.getName(), result);
logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, permission.getName(), result);
return result;
}
@ -107,7 +107,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
}
final boolean result = this.delegate.hasPermission(permission);
logCheck(PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK, permission, result);
logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION, permission, result);
return result;
}
@ -118,7 +118,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
}
final boolean result = this.delegate.hasPermission(permission);
logCheck(PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK, permission.getName(), result);
logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION, permission.getName(), result);
return result;
}

View File

@ -30,6 +30,7 @@ import com.google.common.base.Strings;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator;
import me.lucko.luckperms.common.cacheddata.type.MetaCache;
import me.lucko.luckperms.common.cacheddata.type.MonitoredMetaCache;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
@ -37,7 +38,7 @@ import me.lucko.luckperms.common.node.types.Meta;
import me.lucko.luckperms.common.node.types.Prefix;
import me.lucko.luckperms.common.node.types.Suffix;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.context.DefaultContextKeys;
import net.luckperms.api.context.ImmutableContextSet;
@ -97,7 +98,7 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
PermissionHolder user = this.vaultPermission.lookupUser(uuid);
QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world);
MetaCache metaData = user.getCachedData().getMetaData(queryOptions);
return Strings.nullToEmpty(metaData.getPrefix(MetaCheckEvent.Origin.THIRD_PARTY_API));
return Strings.nullToEmpty(metaData.getPrefix(CheckOrigin.THIRD_PARTY_API).result());
}
@Override
@ -107,7 +108,7 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
PermissionHolder user = this.vaultPermission.lookupUser(uuid);
QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world);
MetaCache metaData = user.getCachedData().getMetaData(queryOptions);
return Strings.nullToEmpty(metaData.getSuffix(MetaCheckEvent.Origin.THIRD_PARTY_API));
return Strings.nullToEmpty(metaData.getSuffix(CheckOrigin.THIRD_PARTY_API).result());
}
@Override
@ -139,8 +140,8 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
PermissionHolder user = this.vaultPermission.lookupUser(uuid);
QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world);
MetaCache metaData = user.getCachedData().getMetaData(queryOptions);
return metaData.getMetaValue(key, MetaCheckEvent.Origin.THIRD_PARTY_API);
MonitoredMetaCache metaData = user.getCachedData().getMetaData(queryOptions);
return metaData.getMetaValue(key, CheckOrigin.THIRD_PARTY_API).result();
}
@Override
@ -158,21 +159,21 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
@Override
public String getGroupChatPrefix(String world, String name) {
Objects.requireNonNull(name, "name");
MetaCache metaData = getGroupMetaCache(name, world);
MonitoredMetaCache metaData = getGroupMetaCache(name, world);
if (metaData == null) {
return null;
}
return Strings.nullToEmpty(metaData.getPrefix(MetaCheckEvent.Origin.THIRD_PARTY_API));
return Strings.nullToEmpty(metaData.getPrefix(CheckOrigin.THIRD_PARTY_API).result());
}
@Override
public String getGroupChatSuffix(String world, String name) {
Objects.requireNonNull(name, "name");
MetaCache metaData = getGroupMetaCache(name, world);
MonitoredMetaCache metaData = getGroupMetaCache(name, world);
if (metaData == null) {
return null;
}
return Strings.nullToEmpty(metaData.getSuffix(MetaCheckEvent.Origin.THIRD_PARTY_API));
return Strings.nullToEmpty(metaData.getSuffix(CheckOrigin.THIRD_PARTY_API).result());
}
@Override
@ -199,11 +200,11 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
public String getGroupMeta(String world, String name, String key) {
Objects.requireNonNull(name, "name");
Objects.requireNonNull(key, "key");
MetaCache metaData = getGroupMetaCache(name, world);
MonitoredMetaCache metaData = getGroupMetaCache(name, world);
if (metaData == null) {
return null;
}
return metaData.getMetaValue(key, MetaCheckEvent.Origin.THIRD_PARTY_API);
return metaData.getMetaValue(key, CheckOrigin.THIRD_PARTY_API).result();
}
@Override
@ -223,7 +224,7 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
return this.plugin.getGroupManager().getByDisplayName(name);
}
private MetaCache getGroupMetaCache(String name, String world) {
private MonitoredMetaCache getGroupMetaCache(String name, String world) {
Group group = getGroup(name);
if (group == null) {
return null;

View File

@ -29,10 +29,10 @@ import com.google.common.base.Preconditions;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.bukkit.context.BukkitContextManager;
import me.lucko.luckperms.common.cacheddata.type.MetaCache;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.type.MonitoredMetaCache;
import me.lucko.luckperms.common.cacheddata.type.PermissionCache;
import me.lucko.luckperms.common.calculator.processor.DirectProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.HolderType;
@ -44,8 +44,7 @@ import me.lucko.luckperms.common.node.types.Inheritance;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.util.UniqueIdType;
import me.lucko.luckperms.common.util.Uuids;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.DefaultContextKeys;
@ -175,7 +174,7 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
PermissionHolder user = lookupUser(uuid);
QueryOptions queryOptions = getQueryOptions(uuid, world);
PermissionCache permissionData = user.getCachedData().getPermissionData(queryOptions);
return permissionData.checkPermission(permission, PermissionCheckEvent.Origin.THIRD_PARTY_API).result().asBoolean();
return permissionData.checkPermission(permission, CheckOrigin.THIRD_PARTY_API).result().asBoolean();
}
@Override
@ -211,7 +210,7 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
QueryOptions queryOptions = getQueryOptions(uuid, world);
PermissionCache permissionData = user.getCachedData().getPermissionData(queryOptions);
TristateResult result = permissionData.checkPermission(Inheritance.key(rewriteGroupName(group)), PermissionCheckEvent.Origin.THIRD_PARTY_API);
TristateResult result = permissionData.checkPermission(Inheritance.key(rewriteGroupName(group)), CheckOrigin.THIRD_PARTY_API);
return result.processorClass() == DirectProcessor.class && result.result().asBoolean();
}
@ -254,8 +253,8 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
}
QueryOptions queryOptions = getQueryOptions(uuid, world);
MetaCache metaData = user.getCachedData().getMetaData(queryOptions);
String value = metaData.getPrimaryGroup(MetaCheckEvent.Origin.THIRD_PARTY_API);
MonitoredMetaCache metaData = user.getCachedData().getMetaData(queryOptions);
String value = metaData.getPrimaryGroup(CheckOrigin.THIRD_PARTY_API);
if (value == null) {
return null;
}
@ -276,7 +275,7 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
QueryOptions queryOptions = getQueryOptions(null, world);
PermissionCache permissionData = group.getCachedData().getPermissionData(queryOptions);
return permissionData.checkPermission(permission, PermissionCheckEvent.Origin.THIRD_PARTY_API).result().asBoolean();
return permissionData.checkPermission(permission, CheckOrigin.THIRD_PARTY_API).result().asBoolean();
}
@Override

View File

@ -27,12 +27,12 @@ package me.lucko.luckperms.bungee.listeners;
import me.lucko.luckperms.bungee.LPBungeePlugin;
import me.lucko.luckperms.bungee.event.TristateCheckEvent;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent.Origin;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
@ -72,7 +72,7 @@ public class BungeePermissionCheckListener implements Listener {
}
QueryOptions queryOptions = this.plugin.getContextManager().getQueryOptions(player);
Tristate result = user.getCachedData().getPermissionData(queryOptions).checkPermission(e.getPermission(), Origin.PLATFORM_PERMISSION_CHECK).result();
Tristate result = user.getCachedData().getPermissionData(queryOptions).checkPermission(e.getPermission(), CheckOrigin.PLATFORM_API_HAS_PERMISSION).result();
if (result == Tristate.UNDEFINED && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUNGEE_CONFIG_PERMISSIONS)) {
return; // just use the result provided by the proxy when the event was created
}
@ -101,7 +101,7 @@ public class BungeePermissionCheckListener implements Listener {
}
QueryOptions queryOptions = this.plugin.getContextManager().getQueryOptions(player);
Tristate result = user.getCachedData().getPermissionData(queryOptions).checkPermission(e.getPermission(), Origin.PLATFORM_LOOKUP_CHECK).result();
Tristate result = user.getCachedData().getPermissionData(queryOptions).checkPermission(e.getPermission(), CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET).result();
if (result == Tristate.UNDEFINED && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUNGEE_CONFIG_PERMISSIONS)) {
return; // just use the result provided by the proxy when the event was created
}
@ -122,7 +122,7 @@ public class BungeePermissionCheckListener implements Listener {
Tristate result = Tristate.of(e.hasPermission());
VerboseCheckTarget target = VerboseCheckTarget.internal(e.getSender().getName());
this.plugin.getVerboseHandler().offerPermissionCheckEvent(Origin.PLATFORM_PERMISSION_CHECK, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(result));
this.plugin.getVerboseHandler().offerPermissionCheckEvent(CheckOrigin.PLATFORM_API_HAS_PERMISSION, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(result));
this.plugin.getPermissionRegistry().offer(permission);
}
@ -139,7 +139,7 @@ public class BungeePermissionCheckListener implements Listener {
Tristate result = e.getResult();
VerboseCheckTarget target = VerboseCheckTarget.internal(e.getSender().getName());
this.plugin.getVerboseHandler().offerPermissionCheckEvent(Origin.PLATFORM_LOOKUP_CHECK, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(result));
this.plugin.getVerboseHandler().offerPermissionCheckEvent(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(result));
this.plugin.getPermissionRegistry().offer(permission);
}
}

View File

@ -30,7 +30,7 @@ import com.google.common.base.Preconditions;
import me.lucko.luckperms.common.cacheddata.UserCachedDataManager;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.types.Inheritance;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.model.data.DataMutateResult;
import net.luckperms.api.model.data.DataType;
@ -72,7 +72,7 @@ public class ApiUser extends ApiPermissionHolder implements net.luckperms.api.mo
@Override
public @NonNull String getPrimaryGroup() {
String value = this.handle.getCachedData().getMetaData(this.handle.getQueryOptions()).getPrimaryGroup(MetaCheckEvent.Origin.LUCKPERMS_API);
String value = this.handle.getCachedData().getMetaData(this.handle.getQueryOptions()).getPrimaryGroup(CheckOrigin.LUCKPERMS_API);
Objects.requireNonNull(value, "value"); // assert nonnull
return value;
}

View File

@ -27,7 +27,7 @@ package me.lucko.luckperms.common.cacheddata;
import me.lucko.luckperms.common.cache.LoadingMap;
import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator;
import me.lucko.luckperms.common.cacheddata.type.MetaCache;
import me.lucko.luckperms.common.cacheddata.type.MonitoredMetaCache;
import me.lucko.luckperms.common.cacheddata.type.PermissionCache;
import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.calculator.PermissionCalculator;
@ -40,6 +40,7 @@ import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.cacheddata.CachedPermissionData;
import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.node.ChatMetaType;
import net.luckperms.api.node.Node;
import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull;
@ -59,7 +60,7 @@ import java.util.function.IntFunction;
public abstract class AbstractCachedDataManager implements CachedDataManager {
private final LuckPermsPlugin plugin;
private final AbstractContainer<PermissionCache, CachedPermissionData> permission;
private final AbstractContainer<MetaCache, CachedMetaData> meta;
private final AbstractContainer<MonitoredMetaCache, CachedMetaData> meta;
protected AbstractCachedDataManager(LuckPermsPlugin plugin) {
this.plugin = plugin;
@ -87,7 +88,7 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
}
@Override
public @NonNull MetaCache getMetaData(@NonNull QueryOptions queryOptions) {
public @NonNull MonitoredMetaCache getMetaData(@NonNull QueryOptions queryOptions) {
return this.meta.get(queryOptions);
}
@ -97,7 +98,7 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
}
@Override
public @NonNull MetaCache getMetaData() {
public @NonNull MonitoredMetaCache getMetaData() {
return getMetaData(getQueryOptions());
}
@ -139,7 +140,7 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
* @param <M> the map type
* @return the resolved permissions
*/
protected abstract <M extends Map<String, Boolean>> M resolvePermissions(IntFunction<M> mapFactory, QueryOptions queryOptions);
protected abstract <M extends Map<String, Node>> M resolvePermissions(IntFunction<M> mapFactory, QueryOptions queryOptions);
/**
* Resolves the owners meta data for the given {@link QueryOptions}.
@ -153,18 +154,18 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
Objects.requireNonNull(queryOptions, "queryOptions");
CacheMetadata metadata = getMetadataForQueryOptions(queryOptions);
ConcurrentHashMap<String, Boolean> sourcePermissions = resolvePermissions(ConcurrentHashMap::new, queryOptions);
ConcurrentHashMap<String, Node> sourcePermissions = resolvePermissions(ConcurrentHashMap::new, queryOptions);
return new PermissionCache(queryOptions, metadata, getCalculatorFactory(), sourcePermissions);
}
private MetaCache calculateMeta(QueryOptions queryOptions) {
private MonitoredMetaCache calculateMeta(QueryOptions queryOptions) {
Objects.requireNonNull(queryOptions, "queryOptions");
CacheMetadata metadata = getMetadataForQueryOptions(queryOptions);
MetaAccumulator accumulator = newAccumulator(queryOptions);
resolveMeta(accumulator, queryOptions);
return new MetaCache(this.plugin, queryOptions, metadata, accumulator);
return new MonitoredMetaCache(this.plugin, queryOptions, metadata, accumulator);
}
@Override

View File

@ -32,6 +32,7 @@ import me.lucko.luckperms.common.model.PermissionHolder;
import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.node.ChatMetaType;
import net.luckperms.api.node.Node;
import net.luckperms.api.query.QueryOptions;
import java.util.Map;
@ -75,7 +76,7 @@ public abstract class HolderCachedDataManager<T extends PermissionHolder> extend
}
@Override
protected <M extends Map<String, Boolean>> M resolvePermissions(IntFunction<M> mapFactory, QueryOptions queryOptions) {
protected <M extends Map<String, Node>> M resolvePermissions(IntFunction<M> mapFactory, QueryOptions queryOptions) {
return this.holder.exportPermissions(mapFactory, queryOptions, true, getPlugin().getConfiguration().get(ConfigKeys.APPLYING_SHORTHAND));
}

View File

@ -0,0 +1,60 @@
/*
* 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.cacheddata.result;
import net.luckperms.api.node.Node;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Represents the result of a cached data lookup
*
* @param <T> the result type
*/
public interface Result<T, N extends Node> {
/**
* Gets the underlying result.
*
* @return the underlying result
*/
T result();
/**
* Gets the node that caused the result.
*
* @return the causing node
*/
@Nullable N node();
/**
* Gets the result that this result overrides, if applicable.
*
* @return the overridden result
*/
@Nullable Result<T, N> overriddenResult();
}

View File

@ -0,0 +1,107 @@
/*
* 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.cacheddata.result;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.types.ChatMetaNode;
import net.luckperms.api.node.types.MetaNode;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Represents the result of a meta lookup
*
* @param <N> the node type
*/
public final class StringResult<N extends Node> implements Result<String, N> {
/** The result, nullable */
private final String result;
/** The node that caused the result */
private final N node;
/** A reference to another result that this one overrides */
private StringResult<N> overriddenResult;
public StringResult(String result, N node, StringResult<N> overriddenResult) {
this.result = result;
this.node = node;
this.overriddenResult = overriddenResult;
}
@Override
public @Nullable String result() {
return this.result;
}
@Override
public @Nullable N node() {
return this.node;
}
@Override
public @Nullable StringResult<N> overriddenResult() {
return this.overriddenResult;
}
public void setOverriddenResult(StringResult<N> overriddenResult) {
this.overriddenResult = overriddenResult;
}
public StringResult<N> copy() {
return new StringResult<>(this.result, this.node, this.overriddenResult);
}
@Override
public String toString() {
return "StringResult(" +
"result=" + this.result + ", " +
"node=" + this.node + ", " +
"overriddenResult=" + this.overriddenResult + ')';
}
private static final StringResult<?> NULL_RESULT = new StringResult<>(null, null, null);
@SuppressWarnings("unchecked")
public static <T extends Node> StringResult<T> nullResult() {
return (StringResult<T>) NULL_RESULT;
}
public static <T extends Node> StringResult<T> of(String result) {
return new StringResult<>(result, null, null);
}
public static StringResult<MetaNode> of(MetaNode node) {
return new StringResult<>(node.getMetaValue(), node, null);
}
public static StringResult<ChatMetaNode<?, ?>> of(ChatMetaNode<?, ?> node) {
return new StringResult<>(node.getMetaValue(), node, null);
}
public static StringResult<ChatMetaNode<?, ?>> of(String result, ChatMetaNode<?, ?> node) {
return new StringResult<>(result, node, null);
}
}

View File

@ -23,78 +23,110 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.calculator.result;
package me.lucko.luckperms.common.cacheddata.result;
import me.lucko.luckperms.common.calculator.PermissionCalculator;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import net.luckperms.api.node.Node;
import net.luckperms.api.util.Tristate;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Represents the result of a {@link PermissionCalculator} lookup.
*/
public final class TristateResult {
public final class TristateResult implements Result<Tristate, Node> {
private static final Factory NULL_FACTORY = new Factory(null, null);
public static final TristateResult UNDEFINED = new TristateResult(Tristate.UNDEFINED, null, null);
public static TristateResult of(Tristate result) {
return NULL_FACTORY.result(result);
}
/** The result */
private final Tristate result;
/** The node that caused the result */
private final Node node;
/** The permission processor that provided the result */
private final Class<? extends PermissionProcessor> processorClass;
private final String cause;
/** A reference to another result that this one overrides */
private TristateResult overriddenResult;
private TristateResult(Tristate result, Class<? extends PermissionProcessor> processorClass, String cause) {
private TristateResult(Tristate result, Node node, Class<? extends PermissionProcessor> processorClass) {
this.result = result;
this.node = node;
this.processorClass = processorClass;
this.cause = cause;
}
public Tristate result() {
@Override
public @NonNull Tristate result() {
return this.result;
}
public Class<? extends PermissionProcessor> processorClass() {
@Override
public @Nullable Node node() {
return this.node;
}
public @Nullable Class<? extends PermissionProcessor> processorClass() {
return this.processorClass;
}
public String cause() {
return this.cause;
public @Nullable String processorClassFriendly() {
if (this.processorClass == null) {
return null;
} else if (this.processorClass.getName().startsWith("me.lucko.luckperms.")) {
String simpleName = this.processorClass.getSimpleName();
String platform = this.processorClass.getName().split("\\.")[3];
return platform + "." + simpleName;
} else {
return this.processorClass.getName();
}
}
@Override
public @Nullable TristateResult overriddenResult() {
return this.overriddenResult;
}
public void setOverriddenResult(TristateResult overriddenResult) {
this.overriddenResult = overriddenResult;
}
@Override
public String toString() {
return "TristateResult(" +
"result=" + this.result + ", " +
"node=" + this.node + ", " +
"processorClass=" + this.processorClass + ", " +
"cause=" + this.cause + ')';
"overriddenResult=" + this.overriddenResult + ')';
}
private static final TristateResult TRUE = new TristateResult(Tristate.TRUE, null,null);
private static final TristateResult FALSE = new TristateResult(Tristate.FALSE, null,null);
public static final TristateResult UNDEFINED = new TristateResult(Tristate.UNDEFINED, null,null);
public static TristateResult forMonitoredResult(Tristate result) {
switch (result) {
case TRUE:
return TRUE;
case FALSE:
return FALSE;
case UNDEFINED:
return UNDEFINED;
default:
throw new AssertionError();
}
}
public static final class Factory {
private final Class<? extends PermissionProcessor> processorClass;
private final TristateResult trueResult;
private final TristateResult falseResult;
public Factory(Class<? extends PermissionProcessor> processorClass, String defaultCause) {
this.processorClass = processorClass;
this.trueResult = new TristateResult(Tristate.TRUE, processorClass, defaultCause);
this.falseResult = new TristateResult(Tristate.FALSE, processorClass, defaultCause);
}
public Factory(Class<? extends PermissionProcessor> processorClass) {
this(processorClass, null);
this.processorClass = processorClass;
}
public TristateResult result(Tristate result) {
switch (result) {
case TRUE:
return this.trueResult;
case FALSE:
return this.falseResult;
return new TristateResult(result, null, this.processorClass);
case UNDEFINED:
return UNDEFINED;
default:
@ -102,11 +134,12 @@ public final class TristateResult {
}
}
public TristateResult result(Tristate result, String cause) {
if (result == Tristate.UNDEFINED) {
return UNDEFINED;
}
return new TristateResult(result, this.processorClass, cause);
public TristateResult result(@NonNull Node node) {
return new TristateResult(Tristate.of(node.getValue()), node, this.processorClass);
}
public TristateResult resultWithOverride(@NonNull Node node, Tristate result) {
return new TristateResult(result, node, this.processorClass);
}
}
}

View File

@ -28,6 +28,7 @@ package me.lucko.luckperms.common.cacheddata.type;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import me.lucko.luckperms.common.cacheddata.result.StringResult;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.node.types.Weight;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@ -35,6 +36,7 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.node.ChatMetaType;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.types.ChatMetaNode;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.node.types.PrefixNode;
import net.luckperms.api.node.types.SuffixNode;
@ -75,9 +77,9 @@ public class MetaAccumulator {
private final AtomicReference<State> state = new AtomicReference<>(State.ACCUMULATING);
private final ListMultimap<String, String> meta;
private final SortedMap<Integer, String> prefixes;
private final SortedMap<Integer, String> suffixes;
private final ListMultimap<String, StringResult<MetaNode>> meta;
private final SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> prefixes;
private final SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> suffixes;
private int weight = 0;
private String primaryGroup;
@ -119,10 +121,10 @@ public class MetaAccumulator {
// perform final changes
if (!this.meta.containsKey(Weight.NODE_KEY) && this.weight != 0) {
this.meta.put(Weight.NODE_KEY, String.valueOf(this.weight));
this.meta.put(Weight.NODE_KEY, StringResult.of(String.valueOf(this.weight)));
}
if (this.primaryGroup != null && !this.meta.containsKey("primarygroup")) {
this.meta.put("primarygroup", this.primaryGroup);
this.meta.put("primarygroup", StringResult.of(this.primaryGroup));
}
this.seenNodeKeys = null; // free up for GC
@ -146,27 +148,22 @@ public class MetaAccumulator {
if (n instanceof MetaNode) {
MetaNode mn = (MetaNode) n;
this.meta.put(mn.getMetaKey(), mn.getMetaValue());
this.meta.put(mn.getMetaKey(), StringResult.of(mn));
}
if (n instanceof PrefixNode) {
PrefixNode pn = (PrefixNode) n;
this.prefixes.putIfAbsent(pn.getPriority(), pn.getMetaValue());
this.prefixes.putIfAbsent(pn.getPriority(), StringResult.of(pn));
this.prefixAccumulator.offer(pn);
}
if (n instanceof SuffixNode) {
SuffixNode pn = (SuffixNode) n;
this.suffixes.putIfAbsent(pn.getPriority(), pn.getMetaValue());
this.suffixes.putIfAbsent(pn.getPriority(), StringResult.of(pn));
this.suffixAccumulator.offer(pn);
}
}
public void accumulateMeta(String key, String value) {
ensureState(State.ACCUMULATING);
this.meta.put(key, value);
}
public void accumulateWeight(int weight) {
ensureState(State.ACCUMULATING);
this.weight = Math.max(this.weight, weight);
@ -179,22 +176,22 @@ public class MetaAccumulator {
// read methods
public ListMultimap<String, String> getMeta() {
public ListMultimap<String, StringResult<MetaNode>> getMeta() {
ensureState(State.COMPLETE);
return this.meta;
}
public Map<Integer, String> getChatMeta(ChatMetaType type) {
public Map<Integer, StringResult<ChatMetaNode<?, ?>>> getChatMeta(ChatMetaType type) {
ensureState(State.COMPLETE);
return type == ChatMetaType.PREFIX ? this.prefixes : this.suffixes;
}
public SortedMap<Integer, String> getPrefixes() {
public SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> getPrefixes() {
ensureState(State.COMPLETE);
return this.prefixes;
}
public SortedMap<Integer, String> getSuffixes() {
public SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> getSuffixes() {
ensureState(State.COMPLETE);
return this.suffixes;
}
@ -219,14 +216,14 @@ public class MetaAccumulator {
return this.suffixDefinition;
}
public String getPrefix() {
public StringResult<ChatMetaNode<?, ?>> getPrefix() {
ensureState(State.COMPLETE);
return this.prefixAccumulator.toFormattedString();
return this.prefixAccumulator.toResult();
}
public String getSuffix() {
public StringResult<ChatMetaNode<?, ?>> getSuffix() {
ensureState(State.COMPLETE);
return this.suffixAccumulator.toFormattedString();
return this.suffixAccumulator.toResult();
}
@Override

View File

@ -26,102 +26,196 @@
package me.lucko.luckperms.common.cacheddata.type;
import com.google.common.collect.ForwardingMap;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimaps;
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
import me.lucko.luckperms.common.node.types.Prefix;
import me.lucko.luckperms.common.node.types.Suffix;
import me.lucko.luckperms.common.cacheddata.UsageTracked;
import me.lucko.luckperms.common.cacheddata.result.StringResult;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.node.types.ChatMetaNode;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.query.meta.MetaValueSelector;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.SortedMap;
/**
* Holds cached meta for a given context
*/
public class MetaCache extends SimpleMetaCache implements CachedMetaData {
public class MetaCache extends UsageTracked implements CachedMetaData {
/** The plugin instance */
private final LuckPermsPlugin plugin;
/** The metadata for this cache */
private final CacheMetadata metadata;
/** The query options this container is holding data for */
private final QueryOptions queryOptions;
public MetaCache(LuckPermsPlugin plugin, QueryOptions queryOptions, CacheMetadata metadata, MetaAccumulator sourceMeta) {
super(plugin, queryOptions, sourceMeta);
/* The data */
private final Map<String, List<StringResult<MetaNode>>> meta;
private final Map<String, StringResult<MetaNode>> flattenedMeta;
private final SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> prefixes;
private final SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> suffixes;
private final int weight;
private final String primaryGroup;
private final MetaStackDefinition prefixDefinition;
private final MetaStackDefinition suffixDefinition;
private final StringResult<ChatMetaNode<?, ?>> prefix;
private final StringResult<ChatMetaNode<?, ?>> suffix;
public MetaCache(LuckPermsPlugin plugin, QueryOptions queryOptions, MetaAccumulator sourceMeta) {
this.plugin = plugin;
this.metadata = metadata;
this.queryOptions = queryOptions;
Map<String, List<StringResult<MetaNode>>> meta = Multimaps.asMap(ImmutableListMultimap.copyOf(sourceMeta.getMeta()));
MetaValueSelector metaValueSelector = this.queryOptions.option(MetaValueSelector.KEY)
.orElseGet(() -> this.plugin.getConfiguration().get(ConfigKeys.META_VALUE_SELECTOR));
ImmutableMap.Builder<String, StringResult<MetaNode>> builder = ImmutableMap.builder();
for (Map.Entry<String, List<StringResult<MetaNode>>> e : meta.entrySet()) {
if (e.getValue().isEmpty()) {
continue;
}
MetaNode selected = metaValueSelector.selectValue(e.getKey(), Lists.transform(e.getValue(), StringResult::node));
if (selected == null) {
throw new NullPointerException(metaValueSelector + " returned null");
}
builder.put(e.getKey(), StringResult.of(selected));
}
this.flattenedMeta = builder.build();
this.meta = new LowerCaseMetaMap(meta);
this.prefixes = ImmutableSortedMap.copyOfSorted(sourceMeta.getPrefixes());
this.suffixes = ImmutableSortedMap.copyOfSorted(sourceMeta.getSuffixes());
this.weight = sourceMeta.getWeight();
this.primaryGroup = sourceMeta.getPrimaryGroup();
this.prefixDefinition = sourceMeta.getPrefixDefinition();
this.suffixDefinition = sourceMeta.getSuffixDefinition();
this.prefix = sourceMeta.getPrefix();
this.suffix = sourceMeta.getSuffix();
}
public @NonNull StringResult<MetaNode> getMetaValue(String key, CheckOrigin origin) {
Objects.requireNonNull(key, "key");
return this.flattenedMeta.getOrDefault(key.toLowerCase(Locale.ROOT), StringResult.nullResult());
}
@Override
public String getMetaValue(String key, MetaCheckEvent.Origin origin) {
String value = super.getMetaValue(key, origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), key, String.valueOf(value));
return value;
public final @Nullable String getMetaValue(@NonNull String key) {
return getMetaValue(key, CheckOrigin.LUCKPERMS_API).result();
}
public @NonNull StringResult<ChatMetaNode<?,?>> getPrefix(CheckOrigin origin) {
return this.prefix;
}
@Override
public String getPrefix(MetaCheckEvent.Origin origin) {
String value = super.getPrefix(origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Prefix.NODE_KEY, String.valueOf(value));
return value;
public final @Nullable String getPrefix() {
return getPrefix(CheckOrigin.LUCKPERMS_API).result();
}
public @NonNull StringResult<ChatMetaNode<?,?>> getSuffix(CheckOrigin origin) {
return this.suffix;
}
@Override
public String getSuffix(MetaCheckEvent.Origin origin) {
String value = super.getSuffix(origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Suffix.NODE_KEY, String.valueOf(value));
return value;
public final @Nullable String getSuffix() {
return getSuffix(CheckOrigin.LUCKPERMS_API).result();
}
protected Map<String, List<StringResult<MetaNode>>> getMetaResults(CheckOrigin origin) {
return this.meta;
}
public final Map<String, List<String>> getMeta(CheckOrigin origin) {
return Maps.transformValues(getMetaResults(origin), list -> Lists.transform(list, StringResult::result));
}
@Override
public Map<String, List<String>> getMeta(MetaCheckEvent.Origin origin) {
return new MonitoredMetaMap(super.getMeta(origin), origin);
public final @NonNull Map<String, List<String>> getMeta() {
return getMeta(CheckOrigin.LUCKPERMS_API);
}
@Override
public int getWeight(MetaCheckEvent.Origin origin) {
int value = super.getWeight(origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), "weight", String.valueOf(value));
return value;
public @NonNull SortedMap<Integer, String> getPrefixes() {
return Maps.transformValues(this.prefixes, StringResult::result);
}
@Override
public @Nullable String getPrimaryGroup(MetaCheckEvent.Origin origin) {
String value = super.getPrimaryGroup(origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), "primarygroup", String.valueOf(value));
return value;
public @NonNull SortedMap<Integer, String> getSuffixes() {
return Maps.transformValues(this.suffixes, StringResult::result);
}
private final class MonitoredMetaMap extends ForwardingMap<String, List<String>> {
private final Map<String, List<String>> delegate;
private final MetaCheckEvent.Origin origin;
public int getWeight(CheckOrigin origin) {
return this.weight;
}
private MonitoredMetaMap(Map<String, List<String>> delegate, MetaCheckEvent.Origin origin) {
//@Override - not actually exposed in the API atm
public final int getWeight() {
return getWeight(CheckOrigin.LUCKPERMS_API);
}
public @Nullable String getPrimaryGroup(CheckOrigin origin) {
return this.primaryGroup;
}
@Override
public final @Nullable String getPrimaryGroup() {
return getPrimaryGroup(CheckOrigin.LUCKPERMS_API);
}
@Override
public @NonNull MetaStackDefinition getPrefixStackDefinition() {
return this.prefixDefinition;
}
@Override
public @NonNull MetaStackDefinition getSuffixStackDefinition() {
return this.suffixDefinition;
}
@Override
public @NonNull QueryOptions getQueryOptions() {
return this.queryOptions;
}
private static final class LowerCaseMetaMap extends ForwardingMap<String, List<StringResult<MetaNode>>> {
private final Map<String, List<StringResult<MetaNode>>> delegate;
private LowerCaseMetaMap(Map<String, List<StringResult<MetaNode>>> delegate) {
this.delegate = delegate;
this.origin = origin;
}
@Override
protected Map<String, List<String>> delegate() {
protected Map<String, List<StringResult<MetaNode>>> delegate() {
return this.delegate;
}
@Override
public List<String> get(Object k) {
public List<StringResult<MetaNode>> get(Object k) {
if (k == null) {
return null;
}
String key = (String) k;
List<String> values = super.get(key);
MetaCache.this.plugin.getVerboseHandler().offerMetaCheckEvent(this.origin, MetaCache.this.metadata.getVerboseCheckInfo(), MetaCache.this.metadata.getQueryOptions(), key, String.valueOf(values));
return values;
return super.get(key.toLowerCase(Locale.ROOT));
}
}

View File

@ -25,6 +25,8 @@
package me.lucko.luckperms.common.cacheddata.type;
import me.lucko.luckperms.common.cacheddata.result.StringResult;
import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.metastacking.MetaStackElement;
import net.luckperms.api.node.ChatMetaType;
@ -36,6 +38,8 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class MetaStackAccumulator {
private final MetaStackDefinition definition;
@ -57,6 +61,13 @@ public class MetaStackAccumulator {
}
}
public List<ChatMetaNode<?, ?>> getElements() {
return this.entries.stream()
.map(Entry::getNode)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
public String toFormattedString() {
List<String> elements = new LinkedList<>();
for (Entry entry : this.entries) {
@ -94,6 +105,35 @@ public class MetaStackAccumulator {
return sb.toString();
}
public StringResult<ChatMetaNode<?, ?>> toResult() {
String formatted = toFormattedString();
if (formatted == null) {
return StringResult.nullResult();
}
List<ChatMetaNode<?, ?>> elements = getElements();
switch (elements.size()) {
case 0:
throw new AssertionError();
case 1:
return StringResult.of(formatted, elements.get(0));
default: {
Iterator<ChatMetaNode<?, ?>> it = elements.iterator();
StringResult<ChatMetaNode<?, ?>> result = StringResult.of(formatted, it.next());
StringResult<ChatMetaNode<?, ?>> root = result;
while (it.hasNext()) {
StringResult<ChatMetaNode<?, ?>> nested = StringResult.of(it.next());
root.setOverriddenResult(nested);
root = nested;
}
return result;
}
}
}
private static final class Entry {
private final MetaStackElement element;
private final ChatMetaType type;

View File

@ -0,0 +1,152 @@
/*
* 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.cacheddata.type;
import com.google.common.collect.ForwardingMap;
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
import me.lucko.luckperms.common.cacheddata.result.StringResult;
import me.lucko.luckperms.common.node.types.Prefix;
import me.lucko.luckperms.common.node.types.Suffix;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.node.types.ChatMetaNode;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Holds cached meta for a given context
*/
public class MonitoredMetaCache extends MetaCache implements CachedMetaData {
/** The plugin instance */
private final LuckPermsPlugin plugin;
/** The metadata for this cache */
private final CacheMetadata metadata;
public MonitoredMetaCache(LuckPermsPlugin plugin, QueryOptions queryOptions, CacheMetadata metadata, MetaAccumulator sourceMeta) {
super(plugin, queryOptions, sourceMeta);
this.plugin = plugin;
this.metadata = metadata;
}
@Override
@NonNull
public StringResult<MetaNode> getMetaValue(String key, CheckOrigin origin) {
StringResult<MetaNode> value = super.getMetaValue(key, origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), key, value);
return value;
}
@Override
@NonNull
public StringResult<ChatMetaNode<?, ?>> getPrefix(CheckOrigin origin) {
StringResult<ChatMetaNode<?, ?>> value = super.getPrefix(origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Prefix.NODE_KEY, value);
return value;
}
@Override
@NonNull
public StringResult<ChatMetaNode<?, ?>> getSuffix(CheckOrigin origin) {
StringResult<ChatMetaNode<?, ?>> value = super.getSuffix(origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Suffix.NODE_KEY, value);
return value;
}
@Override
protected Map<String, List<StringResult<MetaNode>>> getMetaResults(CheckOrigin origin) {
return new MonitoredMetaMap(super.getMetaResults(origin), origin);
}
@Override
public int getWeight(CheckOrigin origin) {
int value = super.getWeight(origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), "weight", StringResult.of(String.valueOf(value)));
return value;
}
@Override
public @Nullable String getPrimaryGroup(CheckOrigin origin) {
String value = super.getPrimaryGroup(origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), "primarygroup", StringResult.of(value));
return value;
}
private final class MonitoredMetaMap extends ForwardingMap<String, List<StringResult<MetaNode>>> {
private final Map<String, List<StringResult<MetaNode>>> delegate;
private final CheckOrigin origin;
private MonitoredMetaMap(Map<String, List<StringResult<MetaNode>>> delegate, CheckOrigin origin) {
this.delegate = delegate;
this.origin = origin;
}
@Override
protected Map<String, List<StringResult<MetaNode>>> delegate() {
return this.delegate;
}
@Override
public List<StringResult<MetaNode>> get(Object k) {
if (k == null) {
return null;
}
String key = (String) k;
List<StringResult<MetaNode>> values = super.get(key);
if (values == null || values.isEmpty()) {
MonitoredMetaCache.this.plugin.getVerboseHandler().offerMetaCheckEvent(this.origin, MonitoredMetaCache.this.metadata.getVerboseCheckInfo(), MonitoredMetaCache.this.metadata.getQueryOptions(), key, StringResult.nullResult());
} else {
Iterator<StringResult<MetaNode>> it = values.iterator();
StringResult<MetaNode> result = it.next().copy();
StringResult<MetaNode> root = result;
while (it.hasNext()) {
StringResult<MetaNode> nested = it.next().copy();
root.setOverriddenResult(nested);
root = nested;
}
MonitoredMetaCache.this.plugin.getVerboseHandler().offerMetaCheckEvent(this.origin, MonitoredMetaCache.this.metadata.getVerboseCheckInfo(), MonitoredMetaCache.this.metadata.getQueryOptions(), key, result);
}
return values;
}
}
}

View File

@ -25,14 +25,17 @@
package me.lucko.luckperms.common.cacheddata.type;
import com.google.common.collect.Maps;
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
import me.lucko.luckperms.common.cacheddata.UsageTracked;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.calculator.PermissionCalculator;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.cacheddata.CachedPermissionData;
import net.luckperms.api.node.Node;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
@ -55,12 +58,12 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat
/**
* The raw set of permission strings.
*/
private final Map<String, Boolean> permissions;
private final Map<String, Node> permissions;
/**
* An immutable copy of {@link #permissions}
* A string->boolean view of {@link #permissions}
*/
private final Map<String, Boolean> permissionsUnmodifiable;
private final Map<String, Boolean> permissionsView;
/**
* The calculator instance responsible for resolving the raw permission strings in the permission map.
@ -69,10 +72,10 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat
*/
private final PermissionCalculator calculator;
public PermissionCache(QueryOptions queryOptions, CacheMetadata metadata, CalculatorFactory calculatorFactory, ConcurrentHashMap<String, Boolean> sourcePermissions) {
public PermissionCache(QueryOptions queryOptions, CacheMetadata metadata, CalculatorFactory calculatorFactory, ConcurrentHashMap<String, Node> sourcePermissions) {
this.queryOptions = queryOptions;
this.permissions = sourcePermissions;
this.permissionsUnmodifiable = Collections.unmodifiableMap(this.permissions);
this.permissionsView = Collections.unmodifiableMap(Maps.transformValues(this.permissions, Node::getValue));
this.calculator = calculatorFactory.build(queryOptions, metadata);
this.calculator.setSourcePermissions(this.permissions);
@ -89,10 +92,10 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat
@Override
public @NonNull Map<String, Boolean> getPermissionMap() {
return this.permissionsUnmodifiable;
return this.permissionsView;
}
public TristateResult checkPermission(String permission, PermissionCheckEvent.Origin origin) {
public TristateResult checkPermission(String permission, CheckOrigin origin) {
if (permission == null) {
throw new NullPointerException("permission");
}
@ -101,7 +104,7 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat
@Override
public @NonNull Tristate checkPermission(@NonNull String permission) {
return checkPermission(permission, PermissionCheckEvent.Origin.LUCKPERMS_API).result();
return checkPermission(permission, CheckOrigin.LUCKPERMS_API).result();
}
@Override

View File

@ -1,213 +0,0 @@
/*
* 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.cacheddata.type;
import com.google.common.collect.ForwardingMap;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Multimaps;
import me.lucko.luckperms.common.cacheddata.UsageTracked;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.query.meta.MetaValueSelector;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.SortedMap;
/**
* Holds cached meta for a given context
*/
public class SimpleMetaCache extends UsageTracked implements CachedMetaData {
private final LuckPermsPlugin plugin;
/** The query options this container is holding data for */
private final QueryOptions queryOptions;
/* The data */
protected final Map<String, List<String>> meta;
protected final Map<String, String> flattenedMeta;
protected final SortedMap<Integer, String> prefixes;
protected final SortedMap<Integer, String> suffixes;
protected final int weight;
protected final String primaryGroup;
private final MetaStackDefinition prefixDefinition;
private final MetaStackDefinition suffixDefinition;
private final String prefix;
private final String suffix;
public SimpleMetaCache(LuckPermsPlugin plugin, QueryOptions queryOptions, MetaAccumulator sourceMeta) {
this.plugin = plugin;
this.queryOptions = queryOptions;
Map<String, List<String>> meta = Multimaps.asMap(ImmutableListMultimap.copyOf(sourceMeta.getMeta()));
MetaValueSelector metaValueSelector = this.queryOptions.option(MetaValueSelector.KEY)
.orElseGet(() -> this.plugin.getConfiguration().get(ConfigKeys.META_VALUE_SELECTOR));
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
for (Map.Entry<String, List<String>> e : meta.entrySet()) {
if (e.getValue().isEmpty()) {
continue;
}
String selected = metaValueSelector.selectValue(e.getKey(), e.getValue());
if (selected == null) {
throw new NullPointerException(metaValueSelector + " returned null");
}
builder.put(e.getKey(), selected);
}
this.flattenedMeta = builder.build();
this.meta = new LowerCaseMetaMap(meta);
this.prefixes = ImmutableSortedMap.copyOfSorted(sourceMeta.getPrefixes());
this.suffixes = ImmutableSortedMap.copyOfSorted(sourceMeta.getSuffixes());
this.weight = sourceMeta.getWeight();
this.primaryGroup = sourceMeta.getPrimaryGroup();
this.prefixDefinition = sourceMeta.getPrefixDefinition();
this.suffixDefinition = sourceMeta.getSuffixDefinition();
this.prefix = sourceMeta.getPrefix();
this.suffix = sourceMeta.getSuffix();
}
public String getMetaValue(String key, MetaCheckEvent.Origin origin) {
Objects.requireNonNull(key, "key");
return this.flattenedMeta.get(key.toLowerCase(Locale.ROOT));
}
@Override
public final String getMetaValue(@NonNull String key) {
return getMetaValue(key, MetaCheckEvent.Origin.LUCKPERMS_API);
}
public String getPrefix(MetaCheckEvent.Origin origin) {
return this.prefix;
}
@Override
public final String getPrefix() {
return getPrefix(MetaCheckEvent.Origin.LUCKPERMS_API);
}
public String getSuffix(MetaCheckEvent.Origin origin) {
return this.suffix;
}
@Override
public final String getSuffix() {
return getSuffix(MetaCheckEvent.Origin.LUCKPERMS_API);
}
public Map<String, List<String>> getMeta(MetaCheckEvent.Origin origin) {
return this.meta;
}
@Override
public final @NonNull Map<String, List<String>> getMeta() {
return getMeta(MetaCheckEvent.Origin.LUCKPERMS_API);
}
@Override
public @NonNull SortedMap<Integer, String> getPrefixes() {
return this.prefixes;
}
@Override
public @NonNull SortedMap<Integer, String> getSuffixes() {
return this.suffixes;
}
public int getWeight(MetaCheckEvent.Origin origin) {
return this.weight;
}
//@Override - not actually exposed in the API atm
public final int getWeight() {
return getWeight(MetaCheckEvent.Origin.LUCKPERMS_API);
}
public @Nullable String getPrimaryGroup(MetaCheckEvent.Origin origin) {
return this.primaryGroup;
}
@Override
public final @Nullable String getPrimaryGroup() {
return getPrimaryGroup(MetaCheckEvent.Origin.LUCKPERMS_API);
}
@Override
public @NonNull MetaStackDefinition getPrefixStackDefinition() {
return this.prefixDefinition;
}
@Override
public @NonNull MetaStackDefinition getSuffixStackDefinition() {
return this.suffixDefinition;
}
@Override
public @NonNull QueryOptions getQueryOptions() {
return this.queryOptions;
}
private static final class LowerCaseMetaMap extends ForwardingMap<String, List<String>> {
private final Map<String, List<String>> delegate;
private LowerCaseMetaMap(Map<String, List<String>> delegate) {
this.delegate = delegate;
}
@Override
protected Map<String, List<String>> delegate() {
return this.delegate;
}
@Override
public List<String> get(Object k) {
if (k == null) {
return null;
}
String key = (String) k;
return super.get(key.toLowerCase(Locale.ROOT));
}
}
}

View File

@ -25,6 +25,7 @@
package me.lucko.luckperms.common.cacheddata.type;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.query.meta.MetaValueSelector;
import org.checkerframework.checker.nullness.qual.NonNull;
@ -43,7 +44,7 @@ public class SimpleMetaValueSelector implements MetaValueSelector {
}
@Override
public @NonNull String selectValue(@NonNull String key, @NonNull List<String> values) {
public @NonNull MetaNode selectValue(@NonNull String key, @NonNull List<MetaNode> values) {
switch (values.size()) {
case 0:
throw new IllegalArgumentException("values is empty");
@ -57,7 +58,7 @@ public class SimpleMetaValueSelector implements MetaValueSelector {
public enum Strategy {
INHERITANCE {
@Override
public String select(List<String> values) {
public MetaNode select(List<MetaNode> values) {
return values.get(0);
}
},
@ -65,7 +66,7 @@ public class SimpleMetaValueSelector implements MetaValueSelector {
private final DoubleSelectionPredicate selection = (value, current) -> value > current;
@Override
public String select(List<String> values) {
public MetaNode select(List<MetaNode> values) {
return selectNumber(values, this.selection);
}
},
@ -73,12 +74,12 @@ public class SimpleMetaValueSelector implements MetaValueSelector {
private final DoubleSelectionPredicate selection = (value, current) -> value < current;
@Override
public String select(List<String> values) {
public MetaNode select(List<MetaNode> values) {
return selectNumber(values, this.selection);
}
};
public abstract String select(List<String> values);
public abstract MetaNode select(List<MetaNode> values);
public static Strategy parse(String s) {
try {
@ -94,15 +95,16 @@ public class SimpleMetaValueSelector implements MetaValueSelector {
boolean shouldSelect(double value, double current);
}
private static String selectNumber(List<String> values, DoubleSelectionPredicate selection) {
private static MetaNode selectNumber(List<MetaNode> values, DoubleSelectionPredicate selection) {
double current = 0;
String selected = null;
MetaNode selected = null;
for (String value : values) {
for (MetaNode node : values) {
String value = node.getMetaValue();
try {
double parse = Double.parseDouble(value);
if (selected == null || selection.shouldSelect(parse, current)) {
selected = value;
selected = node;
current = parse;
}
} catch (NumberFormatException e) {

View File

@ -27,10 +27,12 @@ package me.lucko.luckperms.common.calculator;
import me.lucko.luckperms.common.cache.LoadingMap;
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.node.Node;
import org.checkerframework.checker.nullness.qual.NonNull;
@ -71,7 +73,7 @@ public class PermissionCalculator implements Function<String, TristateResult> {
* @param origin marks where this check originated from
* @return the result
*/
public TristateResult checkPermission(String permission, PermissionCheckEvent.Origin origin) {
public TristateResult checkPermission(String permission, CheckOrigin origin) {
// get the result
TristateResult result = this.lookupCache.get(permission);
@ -106,7 +108,7 @@ public class PermissionCalculator implements Function<String, TristateResult> {
*
* @param sourceMap the source map
*/
public synchronized void setSourcePermissions(Map<String, Boolean> sourceMap) {
public synchronized void setSourcePermissions(Map<String, Node> sourceMap) {
for (PermissionProcessor processor : this.processors) {
processor.setSource(sourceMap);
processor.refresh();

View File

@ -0,0 +1,58 @@
/*
* 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.calculator.processor;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import net.luckperms.api.util.Tristate;
public abstract class AbstractOverrideWildcardProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
private final boolean overrideWildcards;
public AbstractOverrideWildcardProcessor(boolean overrideWildcards) {
this.overrideWildcards = overrideWildcards;
}
private boolean canOverrideWildcard(TristateResult prev) {
return this.overrideWildcards &&
(prev.processorClass() == WildcardProcessor.class || prev.processorClass() == SpongeWildcardProcessor.class) &&
prev.result() == Tristate.TRUE;
}
@Override
protected TristateResult hasPermissionOverride(TristateResult prev, String permission) {
if (canOverrideWildcard(prev)) {
TristateResult override = hasPermission(permission);
if (override.result() == Tristate.FALSE) {
override.setOverriddenResult(prev);
return override;
}
}
return prev;
}
}

View File

@ -25,26 +25,28 @@
package me.lucko.luckperms.common.calculator.processor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import java.util.Collections;
import java.util.Map;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
/**
* Abstract implementation of {@link PermissionProcessor} that splits behaviour for normal
* permission checks and override checks into two separate methods.
*/
public abstract class AbstractPermissionProcessor implements PermissionProcessor {
protected Map<String, Boolean> sourceMap = Collections.emptyMap();
@Override
public void setSource(Map<String, Boolean> sourceMap) {
this.sourceMap = sourceMap;
}
@Override
public TristateResult hasPermission(TristateResult prev, String permission) {
public final TristateResult hasPermission(TristateResult prev, String permission) {
if (prev != TristateResult.UNDEFINED) {
return prev;
return hasPermissionOverride(prev, permission);
}
return hasPermission(permission);
}
public abstract TristateResult hasPermission(String permission);
// Performs a regular permission check
protected abstract TristateResult hasPermission(String permission);
// Performs an override permission check
protected TristateResult hasPermissionOverride(TristateResult prev, String permission) {
return prev;
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.calculator.processor;
import net.luckperms.api.node.Node;
import java.util.Collections;
import java.util.Map;
public abstract class AbstractSourceBasedProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
protected Map<String, Node> sourceMap = Collections.emptyMap();
@Override
public void setSource(Map<String, Node> sourceMap) {
this.sourceMap = sourceMap;
}
}

View File

@ -25,16 +25,14 @@
package me.lucko.luckperms.common.calculator.processor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import net.luckperms.api.util.Tristate;
public class DirectProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
public class DirectProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(DirectProcessor.class);
@Override
public TristateResult hasPermission(String permission) {
return RESULT_FACTORY.result(Tristate.of(this.sourceMap.get(permission)));
return RESULT_FACTORY.result(this.sourceMap.get(permission));
}
}

View File

@ -25,8 +25,10 @@
package me.lucko.luckperms.common.calculator.processor;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.PermissionCalculator;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import net.luckperms.api.node.Node;
import java.util.Map;
@ -52,7 +54,7 @@ public interface PermissionProcessor {
*
* @param sourceMap the source map
*/
default void setSource(Map<String, Boolean> sourceMap) {
default void setSource(Map<String, Node> sourceMap) {
}

View File

@ -28,17 +28,17 @@ package me.lucko.luckperms.common.calculator.processor;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.node.types.RegexPermission;
import net.luckperms.api.util.Tristate;
import net.luckperms.api.node.Node;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
public class RegexProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
public class RegexProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(RegexProcessor.class);
private List<Map.Entry<Pattern, TristateResult>> regexPermissions = Collections.emptyList();
@ -56,7 +56,7 @@ public class RegexProcessor extends AbstractPermissionProcessor implements Permi
@Override
public void refresh() {
ImmutableList.Builder<Map.Entry<Pattern, TristateResult>> builder = ImmutableList.builder();
for (Map.Entry<String, Boolean> e : this.sourceMap.entrySet()) {
for (Map.Entry<String, Node> e : this.sourceMap.entrySet()) {
RegexPermission.Builder regexPerm = RegexPermission.parse(e.getKey());
if (regexPerm == null) {
continue;
@ -67,7 +67,7 @@ public class RegexProcessor extends AbstractPermissionProcessor implements Permi
continue;
}
TristateResult value = RESULT_FACTORY.result(Tristate.of(e.getValue()), "pattern: " + pattern.pattern());
TristateResult value = RESULT_FACTORY.result(e.getValue());
builder.add(Maps.immutableEntry(pattern, value));
}
this.regexPermissions = builder.build();

View File

@ -25,12 +25,12 @@
package me.lucko.luckperms.common.calculator.processor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.node.AbstractNode;
import net.luckperms.api.util.Tristate;
import net.luckperms.api.node.Node;
public class SpongeWildcardProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
public class SpongeWildcardProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(SpongeWildcardProcessor.class);
@Override
@ -45,9 +45,9 @@ public class SpongeWildcardProcessor extends AbstractPermissionProcessor impleme
node = node.substring(0, endIndex);
if (!node.isEmpty()) {
Tristate t = Tristate.of(this.sourceMap.get(node));
if (t != Tristate.UNDEFINED) {
return RESULT_FACTORY.result(t, "match: " + node);
Node n = this.sourceMap.get(node);
if (n != null) {
return RESULT_FACTORY.result(n);
}
}
}

View File

@ -27,15 +27,16 @@ package me.lucko.luckperms.common.calculator.processor;
import com.google.common.collect.ImmutableMap;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.node.AbstractNode;
import net.luckperms.api.node.Node;
import net.luckperms.api.util.Tristate;
import java.util.Collections;
import java.util.Map;
public class WildcardProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
public class WildcardProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(WildcardProcessor.class);
public static final String WILDCARD_SUFFIX = ".*";
@ -78,22 +79,22 @@ public class WildcardProcessor extends AbstractPermissionProcessor implements Pe
@Override
public void refresh() {
ImmutableMap.Builder<String, TristateResult> builder = ImmutableMap.builder();
for (Map.Entry<String, Boolean> e : this.sourceMap.entrySet()) {
for (Map.Entry<String, Node> e : this.sourceMap.entrySet()) {
String key = e.getKey();
if (!key.endsWith(WILDCARD_SUFFIX) || key.length() <= 2) {
continue;
}
key = key.substring(0, key.length() - 2);
TristateResult value = RESULT_FACTORY.result(Tristate.of(e.getValue()), "match: " + key);
TristateResult value = RESULT_FACTORY.result(e.getValue());
builder.put(key, value);
}
this.wildcardPermissions = builder.build();
Tristate state = Tristate.of(this.sourceMap.get(ROOT_WILDCARD));
if (state == Tristate.UNDEFINED) {
state = Tristate.of(this.sourceMap.get(ROOT_WILDCARD_WITH_QUOTES));
Node rootWildcard = this.sourceMap.get(ROOT_WILDCARD);
if (rootWildcard == null) {
rootWildcard = this.sourceMap.get(ROOT_WILDCARD_WITH_QUOTES);
}
this.rootWildcardState = RESULT_FACTORY.result(state, "root");
this.rootWildcardState = rootWildcard == null ? TristateResult.UNDEFINED : RESULT_FACTORY.result(rootWildcard);
}
}

View File

@ -25,9 +25,9 @@
package me.lucko.luckperms.common.command.access;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.type.PermissionCache;
import me.lucko.luckperms.common.calculator.processor.DirectProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.HolderType;
@ -38,7 +38,7 @@ import me.lucko.luckperms.common.node.types.Inheritance;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.context.Context;
import net.luckperms.api.context.ContextSet;
@ -305,7 +305,7 @@ public final class ArgumentPermissions {
}
PermissionCache permissionData = user.getCachedData().getPermissionData(QueryOptionsImpl.DEFAULT_CONTEXTUAL.toBuilder().context(contextSet).build());
TristateResult result = permissionData.checkPermission(Inheritance.key(targetGroupName), PermissionCheckEvent.Origin.INTERNAL);
TristateResult result = permissionData.checkPermission(Inheritance.key(targetGroupName), CheckOrigin.INTERNAL);
return result.result() != Tristate.TRUE || result.processorClass() != DirectProcessor.class;
}

View File

@ -25,8 +25,8 @@
package me.lucko.luckperms.common.commands.generic.permission;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.WildcardProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.command.abstraction.CommandException;
import me.lucko.luckperms.common.command.abstraction.GenericChildCommand;
import me.lucko.luckperms.common.command.access.ArgumentPermissions;
@ -43,7 +43,7 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Predicates;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.kyori.adventure.text.Component;
import net.luckperms.api.context.ImmutableContextSet;
@ -123,29 +123,13 @@ public class PermissionCheck extends GenericChildCommand {
// perform a "real" check
QueryOptions queryOptions = target.getQueryOptions();
TristateResult checkResult = target.getCachedData().getPermissionData(queryOptions).checkPermission(node, PermissionCheckEvent.Origin.INTERNAL);
TristateResult checkResult = target.getCachedData().getPermissionData(queryOptions).checkPermission(node, CheckOrigin.INTERNAL);
Tristate result = checkResult.result();
String processor;
String cause;
String processor = checkResult.processorClassFriendly();
Node cause = checkResult.node();
ImmutableContextSet context = queryOptions.context();
if (result != Tristate.UNDEFINED) {
Class<?> processorClass = checkResult.processorClass();
if (processorClass.getName().startsWith("me.lucko.luckperms.")) {
String simpleName = processorClass.getSimpleName();
String platform = processorClass.getName().split("\\.")[3];
processor = platform + "." + simpleName;
} else {
processor = processorClass.getName();
}
cause = checkResult.cause();
} else {
processor = null;
cause = null;
}
// send results
Message.PERMISSION_CHECK_RESULT.send(sender, node, result, processor, cause, context);
}

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.group;
import me.lucko.luckperms.common.cacheddata.type.MetaCache;
import me.lucko.luckperms.common.cacheddata.type.MonitoredMetaCache;
import me.lucko.luckperms.common.command.abstraction.ChildCommand;
import me.lucko.luckperms.common.command.access.ArgumentPermissions;
import me.lucko.luckperms.common.command.access.CommandPermission;
@ -36,7 +36,7 @@ import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Predicates;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.types.InheritanceNode;
@ -85,10 +85,10 @@ public class GroupInfo extends ChildCommand<Group> {
}
QueryOptions queryOptions = plugin.getContextManager().getStaticQueryOptions();
MetaCache data = target.getCachedData().getMetaData(queryOptions);
String prefix = data.getPrefix(MetaCheckEvent.Origin.INTERNAL);
String suffix = data.getSuffix(MetaCheckEvent.Origin.INTERNAL);
Map<String, List<String>> meta = data.getMeta(MetaCheckEvent.Origin.INTERNAL);
MonitoredMetaCache data = target.getCachedData().getMetaData(queryOptions);
String prefix = data.getPrefix(CheckOrigin.INTERNAL).result();
String suffix = data.getSuffix(CheckOrigin.INTERNAL).result();
Map<String, List<String>> meta = data.getMeta(CheckOrigin.INTERNAL);
Message.GROUP_INFO_CONTEXTUAL_DATA.send(sender, prefix, suffix, meta);
}

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.user;
import me.lucko.luckperms.common.cacheddata.type.MetaCache;
import me.lucko.luckperms.common.cacheddata.type.MonitoredMetaCache;
import me.lucko.luckperms.common.command.abstraction.ChildCommand;
import me.lucko.luckperms.common.command.access.ArgumentPermissions;
import me.lucko.luckperms.common.command.access.CommandPermission;
@ -37,7 +37,7 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Predicates;
import me.lucko.luckperms.common.util.UniqueIdType;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.context.ContextSet;
import net.luckperms.api.node.Node;
@ -100,11 +100,11 @@ public class UserInfo extends ChildCommand<User> {
}
ContextSet contextSet = queryOptions.context();
MetaCache data = target.getCachedData().getMetaData(queryOptions);
String prefix = data.getPrefix(MetaCheckEvent.Origin.INTERNAL);
String suffix = data.getSuffix(MetaCheckEvent.Origin.INTERNAL);
String primaryGroup = data.getPrimaryGroup(MetaCheckEvent.Origin.INTERNAL);
Map<String, List<String>> meta = data.getMeta(MetaCheckEvent.Origin.INTERNAL);
MonitoredMetaCache data = target.getCachedData().getMetaData(queryOptions);
String prefix = data.getPrefix(CheckOrigin.INTERNAL).result();
String suffix = data.getSuffix(CheckOrigin.INTERNAL).result();
String primaryGroup = data.getPrimaryGroup(CheckOrigin.INTERNAL);
Map<String, List<String>> meta = data.getMeta(CheckOrigin.INTERNAL);
Message.USER_INFO_CONTEXTUAL_DATA.send(sender, active, contextSet, prefix, suffix, primaryGroup, meta);
}

View File

@ -338,6 +338,108 @@ public interface Message {
.append(text(result, GRAY))
);
Args1<String> VERBOSE_LOG_HOVER_TYPE = type -> translatable()
// "&aType: &2{}"
.key("luckperms.logs.verbose.hover.type-key")
.color(GREEN)
.append(text(": "))
.append(text(type, DARK_GREEN))
.build();
Args1<String> VERBOSE_LOG_HOVER_ORIGIN = origin -> translatable()
// "&bOrigin: &2{}"
.key("luckperms.logs.verbose.hover.origin-key")
.color(AQUA)
.append(text(": "))
.append(text(origin, DARK_GREEN))
.build();
Args1<Node> VERBOSE_LOG_HOVER_CAUSE = causeNode -> translatable()
// "&bCause: {}"
.key("luckperms.logs.verbose.hover.cause-key")
.color(AQUA)
.append(text(": "))
.apply(builder -> {
String origin = causeNode.getMetadata(InheritanceOriginMetadata.KEY)
.map(o -> o.getOrigin().getName()).orElse("?");
builder.append(translatable()
.key("luckperms.command.generic.permission.check.info.directly")
.color(GRAY)
.args(
text().color(AQUA).content(origin),
text(causeNode.getKey(), AQUA),
formatBoolean(causeNode.getValue()),
formatContextSet(causeNode.getContexts())
)
);
})
.build();
Args1<MetaNode> VERBOSE_LOG_HOVER_CAUSE_META = causeNode -> translatable()
// "&bCause: {}"
.key("luckperms.logs.verbose.hover.cause-key")
.color(AQUA)
.append(text(": "))
.apply(builder -> {
String origin = causeNode.getMetadata(InheritanceOriginMetadata.KEY)
.map(o -> o.getOrigin().getName()).orElse("?");
builder.append(translatable()
.key("luckperms.command.generic.permission.check.info.directly")
.color(GRAY)
.args(
text().color(AQUA).content(origin),
text(causeNode.getMetaKey(), AQUA),
formatColoredValue(causeNode.getMetaValue()),
formatContextSet(causeNode.getContexts())
)
);
})
.build();
Args1<ContextSet> VERBOSE_LOG_HOVER_CONTEXT = set -> translatable()
// "&bContext: {}"
.key("luckperms.logs.verbose.hover.context-key")
.color(AQUA)
.append(text(": "))
.append(formatContextSet(set))
.build();
Args1<String> VERBOSE_LOG_HOVER_THREAD = threadName -> translatable()
// "&bThread: &f{}"
.key("luckperms.logs.verbose.hover.thread-key")
.color(AQUA)
.append(text(": "))
.append(text(threadName, WHITE))
.build();
Args0 VERBOSE_LOG_HOVER_TRACE_TITLE = () -> translatable()
// "&bTrace:"
.key("luckperms.logs.verbose.hover.trace-key")
.color(AQUA)
.append(text(':'))
.build();
Args1<String> VERBOSE_LOG_HOVER_TRACE_CONTENT = content -> text(content, GRAY);
Args1<Integer> VERBOSE_LOG_HOVER_TRACE_OVERFLOW = overflow -> text()
// "&f... and {} more"
.color(WHITE)
.content("... ")
.append(translatable()
.key("luckperms.logs.verbose.hover.overflow")
.args(text(overflow))
)
.build();
Args1<String> VERBOSE_LOG_HOVER_PROCESSOR = processor -> translatable()
.key("luckperms.logs.verbose.hover.processor-key")
.color(AQUA)
.append(text(": "))
.append(text(processor, DARK_GREEN))
.build();
Args1<String> EXPORT_LOG = msg -> prefixed(text()
// "&3EXPORT &3&l> &f{}"
.append(translatable("luckperms.logs.export-prefix", DARK_AQUA))
@ -1832,7 +1934,7 @@ public interface Message {
)
);
Args5<String, Tristate, String, String, ContextSet> PERMISSION_CHECK_RESULT = (permission, result, processor, cause, context) -> join(newline(),
Args5<String, Tristate, String, Node, ContextSet> PERMISSION_CHECK_RESULT = (permission, result, processor, causeNode, context) -> join(newline(),
// &aPermission check for &b{}&a:
// &3Result: {}
// &3Processor: &f{}
@ -1867,10 +1969,22 @@ public interface Message {
.append(translatable("luckperms.command.generic.permission.check.result.cause-key"))
.append(text(": "))
.apply(builder -> {
if (cause == null) {
if (causeNode == null) {
builder.append(translatable("luckperms.command.misc.none", AQUA));
} else {
builder.append(text(cause, WHITE));
String origin = causeNode.getMetadata(InheritanceOriginMetadata.KEY)
.map(o -> o.getOrigin().getName()).orElse("?");
builder.append(translatable()
.key("luckperms.command.generic.permission.check.info.directly")
.color(GRAY)
.args(
text().color(AQUA).content(origin),
text(causeNode.getKey(), AQUA),
formatBoolean(causeNode.getValue()),
formatContextSet(causeNode.getContexts())
)
);
}
})),
prefixed(text()

View File

@ -354,19 +354,19 @@ public abstract class PermissionHolder {
return (List) inheritanceTree;
}
public <M extends Map<String, Boolean>> M exportPermissions(IntFunction<M> mapFactory, QueryOptions queryOptions, boolean convertToLowercase, boolean resolveShorthand) {
public <M extends Map<String, Node>> M exportPermissions(IntFunction<M> mapFactory, QueryOptions queryOptions, boolean convertToLowercase, boolean resolveShorthand) {
List<Node> entries = resolveInheritedNodes(queryOptions);
M map = mapFactory.apply(entries.size());
processExportedPermissions(map, entries, convertToLowercase, resolveShorthand);
return map;
}
private static void processExportedPermissions(Map<String, Boolean> accumulator, List<Node> entries, boolean convertToLowercase, boolean resolveShorthand) {
private static void processExportedPermissions(Map<String, Node> accumulator, List<Node> entries, boolean convertToLowercase, boolean resolveShorthand) {
for (Node node : entries) {
if (convertToLowercase) {
accumulator.putIfAbsent(node.getKey().toLowerCase(Locale.ROOT), node.getValue());
accumulator.putIfAbsent(node.getKey().toLowerCase(Locale.ROOT), node);
} else {
accumulator.putIfAbsent(node.getKey(), node.getValue());
accumulator.putIfAbsent(node.getKey(), node);
}
}
@ -375,9 +375,9 @@ public abstract class PermissionHolder {
Collection<String> shorthand = node.resolveShorthand();
for (String s : shorthand) {
if (convertToLowercase) {
accumulator.putIfAbsent(s.toLowerCase(Locale.ROOT), node.getValue());
accumulator.putIfAbsent(s.toLowerCase(Locale.ROOT), node);
} else {
accumulator.putIfAbsent(s, node.getValue());
accumulator.putIfAbsent(s, node);
}
}
}

View File

@ -40,6 +40,11 @@ public final class PermissionHolderIdentifier implements Identifier {
this.name = name;
}
public PermissionHolderIdentifier(String type, String name) {
this.type = type;
this.name = name;
}
@Override
public @NonNull String getName() {
return this.name;

View File

@ -32,7 +32,7 @@ import me.lucko.luckperms.common.model.manager.AbstractManager;
import me.lucko.luckperms.common.model.manager.group.GroupManager;
import me.lucko.luckperms.common.node.types.Inheritance;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.model.data.DataType;
import net.luckperms.api.node.Node;
@ -86,7 +86,7 @@ public abstract class AbstractUserManager<T extends User> extends AbstractManage
// check that they are actually a member of their primary group, otherwise remove it
if (this.plugin.getConfiguration().get(ConfigKeys.PRIMARY_GROUP_CALCULATION_METHOD).equals("stored")) {
String primaryGroup = user.getCachedData().getMetaData(this.plugin.getConfiguration().get(ConfigKeys.GLOBAL_QUERY_OPTIONS)).getPrimaryGroup(MetaCheckEvent.Origin.INTERNAL);
String primaryGroup = user.getCachedData().getMetaData(this.plugin.getConfiguration().get(ConfigKeys.GLOBAL_QUERY_OPTIONS)).getPrimaryGroup(CheckOrigin.INTERNAL);
boolean memberOfPrimaryGroup = false;
for (InheritanceNode node : globalGroups) {

View File

@ -34,6 +34,7 @@ import me.lucko.luckperms.common.node.factory.NodeBuilders;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.NodeBuilder;
import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata;
import java.time.Instant;
import java.util.Collection;
@ -47,54 +48,81 @@ public class NodeJsonSerializer {
}
public static JsonObject serializeNode(Node node, boolean includeInheritanceOrigin) {
JsonObject attributes = new JsonObject();
attributes.addProperty("type", node.getType().name().toLowerCase(Locale.ROOT));
attributes.addProperty("key", node.getKey());
attributes.addProperty("value", node.getValue());
Instant expiry = node.getExpiry();
if (expiry != null) {
attributes.addProperty("expiry", expiry.getEpochSecond());
}
if (!node.getContexts().isEmpty()) {
attributes.add("context", ContextSetJsonSerializer.serialize(node.getContexts()));
}
if (includeInheritanceOrigin) {
InheritanceOriginMetadata origin = node.getMetadata(InheritanceOriginMetadata.KEY).orElse(null);
if (origin != null) {
JsonObject metadata = new JsonObject();
metadata.add("inheritanceOrigin", serializeInheritanceOrigin(origin));
attributes.add("metadata", metadata);
}
}
return attributes;
}
private static JsonObject serializeInheritanceOrigin(InheritanceOriginMetadata origin) {
JsonObject obj = new JsonObject();
obj.addProperty("type", origin.getOrigin().getType());
obj.addProperty("name", origin.getOrigin().getName());
return obj;
}
public static JsonArray serializeNodes(Collection<Node> nodes) {
JsonArray arr = new JsonArray();
for (Node node : nodes) {
JsonObject attributes = new JsonObject();
attributes.addProperty("type", node.getType().name().toLowerCase(Locale.ROOT));
attributes.addProperty("key", node.getKey());
attributes.addProperty("value", node.getValue());
Instant expiry = node.getExpiry();
if (expiry != null) {
attributes.addProperty("expiry", expiry.getEpochSecond());
}
if (!node.getContexts().isEmpty()) {
attributes.add("context", ContextSetJsonSerializer.serialize(node.getContexts()));
}
arr.add(attributes);
arr.add(serializeNode(node, false));
}
return arr;
}
public static Node deserializeNode(JsonElement ent) {
JsonObject attributes = ent.getAsJsonObject();
String key = attributes.get("key").getAsString();
if (key.isEmpty()) {
return null; // skip
}
NodeBuilder<?, ?> builder = NodeBuilders.determineMostApplicable(key);
boolean value = attributes.get("value").getAsBoolean();
builder.value(value);
if (attributes.has("expiry")) {
builder.expiry(attributes.get("expiry").getAsLong());
}
if (attributes.has("context")) {
builder.context(ContextSetJsonSerializer.deserialize(attributes.get("context")));
}
return builder.build();
}
public static Set<Node> deserializeNodes(JsonArray arr) {
Set<Node> nodes = new HashSet<>();
for (JsonElement ent : arr) {
JsonObject attributes = ent.getAsJsonObject();
String key = attributes.get("key").getAsString();
if (key.isEmpty()) {
continue; // skip
Node node = deserializeNode(ent);
if (node != null) {
nodes.add(node);
}
NodeBuilder<?, ?> builder = NodeBuilders.determineMostApplicable(key);
boolean value = attributes.get("value").getAsBoolean();
builder.value(value);
if (attributes.has("expiry")) {
builder.expiry(attributes.get("expiry").getAsLong());
}
if (attributes.has("context")) {
builder.context(ContextSetJsonSerializer.deserialize(attributes.get("context")));
}
nodes.add(builder.build());
}
return nodes;
}

View File

@ -36,7 +36,7 @@ import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.gson.GsonProvider;
import me.lucko.luckperms.common.util.gson.JObject;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -161,7 +161,7 @@ public class TreeView {
checks = new JObject();
for (Map.Entry<Integer, String> node : this.view.getNodeEndings()) {
String permission = prefix + node.getValue();
checks.add(permission, checker.checkPermission(permission, PermissionCheckEvent.Origin.INTERNAL).result().name().toLowerCase(Locale.ROOT));
checks.add(permission, checker.checkPermission(permission, CheckOrigin.INTERNAL).result().name().toLowerCase(Locale.ROOT));
}
} else {
checks = null;

View File

@ -25,10 +25,12 @@
package me.lucko.luckperms.common.verbose;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.StringResult;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerTask;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.VerboseEvent;
@ -74,7 +76,7 @@ public class VerboseHandler implements AutoCloseable {
* @param permission the permission which was checked for
* @param result the result of the permission check
*/
public void offerPermissionCheckEvent(PermissionCheckEvent.Origin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, String permission, TristateResult result) {
public void offerPermissionCheckEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, String permission, TristateResult result) {
// don't bother even processing the check if there are no listeners registered
if (!this.listening) {
return;
@ -100,7 +102,7 @@ public class VerboseHandler implements AutoCloseable {
* @param key the meta key which was checked for
* @param result the result of the meta check
*/
public void offerMetaCheckEvent(MetaCheckEvent.Origin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, String key, String result) {
public void offerMetaCheckEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, String key, StringResult<?> result) {
// don't bother even processing the check if there are no listeners registered
if (!this.listening) {
return;

View File

@ -27,7 +27,8 @@ package me.lucko.luckperms.common.verbose;
import com.google.gson.JsonObject;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.Result;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.http.AbstractHttpClient;
import me.lucko.luckperms.common.http.BytebinClient;
import me.lucko.luckperms.common.http.UnsuccessfulRequestException;
@ -38,6 +39,7 @@ import me.lucko.luckperms.common.util.StackTracePrinter;
import me.lucko.luckperms.common.util.gson.GsonProvider;
import me.lucko.luckperms.common.util.gson.JArray;
import me.lucko.luckperms.common.util.gson.JObject;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.VerboseEvent;
@ -45,7 +47,8 @@ import me.lucko.luckperms.common.verbose.event.VerboseEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.query.QueryMode;
import java.io.ByteArrayOutputStream;
@ -150,28 +153,6 @@ public class VerboseListener {
}
private void sendNotification(VerboseEvent event) {
if (this.notifiedSender.isConsole()) {
// just send as a raw message
if (event instanceof PermissionCheckEvent) {
PermissionCheckEvent permissionEvent = (PermissionCheckEvent) event;
Message.VERBOSE_LOG_PERMISSION.send(this.notifiedSender,
permissionEvent.getCheckTarget().describe(),
permissionEvent.getPermission(),
permissionEvent.getResult().result()
);
} else if (event instanceof MetaCheckEvent) {
MetaCheckEvent metaEvent = (MetaCheckEvent) event;
Message.VERBOSE_LOG_META.send(this.notifiedSender,
metaEvent.getCheckTarget().describe(),
metaEvent.getKey(),
metaEvent.getResult()
);
} else {
throw new IllegalArgumentException("Unknown event type: " + event);
}
return;
}
// form a text component from the check trace
Component component;
if (event instanceof PermissionCheckEvent) {
@ -186,69 +167,52 @@ public class VerboseListener {
component = Message.VERBOSE_LOG_META.build(
metaEvent.getCheckTarget().describe(),
metaEvent.getKey(),
metaEvent.getResult()
String.valueOf(metaEvent.getResult().result())
);
} else {
throw new IllegalArgumentException("Unknown event type: " + event);
}
// just send as a raw message
if (this.notifiedSender.isConsole()) {
this.notifiedSender.sendMessage(component);
return;
}
// build the hover text
List<ComponentLike> hover = new ArrayList<>();
if (event instanceof PermissionCheckEvent) {
PermissionCheckEvent permissionEvent = (PermissionCheckEvent) event;
hover.add(Component.text()
.append(Component.text("Type: ", NamedTextColor.GREEN))
.append(Component.text("permission", NamedTextColor.DARK_GREEN))
);
hover.add(Component.text()
.append(Component.text("Origin: ", NamedTextColor.AQUA))
.append(Component.text(permissionEvent.getOrigin().name(), NamedTextColor.DARK_GREEN))
);
hover.add(Message.VERBOSE_LOG_HOVER_TYPE.build(event.getType().toString()));
hover.add(Message.VERBOSE_LOG_HOVER_ORIGIN.build(event.getOrigin().name()));
TristateResult result = permissionEvent.getResult();
if (result.processorClass() != null) {
hover.add(Component.text()
.append(Component.text("Processor: ", NamedTextColor.AQUA))
.append(Component.text(result.processorClass().getName(), NamedTextColor.DARK_GREEN))
);
}
if (result.cause() != null) {
hover.add(Component.text()
.append(Component.text("Cause: ", NamedTextColor.AQUA))
.append(Component.text(result.cause(), NamedTextColor.DARK_GREEN))
);
Result<?, ?> result = event.getResult();
if (result instanceof TristateResult) {
TristateResult tristateResult = (TristateResult) result;
if (tristateResult.processorClass() != null) {
hover.add(Message.VERBOSE_LOG_HOVER_PROCESSOR.build(tristateResult.processorClassFriendly()));
}
}
if (event instanceof MetaCheckEvent) {
MetaCheckEvent metaEvent = (MetaCheckEvent) event;
hover.add(Component.text()
.append(Component.text("Type: ", NamedTextColor.GREEN))
.append(Component.text("meta", NamedTextColor.DARK_GREEN))
);
hover.add(Component.text()
.append(Component.text("Origin: ", NamedTextColor.AQUA))
.append(Component.text(metaEvent.getOrigin().name(), NamedTextColor.DARK_GREEN))
);
Node node = result.node();
if (node != null) {
if (node instanceof MetaNode) {
hover.add(Message.VERBOSE_LOG_HOVER_CAUSE_META.build((MetaNode) node));
} else {
hover.add(Message.VERBOSE_LOG_HOVER_CAUSE.build(node));
}
}
if (event.getCheckQueryOptions().mode() == QueryMode.CONTEXTUAL) {
hover.add(Component.text()
.append(Component.text("Context: ", NamedTextColor.AQUA))
.append(Message.formatContextSet(event.getCheckQueryOptions().context()))
);
hover.add(Message.VERBOSE_LOG_HOVER_CONTEXT.build(event.getCheckQueryOptions().context()));
}
hover.add(Component.text()
.append(Component.text("Thread: ", NamedTextColor.AQUA))
.append(Component.text(event.getCheckThread(), NamedTextColor.WHITE))
);
hover.add(Message.VERBOSE_LOG_HOVER_THREAD.build(event.getCheckThread()));
hover.add(Component.text()
.append(Component.text("Trace: ", NamedTextColor.AQUA))
);
hover.add(Message.VERBOSE_LOG_HOVER_TRACE_TITLE.build());
Consumer<StackTraceElement> printer = StackTracePrinter.elementToString(str -> hover.add(Component.text(str, NamedTextColor.GRAY)));
Consumer<StackTraceElement> printer = StackTracePrinter.elementToString(str -> hover.add(Message.VERBOSE_LOG_HOVER_TRACE_CONTENT.build(str)));
int overflow;
if (shouldFilterStackTrace(event)) {
overflow = CHAT_FILTERED_PRINTER.process(event.getCheckTrace(), printer);
@ -256,7 +220,7 @@ public class VerboseListener {
overflow = CHAT_UNFILTERED_PRINTER.process(event.getCheckTrace(), printer);
}
if (overflow != 0) {
hover.add(Component.text("... and " + overflow + " more", NamedTextColor.WHITE));
hover.add(Message.VERBOSE_LOG_HOVER_TRACE_OVERFLOW.build(overflow));
}
// send the message
@ -267,8 +231,8 @@ public class VerboseListener {
private static boolean shouldFilterStackTrace(VerboseEvent event) {
if (event instanceof PermissionCheckEvent) {
PermissionCheckEvent permissionEvent = (PermissionCheckEvent) event;
return permissionEvent.getOrigin() == PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK ||
permissionEvent.getOrigin() == PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK;
return permissionEvent.getOrigin() == CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET ||
permissionEvent.getOrigin() == CheckOrigin.PLATFORM_API_HAS_PERMISSION;
}
return false;
}
@ -302,8 +266,8 @@ public class VerboseListener {
.add("truncated", truncated);
JArray data = new JArray();
for (VerboseEvent events : this.results) {
data.add(events.toJson(shouldFilterStackTrace(events) ? WEB_FILTERED_PRINTER : WEB_UNFILTERED_PRINTER));
for (VerboseEvent event : this.results) {
data.add(event.toJson(shouldFilterStackTrace(event) ? WEB_FILTERED_PRINTER : WEB_UNFILTERED_PRINTER));
}
this.results.clear();

View File

@ -0,0 +1,63 @@
/*
* 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.verbose.event;
/**
* Represents the origin of a meta check
*/
public enum CheckOrigin {
/**
* Indicates the check was caused by a lookup in a platform API
*/
PLATFORM_API,
/**
* Indicates the check was caused by a 'hasPermission' check on the platform
*/
PLATFORM_API_HAS_PERMISSION,
/**
* Indicates the check was caused by a 'hasPermissionSet' type check on the platform
*/
PLATFORM_API_HAS_PERMISSION_SET,
/**
* Indicates the check was caused by a 3rd party API call
*/
THIRD_PARTY_API,
/**
* Indicates the check was caused by a LuckPerms API call
*/
LUCKPERMS_API,
/**
* Indicates the check was caused by a LuckPerms internal
*/
INTERNAL
}

View File

@ -25,6 +25,10 @@
package me.lucko.luckperms.common.verbose.event;
import com.google.gson.JsonArray;
import me.lucko.luckperms.common.cacheddata.result.StringResult;
import me.lucko.luckperms.common.node.utils.NodeJsonSerializer;
import me.lucko.luckperms.common.util.gson.JObject;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
@ -34,11 +38,6 @@ import java.util.Locale;
public class MetaCheckEvent extends VerboseEvent {
/**
* The origin of the check
*/
private final Origin origin;
/**
* The meta key which was checked for
*/
@ -47,33 +46,59 @@ public class MetaCheckEvent extends VerboseEvent {
/**
* The result of the meta check
*/
private final String result;
private final StringResult<?> result;
public MetaCheckEvent(Origin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread, String key, String result) {
super(checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread);
this.origin = origin;
public MetaCheckEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread, String key, StringResult<?> result) {
super(origin, checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread);
this.key = key;
this.result = result;
}
public Origin getOrigin() {
return this.origin;
}
public String getKey() {
return this.key;
}
public String getResult() {
@Override
public StringResult<?> getResult() {
return this.result;
}
@Override
public VerboseEventType getType() {
return VerboseEventType.META;
}
@Override
protected void serializeTo(JObject object) {
object.add("type", "meta")
.add("key", this.key)
.add("result", this.result)
.add("origin", this.origin.name().toLowerCase(Locale.ROOT));
object.add("key", this.key);
object.add("result", String.valueOf(this.result.result()));
if (this.result != StringResult.nullResult()) {
object.add("resultInfo", serializeResult(this.result));
}
}
private static JObject serializeResult(StringResult<?> result) {
JObject object = new JObject();
object.add("result", String.valueOf(result.result()));
if (result.node() != null) {
object.add("node", NodeJsonSerializer.serializeNode(result.node(), true));
}
if (result.overriddenResult() != null) {
JsonArray overridden = new JsonArray();
StringResult<?> next = result.overriddenResult();
while (next != null) {
overridden.add(serializeResult(next).toJson());
next = next.overriddenResult();
}
object.add("overridden", overridden);
}
return object;
}
@Override
@ -81,33 +106,7 @@ public class MetaCheckEvent extends VerboseEvent {
return variable.equals("meta") ||
getCheckTarget().describe().equalsIgnoreCase(variable) ||
getKey().toLowerCase(Locale.ROOT).startsWith(variable.toLowerCase(Locale.ROOT)) ||
getResult().equalsIgnoreCase(variable);
String.valueOf(getResult().result()).equalsIgnoreCase(variable);
}
/**
* Represents the origin of a meta check
*/
public enum Origin {
/**
* Indicates the check was caused by a lookup in a platform API
*/
PLATFORM_API,
/**
* Indicates the check was caused by a 3rd party API call
*/
THIRD_PARTY_API,
/**
* Indicates the check was caused by a LuckPerms API call
*/
LUCKPERMS_API,
/**
* Indicates the check was caused by a LuckPerms internal
*/
INTERNAL
}
}

View File

@ -25,7 +25,10 @@
package me.lucko.luckperms.common.verbose.event;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import com.google.gson.JsonArray;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.node.utils.NodeJsonSerializer;
import me.lucko.luckperms.common.util.gson.JObject;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
@ -35,11 +38,6 @@ import java.util.Locale;
public class PermissionCheckEvent extends VerboseEvent {
/**
* The origin of the check
*/
private final Origin origin;
/**
* The permission which was checked for
*/
@ -50,43 +48,60 @@ public class PermissionCheckEvent extends VerboseEvent {
*/
private final TristateResult result;
public PermissionCheckEvent(Origin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread, String permission, TristateResult result) {
super(checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread);
this.origin = origin;
public PermissionCheckEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread, String permission, TristateResult result) {
super(origin, checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread);
this.permission = permission;
this.result = result;
}
public Origin getOrigin() {
return this.origin;
}
public String getPermission() {
return this.permission;
}
@Override
public TristateResult getResult() {
return this.result;
}
@Override
public VerboseEventType getType() {
return VerboseEventType.PERMISSION;
}
@Override
protected void serializeTo(JObject object) {
object.add("type", "permission");
object.add("permission", this.permission);
object.add("result", this.result.result().name().toLowerCase(Locale.ROOT));
if (this.result.processorClass() != null || this.result.cause() != null) {
JObject resultInfo = new JObject();
if (this.result.processorClass() != null) {
resultInfo.add("processorClass", this.result.processorClass().getName());
}
if (this.result.cause() != null) {
resultInfo.add("cause", this.result.cause());
}
object.add("resultInfo", resultInfo);
if (this.result != TristateResult.UNDEFINED) {
object.add("resultInfo", serializeResult(this.result));
}
}
private static JObject serializeResult(TristateResult result) {
JObject object = new JObject();
object.add("result", result.result().name().toLowerCase(Locale.ROOT));
if (result.processorClass() != null) {
object.add("processorClass", result.processorClass().getName());
}
if (result.node() != null) {
object.add("node", NodeJsonSerializer.serializeNode(result.node(), true));
}
object.add("origin", this.origin.name().toLowerCase(Locale.ROOT));
if (result.overriddenResult() != null) {
JsonArray overridden = new JsonArray();
TristateResult next = result.overriddenResult();
while (next != null) {
overridden.add(serializeResult(next).toJson());
next = next.overriddenResult();
}
object.add("overridden", overridden);
}
return object;
}
@Override
@ -97,35 +112,4 @@ public class PermissionCheckEvent extends VerboseEvent {
getResult().result().name().equalsIgnoreCase(variable);
}
/**
* Represents the origin of a permission check
*/
public enum Origin {
/**
* Indicates the check was caused by a 'hasPermission' check on the platform
*/
PLATFORM_PERMISSION_CHECK,
/**
* Indicates the check was caused by a 'hasPermissionSet' type check on the platform
*/
PLATFORM_LOOKUP_CHECK,
/**
* Indicates the check was caused by a 3rd party API call
*/
THIRD_PARTY_API,
/**
* Indicates the check was caused by an LuckPerms API call
*/
LUCKPERMS_API,
/**
* Indicates the check was caused by a LuckPerms internal
*/
INTERNAL
}
}

View File

@ -27,6 +27,7 @@ package me.lucko.luckperms.common.verbose.event;
import com.google.gson.JsonObject;
import me.lucko.luckperms.common.cacheddata.result.Result;
import me.lucko.luckperms.common.util.StackTracePrinter;
import me.lucko.luckperms.common.util.gson.JArray;
import me.lucko.luckperms.common.util.gson.JObject;
@ -46,6 +47,11 @@ import java.util.UUID;
*/
public abstract class VerboseEvent implements VariableEvaluator {
/**
* The origin of the check
*/
private final CheckOrigin origin;
/**
* The name of the entity which was checked
*/
@ -71,7 +77,8 @@ public abstract class VerboseEvent implements VariableEvaluator {
*/
private final String checkThread;
protected VerboseEvent(VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread) {
protected VerboseEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread) {
this.origin = origin;
this.checkTarget = checkTarget;
this.checkQueryOptions = checkQueryOptions;
this.checkTime = checkTime;
@ -79,10 +86,16 @@ public abstract class VerboseEvent implements VariableEvaluator {
this.checkThread = checkThread;
}
public CheckOrigin getOrigin() {
return this.origin;
}
public VerboseCheckTarget getCheckTarget() {
return this.checkTarget;
}
public abstract Result<?, ?> getResult();
public QueryOptions getCheckQueryOptions() {
return this.checkQueryOptions;
}
@ -99,10 +112,14 @@ public abstract class VerboseEvent implements VariableEvaluator {
return this.checkThread;
}
public abstract VerboseEventType getType();
protected abstract void serializeTo(JObject object);
public JsonObject toJson(StackTracePrinter tracePrinter) {
return new JObject()
.add("type", getType().toString())
.add("origin", this.origin.name().toLowerCase(Locale.ROOT))
.add("who", new JObject()
.add("identifier", this.checkTarget.describe())
.add("type", this.checkTarget.getType())

View File

@ -0,0 +1,46 @@
/*
* 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.verbose.event;
import java.util.Locale;
public enum VerboseEventType {
/**
* {@link PermissionCheckEvent}
*/
PERMISSION,
/**
* {@link MetaCheckEvent}
*/
META;
@Override
public String toString() {
return name().toLowerCase(Locale.ROOT);
}
}

View File

@ -46,7 +46,7 @@ import me.lucko.luckperms.common.storage.misc.NodeEntry;
import me.lucko.luckperms.common.util.gson.GsonProvider;
import me.lucko.luckperms.common.util.gson.JArray;
import me.lucko.luckperms.common.util.gson.JObject;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.node.Node;
@ -233,7 +233,7 @@ public class WebEditorRequest {
users.values().stream()
.sorted(Comparator
// sort firstly by the users relative weight (depends on the groups they inherit)
.<User>comparingInt(u -> u.getCachedData().getMetaData(QueryOptions.nonContextual()).getWeight(MetaCheckEvent.Origin.INTERNAL)).reversed()
.<User>comparingInt(u -> u.getCachedData().getMetaData(QueryOptions.nonContextual()).getWeight(CheckOrigin.INTERNAL)).reversed()
// then, prioritise users we actually have a username for
.thenComparing(u -> u.getUsername().isPresent(), ((Comparator<Boolean>) Boolean::compare).reversed())
// then sort according to their username

View File

@ -1,5 +1,13 @@
luckperms.logs.actionlog-prefix=LOG
luckperms.logs.verbose-prefix=VB
luckperms.logs.verbose.hover.type-key=Type
luckperms.logs.verbose.hover.origin-key=Origin
luckperms.logs.verbose.hover.cause-key=Cause
luckperms.logs.verbose.hover.context-key=Context
luckperms.logs.verbose.hover.thread-key=Thread
luckperms.logs.verbose.hover.trace-key=Trace
luckperms.logs.verbose.hover.processor-key=Processor
luckperms.logs.verbose.hover.overflow=and {0} more
luckperms.logs.export-prefix=EXPORT
luckperms.commandsystem.available-commands=Use {0} to view available commands
luckperms.commandsystem.command-not-recognised=Command not recognised

View File

@ -69,7 +69,7 @@ public class FabricCalculatorFactory implements CalculatorFactory {
boolean integratedOwner = queryOptions.option(FabricContextManager.INTEGRATED_SERVER_OWNER).orElse(false);
if (integratedOwner && this.plugin.getConfiguration().get(ConfigKeys.FABRIC_INTEGRATED_SERVER_OWNER_BYPASSES_CHECKS)) {
processors.add(new ServerOwnerProcessor());
processors.add(ServerOwnerProcessor.INSTANCE);
}
return new PermissionCalculator(this.plugin, metadata, processors);

View File

@ -25,8 +25,9 @@
package me.lucko.luckperms.fabric.calculator;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import net.luckperms.api.util.Tristate;
@ -34,9 +35,15 @@ import net.luckperms.api.util.Tristate;
* Permission processor which is added to the owner of an Integrated server to
* simply return true if no other processors match.
*/
public class ServerOwnerProcessor extends AbstractPermissionProcessor {
public class ServerOwnerProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
private static final TristateResult TRUE_RESULT = new TristateResult.Factory(ServerOwnerProcessor.class).result(Tristate.TRUE);
public static final ServerOwnerProcessor INSTANCE = new ServerOwnerProcessor();
private ServerOwnerProcessor() {
}
@Override
public TristateResult hasPermission(String permission) {
return TRUE_RESULT;

View File

@ -26,10 +26,10 @@
package me.lucko.luckperms.fabric.listeners;
import me.lucko.fabric.api.permissions.v0.PermissionCheckEvent;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent.Origin;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.fabric.LPFabricPlugin;
import me.lucko.luckperms.fabric.model.MixinUser;
@ -83,7 +83,7 @@ public class PermissionCheckListener {
String name = ((ServerCommandSource) source).getName();
VerboseCheckTarget target = VerboseCheckTarget.internal(name);
this.plugin.getVerboseHandler().offerPermissionCheckEvent(Origin.PLATFORM_PERMISSION_CHECK, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.UNDEFINED);
this.plugin.getVerboseHandler().offerPermissionCheckEvent(CheckOrigin.PLATFORM_API_HAS_PERMISSION, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.UNDEFINED);
this.plugin.getPermissionRegistry().offer(permission);
}

View File

@ -29,7 +29,7 @@ import me.lucko.luckperms.common.cacheddata.type.PermissionCache;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.locale.TranslationManager;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.fabric.context.FabricContextManager;
import me.lucko.luckperms.fabric.event.PlayerChangeWorldCallback;
import me.lucko.luckperms.fabric.model.MixinUser;
@ -133,7 +133,7 @@ public abstract class ServerPlayerEntityMixin implements MixinUser {
}
PermissionCache data = user.getCachedData().getPermissionData(queryOptions);
return data.checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK).result();
return data.checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result();
}

View File

@ -25,9 +25,9 @@
package me.lucko.luckperms.nukkit.calculator;
import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.AbstractSourceBasedProcessor;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.nukkit.LPNukkitPlugin;
import net.luckperms.api.util.Tristate;
@ -40,7 +40,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* Permission Processor for Nukkits "child" permission system.
*/
public class ChildProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
public class ChildProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(ChildProcessor.class);
private final LPNukkitPlugin plugin;
@ -62,10 +62,10 @@ public class ChildProcessor extends AbstractPermissionProcessor implements Permi
@Override
public void refresh() {
Map<String, TristateResult> childPermissions = new HashMap<>();
this.sourceMap.forEach((key, value) -> {
Map<String, Boolean> children = this.plugin.getPermissionMap().getChildPermissions(key, value);
this.sourceMap.forEach((key, node) -> {
Map<String, Boolean> children = this.plugin.getPermissionMap().getChildPermissions(key, node.getValue());
children.forEach((childKey, childValue) -> {
childPermissions.put(childKey, RESULT_FACTORY.result(Tristate.of(childValue), "parent: " + key));
childPermissions.put(childKey, RESULT_FACTORY.resultWithOverride(node, Tristate.of(childValue)));
});
});
this.childPermissions = childPermissions;

View File

@ -0,0 +1,58 @@
/*
* 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.nukkit.calculator;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.nukkit.LPNukkitPlugin;
import net.luckperms.api.util.Tristate;
/**
* Permission Processor for Nukkits "default" permission system.
*/
public class DefaultPermissionMapProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(DefaultPermissionMapProcessor.class);
private final LPNukkitPlugin plugin;
private final boolean isOp;
public DefaultPermissionMapProcessor(LPNukkitPlugin plugin, boolean isOp) {
this.plugin = plugin;
this.isOp = isOp;
}
@Override
public TristateResult hasPermission(String permission) {
Tristate t = this.plugin.getDefaultPermissionMap().lookupDefaultPermission(permission, this.isOp);
if (t != Tristate.UNDEFINED) {
return RESULT_FACTORY.result(t);
}
return TristateResult.UNDEFINED;
}
}

View File

@ -1,87 +0,0 @@
/*
* 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.nukkit.calculator;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.processor.SpongeWildcardProcessor;
import me.lucko.luckperms.common.calculator.processor.WildcardProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.nukkit.LPNukkitPlugin;
import me.lucko.luckperms.nukkit.inject.PermissionDefault;
import net.luckperms.api.util.Tristate;
/**
* Permission Processor for Nukkits "default" permission system.
*/
public class DefaultsProcessor implements PermissionProcessor {
private static final TristateResult.Factory DEFAULT_PERMISSION_MAP_RESULT_FACTORY = new TristateResult.Factory(DefaultsProcessor.class, "default permission map");
private static final TristateResult.Factory PERMISSION_MAP_RESULT_FACTORY = new TristateResult.Factory(DefaultsProcessor.class, "permission map");
private final LPNukkitPlugin plugin;
private final boolean overrideWildcards;
private final boolean isOp;
public DefaultsProcessor(LPNukkitPlugin plugin, boolean overrideWildcards, boolean isOp) {
this.plugin = plugin;
this.overrideWildcards = overrideWildcards;
this.isOp = isOp;
}
private boolean canOverrideWildcard(TristateResult prev) {
return this.overrideWildcards &&
(prev.processorClass() == WildcardProcessor.class || prev.processorClass() == SpongeWildcardProcessor.class) &&
prev.result() == Tristate.TRUE;
}
@Override
public TristateResult hasPermission(TristateResult prev, String permission) {
if (prev != TristateResult.UNDEFINED) {
// Check to see if the result should be overridden
if (canOverrideWildcard(prev)) {
PermissionDefault def = PermissionDefault.fromPermission(this.plugin.getPermissionMap().get(permission));
if (def != null) {
if (def == PermissionDefault.FALSE || this.isOp && def == PermissionDefault.NOT_OP) {
return PERMISSION_MAP_RESULT_FACTORY.result(Tristate.FALSE, "permission map (overriding wildcard): " + prev.cause());
}
}
}
return prev;
}
Tristate t = this.plugin.getDefaultPermissionMap().lookupDefaultPermission(permission, this.isOp);
if (t != Tristate.UNDEFINED) {
return DEFAULT_PERMISSION_MAP_RESULT_FACTORY.result(t);
}
PermissionDefault def = PermissionDefault.fromPermission(this.plugin.getPermissionMap().get(permission));
if (def == null) {
return TristateResult.UNDEFINED;
}
return PERMISSION_MAP_RESULT_FACTORY.result(Tristate.of(def.getValue(this.isOp)));
}
}

View File

@ -52,7 +52,7 @@ public class NukkitCalculatorFactory implements CalculatorFactory {
@Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
List<PermissionProcessor> processors = new ArrayList<>(7);
List<PermissionProcessor> processors = new ArrayList<>(8);
processors.add(new DirectProcessor());
@ -75,7 +75,8 @@ public class NukkitCalculatorFactory implements CalculatorFactory {
boolean op = queryOptions.option(NukkitContextManager.OP_OPTION).orElse(false);
if (metadata.getHolderType() == HolderType.USER && this.plugin.getConfiguration().get(ConfigKeys.APPLY_NUKKIT_DEFAULT_PERMISSIONS)) {
boolean overrideWildcards = this.plugin.getConfiguration().get(ConfigKeys.APPLY_DEFAULT_NEGATIONS_BEFORE_WILDCARDS);
processors.add(new DefaultsProcessor(this.plugin, overrideWildcards, op));
processors.add(new DefaultPermissionMapProcessor(this.plugin, op));
processors.add(new PermissionMapProcessor(this.plugin, overrideWildcards, op));
}
if (op) {

View File

@ -25,8 +25,9 @@
package me.lucko.luckperms.nukkit.calculator;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import net.luckperms.api.util.Tristate;
@ -34,7 +35,7 @@ import net.luckperms.api.util.Tristate;
* Permission Processor which is added for opped users, to simply return true if
* no other processors match.
*/
public final class OpProcessor implements PermissionProcessor {
public final class OpProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
private static final TristateResult TRUE_RESULT = new TristateResult.Factory(OpProcessor.class).result(Tristate.TRUE);
public static final OpProcessor INSTANCE = new OpProcessor();
@ -44,10 +45,7 @@ public final class OpProcessor implements PermissionProcessor {
}
@Override
public TristateResult hasPermission(TristateResult prev, String permission) {
if (prev != TristateResult.UNDEFINED) {
return prev;
}
public TristateResult hasPermission(String permission) {
return TRUE_RESULT;
}
}

View File

@ -0,0 +1,59 @@
/*
* 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.nukkit.calculator;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.AbstractOverrideWildcardProcessor;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.nukkit.LPNukkitPlugin;
import me.lucko.luckperms.nukkit.inject.PermissionDefault;
import net.luckperms.api.util.Tristate;
/**
* Permission Processor for Nukkits "default" permission system.
*/
public class PermissionMapProcessor extends AbstractOverrideWildcardProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(PermissionMapProcessor.class);
private final LPNukkitPlugin plugin;
private final boolean isOp;
public PermissionMapProcessor(LPNukkitPlugin plugin, boolean overrideWildcards, boolean isOp) {
super(overrideWildcards);
this.plugin = plugin;
this.isOp = isOp;
}
@Override
public TristateResult hasPermission(String permission) {
PermissionDefault def = PermissionDefault.fromPermission(this.plugin.getPermissionMap().get(permission));
if (def == null) {
return TristateResult.UNDEFINED;
}
return RESULT_FACTORY.result(Tristate.of(def.getValue(this.isOp)));
}
}

View File

@ -28,14 +28,14 @@ package me.lucko.luckperms.nukkit.inject.permissible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.nukkit.LPNukkitPlugin;
import me.lucko.luckperms.nukkit.calculator.DefaultsProcessor;
import me.lucko.luckperms.nukkit.calculator.OpProcessor;
import me.lucko.luckperms.nukkit.calculator.PermissionMapProcessor;
import me.lucko.luckperms.nukkit.inject.PermissionDefault;
import net.luckperms.api.query.QueryOptions;
@ -144,13 +144,13 @@ public class LuckPermsPermissible extends PermissibleBase {
}
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions();
TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK);
TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET);
if (result.result() == Tristate.UNDEFINED) {
return false;
}
// ignore matches made from looking up in the permission map (replicate nukkit behaviour)
if (result.processorClass() == DefaultsProcessor.class && "permission map".equals(result.cause())) {
if (result.processorClass() == PermissionMapProcessor.class) {
return false;
}
@ -174,7 +174,7 @@ public class LuckPermsPermissible extends PermissibleBase {
}
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions();
return this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK).result().asBoolean();
return this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result().asBoolean();
}
@Override
@ -184,7 +184,7 @@ public class LuckPermsPermissible extends PermissibleBase {
}
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions();
TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission.getName(), PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK);
TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission.getName(), CheckOrigin.PLATFORM_API_HAS_PERMISSION);
// override default op handling using the Permission class we have
if (result.processorClass() == OpProcessor.class && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) {

View File

@ -25,12 +25,12 @@
package me.lucko.luckperms.nukkit.inject.permissible;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import net.luckperms.api.util.Tristate;
@ -68,8 +68,8 @@ public class MonitoredPermissibleBase extends PermissibleBase {
this.initialised = true;
}
private void logCheck(PermissionCheckEvent.Origin origin, String permission, boolean result) {
this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(Tristate.of(result)));
private void logCheck(CheckOrigin origin, String permission, boolean result) {
this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(Tristate.of(result)));
this.plugin.getPermissionRegistry().offer(permission);
}
@ -84,7 +84,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
}
final boolean result = this.delegate.isPermissionSet(permission);
logCheck(PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK, permission, result);
logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, permission, result);
return result;
}
@ -95,7 +95,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
}
final boolean result = this.delegate.isPermissionSet(permission);
logCheck(PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK, permission.getName(), result);
logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, permission.getName(), result);
return result;
}
@ -106,7 +106,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
}
final boolean result = this.delegate.hasPermission(permission);
logCheck(PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK, permission, result);
logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION, permission, result);
return result;
}
@ -117,7 +117,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
}
final boolean result = this.delegate.hasPermission(permission);
logCheck(PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK, permission.getName(), result);
logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION, permission.getName(), result);
return result;
}

View File

@ -80,7 +80,7 @@ public final class SubjectCollectionProxy implements SubjectCollection, ProxiedS
@Override
public @NonNull CompletableFuture<Map<String, Subject>> loadSubjects(@NonNull Set<String> set) {
return this.handle.loadSubjects(set).thenApply(subs -> subs.stream().collect(ImmutableCollectors.toMap(LPSubject::getIdentifier, LPSubject::sponge)));
return this.handle.loadSubjects(set).thenApply(subs -> subs.stream().collect(ImmutableCollectors.toMap(lpSubject -> lpSubject.getIdentifier().getName(), LPSubject::sponge)));
}
@Override

View File

@ -28,6 +28,7 @@ package me.lucko.luckperms.sponge.service.model;
import com.google.common.collect.ImmutableList;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.model.PermissionHolder;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
@ -45,7 +46,7 @@ public interface LPSubject {
LPPermissionService getService();
String getIdentifier();
PermissionHolder.Identifier getIdentifier();
default LPSubjectReference toReference() {
return getService().getReferenceFactory().obtain(this);

View File

@ -79,7 +79,7 @@ public final class SubjectReferenceFactory {
public LPSubjectReference obtain(LPSubject subject) {
Objects.requireNonNull(subject, "subject");
LPSubjectReference reference = obtain(subject.getParentCollection().getIdentifier(), subject.getIdentifier());
LPSubjectReference reference = obtain(subject.getParentCollection().getIdentifier(), subject.getIdentifier().getName());
((CachedSubjectReference) reference).fillCache(subject);
return reference;
}

View File

@ -1,91 +0,0 @@
/*
* 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.sponge.calculator;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.processor.SpongeWildcardProcessor;
import me.lucko.luckperms.common.calculator.processor.WildcardProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubject;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
public abstract class DefaultsProcessor implements PermissionProcessor {
private static final TristateResult.Factory TYPE_DEFAULTS_RESULT_FACTORY = new TristateResult.Factory(DefaultsProcessor.class, "type defaults");
private static final TristateResult.Factory ROOT_DEFAULTS_RESULT_FACTORY = new TristateResult.Factory(DefaultsProcessor.class, "root defaults");
protected final LPPermissionService service;
private final QueryOptions queryOptions;
private final boolean overrideWildcards;
public DefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) {
this.service = service;
this.queryOptions = queryOptions;
this.overrideWildcards = overrideWildcards;
}
protected abstract LPSubject getTypeDefaults();
private boolean canOverrideWildcard(TristateResult prev) {
return this.overrideWildcards &&
(prev.processorClass() == WildcardProcessor.class || prev.processorClass() == SpongeWildcardProcessor.class) &&
prev.result() == Tristate.TRUE;
}
@Override
public TristateResult hasPermission(TristateResult prev, String permission) {
if (prev != TristateResult.UNDEFINED) {
// Check to see if the result should be overridden
if (canOverrideWildcard(prev)) {
Tristate t = getTypeDefaults().getPermissionValue(this.queryOptions, permission);
if (t == Tristate.FALSE) {
return TYPE_DEFAULTS_RESULT_FACTORY.result(Tristate.FALSE, "type defaults (overriding wildcard): " + prev.cause());
}
t = this.service.getRootDefaults().getPermissionValue(this.queryOptions, permission);
if (t == Tristate.FALSE) {
return ROOT_DEFAULTS_RESULT_FACTORY.result(Tristate.FALSE, "root defaults (overriding wildcard): " + prev.cause());
}
}
return prev;
}
Tristate t = getTypeDefaults().getPermissionValue(this.queryOptions, permission);
if (t != Tristate.UNDEFINED) {
return TYPE_DEFAULTS_RESULT_FACTORY.result(t);
}
t = this.service.getRootDefaults().getPermissionValue(this.queryOptions, permission);
if (t != Tristate.UNDEFINED) {
return ROOT_DEFAULTS_RESULT_FACTORY.result(t);
}
return TristateResult.UNDEFINED;
}
}

View File

@ -30,10 +30,10 @@ import me.lucko.luckperms.sponge.service.model.LPSubject;
import net.luckperms.api.query.QueryOptions;
public class FixedDefaultsProcessor extends DefaultsProcessor {
public class FixedTypeDefaultsProcessor extends TypeDefaultsProcessor {
private final LPSubject defaultsSubject;
public FixedDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, LPSubject defaultsSubject, boolean overrideWildcards) {
public FixedTypeDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, LPSubject defaultsSubject, boolean overrideWildcards) {
super(service, queryOptions, overrideWildcards);
this.defaultsSubject = defaultsSubject;
}

View File

@ -31,8 +31,8 @@ import me.lucko.luckperms.sponge.service.model.LPSubject;
import net.luckperms.api.query.QueryOptions;
public class GroupDefaultsProcessor extends DefaultsProcessor implements PermissionProcessor {
public GroupDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) {
public class GroupTypeDefaultsProcessor extends TypeDefaultsProcessor implements PermissionProcessor {
public GroupTypeDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) {
super(service, queryOptions, overrideWildcards);
}

View File

@ -0,0 +1,57 @@
/*
* 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.sponge.calculator;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.AbstractOverrideWildcardProcessor;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
public class RootDefaultsProcessor extends AbstractOverrideWildcardProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(RootDefaultsProcessor.class);
protected final LPPermissionService service;
private final QueryOptions queryOptions;
public RootDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) {
super(overrideWildcards);
this.service = service;
this.queryOptions = queryOptions;
}
@Override
public TristateResult hasPermission(String permission) {
Tristate t = this.service.getRootDefaults().getPermissionValue(this.queryOptions, permission);
if (t != Tristate.UNDEFINED) {
return RESULT_FACTORY.result(t);
}
return TristateResult.UNDEFINED;
}
}

View File

@ -70,10 +70,11 @@ public class SpongeCalculatorFactory implements CalculatorFactory {
if (this.plugin.getConfiguration().get(ConfigKeys.APPLY_SPONGE_DEFAULT_SUBJECTS)) {
boolean overrideWildcards = this.plugin.getConfiguration().get(ConfigKeys.APPLY_DEFAULT_NEGATIONS_BEFORE_WILDCARDS);
if (metadata.getHolderType() == HolderType.USER) {
processors.add(new UserDefaultsProcessor(this.plugin.getService(), queryOptions, overrideWildcards));
processors.add(new UserTypeDefaultsProcessor(this.plugin.getService(), queryOptions, overrideWildcards));
} else if (metadata.getHolderType() == HolderType.GROUP) {
processors.add(new GroupDefaultsProcessor(this.plugin.getService(), queryOptions, overrideWildcards));
processors.add(new GroupTypeDefaultsProcessor(this.plugin.getService(), queryOptions, overrideWildcards));
}
processors.add(new RootDefaultsProcessor(this.plugin.getService(), queryOptions, overrideWildcards));
}
return new PermissionCalculator(this.plugin, metadata, processors);

View File

@ -0,0 +1,60 @@
/*
* 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.sponge.calculator;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.calculator.processor.AbstractOverrideWildcardProcessor;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubject;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
public abstract class TypeDefaultsProcessor extends AbstractOverrideWildcardProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(TypeDefaultsProcessor.class);
protected final LPPermissionService service;
private final QueryOptions queryOptions;
public TypeDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) {
super(overrideWildcards);
this.service = service;
this.queryOptions = queryOptions;
}
protected abstract LPSubject getTypeDefaults();
@Override
public TristateResult hasPermission(String permission) {
Tristate t = getTypeDefaults().getPermissionValue(this.queryOptions, permission);
if (t != Tristate.UNDEFINED) {
return RESULT_FACTORY.result(t);
}
return TristateResult.UNDEFINED;
}
}

View File

@ -31,8 +31,8 @@ import me.lucko.luckperms.sponge.service.model.LPSubject;
import net.luckperms.api.query.QueryOptions;
public class UserDefaultsProcessor extends DefaultsProcessor implements PermissionProcessor {
public UserDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) {
public class UserTypeDefaultsProcessor extends TypeDefaultsProcessor implements PermissionProcessor {
public UserTypeDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) {
super(service, queryOptions, overrideWildcards);
}

View File

@ -66,7 +66,7 @@ public class ParentAdd extends ChildCommand<LPSubjectData> {
if (subjectData.addParent(contextSet, subject.toReference()).join()) {
SpongeCommandUtils.sendPrefixed(sender, "&aAdded parent &b" + subject.getParentCollection().getIdentifier() +
"&a/&b" + subject.getIdentifier() + "&a in context " + SpongeCommandUtils.contextToString(contextSet));
"&a/&b" + subject.getIdentifier().getName() + "&a in context " + SpongeCommandUtils.contextToString(contextSet));
} else {
SpongeCommandUtils.sendPrefixed(sender, "Unable to add parent. Does the Subject already have it added?");
}

View File

@ -66,7 +66,7 @@ public class ParentRemove extends ChildCommand<LPSubjectData> {
if (subjectData.removeParent(contextSet, subject.toReference()).join()) {
SpongeCommandUtils.sendPrefixed(sender, "&aRemoved parent &b" + subject.getParentCollection().getIdentifier() +
"&a/&b" + subject.getIdentifier() + "&a in context " + SpongeCommandUtils.contextToString(contextSet));
"&a/&b" + subject.getIdentifier().getName() + "&a in context " + SpongeCommandUtils.contextToString(contextSet));
} else {
SpongeCommandUtils.sendPrefixed(sender, "Unable to remove parent. Are you sure the Subject has it added?");
}

View File

@ -111,7 +111,7 @@ public class SpongeParentCommand extends Command<Void> {
if (args.size() < 2) {
List<String> subjects = collection.getLoadedSubjects().stream()
.map(LPSubject::getIdentifier)
.map(lpSubject -> lpSubject.getIdentifier().getName())
.collect(Collectors.toList());
if (subjects.size() > 50) {

View File

@ -28,16 +28,18 @@ package me.lucko.luckperms.sponge.service.model.calculated;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator;
import me.lucko.luckperms.common.cacheddata.type.MetaCache;
import me.lucko.luckperms.common.graph.TraversalAlgorithm;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.service.inheritance.SubjectInheritanceGraph;
import me.lucko.luckperms.sponge.service.model.LPSubject;
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
@ -67,9 +69,9 @@ public abstract class CalculatedSubject implements LPSubject {
@Override
public abstract CalculatedSubjectData getTransientSubjectData();
public Map<String, Boolean> getCombinedPermissions(QueryOptions filter) {
Map<String, Boolean> permissions;
Map<String, Boolean> merging;
public Map<String, Node> getCombinedPermissions(QueryOptions filter) {
Map<String, Node> permissions;
Map<String, Node> merging;
switch (getParentCollection().getResolutionOrder()) {
case TRANSIENT_FIRST:
permissions = getTransientSubjectData().resolvePermissions(filter);
@ -83,18 +85,18 @@ public abstract class CalculatedSubject implements LPSubject {
throw new AssertionError();
}
for (Map.Entry<String, Boolean> entry : merging.entrySet()) {
for (Map.Entry<String, Node> entry : merging.entrySet()) {
permissions.putIfAbsent(entry.getKey(), entry.getValue());
}
return permissions;
}
public void resolveAllPermissions(Map<String, Boolean> accumulator, QueryOptions filter) {
public void resolveAllPermissions(Map<String, Node> accumulator, QueryOptions filter) {
SubjectInheritanceGraph graph = new SubjectInheritanceGraph(filter);
Iterable<CalculatedSubject> traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this);
for (CalculatedSubject subject : traversal) {
for (Map.Entry<String, Boolean> entry : subject.getCombinedPermissions(filter).entrySet()) {
for (Map.Entry<String, Node> entry : subject.getCombinedPermissions(filter).entrySet()) {
accumulator.putIfAbsent(entry.getKey(), entry.getValue());
}
}
@ -132,9 +134,9 @@ public abstract class CalculatedSubject implements LPSubject {
return result;
}
public Map<String, String> getCombinedOptions(QueryOptions filter) {
Map<String, String> options;
Map<String, String> merging;
public Map<String, MetaNode> getCombinedOptions(QueryOptions filter) {
Map<String, MetaNode> options;
Map<String, MetaNode> merging;
switch (getParentCollection().getResolutionOrder()) {
case TRANSIENT_FIRST:
options = getTransientSubjectData().resolveOptions(filter);
@ -148,7 +150,7 @@ public abstract class CalculatedSubject implements LPSubject {
throw new AssertionError();
}
for (Map.Entry<String, String> entry : merging.entrySet()) {
for (Map.Entry<String, MetaNode> entry : merging.entrySet()) {
options.putIfAbsent(entry.getKey(), entry.getValue());
}
return options;
@ -160,8 +162,8 @@ public abstract class CalculatedSubject implements LPSubject {
Iterable<CalculatedSubject> traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this);
for (CalculatedSubject subject : traversal) {
for (Map.Entry<String, String> entry : subject.getCombinedOptions(filter).entrySet()) {
result.putIfAbsent(entry.getKey(), entry.getValue());
for (MetaNode entry : subject.getCombinedOptions(filter).values()) {
result.putIfAbsent(entry.getMetaKey(), entry.getMetaValue());
}
}
@ -170,18 +172,20 @@ public abstract class CalculatedSubject implements LPSubject {
public void resolveAllOptions(MetaAccumulator accumulator, QueryOptions filter) {
SubjectInheritanceGraph graph = new SubjectInheritanceGraph(filter);
Iterable<CalculatedSubject> traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this);
for (CalculatedSubject subject : traversal) {
for (Map.Entry<String, String> entry : subject.getCombinedOptions(filter).entrySet()) {
accumulator.accumulateMeta(entry.getKey(), entry.getValue());
for (MetaNode entry : subject.getCombinedOptions(filter).values()) {
accumulator.accumulateNode(entry);
}
}
accumulator.complete();
}
@Override
public Tristate getPermissionValue(QueryOptions options, String permission) {
return this.cachedData.getPermissionData(options).checkPermission(permission, PermissionCheckEvent.Origin.INTERNAL).result();
return this.cachedData.getPermissionData(options).checkPermission(permission, CheckOrigin.INTERNAL).result();
}
@Override
@ -201,7 +205,7 @@ public abstract class CalculatedSubject implements LPSubject {
@Override
public Optional<String> getOption(ImmutableContextSet contexts, String key) {
return Optional.ofNullable(this.cachedData.getMetaData(QueryOptionsImpl.DEFAULT_CONTEXTUAL.toBuilder().context(contexts).build()).getMetaValue(key, MetaCheckEvent.Origin.PLATFORM_API));
return Optional.ofNullable(((MetaCache) this.cachedData.getMetaData(QueryOptionsImpl.DEFAULT_CONTEXTUAL.toBuilder().context(contexts).build())).getMetaValue(key, CheckOrigin.PLATFORM_API).result());
}
@Override

View File

@ -40,11 +40,13 @@ import me.lucko.luckperms.common.metastacking.SimpleMetaStackDefinition;
import me.lucko.luckperms.common.metastacking.StandardStackElements;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
import me.lucko.luckperms.sponge.calculator.FixedDefaultsProcessor;
import me.lucko.luckperms.sponge.calculator.FixedTypeDefaultsProcessor;
import me.lucko.luckperms.sponge.calculator.RootDefaultsProcessor;
import net.luckperms.api.metastacking.DuplicateRemovalFunction;
import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.node.ChatMetaType;
import net.luckperms.api.node.Node;
import net.luckperms.api.query.QueryOptions;
import java.util.ArrayList;
@ -68,7 +70,7 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage
@Override
protected CacheMetadata getMetadataForQueryOptions(QueryOptions queryOptions) {
VerboseCheckTarget target = VerboseCheckTarget.of(this.subject.getParentCollection().getIdentifier(), this.subject.getIdentifier());
VerboseCheckTarget target = VerboseCheckTarget.of(this.subject.getParentCollection().getIdentifier(), this.subject.getIdentifier().getName());
return new CacheMetadata(null, target, queryOptions);
}
@ -88,7 +90,7 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage
}
@Override
protected <M extends Map<String, Boolean>> M resolvePermissions(IntFunction<M> mapFactory, QueryOptions queryOptions) {
protected <M extends Map<String, Node>> M resolvePermissions(IntFunction<M> mapFactory, QueryOptions queryOptions) {
M map = mapFactory.apply(16);
this.subject.resolveAllPermissions(map, queryOptions);
return map;
@ -101,13 +103,14 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage
@Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
List<PermissionProcessor> processors = new ArrayList<>(4);
List<PermissionProcessor> processors = new ArrayList<>(5);
processors.add(new DirectProcessor());
processors.add(new SpongeWildcardProcessor());
processors.add(new WildcardProcessor());
if (!this.subject.getParentCollection().isDefaultsCollection()) {
processors.add(new FixedDefaultsProcessor(this.subject.getService(), queryOptions, this.subject.getDefaults(), true));
processors.add(new FixedTypeDefaultsProcessor(this.subject.getService(), queryOptions, this.subject.getDefaults(), true));
processors.add(new RootDefaultsProcessor(this.subject.getService(), queryOptions, true));
}
return new PermissionCalculator(getPlugin(), metadata, processors);

View File

@ -31,6 +31,9 @@ import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.comparator.ContextSetComparator;
import me.lucko.luckperms.common.model.InheritanceOrigin;
import me.lucko.luckperms.common.node.types.Meta;
import me.lucko.luckperms.common.node.types.Permission;
import me.lucko.luckperms.sponge.service.ProxyFactory;
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubject;
@ -40,6 +43,10 @@ import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
import net.luckperms.api.context.ContextSatisfyMode;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.model.data.DataType;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.node.types.PermissionNode;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
@ -134,21 +141,32 @@ public class CalculatedSubjectData implements LPSubjectData {
return ImmutableMap.copyOf(this.permissions.getOrDefault(contexts, ImmutableMap.of()));
}
public Map<String, Boolean> resolvePermissions(QueryOptions filter) {
public Map<String, Node> resolvePermissions(QueryOptions filter) {
// get relevant entries
SortedMap<ImmutableContextSet, Map<String, Boolean>> sorted = new TreeMap<>(ContextSetComparator.reverse());
SortedMap<ImmutableContextSet, Map<String, Node>> sorted = new TreeMap<>(ContextSetComparator.reverse());
for (Map.Entry<ImmutableContextSet, Map<String, Boolean>> entry : this.permissions.entrySet()) {
if (!filter.satisfies(entry.getKey(), defaultSatisfyMode())) {
continue;
}
sorted.put(entry.getKey(), entry.getValue());
Map<String, Node> nodeMap = new HashMap<>();
entry.getValue().forEach((key, value) -> {
PermissionNode node = Permission.builder()
.permission(key)
.value(value)
.context(entry.getKey())
.withMetadata(InheritanceOriginMetadata.KEY, new InheritanceOrigin(this.parentSubject.getIdentifier()))
.build();
nodeMap.put(key, node);
});
sorted.put(entry.getKey(), nodeMap);
}
// flatten
Map<String, Boolean> result = new HashMap<>();
for (Map<String, Boolean> map : sorted.values()) {
for (Map.Entry<String, Boolean> e : map.entrySet()) {
Map<String, Node> result = new HashMap<>();
for (Map<String, Node> map : sorted.values()) {
for (Map.Entry<String, Node> e : map.entrySet()) {
result.putIfAbsent(e.getKey(), e.getValue());
}
}
@ -288,21 +306,32 @@ public class CalculatedSubjectData implements LPSubjectData {
return ImmutableMap.copyOf(this.options.getOrDefault(contexts, ImmutableMap.of()));
}
public Map<String, String> resolveOptions(QueryOptions filter) {
public Map<String, MetaNode> resolveOptions(QueryOptions filter) {
// get relevant entries
SortedMap<ImmutableContextSet, Map<String, String>> sorted = new TreeMap<>(ContextSetComparator.reverse());
SortedMap<ImmutableContextSet, Map<String, MetaNode>> sorted = new TreeMap<>(ContextSetComparator.reverse());
for (Map.Entry<ImmutableContextSet, Map<String, String>> entry : this.options.entrySet()) {
if (!filter.satisfies(entry.getKey(), defaultSatisfyMode())) {
continue;
}
sorted.put(entry.getKey(), entry.getValue());
Map<String, MetaNode> nodeMap = new HashMap<>();
entry.getValue().forEach((key, value) -> {
MetaNode node = Meta.builder()
.key(key)
.value(value)
.context(entry.getKey())
.withMetadata(InheritanceOriginMetadata.KEY, new InheritanceOrigin(this.parentSubject.getIdentifier()))
.build();
nodeMap.put(key, node);
});
sorted.put(entry.getKey(), nodeMap);
}
// flatten
Map<String, String> result = new HashMap<>();
for (Map<String, String> map : sorted.values()) {
for (Map.Entry<String, String> e : map.entrySet()) {
Map<String, MetaNode> result = new HashMap<>();
for (Map<String, MetaNode> map : sorted.values()) {
for (Map.Entry<String, MetaNode> e : map.entrySet()) {
result.putIfAbsent(e.getKey(), e.getValue());
}
}

View File

@ -30,6 +30,8 @@ import me.lucko.luckperms.sponge.model.SpongeGroup;
import me.lucko.luckperms.sponge.service.model.LPSubject;
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
import net.luckperms.api.model.PermissionHolder;
import org.spongepowered.api.command.CommandSource;
import java.util.Optional;
@ -43,8 +45,8 @@ public class GroupSubject extends PermissionHolderSubject<SpongeGroup> implement
}
@Override
public String getIdentifier() {
return this.parent.getObjectName();
public PermissionHolder.Identifier getIdentifier() {
return this.parent.getIdentifier();
}
@Override

View File

@ -35,8 +35,7 @@ import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.node.types.Inheritance;
import me.lucko.luckperms.common.node.types.Prefix;
import me.lucko.luckperms.common.node.types.Suffix;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.model.SpongeGroup;
import me.lucko.luckperms.sponge.service.LuckPermsService;
@ -113,7 +112,7 @@ public abstract class PermissionHolderSubject<T extends PermissionHolder> implem
@Override
public Tristate getPermissionValue(QueryOptions options, String permission) {
return this.parent.getCachedData().getPermissionData(options).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK).result();
return this.parent.getCachedData().getPermissionData(options).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET).result();
}
@Override
@ -148,20 +147,20 @@ public abstract class PermissionHolderSubject<T extends PermissionHolder> implem
public Optional<String> getOption(ImmutableContextSet contexts, String s) {
MetaCache data = this.parent.getCachedData().getMetaData(this.plugin.getContextManager().formQueryOptions(contexts));
if (s.equalsIgnoreCase(Prefix.NODE_KEY)) {
String prefix = data.getPrefix(MetaCheckEvent.Origin.PLATFORM_API);
String prefix = data.getPrefix(CheckOrigin.PLATFORM_API).result();
if (prefix != null) {
return Optional.of(prefix);
}
}
if (s.equalsIgnoreCase(Suffix.NODE_KEY)) {
String suffix = data.getSuffix(MetaCheckEvent.Origin.PLATFORM_API);
String suffix = data.getSuffix(CheckOrigin.PLATFORM_API).result();
if (suffix != null) {
return Optional.of(suffix);
}
}
String val = data.getMetaValue(s, MetaCheckEvent.Origin.PLATFORM_API);
String val = data.getMetaValue(s, CheckOrigin.PLATFORM_API).result();
if (val != null) {
return Optional.of(val);
}

View File

@ -30,6 +30,8 @@ import me.lucko.luckperms.sponge.model.SpongeUser;
import me.lucko.luckperms.sponge.service.model.LPSubject;
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
import net.luckperms.api.model.PermissionHolder;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
@ -46,8 +48,8 @@ public final class UserSubject extends PermissionHolderSubject<SpongeUser> imple
}
@Override
public String getIdentifier() {
return this.parent.getUniqueId().toString();
public PermissionHolder.Identifier getIdentifier() {
return this.parent.getIdentifier();
}
@Override

View File

@ -26,6 +26,7 @@
package me.lucko.luckperms.sponge.service.model.persisted;
import me.lucko.luckperms.common.cache.BufferedRequest;
import me.lucko.luckperms.common.model.PermissionHolderIdentifier;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.ProxyFactory;
@ -37,6 +38,7 @@ import me.lucko.luckperms.sponge.service.model.calculated.CalculatedSubject;
import me.lucko.luckperms.sponge.service.model.calculated.CalculatedSubjectData;
import me.lucko.luckperms.sponge.service.model.calculated.MonitoredSubjectData;
import net.luckperms.api.model.PermissionHolder;
import net.luckperms.api.model.data.DataType;
import org.spongepowered.api.command.CommandSource;
@ -54,7 +56,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject {
/**
* The subjects identifier
*/
private final String identifier;
private final PermissionHolderIdentifier identifier;
/**
* The parent collection
@ -81,7 +83,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject {
super(service.getPlugin());
this.service = service;
this.parentCollection = parentCollection;
this.identifier = identifier;
this.identifier = new PermissionHolderIdentifier(parentCollection.getIdentifier(), identifier);
this.subjectData = new PersistedSubjectData(this, DataType.NORMAL, service) {
@Override
@ -156,7 +158,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject {
}
@Override
public String getIdentifier() {
public PermissionHolder.Identifier getIdentifier() {
return this.identifier;
}

View File

@ -110,7 +110,7 @@ public class SubjectStorage {
* @throws IOException if the write fails
*/
public void saveToFile(PersistedSubject subject) throws IOException {
Path subjectFile = resolveFile(subject.getParentCollection().getIdentifier(), subject.getIdentifier());
Path subjectFile = resolveFile(subject.getParentCollection().getIdentifier(), subject.getIdentifier().getName());
saveToFile(SubjectDataContainer.copyOf(subject.getSubjectData()), subjectFile);
}

View File

@ -33,10 +33,10 @@ import com.velocitypowered.api.permission.PermissionProvider;
import com.velocitypowered.api.permission.PermissionSubject;
import com.velocitypowered.api.proxy.Player;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.velocity.LPVelocityPlugin;
import me.lucko.luckperms.velocity.service.CompatibilityUtil;
@ -91,7 +91,7 @@ public class MonitoringPermissionCheckListener {
// report result
Tristate result = CompatibilityUtil.convertTristate(setting);
MonitoringPermissionCheckListener.this.plugin.getVerboseHandler().offerPermissionCheckEvent(PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(result));
MonitoringPermissionCheckListener.this.plugin.getVerboseHandler().offerPermissionCheckEvent(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(result));
MonitoringPermissionCheckListener.this.plugin.getPermissionRegistry().offer(permission);
return setting;

View File

@ -34,7 +34,7 @@ import com.velocitypowered.api.proxy.Player;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import org.checkerframework.checker.nullness.qual.NonNull;
@ -57,6 +57,6 @@ public class PlayerPermissionProvider implements PermissionProvider, PermissionF
@Override
public @NonNull Tristate getPermissionValue(@NonNull String permission) {
return CompatibilityUtil.convertTristate(this.user.getCachedData().getPermissionData(this.queryOptionsSupplier.getQueryOptions()).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK).result());
return CompatibilityUtil.convertTristate(this.user.getCachedData().getPermissionData(this.queryOptionsSupplier.getQueryOptions()).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result());
}
}