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. * @param values the values, in the order in which they were accumulated.
* @return the selected value * @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 @Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) { public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
List<PermissionProcessor> processors = new ArrayList<>(7); List<PermissionProcessor> processors = new ArrayList<>(8);
processors.add(new DirectProcessor()); processors.add(new DirectProcessor());
@ -75,7 +75,8 @@ public class BukkitCalculatorFactory implements CalculatorFactory {
boolean op = queryOptions.option(BukkitContextManager.OP_OPTION).orElse(false); boolean op = queryOptions.option(BukkitContextManager.OP_OPTION).orElse(false);
if (metadata.getHolderType() == HolderType.USER && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) { 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); 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) { if (op) {

View File

@ -26,9 +26,9 @@
package me.lucko.luckperms.bukkit.calculator; package me.lucko.luckperms.bukkit.calculator;
import me.lucko.luckperms.bukkit.LPBukkitPlugin; 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.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import net.luckperms.api.util.Tristate; import net.luckperms.api.util.Tristate;
@ -40,7 +40,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
/** /**
* Permission Processor for Bukkits "child" permission system. * 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 static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(ChildProcessor.class);
private final LPBukkitPlugin plugin; private final LPBukkitPlugin plugin;
@ -62,10 +62,10 @@ public class ChildProcessor extends AbstractPermissionProcessor implements Permi
@Override @Override
public void refresh() { public void refresh() {
Map<String, TristateResult> childPermissions = new HashMap<>(); Map<String, TristateResult> childPermissions = new HashMap<>();
this.sourceMap.forEach((key, value) -> { this.sourceMap.forEach((key, node) -> {
Map<String, Boolean> children = this.plugin.getPermissionMap().getChildPermissions(key, value); Map<String, Boolean> children = this.plugin.getPermissionMap().getChildPermissions(key, node.getValue());
children.forEach((childKey, childValue) -> { 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; 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; 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.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import net.luckperms.api.util.Tristate; 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 * Permission Processor which is added for opped users, to simply return true if
* no other processors match. * 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); private static final TristateResult TRUE_RESULT = new TristateResult.Factory(OpProcessor.class).result(Tristate.TRUE);
public static final OpProcessor INSTANCE = new OpProcessor(); public static final OpProcessor INSTANCE = new OpProcessor();
@ -44,10 +45,7 @@ public final class OpProcessor implements PermissionProcessor {
} }
@Override @Override
public TristateResult hasPermission(TristateResult prev, String permission) { public TristateResult hasPermission(String permission) {
if (prev != TristateResult.UNDEFINED) {
return prev;
}
return TRUE_RESULT; 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 com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.bukkit.LPBukkitPlugin; import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.bukkit.calculator.DefaultsProcessor;
import me.lucko.luckperms.bukkit.calculator.OpProcessor; 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.config.ConfigKeys;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache; import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.model.User; 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.query.QueryOptions;
import net.luckperms.api.util.Tristate; import net.luckperms.api.util.Tristate;
@ -143,13 +143,13 @@ public class LuckPermsPermissible extends PermissibleBase {
} }
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); 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) { if (result.result() == Tristate.UNDEFINED) {
return false; return false;
} }
// ignore matches made from looking up in the permission map (replicate bukkit behaviour) // 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; return false;
} }
@ -173,7 +173,7 @@ public class LuckPermsPermissible extends PermissibleBase {
} }
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); 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 @Override
@ -183,7 +183,7 @@ public class LuckPermsPermissible extends PermissibleBase {
} }
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); 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 // override default op handling using the Permission class we have
if (result.processorClass() == OpProcessor.class && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) { 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; 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.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget; import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
import me.lucko.luckperms.common.verbose.VerboseHandler; 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; import net.luckperms.api.util.Tristate;
@ -69,8 +69,8 @@ public class MonitoredPermissibleBase extends PermissibleBase {
this.initialised = true; this.initialised = true;
} }
private void logCheck(PermissionCheckEvent.Origin origin, String permission, boolean result) { private void logCheck(CheckOrigin origin, String permission, boolean result) {
this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(Tristate.of(result))); this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(Tristate.of(result)));
this.plugin.getPermissionRegistry().offer(permission); this.plugin.getPermissionRegistry().offer(permission);
} }
@ -85,7 +85,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
} }
final boolean result = this.delegate.isPermissionSet(permission); 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; return result;
} }
@ -96,7 +96,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
} }
final boolean result = this.delegate.isPermissionSet(permission); 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; return result;
} }
@ -107,7 +107,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
} }
final boolean result = this.delegate.hasPermission(permission); 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; return result;
} }
@ -118,7 +118,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
} }
final boolean result = this.delegate.hasPermission(permission); 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; return result;
} }

View File

@ -30,6 +30,7 @@ import com.google.common.base.Strings;
import me.lucko.luckperms.bukkit.LPBukkitPlugin; import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator; import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator;
import me.lucko.luckperms.common.cacheddata.type.MetaCache; 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.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.model.PermissionHolder;
@ -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.Prefix;
import me.lucko.luckperms.common.node.types.Suffix; import me.lucko.luckperms.common.node.types.Suffix;
import me.lucko.luckperms.common.query.QueryOptionsImpl; 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.DefaultContextKeys;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.context.ImmutableContextSet;
@ -97,7 +98,7 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
PermissionHolder user = this.vaultPermission.lookupUser(uuid); PermissionHolder user = this.vaultPermission.lookupUser(uuid);
QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world); QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world);
MetaCache metaData = user.getCachedData().getMetaData(queryOptions); 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 @Override
@ -107,7 +108,7 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
PermissionHolder user = this.vaultPermission.lookupUser(uuid); PermissionHolder user = this.vaultPermission.lookupUser(uuid);
QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world); QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world);
MetaCache metaData = user.getCachedData().getMetaData(queryOptions); 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 @Override
@ -139,8 +140,8 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
PermissionHolder user = this.vaultPermission.lookupUser(uuid); PermissionHolder user = this.vaultPermission.lookupUser(uuid);
QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world); QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world);
MetaCache metaData = user.getCachedData().getMetaData(queryOptions); MonitoredMetaCache metaData = user.getCachedData().getMetaData(queryOptions);
return metaData.getMetaValue(key, MetaCheckEvent.Origin.THIRD_PARTY_API); return metaData.getMetaValue(key, CheckOrigin.THIRD_PARTY_API).result();
} }
@Override @Override
@ -158,21 +159,21 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
@Override @Override
public String getGroupChatPrefix(String world, String name) { public String getGroupChatPrefix(String world, String name) {
Objects.requireNonNull(name, "name"); Objects.requireNonNull(name, "name");
MetaCache metaData = getGroupMetaCache(name, world); MonitoredMetaCache metaData = getGroupMetaCache(name, world);
if (metaData == null) { if (metaData == null) {
return null; return null;
} }
return Strings.nullToEmpty(metaData.getPrefix(MetaCheckEvent.Origin.THIRD_PARTY_API)); return Strings.nullToEmpty(metaData.getPrefix(CheckOrigin.THIRD_PARTY_API).result());
} }
@Override @Override
public String getGroupChatSuffix(String world, String name) { public String getGroupChatSuffix(String world, String name) {
Objects.requireNonNull(name, "name"); Objects.requireNonNull(name, "name");
MetaCache metaData = getGroupMetaCache(name, world); MonitoredMetaCache metaData = getGroupMetaCache(name, world);
if (metaData == null) { if (metaData == null) {
return null; return null;
} }
return Strings.nullToEmpty(metaData.getSuffix(MetaCheckEvent.Origin.THIRD_PARTY_API)); return Strings.nullToEmpty(metaData.getSuffix(CheckOrigin.THIRD_PARTY_API).result());
} }
@Override @Override
@ -199,11 +200,11 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
public String getGroupMeta(String world, String name, String key) { public String getGroupMeta(String world, String name, String key) {
Objects.requireNonNull(name, "name"); Objects.requireNonNull(name, "name");
Objects.requireNonNull(key, "key"); Objects.requireNonNull(key, "key");
MetaCache metaData = getGroupMetaCache(name, world); MonitoredMetaCache metaData = getGroupMetaCache(name, world);
if (metaData == null) { if (metaData == null) {
return null; return null;
} }
return metaData.getMetaValue(key, MetaCheckEvent.Origin.THIRD_PARTY_API); return metaData.getMetaValue(key, CheckOrigin.THIRD_PARTY_API).result();
} }
@Override @Override
@ -223,7 +224,7 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
return this.plugin.getGroupManager().getByDisplayName(name); return this.plugin.getGroupManager().getByDisplayName(name);
} }
private MetaCache getGroupMetaCache(String name, String world) { private MonitoredMetaCache getGroupMetaCache(String name, String world) {
Group group = getGroup(name); Group group = getGroup(name);
if (group == null) { if (group == null) {
return 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.LPBukkitPlugin;
import me.lucko.luckperms.bukkit.context.BukkitContextManager; 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.cacheddata.type.PermissionCache;
import me.lucko.luckperms.common.calculator.processor.DirectProcessor; 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.config.ConfigKeys;
import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.HolderType; 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.query.QueryOptionsImpl;
import me.lucko.luckperms.common.util.UniqueIdType; import me.lucko.luckperms.common.util.UniqueIdType;
import me.lucko.luckperms.common.util.Uuids; import me.lucko.luckperms.common.util.Uuids;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import net.luckperms.api.context.ContextSet; import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.DefaultContextKeys; import net.luckperms.api.context.DefaultContextKeys;
@ -175,7 +174,7 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
PermissionHolder user = lookupUser(uuid); PermissionHolder user = lookupUser(uuid);
QueryOptions queryOptions = getQueryOptions(uuid, world); QueryOptions queryOptions = getQueryOptions(uuid, world);
PermissionCache permissionData = user.getCachedData().getPermissionData(queryOptions); 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 @Override
@ -211,7 +210,7 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
QueryOptions queryOptions = getQueryOptions(uuid, world); QueryOptions queryOptions = getQueryOptions(uuid, world);
PermissionCache permissionData = user.getCachedData().getPermissionData(queryOptions); 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(); return result.processorClass() == DirectProcessor.class && result.result().asBoolean();
} }
@ -254,8 +253,8 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
} }
QueryOptions queryOptions = getQueryOptions(uuid, world); QueryOptions queryOptions = getQueryOptions(uuid, world);
MetaCache metaData = user.getCachedData().getMetaData(queryOptions); MonitoredMetaCache metaData = user.getCachedData().getMetaData(queryOptions);
String value = metaData.getPrimaryGroup(MetaCheckEvent.Origin.THIRD_PARTY_API); String value = metaData.getPrimaryGroup(CheckOrigin.THIRD_PARTY_API);
if (value == null) { if (value == null) {
return null; return null;
} }
@ -276,7 +275,7 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission {
QueryOptions queryOptions = getQueryOptions(null, world); QueryOptions queryOptions = getQueryOptions(null, world);
PermissionCache permissionData = group.getCachedData().getPermissionData(queryOptions); 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 @Override

View File

@ -27,12 +27,12 @@ package me.lucko.luckperms.bungee.listeners;
import me.lucko.luckperms.bungee.LPBungeePlugin; import me.lucko.luckperms.bungee.LPBungeePlugin;
import me.lucko.luckperms.bungee.event.TristateCheckEvent; 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.config.ConfigKeys;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget; 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.query.QueryOptions;
import net.luckperms.api.util.Tristate; import net.luckperms.api.util.Tristate;
@ -72,7 +72,7 @@ public class BungeePermissionCheckListener implements Listener {
} }
QueryOptions queryOptions = this.plugin.getContextManager().getQueryOptions(player); 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)) { 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 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); 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)) { 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 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()); Tristate result = Tristate.of(e.hasPermission());
VerboseCheckTarget target = VerboseCheckTarget.internal(e.getSender().getName()); 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); this.plugin.getPermissionRegistry().offer(permission);
} }
@ -139,7 +139,7 @@ public class BungeePermissionCheckListener implements Listener {
Tristate result = e.getResult(); Tristate result = e.getResult();
VerboseCheckTarget target = VerboseCheckTarget.internal(e.getSender().getName()); 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); 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.cacheddata.UserCachedDataManager;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.types.Inheritance; 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.DataMutateResult;
import net.luckperms.api.model.data.DataType; import net.luckperms.api.model.data.DataType;
@ -72,7 +72,7 @@ public class ApiUser extends ApiPermissionHolder implements net.luckperms.api.mo
@Override @Override
public @NonNull String getPrimaryGroup() { 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 Objects.requireNonNull(value, "value"); // assert nonnull
return value; 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.cache.LoadingMap;
import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator; 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.cacheddata.type.PermissionCache;
import me.lucko.luckperms.common.calculator.CalculatorFactory; import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.calculator.PermissionCalculator; 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.cacheddata.CachedPermissionData;
import net.luckperms.api.metastacking.MetaStackDefinition; import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.node.ChatMetaType; import net.luckperms.api.node.ChatMetaType;
import net.luckperms.api.node.Node;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
@ -59,7 +60,7 @@ import java.util.function.IntFunction;
public abstract class AbstractCachedDataManager implements CachedDataManager { public abstract class AbstractCachedDataManager implements CachedDataManager {
private final LuckPermsPlugin plugin; private final LuckPermsPlugin plugin;
private final AbstractContainer<PermissionCache, CachedPermissionData> permission; private final AbstractContainer<PermissionCache, CachedPermissionData> permission;
private final AbstractContainer<MetaCache, CachedMetaData> meta; private final AbstractContainer<MonitoredMetaCache, CachedMetaData> meta;
protected AbstractCachedDataManager(LuckPermsPlugin plugin) { protected AbstractCachedDataManager(LuckPermsPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
@ -87,7 +88,7 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
} }
@Override @Override
public @NonNull MetaCache getMetaData(@NonNull QueryOptions queryOptions) { public @NonNull MonitoredMetaCache getMetaData(@NonNull QueryOptions queryOptions) {
return this.meta.get(queryOptions); return this.meta.get(queryOptions);
} }
@ -97,7 +98,7 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
} }
@Override @Override
public @NonNull MetaCache getMetaData() { public @NonNull MonitoredMetaCache getMetaData() {
return getMetaData(getQueryOptions()); return getMetaData(getQueryOptions());
} }
@ -139,7 +140,7 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
* @param <M> the map type * @param <M> the map type
* @return the resolved permissions * @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}. * Resolves the owners meta data for the given {@link QueryOptions}.
@ -153,18 +154,18 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
Objects.requireNonNull(queryOptions, "queryOptions"); Objects.requireNonNull(queryOptions, "queryOptions");
CacheMetadata metadata = getMetadataForQueryOptions(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); return new PermissionCache(queryOptions, metadata, getCalculatorFactory(), sourcePermissions);
} }
private MetaCache calculateMeta(QueryOptions queryOptions) { private MonitoredMetaCache calculateMeta(QueryOptions queryOptions) {
Objects.requireNonNull(queryOptions, "queryOptions"); Objects.requireNonNull(queryOptions, "queryOptions");
CacheMetadata metadata = getMetadataForQueryOptions(queryOptions); CacheMetadata metadata = getMetadataForQueryOptions(queryOptions);
MetaAccumulator accumulator = newAccumulator(queryOptions); MetaAccumulator accumulator = newAccumulator(queryOptions);
resolveMeta(accumulator, queryOptions); resolveMeta(accumulator, queryOptions);
return new MetaCache(this.plugin, queryOptions, metadata, accumulator); return new MonitoredMetaCache(this.plugin, queryOptions, metadata, accumulator);
} }
@Override @Override

View File

@ -32,6 +32,7 @@ import me.lucko.luckperms.common.model.PermissionHolder;
import net.luckperms.api.metastacking.MetaStackDefinition; import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.node.ChatMetaType; import net.luckperms.api.node.ChatMetaType;
import net.luckperms.api.node.Node;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import java.util.Map; import java.util.Map;
@ -75,7 +76,7 @@ public abstract class HolderCachedDataManager<T extends PermissionHolder> extend
} }
@Override @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)); 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. * 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.PermissionCalculator;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor; import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
import net.luckperms.api.node.Node;
import net.luckperms.api.util.Tristate; 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. * 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); /** The result */
public static final TristateResult UNDEFINED = new TristateResult(Tristate.UNDEFINED, null, null);
public static TristateResult of(Tristate result) {
return NULL_FACTORY.result(result);
}
private final Tristate 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 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.result = result;
this.node = node;
this.processorClass = processorClass; this.processorClass = processorClass;
this.cause = cause;
} }
public Tristate result() { @Override
public @NonNull Tristate result() {
return this.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; return this.processorClass;
} }
public String cause() { public @Nullable String processorClassFriendly() {
return this.cause; 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 @Override
public String toString() { public String toString() {
return "TristateResult(" + return "TristateResult(" +
"result=" + this.result + ", " + "result=" + this.result + ", " +
"node=" + this.node + ", " +
"processorClass=" + this.processorClass + ", " + "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 { public static final class Factory {
private final Class<? extends PermissionProcessor> processorClass; 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) { public Factory(Class<? extends PermissionProcessor> processorClass) {
this(processorClass, null); this.processorClass = processorClass;
} }
public TristateResult result(Tristate result) { public TristateResult result(Tristate result) {
switch (result) { switch (result) {
case TRUE: case TRUE:
return this.trueResult;
case FALSE: case FALSE:
return this.falseResult; return new TristateResult(result, null, this.processorClass);
case UNDEFINED: case UNDEFINED:
return UNDEFINED; return UNDEFINED;
default: default:
@ -102,11 +134,12 @@ public final class TristateResult {
} }
} }
public TristateResult result(Tristate result, String cause) { public TristateResult result(@NonNull Node node) {
if (result == Tristate.UNDEFINED) { return new TristateResult(Tristate.of(node.getValue()), node, this.processorClass);
return UNDEFINED; }
}
return new TristateResult(result, this.processorClass, cause); 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.ArrayListMultimap;
import com.google.common.collect.ListMultimap; 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.config.ConfigKeys;
import me.lucko.luckperms.common.node.types.Weight; import me.lucko.luckperms.common.node.types.Weight;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; 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.metastacking.MetaStackDefinition;
import net.luckperms.api.node.ChatMetaType; import net.luckperms.api.node.ChatMetaType;
import net.luckperms.api.node.Node; 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.MetaNode;
import net.luckperms.api.node.types.PrefixNode; import net.luckperms.api.node.types.PrefixNode;
import net.luckperms.api.node.types.SuffixNode; 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 AtomicReference<State> state = new AtomicReference<>(State.ACCUMULATING);
private final ListMultimap<String, String> meta; private final ListMultimap<String, StringResult<MetaNode>> meta;
private final SortedMap<Integer, String> prefixes; private final SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> prefixes;
private final SortedMap<Integer, String> suffixes; private final SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> suffixes;
private int weight = 0; private int weight = 0;
private String primaryGroup; private String primaryGroup;
@ -119,10 +121,10 @@ public class MetaAccumulator {
// perform final changes // perform final changes
if (!this.meta.containsKey(Weight.NODE_KEY) && this.weight != 0) { 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")) { 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 this.seenNodeKeys = null; // free up for GC
@ -146,27 +148,22 @@ public class MetaAccumulator {
if (n instanceof MetaNode) { if (n instanceof MetaNode) {
MetaNode mn = (MetaNode) n; MetaNode mn = (MetaNode) n;
this.meta.put(mn.getMetaKey(), mn.getMetaValue()); this.meta.put(mn.getMetaKey(), StringResult.of(mn));
} }
if (n instanceof PrefixNode) { if (n instanceof PrefixNode) {
PrefixNode pn = (PrefixNode) n; PrefixNode pn = (PrefixNode) n;
this.prefixes.putIfAbsent(pn.getPriority(), pn.getMetaValue()); this.prefixes.putIfAbsent(pn.getPriority(), StringResult.of(pn));
this.prefixAccumulator.offer(pn); this.prefixAccumulator.offer(pn);
} }
if (n instanceof SuffixNode) { if (n instanceof SuffixNode) {
SuffixNode pn = (SuffixNode) n; SuffixNode pn = (SuffixNode) n;
this.suffixes.putIfAbsent(pn.getPriority(), pn.getMetaValue()); this.suffixes.putIfAbsent(pn.getPriority(), StringResult.of(pn));
this.suffixAccumulator.offer(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) { public void accumulateWeight(int weight) {
ensureState(State.ACCUMULATING); ensureState(State.ACCUMULATING);
this.weight = Math.max(this.weight, weight); this.weight = Math.max(this.weight, weight);
@ -179,22 +176,22 @@ public class MetaAccumulator {
// read methods // read methods
public ListMultimap<String, String> getMeta() { public ListMultimap<String, StringResult<MetaNode>> getMeta() {
ensureState(State.COMPLETE); ensureState(State.COMPLETE);
return this.meta; return this.meta;
} }
public Map<Integer, String> getChatMeta(ChatMetaType type) { public Map<Integer, StringResult<ChatMetaNode<?, ?>>> getChatMeta(ChatMetaType type) {
ensureState(State.COMPLETE); ensureState(State.COMPLETE);
return type == ChatMetaType.PREFIX ? this.prefixes : this.suffixes; return type == ChatMetaType.PREFIX ? this.prefixes : this.suffixes;
} }
public SortedMap<Integer, String> getPrefixes() { public SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> getPrefixes() {
ensureState(State.COMPLETE); ensureState(State.COMPLETE);
return this.prefixes; return this.prefixes;
} }
public SortedMap<Integer, String> getSuffixes() { public SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> getSuffixes() {
ensureState(State.COMPLETE); ensureState(State.COMPLETE);
return this.suffixes; return this.suffixes;
} }
@ -219,14 +216,14 @@ public class MetaAccumulator {
return this.suffixDefinition; return this.suffixDefinition;
} }
public String getPrefix() { public StringResult<ChatMetaNode<?, ?>> getPrefix() {
ensureState(State.COMPLETE); ensureState(State.COMPLETE);
return this.prefixAccumulator.toFormattedString(); return this.prefixAccumulator.toResult();
} }
public String getSuffix() { public StringResult<ChatMetaNode<?, ?>> getSuffix() {
ensureState(State.COMPLETE); ensureState(State.COMPLETE);
return this.suffixAccumulator.toFormattedString(); return this.suffixAccumulator.toResult();
} }
@Override @Override

View File

@ -26,102 +26,196 @@
package me.lucko.luckperms.common.cacheddata.type; package me.lucko.luckperms.common.cacheddata.type;
import com.google.common.collect.ForwardingMap; 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.cacheddata.UsageTracked;
import me.lucko.luckperms.common.node.types.Prefix; import me.lucko.luckperms.common.cacheddata.result.StringResult;
import me.lucko.luckperms.common.node.types.Suffix; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; 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.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.QueryOptions;
import net.luckperms.api.query.meta.MetaValueSelector;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.SortedMap;
/** /**
* Holds cached meta for a given context * 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; private final LuckPermsPlugin plugin;
/** The metadata for this cache */ /** The query options this container is holding data for */
private final CacheMetadata metadata; private final QueryOptions queryOptions;
public MetaCache(LuckPermsPlugin plugin, QueryOptions queryOptions, CacheMetadata metadata, MetaAccumulator sourceMeta) { /* The data */
super(plugin, queryOptions, sourceMeta); 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.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 @Override
public String getMetaValue(String key, MetaCheckEvent.Origin origin) { public final @Nullable String getMetaValue(@NonNull String key) {
String value = super.getMetaValue(key, origin); return getMetaValue(key, CheckOrigin.LUCKPERMS_API).result();
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), key, String.valueOf(value)); }
return value;
public @NonNull StringResult<ChatMetaNode<?,?>> getPrefix(CheckOrigin origin) {
return this.prefix;
} }
@Override @Override
public String getPrefix(MetaCheckEvent.Origin origin) { public final @Nullable String getPrefix() {
String value = super.getPrefix(origin); return getPrefix(CheckOrigin.LUCKPERMS_API).result();
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Prefix.NODE_KEY, String.valueOf(value)); }
return value;
public @NonNull StringResult<ChatMetaNode<?,?>> getSuffix(CheckOrigin origin) {
return this.suffix;
} }
@Override @Override
public String getSuffix(MetaCheckEvent.Origin origin) { public final @Nullable String getSuffix() {
String value = super.getSuffix(origin); return getSuffix(CheckOrigin.LUCKPERMS_API).result();
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Suffix.NODE_KEY, String.valueOf(value)); }
return value;
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 @Override
public Map<String, List<String>> getMeta(MetaCheckEvent.Origin origin) { public final @NonNull Map<String, List<String>> getMeta() {
return new MonitoredMetaMap(super.getMeta(origin), origin); return getMeta(CheckOrigin.LUCKPERMS_API);
} }
@Override @Override
public int getWeight(MetaCheckEvent.Origin origin) { public @NonNull SortedMap<Integer, String> getPrefixes() {
int value = super.getWeight(origin); return Maps.transformValues(this.prefixes, StringResult::result);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), "weight", String.valueOf(value));
return value;
} }
@Override @Override
public @Nullable String getPrimaryGroup(MetaCheckEvent.Origin origin) { public @NonNull SortedMap<Integer, String> getSuffixes() {
String value = super.getPrimaryGroup(origin); return Maps.transformValues(this.suffixes, StringResult::result);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), "primarygroup", String.valueOf(value));
return value;
} }
private final class MonitoredMetaMap extends ForwardingMap<String, List<String>> { public int getWeight(CheckOrigin origin) {
private final Map<String, List<String>> delegate; return this.weight;
private final MetaCheckEvent.Origin origin; }
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.delegate = delegate;
this.origin = origin;
} }
@Override @Override
protected Map<String, List<String>> delegate() { protected Map<String, List<StringResult<MetaNode>>> delegate() {
return this.delegate; return this.delegate;
} }
@Override @Override
public List<String> get(Object k) { public List<StringResult<MetaNode>> get(Object k) {
if (k == null) { if (k == null) {
return null; return null;
} }
String key = (String) k; String key = (String) k;
List<String> values = super.get(key); return super.get(key.toLowerCase(Locale.ROOT));
MetaCache.this.plugin.getVerboseHandler().offerMetaCheckEvent(this.origin, MetaCache.this.metadata.getVerboseCheckInfo(), MetaCache.this.metadata.getQueryOptions(), key, String.valueOf(values));
return values;
} }
} }

View File

@ -25,6 +25,8 @@
package me.lucko.luckperms.common.cacheddata.type; 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.MetaStackDefinition;
import net.luckperms.api.metastacking.MetaStackElement; import net.luckperms.api.metastacking.MetaStackElement;
import net.luckperms.api.node.ChatMetaType; import net.luckperms.api.node.ChatMetaType;
@ -36,6 +38,8 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class MetaStackAccumulator { public class MetaStackAccumulator {
private final MetaStackDefinition definition; 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() { public String toFormattedString() {
List<String> elements = new LinkedList<>(); List<String> elements = new LinkedList<>();
for (Entry entry : this.entries) { for (Entry entry : this.entries) {
@ -94,6 +105,35 @@ public class MetaStackAccumulator {
return sb.toString(); 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 static final class Entry {
private final MetaStackElement element; private final MetaStackElement element;
private final ChatMetaType type; 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; 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.CacheMetadata;
import me.lucko.luckperms.common.cacheddata.UsageTracked; 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.CalculatorFactory;
import me.lucko.luckperms.common.calculator.PermissionCalculator; import me.lucko.luckperms.common.calculator.PermissionCalculator;
import me.lucko.luckperms.common.calculator.result.TristateResult; import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import net.luckperms.api.cacheddata.CachedPermissionData; import net.luckperms.api.cacheddata.CachedPermissionData;
import net.luckperms.api.node.Node;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate; import net.luckperms.api.util.Tristate;
@ -55,12 +58,12 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat
/** /**
* The raw set of permission strings. * 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. * 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; 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.queryOptions = queryOptions;
this.permissions = sourcePermissions; 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 = calculatorFactory.build(queryOptions, metadata);
this.calculator.setSourcePermissions(this.permissions); this.calculator.setSourcePermissions(this.permissions);
@ -89,10 +92,10 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat
@Override @Override
public @NonNull Map<String, Boolean> getPermissionMap() { 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) { if (permission == null) {
throw new NullPointerException("permission"); throw new NullPointerException("permission");
} }
@ -101,7 +104,7 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat
@Override @Override
public @NonNull Tristate checkPermission(@NonNull String permission) { public @NonNull Tristate checkPermission(@NonNull String permission) {
return checkPermission(permission, PermissionCheckEvent.Origin.LUCKPERMS_API).result(); return checkPermission(permission, CheckOrigin.LUCKPERMS_API).result();
} }
@Override @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; package me.lucko.luckperms.common.cacheddata.type;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.query.meta.MetaValueSelector; import net.luckperms.api.query.meta.MetaValueSelector;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
@ -43,7 +44,7 @@ public class SimpleMetaValueSelector implements MetaValueSelector {
} }
@Override @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()) { switch (values.size()) {
case 0: case 0:
throw new IllegalArgumentException("values is empty"); throw new IllegalArgumentException("values is empty");
@ -57,7 +58,7 @@ public class SimpleMetaValueSelector implements MetaValueSelector {
public enum Strategy { public enum Strategy {
INHERITANCE { INHERITANCE {
@Override @Override
public String select(List<String> values) { public MetaNode select(List<MetaNode> values) {
return values.get(0); return values.get(0);
} }
}, },
@ -65,7 +66,7 @@ public class SimpleMetaValueSelector implements MetaValueSelector {
private final DoubleSelectionPredicate selection = (value, current) -> value > current; private final DoubleSelectionPredicate selection = (value, current) -> value > current;
@Override @Override
public String select(List<String> values) { public MetaNode select(List<MetaNode> values) {
return selectNumber(values, this.selection); return selectNumber(values, this.selection);
} }
}, },
@ -73,12 +74,12 @@ public class SimpleMetaValueSelector implements MetaValueSelector {
private final DoubleSelectionPredicate selection = (value, current) -> value < current; private final DoubleSelectionPredicate selection = (value, current) -> value < current;
@Override @Override
public String select(List<String> values) { public MetaNode select(List<MetaNode> values) {
return selectNumber(values, this.selection); 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) { public static Strategy parse(String s) {
try { try {
@ -94,15 +95,16 @@ public class SimpleMetaValueSelector implements MetaValueSelector {
boolean shouldSelect(double value, double current); 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; double current = 0;
String selected = null; MetaNode selected = null;
for (String value : values) { for (MetaNode node : values) {
String value = node.getMetaValue();
try { try {
double parse = Double.parseDouble(value); double parse = Double.parseDouble(value);
if (selected == null || selection.shouldSelect(parse, current)) { if (selected == null || selection.shouldSelect(parse, current)) {
selected = value; selected = node;
current = parse; current = parse;
} }
} catch (NumberFormatException e) { } 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.cache.LoadingMap;
import me.lucko.luckperms.common.cacheddata.CacheMetadata; 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.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; 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; 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 * @param origin marks where this check originated from
* @return the result * @return the result
*/ */
public TristateResult checkPermission(String permission, PermissionCheckEvent.Origin origin) { public TristateResult checkPermission(String permission, CheckOrigin origin) {
// get the result // get the result
TristateResult result = this.lookupCache.get(permission); TristateResult result = this.lookupCache.get(permission);
@ -106,7 +108,7 @@ public class PermissionCalculator implements Function<String, TristateResult> {
* *
* @param sourceMap the source map * @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) { for (PermissionProcessor processor : this.processors) {
processor.setSource(sourceMap); processor.setSource(sourceMap);
processor.refresh(); 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; package me.lucko.luckperms.common.calculator.processor;
import me.lucko.luckperms.common.calculator.result.TristateResult; import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import java.util.Collections;
import java.util.Map;
/**
* 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 { public abstract class AbstractPermissionProcessor implements PermissionProcessor {
protected Map<String, Boolean> sourceMap = Collections.emptyMap();
@Override @Override
public void setSource(Map<String, Boolean> sourceMap) { public final TristateResult hasPermission(TristateResult prev, String permission) {
this.sourceMap = sourceMap;
}
@Override
public TristateResult hasPermission(TristateResult prev, String permission) {
if (prev != TristateResult.UNDEFINED) { if (prev != TristateResult.UNDEFINED) {
return prev; return hasPermissionOverride(prev, permission);
} }
return hasPermission(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; 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 AbstractSourceBasedProcessor implements PermissionProcessor {
public class DirectProcessor extends AbstractPermissionProcessor implements PermissionProcessor {
private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(DirectProcessor.class); private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(DirectProcessor.class);
@Override @Override
public TristateResult hasPermission(String permission) { 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; 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.PermissionCalculator;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import net.luckperms.api.node.Node;
import java.util.Map; import java.util.Map;
@ -52,7 +54,7 @@ public interface PermissionProcessor {
* *
* @param sourceMap the source map * @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.ImmutableList;
import com.google.common.collect.Maps; 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 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.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern; 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 static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(RegexProcessor.class);
private List<Map.Entry<Pattern, TristateResult>> regexPermissions = Collections.emptyList(); private List<Map.Entry<Pattern, TristateResult>> regexPermissions = Collections.emptyList();
@ -56,7 +56,7 @@ public class RegexProcessor extends AbstractPermissionProcessor implements Permi
@Override @Override
public void refresh() { public void refresh() {
ImmutableList.Builder<Map.Entry<Pattern, TristateResult>> builder = ImmutableList.builder(); 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()); RegexPermission.Builder regexPerm = RegexPermission.parse(e.getKey());
if (regexPerm == null) { if (regexPerm == null) {
continue; continue;
@ -67,7 +67,7 @@ public class RegexProcessor extends AbstractPermissionProcessor implements Permi
continue; 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)); builder.add(Maps.immutableEntry(pattern, value));
} }
this.regexPermissions = builder.build(); this.regexPermissions = builder.build();

View File

@ -25,12 +25,12 @@
package me.lucko.luckperms.common.calculator.processor; 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 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); private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(SpongeWildcardProcessor.class);
@Override @Override
@ -45,9 +45,9 @@ public class SpongeWildcardProcessor extends AbstractPermissionProcessor impleme
node = node.substring(0, endIndex); node = node.substring(0, endIndex);
if (!node.isEmpty()) { if (!node.isEmpty()) {
Tristate t = Tristate.of(this.sourceMap.get(node)); Node n = this.sourceMap.get(node);
if (t != Tristate.UNDEFINED) { if (n != null) {
return RESULT_FACTORY.result(t, "match: " + node); 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 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 me.lucko.luckperms.common.node.AbstractNode;
import net.luckperms.api.node.Node;
import net.luckperms.api.util.Tristate; import net.luckperms.api.util.Tristate;
import java.util.Collections; import java.util.Collections;
import java.util.Map; 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); private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(WildcardProcessor.class);
public static final String WILDCARD_SUFFIX = ".*"; public static final String WILDCARD_SUFFIX = ".*";
@ -78,22 +79,22 @@ public class WildcardProcessor extends AbstractPermissionProcessor implements Pe
@Override @Override
public void refresh() { public void refresh() {
ImmutableMap.Builder<String, TristateResult> builder = ImmutableMap.builder(); 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(); String key = e.getKey();
if (!key.endsWith(WILDCARD_SUFFIX) || key.length() <= 2) { if (!key.endsWith(WILDCARD_SUFFIX) || key.length() <= 2) {
continue; continue;
} }
key = key.substring(0, key.length() - 2); 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); builder.put(key, value);
} }
this.wildcardPermissions = builder.build(); this.wildcardPermissions = builder.build();
Tristate state = Tristate.of(this.sourceMap.get(ROOT_WILDCARD)); Node rootWildcard = this.sourceMap.get(ROOT_WILDCARD);
if (state == Tristate.UNDEFINED) { if (rootWildcard == null) {
state = Tristate.of(this.sourceMap.get(ROOT_WILDCARD_WITH_QUOTES)); 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; 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.cacheddata.type.PermissionCache;
import me.lucko.luckperms.common.calculator.processor.DirectProcessor; 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.config.ConfigKeys;
import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.HolderType; 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.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.sender.Sender; 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.Context;
import net.luckperms.api.context.ContextSet; 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()); 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; return result.result() != Tristate.TRUE || result.processorClass() != DirectProcessor.class;
} }

View File

@ -25,8 +25,8 @@
package me.lucko.luckperms.common.commands.generic.permission; 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.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.CommandException;
import me.lucko.luckperms.common.command.abstraction.GenericChildCommand; import me.lucko.luckperms.common.command.abstraction.GenericChildCommand;
import me.lucko.luckperms.common.command.access.ArgumentPermissions; 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.query.QueryOptionsImpl;
import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Predicates; 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.kyori.adventure.text.Component;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.context.ImmutableContextSet;
@ -123,29 +123,13 @@ public class PermissionCheck extends GenericChildCommand {
// perform a "real" check // perform a "real" check
QueryOptions queryOptions = target.getQueryOptions(); 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(); Tristate result = checkResult.result();
String processor; String processor = checkResult.processorClassFriendly();
String cause; Node cause = checkResult.node();
ImmutableContextSet context = queryOptions.context(); 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 // send results
Message.PERMISSION_CHECK_RESULT.send(sender, node, result, processor, cause, context); Message.PERMISSION_CHECK_RESULT.send(sender, node, result, processor, cause, context);
} }

View File

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

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.user; 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.abstraction.ChildCommand;
import me.lucko.luckperms.common.command.access.ArgumentPermissions; import me.lucko.luckperms.common.command.access.ArgumentPermissions;
import me.lucko.luckperms.common.command.access.CommandPermission; 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.sender.Sender;
import me.lucko.luckperms.common.util.Predicates; import me.lucko.luckperms.common.util.Predicates;
import me.lucko.luckperms.common.util.UniqueIdType; 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.context.ContextSet;
import net.luckperms.api.node.Node; import net.luckperms.api.node.Node;
@ -100,11 +100,11 @@ public class UserInfo extends ChildCommand<User> {
} }
ContextSet contextSet = queryOptions.context(); ContextSet contextSet = queryOptions.context();
MetaCache data = target.getCachedData().getMetaData(queryOptions); MonitoredMetaCache data = target.getCachedData().getMetaData(queryOptions);
String prefix = data.getPrefix(MetaCheckEvent.Origin.INTERNAL); String prefix = data.getPrefix(CheckOrigin.INTERNAL).result();
String suffix = data.getSuffix(MetaCheckEvent.Origin.INTERNAL); String suffix = data.getSuffix(CheckOrigin.INTERNAL).result();
String primaryGroup = data.getPrimaryGroup(MetaCheckEvent.Origin.INTERNAL); String primaryGroup = data.getPrimaryGroup(CheckOrigin.INTERNAL);
Map<String, List<String>> meta = data.getMeta(MetaCheckEvent.Origin.INTERNAL); Map<String, List<String>> meta = data.getMeta(CheckOrigin.INTERNAL);
Message.USER_INFO_CONTEXTUAL_DATA.send(sender, active, contextSet, prefix, suffix, primaryGroup, meta); 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)) .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() Args1<String> EXPORT_LOG = msg -> prefixed(text()
// "&3EXPORT &3&l> &f{}" // "&3EXPORT &3&l> &f{}"
.append(translatable("luckperms.logs.export-prefix", DARK_AQUA)) .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: // &aPermission check for &b{}&a:
// &3Result: {} // &3Result: {}
// &3Processor: &f{} // &3Processor: &f{}
@ -1867,10 +1969,22 @@ public interface Message {
.append(translatable("luckperms.command.generic.permission.check.result.cause-key")) .append(translatable("luckperms.command.generic.permission.check.result.cause-key"))
.append(text(": ")) .append(text(": "))
.apply(builder -> { .apply(builder -> {
if (cause == null) { if (causeNode == null) {
builder.append(translatable("luckperms.command.misc.none", AQUA)); builder.append(translatable("luckperms.command.misc.none", AQUA));
} else { } 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() prefixed(text()

View File

@ -354,19 +354,19 @@ public abstract class PermissionHolder {
return (List) inheritanceTree; 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); List<Node> entries = resolveInheritedNodes(queryOptions);
M map = mapFactory.apply(entries.size()); M map = mapFactory.apply(entries.size());
processExportedPermissions(map, entries, convertToLowercase, resolveShorthand); processExportedPermissions(map, entries, convertToLowercase, resolveShorthand);
return map; 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) { for (Node node : entries) {
if (convertToLowercase) { if (convertToLowercase) {
accumulator.putIfAbsent(node.getKey().toLowerCase(Locale.ROOT), node.getValue()); accumulator.putIfAbsent(node.getKey().toLowerCase(Locale.ROOT), node);
} else { } 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(); Collection<String> shorthand = node.resolveShorthand();
for (String s : shorthand) { for (String s : shorthand) {
if (convertToLowercase) { if (convertToLowercase) {
accumulator.putIfAbsent(s.toLowerCase(Locale.ROOT), node.getValue()); accumulator.putIfAbsent(s.toLowerCase(Locale.ROOT), node);
} else { } 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; this.name = name;
} }
public PermissionHolderIdentifier(String type, String name) {
this.type = type;
this.name = name;
}
@Override @Override
public @NonNull String getName() { public @NonNull String getName() {
return this.name; 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.model.manager.group.GroupManager;
import me.lucko.luckperms.common.node.types.Inheritance; import me.lucko.luckperms.common.node.types.Inheritance;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; 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.model.data.DataType;
import net.luckperms.api.node.Node; 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 // 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")) { 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; boolean memberOfPrimaryGroup = false;
for (InheritanceNode node : globalGroups) { 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.Node;
import net.luckperms.api.node.NodeBuilder; import net.luckperms.api.node.NodeBuilder;
import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata;
import java.time.Instant; import java.time.Instant;
import java.util.Collection; 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) { public static JsonArray serializeNodes(Collection<Node> nodes) {
JsonArray arr = new JsonArray(); JsonArray arr = new JsonArray();
for (Node node : nodes) { for (Node node : nodes) {
JsonObject attributes = new JsonObject(); arr.add(serializeNode(node, false));
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);
} }
return arr; 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) { public static Set<Node> deserializeNodes(JsonArray arr) {
Set<Node> nodes = new HashSet<>(); Set<Node> nodes = new HashSet<>();
for (JsonElement ent : arr) { for (JsonElement ent : arr) {
JsonObject attributes = ent.getAsJsonObject(); Node node = deserializeNode(ent);
if (node != null) {
String key = attributes.get("key").getAsString(); nodes.add(node);
if (key.isEmpty()) {
continue; // 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")));
}
nodes.add(builder.build());
} }
return nodes; 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.sender.Sender;
import me.lucko.luckperms.common.util.gson.GsonProvider; import me.lucko.luckperms.common.util.gson.GsonProvider;
import me.lucko.luckperms.common.util.gson.JObject; 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.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -161,7 +161,7 @@ public class TreeView {
checks = new JObject(); checks = new JObject();
for (Map.Entry<Integer, String> node : this.view.getNodeEndings()) { for (Map.Entry<Integer, String> node : this.view.getNodeEndings()) {
String permission = prefix + node.getValue(); 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 { } else {
checks = null; checks = null;

View File

@ -25,10 +25,12 @@
package me.lucko.luckperms.common.verbose; 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.SchedulerAdapter;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerTask; import me.lucko.luckperms.common.plugin.scheduler.SchedulerTask;
import me.lucko.luckperms.common.sender.Sender; 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.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.VerboseEvent; 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 permission the permission which was checked for
* @param result the result of the permission check * @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 // don't bother even processing the check if there are no listeners registered
if (!this.listening) { if (!this.listening) {
return; return;
@ -100,7 +102,7 @@ public class VerboseHandler implements AutoCloseable {
* @param key the meta key which was checked for * @param key the meta key which was checked for
* @param result the result of the meta check * @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 // don't bother even processing the check if there are no listeners registered
if (!this.listening) { if (!this.listening) {
return; return;

View File

@ -27,7 +27,8 @@ package me.lucko.luckperms.common.verbose;
import com.google.gson.JsonObject; 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.AbstractHttpClient;
import me.lucko.luckperms.common.http.BytebinClient; import me.lucko.luckperms.common.http.BytebinClient;
import me.lucko.luckperms.common.http.UnsuccessfulRequestException; 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.GsonProvider;
import me.lucko.luckperms.common.util.gson.JArray; import me.lucko.luckperms.common.util.gson.JArray;
import me.lucko.luckperms.common.util.gson.JObject; 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.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.VerboseEvent; 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.Component;
import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.event.HoverEvent; 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 net.luckperms.api.query.QueryMode;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -150,28 +153,6 @@ public class VerboseListener {
} }
private void sendNotification(VerboseEvent event) { 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 // form a text component from the check trace
Component component; Component component;
if (event instanceof PermissionCheckEvent) { if (event instanceof PermissionCheckEvent) {
@ -186,69 +167,52 @@ public class VerboseListener {
component = Message.VERBOSE_LOG_META.build( component = Message.VERBOSE_LOG_META.build(
metaEvent.getCheckTarget().describe(), metaEvent.getCheckTarget().describe(),
metaEvent.getKey(), metaEvent.getKey(),
metaEvent.getResult() String.valueOf(metaEvent.getResult().result())
); );
} else { } else {
throw new IllegalArgumentException("Unknown event type: " + event); 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 // build the hover text
List<ComponentLike> hover = new ArrayList<>(); List<ComponentLike> hover = new ArrayList<>();
if (event instanceof PermissionCheckEvent) { hover.add(Message.VERBOSE_LOG_HOVER_TYPE.build(event.getType().toString()));
PermissionCheckEvent permissionEvent = (PermissionCheckEvent) event; hover.add(Message.VERBOSE_LOG_HOVER_ORIGIN.build(event.getOrigin().name()));
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))
);
TristateResult result = permissionEvent.getResult(); Result<?, ?> result = event.getResult();
if (result.processorClass() != null) {
hover.add(Component.text() if (result instanceof TristateResult) {
.append(Component.text("Processor: ", NamedTextColor.AQUA)) TristateResult tristateResult = (TristateResult) result;
.append(Component.text(result.processorClass().getName(), NamedTextColor.DARK_GREEN))
); if (tristateResult.processorClass() != null) {
} hover.add(Message.VERBOSE_LOG_HOVER_PROCESSOR.build(tristateResult.processorClassFriendly()));
if (result.cause() != null) {
hover.add(Component.text()
.append(Component.text("Cause: ", NamedTextColor.AQUA))
.append(Component.text(result.cause(), NamedTextColor.DARK_GREEN))
);
} }
} }
if (event instanceof MetaCheckEvent) {
MetaCheckEvent metaEvent = (MetaCheckEvent) event; Node node = result.node();
hover.add(Component.text() if (node != null) {
.append(Component.text("Type: ", NamedTextColor.GREEN)) if (node instanceof MetaNode) {
.append(Component.text("meta", NamedTextColor.DARK_GREEN)) hover.add(Message.VERBOSE_LOG_HOVER_CAUSE_META.build((MetaNode) node));
); } else {
hover.add(Component.text() hover.add(Message.VERBOSE_LOG_HOVER_CAUSE.build(node));
.append(Component.text("Origin: ", NamedTextColor.AQUA)) }
.append(Component.text(metaEvent.getOrigin().name(), NamedTextColor.DARK_GREEN))
);
} }
if (event.getCheckQueryOptions().mode() == QueryMode.CONTEXTUAL) { if (event.getCheckQueryOptions().mode() == QueryMode.CONTEXTUAL) {
hover.add(Component.text() hover.add(Message.VERBOSE_LOG_HOVER_CONTEXT.build(event.getCheckQueryOptions().context()));
.append(Component.text("Context: ", NamedTextColor.AQUA))
.append(Message.formatContextSet(event.getCheckQueryOptions().context()))
);
} }
hover.add(Component.text() hover.add(Message.VERBOSE_LOG_HOVER_THREAD.build(event.getCheckThread()));
.append(Component.text("Thread: ", NamedTextColor.AQUA))
.append(Component.text(event.getCheckThread(), NamedTextColor.WHITE))
);
hover.add(Component.text() hover.add(Message.VERBOSE_LOG_HOVER_TRACE_TITLE.build());
.append(Component.text("Trace: ", NamedTextColor.AQUA))
);
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; int overflow;
if (shouldFilterStackTrace(event)) { if (shouldFilterStackTrace(event)) {
overflow = CHAT_FILTERED_PRINTER.process(event.getCheckTrace(), printer); overflow = CHAT_FILTERED_PRINTER.process(event.getCheckTrace(), printer);
@ -256,7 +220,7 @@ public class VerboseListener {
overflow = CHAT_UNFILTERED_PRINTER.process(event.getCheckTrace(), printer); overflow = CHAT_UNFILTERED_PRINTER.process(event.getCheckTrace(), printer);
} }
if (overflow != 0) { 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 // send the message
@ -267,8 +231,8 @@ public class VerboseListener {
private static boolean shouldFilterStackTrace(VerboseEvent event) { private static boolean shouldFilterStackTrace(VerboseEvent event) {
if (event instanceof PermissionCheckEvent) { if (event instanceof PermissionCheckEvent) {
PermissionCheckEvent permissionEvent = (PermissionCheckEvent) event; PermissionCheckEvent permissionEvent = (PermissionCheckEvent) event;
return permissionEvent.getOrigin() == PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK || return permissionEvent.getOrigin() == CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET ||
permissionEvent.getOrigin() == PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK; permissionEvent.getOrigin() == CheckOrigin.PLATFORM_API_HAS_PERMISSION;
} }
return false; return false;
} }
@ -302,8 +266,8 @@ public class VerboseListener {
.add("truncated", truncated); .add("truncated", truncated);
JArray data = new JArray(); JArray data = new JArray();
for (VerboseEvent events : this.results) { for (VerboseEvent event : this.results) {
data.add(events.toJson(shouldFilterStackTrace(events) ? WEB_FILTERED_PRINTER : WEB_UNFILTERED_PRINTER)); data.add(event.toJson(shouldFilterStackTrace(event) ? WEB_FILTERED_PRINTER : WEB_UNFILTERED_PRINTER));
} }
this.results.clear(); 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; 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.util.gson.JObject;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget; import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
@ -34,11 +38,6 @@ import java.util.Locale;
public class MetaCheckEvent extends VerboseEvent { public class MetaCheckEvent extends VerboseEvent {
/**
* The origin of the check
*/
private final Origin origin;
/** /**
* The meta key which was checked for * The meta key which was checked for
*/ */
@ -47,33 +46,59 @@ public class MetaCheckEvent extends VerboseEvent {
/** /**
* The result of the meta check * 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) { public MetaCheckEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread, String key, StringResult<?> result) {
super(checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread); super(origin, checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread);
this.origin = origin;
this.key = key; this.key = key;
this.result = result; this.result = result;
} }
public Origin getOrigin() {
return this.origin;
}
public String getKey() { public String getKey() {
return this.key; return this.key;
} }
public String getResult() { @Override
public StringResult<?> getResult() {
return this.result; return this.result;
} }
@Override
public VerboseEventType getType() {
return VerboseEventType.META;
}
@Override @Override
protected void serializeTo(JObject object) { protected void serializeTo(JObject object) {
object.add("type", "meta") object.add("key", this.key);
.add("key", this.key)
.add("result", this.result) object.add("result", String.valueOf(this.result.result()));
.add("origin", this.origin.name().toLowerCase(Locale.ROOT)); 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 @Override
@ -81,33 +106,7 @@ public class MetaCheckEvent extends VerboseEvent {
return variable.equals("meta") || return variable.equals("meta") ||
getCheckTarget().describe().equalsIgnoreCase(variable) || getCheckTarget().describe().equalsIgnoreCase(variable) ||
getKey().toLowerCase(Locale.ROOT).startsWith(variable.toLowerCase(Locale.ROOT)) || 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; 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.util.gson.JObject;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget; import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
@ -35,11 +38,6 @@ import java.util.Locale;
public class PermissionCheckEvent extends VerboseEvent { public class PermissionCheckEvent extends VerboseEvent {
/**
* The origin of the check
*/
private final Origin origin;
/** /**
* The permission which was checked for * The permission which was checked for
*/ */
@ -50,43 +48,60 @@ public class PermissionCheckEvent extends VerboseEvent {
*/ */
private final TristateResult result; private final TristateResult result;
public PermissionCheckEvent(Origin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread, String permission, TristateResult result) { public PermissionCheckEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread, String permission, TristateResult result) {
super(checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread); super(origin, checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread);
this.origin = origin;
this.permission = permission; this.permission = permission;
this.result = result; this.result = result;
} }
public Origin getOrigin() {
return this.origin;
}
public String getPermission() { public String getPermission() {
return this.permission; return this.permission;
} }
@Override
public TristateResult getResult() { public TristateResult getResult() {
return this.result; return this.result;
} }
@Override
public VerboseEventType getType() {
return VerboseEventType.PERMISSION;
}
@Override @Override
protected void serializeTo(JObject object) { protected void serializeTo(JObject object) {
object.add("type", "permission");
object.add("permission", this.permission); object.add("permission", this.permission);
object.add("result", this.result.result().name().toLowerCase(Locale.ROOT)); object.add("result", this.result.result().name().toLowerCase(Locale.ROOT));
if (this.result.processorClass() != null || this.result.cause() != null) { if (this.result != TristateResult.UNDEFINED) {
JObject resultInfo = new JObject(); object.add("resultInfo", serializeResult(this.result));
if (this.result.processorClass() != null) { }
resultInfo.add("processorClass", this.result.processorClass().getName()); }
}
if (this.result.cause() != null) { private static JObject serializeResult(TristateResult result) {
resultInfo.add("cause", this.result.cause()); JObject object = new JObject();
} object.add("result", result.result().name().toLowerCase(Locale.ROOT));
object.add("resultInfo", resultInfo);
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 @Override
@ -97,35 +112,4 @@ public class PermissionCheckEvent extends VerboseEvent {
getResult().result().name().equalsIgnoreCase(variable); 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 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.StackTracePrinter;
import me.lucko.luckperms.common.util.gson.JArray; import me.lucko.luckperms.common.util.gson.JArray;
import me.lucko.luckperms.common.util.gson.JObject; import me.lucko.luckperms.common.util.gson.JObject;
@ -46,6 +47,11 @@ import java.util.UUID;
*/ */
public abstract class VerboseEvent implements VariableEvaluator { public abstract class VerboseEvent implements VariableEvaluator {
/**
* The origin of the check
*/
private final CheckOrigin origin;
/** /**
* The name of the entity which was checked * The name of the entity which was checked
*/ */
@ -71,7 +77,8 @@ public abstract class VerboseEvent implements VariableEvaluator {
*/ */
private final String checkThread; 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.checkTarget = checkTarget;
this.checkQueryOptions = checkQueryOptions; this.checkQueryOptions = checkQueryOptions;
this.checkTime = checkTime; this.checkTime = checkTime;
@ -79,10 +86,16 @@ public abstract class VerboseEvent implements VariableEvaluator {
this.checkThread = checkThread; this.checkThread = checkThread;
} }
public CheckOrigin getOrigin() {
return this.origin;
}
public VerboseCheckTarget getCheckTarget() { public VerboseCheckTarget getCheckTarget() {
return this.checkTarget; return this.checkTarget;
} }
public abstract Result<?, ?> getResult();
public QueryOptions getCheckQueryOptions() { public QueryOptions getCheckQueryOptions() {
return this.checkQueryOptions; return this.checkQueryOptions;
} }
@ -99,10 +112,14 @@ public abstract class VerboseEvent implements VariableEvaluator {
return this.checkThread; return this.checkThread;
} }
public abstract VerboseEventType getType();
protected abstract void serializeTo(JObject object); protected abstract void serializeTo(JObject object);
public JsonObject toJson(StackTracePrinter tracePrinter) { public JsonObject toJson(StackTracePrinter tracePrinter) {
return new JObject() return new JObject()
.add("type", getType().toString())
.add("origin", this.origin.name().toLowerCase(Locale.ROOT))
.add("who", new JObject() .add("who", new JObject()
.add("identifier", this.checkTarget.describe()) .add("identifier", this.checkTarget.describe())
.add("type", this.checkTarget.getType()) .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.GsonProvider;
import me.lucko.luckperms.common.util.gson.JArray; import me.lucko.luckperms.common.util.gson.JArray;
import me.lucko.luckperms.common.util.gson.JObject; 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.context.ImmutableContextSet;
import net.luckperms.api.node.Node; import net.luckperms.api.node.Node;
@ -233,7 +233,7 @@ public class WebEditorRequest {
users.values().stream() users.values().stream()
.sorted(Comparator .sorted(Comparator
// sort firstly by the users relative weight (depends on the groups they inherit) // 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 // then, prioritise users we actually have a username for
.thenComparing(u -> u.getUsername().isPresent(), ((Comparator<Boolean>) Boolean::compare).reversed()) .thenComparing(u -> u.getUsername().isPresent(), ((Comparator<Boolean>) Boolean::compare).reversed())
// then sort according to their username // then sort according to their username

View File

@ -1,5 +1,13 @@
luckperms.logs.actionlog-prefix=LOG luckperms.logs.actionlog-prefix=LOG
luckperms.logs.verbose-prefix=VB 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.logs.export-prefix=EXPORT
luckperms.commandsystem.available-commands=Use {0} to view available commands luckperms.commandsystem.available-commands=Use {0} to view available commands
luckperms.commandsystem.command-not-recognised=Command not recognised 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); boolean integratedOwner = queryOptions.option(FabricContextManager.INTEGRATED_SERVER_OWNER).orElse(false);
if (integratedOwner && this.plugin.getConfiguration().get(ConfigKeys.FABRIC_INTEGRATED_SERVER_OWNER_BYPASSES_CHECKS)) { 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); return new PermissionCalculator(this.plugin, metadata, processors);

View File

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

View File

@ -26,10 +26,10 @@
package me.lucko.luckperms.fabric.listeners; package me.lucko.luckperms.fabric.listeners;
import me.lucko.fabric.api.permissions.v0.PermissionCheckEvent; 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.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget; 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.LPFabricPlugin;
import me.lucko.luckperms.fabric.model.MixinUser; import me.lucko.luckperms.fabric.model.MixinUser;
@ -83,7 +83,7 @@ public class PermissionCheckListener {
String name = ((ServerCommandSource) source).getName(); String name = ((ServerCommandSource) source).getName();
VerboseCheckTarget target = VerboseCheckTarget.internal(name); 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); 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.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.locale.TranslationManager; import me.lucko.luckperms.common.locale.TranslationManager;
import me.lucko.luckperms.common.model.User; 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.context.FabricContextManager;
import me.lucko.luckperms.fabric.event.PlayerChangeWorldCallback; import me.lucko.luckperms.fabric.event.PlayerChangeWorldCallback;
import me.lucko.luckperms.fabric.model.MixinUser; import me.lucko.luckperms.fabric.model.MixinUser;
@ -133,7 +133,7 @@ public abstract class ServerPlayerEntityMixin implements MixinUser {
} }
PermissionCache data = user.getCachedData().getPermissionData(queryOptions); 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; 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.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.nukkit.LPNukkitPlugin; import me.lucko.luckperms.nukkit.LPNukkitPlugin;
import net.luckperms.api.util.Tristate; import net.luckperms.api.util.Tristate;
@ -40,7 +40,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
/** /**
* Permission Processor for Nukkits "child" permission system. * 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 static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(ChildProcessor.class);
private final LPNukkitPlugin plugin; private final LPNukkitPlugin plugin;
@ -62,10 +62,10 @@ public class ChildProcessor extends AbstractPermissionProcessor implements Permi
@Override @Override
public void refresh() { public void refresh() {
Map<String, TristateResult> childPermissions = new HashMap<>(); Map<String, TristateResult> childPermissions = new HashMap<>();
this.sourceMap.forEach((key, value) -> { this.sourceMap.forEach((key, node) -> {
Map<String, Boolean> children = this.plugin.getPermissionMap().getChildPermissions(key, value); Map<String, Boolean> children = this.plugin.getPermissionMap().getChildPermissions(key, node.getValue());
children.forEach((childKey, childValue) -> { 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; 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 @Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) { public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
List<PermissionProcessor> processors = new ArrayList<>(7); List<PermissionProcessor> processors = new ArrayList<>(8);
processors.add(new DirectProcessor()); processors.add(new DirectProcessor());
@ -75,7 +75,8 @@ public class NukkitCalculatorFactory implements CalculatorFactory {
boolean op = queryOptions.option(NukkitContextManager.OP_OPTION).orElse(false); boolean op = queryOptions.option(NukkitContextManager.OP_OPTION).orElse(false);
if (metadata.getHolderType() == HolderType.USER && this.plugin.getConfiguration().get(ConfigKeys.APPLY_NUKKIT_DEFAULT_PERMISSIONS)) { 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); 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) { if (op) {

View File

@ -25,8 +25,9 @@
package me.lucko.luckperms.nukkit.calculator; 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.processor.PermissionProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import net.luckperms.api.util.Tristate; 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 * Permission Processor which is added for opped users, to simply return true if
* no other processors match. * 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); private static final TristateResult TRUE_RESULT = new TristateResult.Factory(OpProcessor.class).result(Tristate.TRUE);
public static final OpProcessor INSTANCE = new OpProcessor(); public static final OpProcessor INSTANCE = new OpProcessor();
@ -44,10 +45,7 @@ public final class OpProcessor implements PermissionProcessor {
} }
@Override @Override
public TristateResult hasPermission(TristateResult prev, String permission) { public TristateResult hasPermission(String permission) {
if (prev != TristateResult.UNDEFINED) {
return prev;
}
return TRUE_RESULT; 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.ImmutableList;
import com.google.common.collect.ImmutableMap; 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.config.ConfigKeys;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache; import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.model.User; 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.LPNukkitPlugin;
import me.lucko.luckperms.nukkit.calculator.DefaultsProcessor;
import me.lucko.luckperms.nukkit.calculator.OpProcessor; import me.lucko.luckperms.nukkit.calculator.OpProcessor;
import me.lucko.luckperms.nukkit.calculator.PermissionMapProcessor;
import me.lucko.luckperms.nukkit.inject.PermissionDefault; import me.lucko.luckperms.nukkit.inject.PermissionDefault;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
@ -144,13 +144,13 @@ public class LuckPermsPermissible extends PermissibleBase {
} }
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); 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) { if (result.result() == Tristate.UNDEFINED) {
return false; return false;
} }
// ignore matches made from looking up in the permission map (replicate nukkit behaviour) // 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; return false;
} }
@ -174,7 +174,7 @@ public class LuckPermsPermissible extends PermissibleBase {
} }
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); 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 @Override
@ -184,7 +184,7 @@ public class LuckPermsPermissible extends PermissibleBase {
} }
QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); 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 // override default op handling using the Permission class we have
if (result.processorClass() == OpProcessor.class && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) { 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; 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.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget; import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
import me.lucko.luckperms.common.verbose.VerboseHandler; 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; import net.luckperms.api.util.Tristate;
@ -68,8 +68,8 @@ public class MonitoredPermissibleBase extends PermissibleBase {
this.initialised = true; this.initialised = true;
} }
private void logCheck(PermissionCheckEvent.Origin origin, String permission, boolean result) { private void logCheck(CheckOrigin origin, String permission, boolean result) {
this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(Tristate.of(result))); this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(Tristate.of(result)));
this.plugin.getPermissionRegistry().offer(permission); this.plugin.getPermissionRegistry().offer(permission);
} }
@ -84,7 +84,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
} }
final boolean result = this.delegate.isPermissionSet(permission); 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; return result;
} }
@ -95,7 +95,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
} }
final boolean result = this.delegate.isPermissionSet(permission); 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; return result;
} }
@ -106,7 +106,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
} }
final boolean result = this.delegate.hasPermission(permission); 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; return result;
} }
@ -117,7 +117,7 @@ public class MonitoredPermissibleBase extends PermissibleBase {
} }
final boolean result = this.delegate.hasPermission(permission); 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; return result;
} }

View File

@ -80,7 +80,7 @@ public final class SubjectCollectionProxy implements SubjectCollection, ProxiedS
@Override @Override
public @NonNull CompletableFuture<Map<String, Subject>> loadSubjects(@NonNull Set<String> set) { 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 @Override

View File

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

View File

@ -79,7 +79,7 @@ public final class SubjectReferenceFactory {
public LPSubjectReference obtain(LPSubject subject) { public LPSubjectReference obtain(LPSubject subject) {
Objects.requireNonNull(subject, "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); ((CachedSubjectReference) reference).fillCache(subject);
return reference; 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; import net.luckperms.api.query.QueryOptions;
public class FixedDefaultsProcessor extends DefaultsProcessor { public class FixedTypeDefaultsProcessor extends TypeDefaultsProcessor {
private final LPSubject defaultsSubject; 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); super(service, queryOptions, overrideWildcards);
this.defaultsSubject = defaultsSubject; this.defaultsSubject = defaultsSubject;
} }

View File

@ -31,8 +31,8 @@ import me.lucko.luckperms.sponge.service.model.LPSubject;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
public class GroupDefaultsProcessor extends DefaultsProcessor implements PermissionProcessor { public class GroupTypeDefaultsProcessor extends TypeDefaultsProcessor implements PermissionProcessor {
public GroupDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) { public GroupTypeDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) {
super(service, queryOptions, 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)) { if (this.plugin.getConfiguration().get(ConfigKeys.APPLY_SPONGE_DEFAULT_SUBJECTS)) {
boolean overrideWildcards = this.plugin.getConfiguration().get(ConfigKeys.APPLY_DEFAULT_NEGATIONS_BEFORE_WILDCARDS); boolean overrideWildcards = this.plugin.getConfiguration().get(ConfigKeys.APPLY_DEFAULT_NEGATIONS_BEFORE_WILDCARDS);
if (metadata.getHolderType() == HolderType.USER) { 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) { } 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); 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; import net.luckperms.api.query.QueryOptions;
public class UserDefaultsProcessor extends DefaultsProcessor implements PermissionProcessor { public class UserTypeDefaultsProcessor extends TypeDefaultsProcessor implements PermissionProcessor {
public UserDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) { public UserTypeDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) {
super(service, queryOptions, overrideWildcards); super(service, queryOptions, overrideWildcards);
} }

View File

@ -66,7 +66,7 @@ public class ParentAdd extends ChildCommand<LPSubjectData> {
if (subjectData.addParent(contextSet, subject.toReference()).join()) { if (subjectData.addParent(contextSet, subject.toReference()).join()) {
SpongeCommandUtils.sendPrefixed(sender, "&aAdded parent &b" + subject.getParentCollection().getIdentifier() + 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 { } else {
SpongeCommandUtils.sendPrefixed(sender, "Unable to add parent. Does the Subject already have it added?"); 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()) { if (subjectData.removeParent(contextSet, subject.toReference()).join()) {
SpongeCommandUtils.sendPrefixed(sender, "&aRemoved parent &b" + subject.getParentCollection().getIdentifier() + 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 { } else {
SpongeCommandUtils.sendPrefixed(sender, "Unable to remove parent. Are you sure the Subject has it added?"); 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) { if (args.size() < 2) {
List<String> subjects = collection.getLoadedSubjects().stream() List<String> subjects = collection.getLoadedSubjects().stream()
.map(LPSubject::getIdentifier) .map(lpSubject -> lpSubject.getIdentifier().getName())
.collect(Collectors.toList()); .collect(Collectors.toList());
if (subjects.size() > 50) { 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 com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator; 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.graph.TraversalAlgorithm;
import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.sponge.LPSpongePlugin; import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.service.inheritance.SubjectInheritanceGraph; import me.lucko.luckperms.sponge.service.inheritance.SubjectInheritanceGraph;
import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubject;
import me.lucko.luckperms.sponge.service.model.LPSubjectReference; import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
import net.luckperms.api.context.ImmutableContextSet; 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.query.QueryOptions;
import net.luckperms.api.util.Tristate; import net.luckperms.api.util.Tristate;
@ -67,9 +69,9 @@ public abstract class CalculatedSubject implements LPSubject {
@Override @Override
public abstract CalculatedSubjectData getTransientSubjectData(); public abstract CalculatedSubjectData getTransientSubjectData();
public Map<String, Boolean> getCombinedPermissions(QueryOptions filter) { public Map<String, Node> getCombinedPermissions(QueryOptions filter) {
Map<String, Boolean> permissions; Map<String, Node> permissions;
Map<String, Boolean> merging; Map<String, Node> merging;
switch (getParentCollection().getResolutionOrder()) { switch (getParentCollection().getResolutionOrder()) {
case TRANSIENT_FIRST: case TRANSIENT_FIRST:
permissions = getTransientSubjectData().resolvePermissions(filter); permissions = getTransientSubjectData().resolvePermissions(filter);
@ -83,18 +85,18 @@ public abstract class CalculatedSubject implements LPSubject {
throw new AssertionError(); 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()); permissions.putIfAbsent(entry.getKey(), entry.getValue());
} }
return permissions; 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); SubjectInheritanceGraph graph = new SubjectInheritanceGraph(filter);
Iterable<CalculatedSubject> traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this); Iterable<CalculatedSubject> traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this);
for (CalculatedSubject subject : traversal) { 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()); accumulator.putIfAbsent(entry.getKey(), entry.getValue());
} }
} }
@ -132,9 +134,9 @@ public abstract class CalculatedSubject implements LPSubject {
return result; return result;
} }
public Map<String, String> getCombinedOptions(QueryOptions filter) { public Map<String, MetaNode> getCombinedOptions(QueryOptions filter) {
Map<String, String> options; Map<String, MetaNode> options;
Map<String, String> merging; Map<String, MetaNode> merging;
switch (getParentCollection().getResolutionOrder()) { switch (getParentCollection().getResolutionOrder()) {
case TRANSIENT_FIRST: case TRANSIENT_FIRST:
options = getTransientSubjectData().resolveOptions(filter); options = getTransientSubjectData().resolveOptions(filter);
@ -148,7 +150,7 @@ public abstract class CalculatedSubject implements LPSubject {
throw new AssertionError(); 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()); options.putIfAbsent(entry.getKey(), entry.getValue());
} }
return options; return options;
@ -160,8 +162,8 @@ public abstract class CalculatedSubject implements LPSubject {
Iterable<CalculatedSubject> traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this); Iterable<CalculatedSubject> traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this);
for (CalculatedSubject subject : traversal) { for (CalculatedSubject subject : traversal) {
for (Map.Entry<String, String> entry : subject.getCombinedOptions(filter).entrySet()) { for (MetaNode entry : subject.getCombinedOptions(filter).values()) {
result.putIfAbsent(entry.getKey(), entry.getValue()); result.putIfAbsent(entry.getMetaKey(), entry.getMetaValue());
} }
} }
@ -170,18 +172,20 @@ public abstract class CalculatedSubject implements LPSubject {
public void resolveAllOptions(MetaAccumulator accumulator, QueryOptions filter) { public void resolveAllOptions(MetaAccumulator accumulator, QueryOptions filter) {
SubjectInheritanceGraph graph = new SubjectInheritanceGraph(filter); SubjectInheritanceGraph graph = new SubjectInheritanceGraph(filter);
Iterable<CalculatedSubject> traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this); Iterable<CalculatedSubject> traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this);
for (CalculatedSubject subject : traversal) { for (CalculatedSubject subject : traversal) {
for (Map.Entry<String, String> entry : subject.getCombinedOptions(filter).entrySet()) { for (MetaNode entry : subject.getCombinedOptions(filter).values()) {
accumulator.accumulateMeta(entry.getKey(), entry.getValue()); accumulator.accumulateNode(entry);
} }
} }
accumulator.complete(); accumulator.complete();
} }
@Override @Override
public Tristate getPermissionValue(QueryOptions options, String permission) { 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 @Override
@ -201,7 +205,7 @@ public abstract class CalculatedSubject implements LPSubject {
@Override @Override
public Optional<String> getOption(ImmutableContextSet contexts, String key) { 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 @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.metastacking.StandardStackElements;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget; 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.DuplicateRemovalFunction;
import net.luckperms.api.metastacking.MetaStackDefinition; import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.node.ChatMetaType; import net.luckperms.api.node.ChatMetaType;
import net.luckperms.api.node.Node;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import java.util.ArrayList; import java.util.ArrayList;
@ -68,7 +70,7 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage
@Override @Override
protected CacheMetadata getMetadataForQueryOptions(QueryOptions queryOptions) { 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); return new CacheMetadata(null, target, queryOptions);
} }
@ -88,7 +90,7 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage
} }
@Override @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); M map = mapFactory.apply(16);
this.subject.resolveAllPermissions(map, queryOptions); this.subject.resolveAllPermissions(map, queryOptions);
return map; return map;
@ -101,13 +103,14 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage
@Override @Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) { 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 DirectProcessor());
processors.add(new SpongeWildcardProcessor()); processors.add(new SpongeWildcardProcessor());
processors.add(new WildcardProcessor()); processors.add(new WildcardProcessor());
if (!this.subject.getParentCollection().isDefaultsCollection()) { 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); 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.config.ConfigKeys;
import me.lucko.luckperms.common.context.comparator.ContextSetComparator; 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.ProxyFactory;
import me.lucko.luckperms.sponge.service.model.LPPermissionService; import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubject; 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.ContextSatisfyMode;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.model.data.DataType; 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.query.QueryOptions;
import net.luckperms.api.util.Tristate; import net.luckperms.api.util.Tristate;
@ -134,21 +141,32 @@ public class CalculatedSubjectData implements LPSubjectData {
return ImmutableMap.copyOf(this.permissions.getOrDefault(contexts, ImmutableMap.of())); 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 // 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()) { for (Map.Entry<ImmutableContextSet, Map<String, Boolean>> entry : this.permissions.entrySet()) {
if (!filter.satisfies(entry.getKey(), defaultSatisfyMode())) { if (!filter.satisfies(entry.getKey(), defaultSatisfyMode())) {
continue; 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 // flatten
Map<String, Boolean> result = new HashMap<>(); Map<String, Node> result = new HashMap<>();
for (Map<String, Boolean> map : sorted.values()) { for (Map<String, Node> map : sorted.values()) {
for (Map.Entry<String, Boolean> e : map.entrySet()) { for (Map.Entry<String, Node> e : map.entrySet()) {
result.putIfAbsent(e.getKey(), e.getValue()); result.putIfAbsent(e.getKey(), e.getValue());
} }
} }
@ -288,21 +306,32 @@ public class CalculatedSubjectData implements LPSubjectData {
return ImmutableMap.copyOf(this.options.getOrDefault(contexts, ImmutableMap.of())); 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 // 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()) { for (Map.Entry<ImmutableContextSet, Map<String, String>> entry : this.options.entrySet()) {
if (!filter.satisfies(entry.getKey(), defaultSatisfyMode())) { if (!filter.satisfies(entry.getKey(), defaultSatisfyMode())) {
continue; 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 // flatten
Map<String, String> result = new HashMap<>(); Map<String, MetaNode> result = new HashMap<>();
for (Map<String, String> map : sorted.values()) { for (Map<String, MetaNode> map : sorted.values()) {
for (Map.Entry<String, String> e : map.entrySet()) { for (Map.Entry<String, MetaNode> e : map.entrySet()) {
result.putIfAbsent(e.getKey(), e.getValue()); 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.LPSubject;
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
import net.luckperms.api.model.PermissionHolder;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandSource;
import java.util.Optional; import java.util.Optional;
@ -43,8 +45,8 @@ public class GroupSubject extends PermissionHolderSubject<SpongeGroup> implement
} }
@Override @Override
public String getIdentifier() { public PermissionHolder.Identifier getIdentifier() {
return this.parent.getObjectName(); return this.parent.getIdentifier();
} }
@Override @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.Inheritance;
import me.lucko.luckperms.common.node.types.Prefix; import me.lucko.luckperms.common.node.types.Prefix;
import me.lucko.luckperms.common.node.types.Suffix; import me.lucko.luckperms.common.node.types.Suffix;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.sponge.LPSpongePlugin; import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.model.SpongeGroup; import me.lucko.luckperms.sponge.model.SpongeGroup;
import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.LuckPermsService;
@ -113,7 +112,7 @@ public abstract class PermissionHolderSubject<T extends PermissionHolder> implem
@Override @Override
public Tristate getPermissionValue(QueryOptions options, String permission) { 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 @Override
@ -148,20 +147,20 @@ public abstract class PermissionHolderSubject<T extends PermissionHolder> implem
public Optional<String> getOption(ImmutableContextSet contexts, String s) { public Optional<String> getOption(ImmutableContextSet contexts, String s) {
MetaCache data = this.parent.getCachedData().getMetaData(this.plugin.getContextManager().formQueryOptions(contexts)); MetaCache data = this.parent.getCachedData().getMetaData(this.plugin.getContextManager().formQueryOptions(contexts));
if (s.equalsIgnoreCase(Prefix.NODE_KEY)) { 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) { if (prefix != null) {
return Optional.of(prefix); return Optional.of(prefix);
} }
} }
if (s.equalsIgnoreCase(Suffix.NODE_KEY)) { 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) { if (suffix != null) {
return Optional.of(suffix); 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) { if (val != null) {
return Optional.of(val); 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.LPSubject;
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
import net.luckperms.api.model.PermissionHolder;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandSource;
@ -46,8 +48,8 @@ public final class UserSubject extends PermissionHolderSubject<SpongeUser> imple
} }
@Override @Override
public String getIdentifier() { public PermissionHolder.Identifier getIdentifier() {
return this.parent.getUniqueId().toString(); return this.parent.getIdentifier();
} }
@Override @Override

View File

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

View File

@ -110,7 +110,7 @@ public class SubjectStorage {
* @throws IOException if the write fails * @throws IOException if the write fails
*/ */
public void saveToFile(PersistedSubject subject) throws IOException { 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); 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.permission.PermissionSubject;
import com.velocitypowered.api.proxy.Player; 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.query.QueryOptionsImpl;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget; 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.LPVelocityPlugin;
import me.lucko.luckperms.velocity.service.CompatibilityUtil; import me.lucko.luckperms.velocity.service.CompatibilityUtil;
@ -91,7 +91,7 @@ public class MonitoringPermissionCheckListener {
// report result // report result
Tristate result = CompatibilityUtil.convertTristate(setting); 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); MonitoringPermissionCheckListener.this.plugin.getPermissionRegistry().offer(permission);
return setting; 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.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.model.User; 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; import org.checkerframework.checker.nullness.qual.NonNull;
@ -57,6 +57,6 @@ public class PlayerPermissionProvider implements PermissionProvider, PermissionF
@Override @Override
public @NonNull Tristate getPermissionValue(@NonNull String permission) { 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());
} }
} }