From 2d662cbab960c73dbbccc780a50c39203cfb0fd7 Mon Sep 17 00:00:00 2001 From: lucko Date: Fri, 31 Dec 2021 16:03:00 +0000 Subject: [PATCH] Retain cause node information for cached permission/meta data (#3250) --- .../api/query/meta/MetaValueSelector.java | 2 +- .../calculator/BukkitCalculatorFactory.java | 5 +- .../bukkit/calculator/ChildProcessor.java | 12 +- .../DefaultPermissionMapProcessor.java | 58 +++++ .../bukkit/calculator/DefaultsProcessor.java | 90 -------- .../bukkit/calculator/OpProcessor.java | 10 +- .../calculator/PermissionMapProcessor.java | 60 +++++ .../permissible/LuckPermsPermissible.java | 14 +- .../permissible/MonitoredPermissibleBase.java | 16 +- .../bukkit/vault/LuckPermsVaultChat.java | 25 +- .../vault/LuckPermsVaultPermission.java | 17 +- .../BungeePermissionCheckListener.java | 12 +- .../common/api/implementation/ApiUser.java | 4 +- .../cacheddata/AbstractCachedDataManager.java | 17 +- .../cacheddata/HolderCachedDataManager.java | 3 +- .../common/cacheddata/result/Result.java | 60 +++++ .../cacheddata/result/StringResult.java | 107 +++++++++ .../result/TristateResult.java | 103 ++++++--- .../cacheddata/type/MetaAccumulator.java | 39 ++-- .../common/cacheddata/type/MetaCache.java | 180 +++++++++++---- .../cacheddata/type/MetaStackAccumulator.java | 40 ++++ .../cacheddata/type/MonitoredMetaCache.java | 152 +++++++++++++ .../cacheddata/type/PermissionCache.java | 23 +- .../cacheddata/type/SimpleMetaCache.java | 213 ------------------ .../type/SimpleMetaValueSelector.java | 20 +- .../calculator/PermissionCalculator.java | 10 +- .../AbstractOverrideWildcardProcessor.java | 58 +++++ .../AbstractPermissionProcessor.java | 28 +-- .../AbstractSourceBasedProcessor.java | 41 ++++ .../calculator/processor/DirectProcessor.java | 8 +- .../processor/PermissionProcessor.java | 6 +- .../calculator/processor/RegexProcessor.java | 10 +- .../processor/SpongeWildcardProcessor.java | 12 +- .../processor/WildcardProcessor.java | 17 +- .../command/access/ArgumentPermissions.java | 6 +- .../generic/permission/PermissionCheck.java | 26 +-- .../common/commands/group/GroupInfo.java | 12 +- .../common/commands/user/UserInfo.java | 14 +- .../luckperms/common/locale/Message.java | 120 +++++++++- .../common/model/PermissionHolder.java | 12 +- .../model/PermissionHolderIdentifier.java | 5 + .../manager/user/AbstractUserManager.java | 4 +- .../common/node/utils/NodeJsonSerializer.java | 102 ++++++--- .../luckperms/common/treeview/TreeView.java | 4 +- .../common/verbose/VerboseHandler.java | 8 +- .../common/verbose/VerboseListener.java | 112 ++++----- .../common/verbose/event/CheckOrigin.java | 63 ++++++ .../common/verbose/event/MetaCheckEvent.java | 89 ++++---- .../verbose/event/PermissionCheckEvent.java | 94 ++++---- .../common/verbose/event/VerboseEvent.java | 19 +- .../verbose/event/VerboseEventType.java | 46 ++++ .../common/webeditor/WebEditorRequest.java | 4 +- .../main/resources/luckperms_en.properties | 8 + .../fabric/FabricCalculatorFactory.java | 2 +- .../calculator/ServerOwnerProcessor.java | 11 +- .../listeners/PermissionCheckListener.java | 6 +- .../fabric/mixin/ServerPlayerEntityMixin.java | 4 +- .../nukkit/calculator/ChildProcessor.java | 12 +- .../DefaultPermissionMapProcessor.java | 58 +++++ .../nukkit/calculator/DefaultsProcessor.java | 87 ------- .../calculator/NukkitCalculatorFactory.java | 5 +- .../nukkit/calculator/OpProcessor.java | 10 +- .../calculator/PermissionMapProcessor.java | 59 +++++ .../permissible/LuckPermsPermissible.java | 14 +- .../permissible/MonitoredPermissibleBase.java | 16 +- .../proxy/api7/SubjectCollectionProxy.java | 2 +- .../sponge/service/model/LPSubject.java | 3 +- .../reference/SubjectReferenceFactory.java | 2 +- .../sponge/calculator/DefaultsProcessor.java | 91 -------- ...r.java => FixedTypeDefaultsProcessor.java} | 4 +- ...r.java => GroupTypeDefaultsProcessor.java} | 4 +- .../calculator/RootDefaultsProcessor.java | 57 +++++ .../calculator/SpongeCalculatorFactory.java | 5 +- .../calculator/TypeDefaultsProcessor.java | 60 +++++ ...or.java => UserTypeDefaultsProcessor.java} | 4 +- .../luckperms/sponge/commands/ParentAdd.java | 2 +- .../sponge/commands/ParentRemove.java | 2 +- .../sponge/commands/SpongeParentCommand.java | 2 +- .../model/calculated/CalculatedSubject.java | 40 ++-- .../CalculatedSubjectCachedDataManager.java | 13 +- .../calculated/CalculatedSubjectData.java | 53 ++++- .../model/permissionholder/GroupSubject.java | 6 +- .../PermissionHolderSubject.java | 11 +- .../model/permissionholder/UserSubject.java | 6 +- .../model/persisted/PersistedSubject.java | 8 +- .../model/persisted/SubjectStorage.java | 2 +- .../MonitoringPermissionCheckListener.java | 6 +- .../service/PlayerPermissionProvider.java | 4 +- 88 files changed, 1809 insertions(+), 1082 deletions(-) create mode 100644 bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/DefaultPermissionMapProcessor.java delete mode 100644 bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/DefaultsProcessor.java create mode 100644 bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/PermissionMapProcessor.java create mode 100644 common/src/main/java/me/lucko/luckperms/common/cacheddata/result/Result.java create mode 100644 common/src/main/java/me/lucko/luckperms/common/cacheddata/result/StringResult.java rename common/src/main/java/me/lucko/luckperms/common/{calculator => cacheddata}/result/TristateResult.java (50%) create mode 100644 common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MonitoredMetaCache.java delete mode 100644 common/src/main/java/me/lucko/luckperms/common/cacheddata/type/SimpleMetaCache.java create mode 100644 common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractOverrideWildcardProcessor.java create mode 100644 common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractSourceBasedProcessor.java create mode 100644 common/src/main/java/me/lucko/luckperms/common/verbose/event/CheckOrigin.java create mode 100644 common/src/main/java/me/lucko/luckperms/common/verbose/event/VerboseEventType.java create mode 100644 nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/DefaultPermissionMapProcessor.java delete mode 100644 nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/DefaultsProcessor.java create mode 100644 nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/PermissionMapProcessor.java delete mode 100644 sponge/src/main/java/me/lucko/luckperms/sponge/calculator/DefaultsProcessor.java rename sponge/src/main/java/me/lucko/luckperms/sponge/calculator/{FixedDefaultsProcessor.java => FixedTypeDefaultsProcessor.java} (88%) rename sponge/src/main/java/me/lucko/luckperms/sponge/calculator/{GroupDefaultsProcessor.java => GroupTypeDefaultsProcessor.java} (88%) create mode 100644 sponge/src/main/java/me/lucko/luckperms/sponge/calculator/RootDefaultsProcessor.java create mode 100644 sponge/src/main/java/me/lucko/luckperms/sponge/calculator/TypeDefaultsProcessor.java rename sponge/src/main/java/me/lucko/luckperms/sponge/calculator/{UserDefaultsProcessor.java => UserTypeDefaultsProcessor.java} (88%) diff --git a/api/src/main/java/net/luckperms/api/query/meta/MetaValueSelector.java b/api/src/main/java/net/luckperms/api/query/meta/MetaValueSelector.java index ceb2b46a2..a73eac171 100644 --- a/api/src/main/java/net/luckperms/api/query/meta/MetaValueSelector.java +++ b/api/src/main/java/net/luckperms/api/query/meta/MetaValueSelector.java @@ -54,6 +54,6 @@ public interface MetaValueSelector { * @param values the values, in the order in which they were accumulated. * @return the selected value */ - @NonNull String selectValue(@NonNull String key, @NonNull List values); + @NonNull MetaNode selectValue(@NonNull String key, @NonNull List values); } diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/BukkitCalculatorFactory.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/BukkitCalculatorFactory.java index 5233544dd..143bde77d 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/BukkitCalculatorFactory.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/BukkitCalculatorFactory.java @@ -52,7 +52,7 @@ public class BukkitCalculatorFactory implements CalculatorFactory { @Override public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) { - List processors = new ArrayList<>(7); + List processors = new ArrayList<>(8); processors.add(new DirectProcessor()); @@ -75,7 +75,8 @@ public class BukkitCalculatorFactory implements CalculatorFactory { boolean op = queryOptions.option(BukkitContextManager.OP_OPTION).orElse(false); if (metadata.getHolderType() == HolderType.USER && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) { boolean overrideWildcards = this.plugin.getConfiguration().get(ConfigKeys.APPLY_DEFAULT_NEGATIONS_BEFORE_WILDCARDS); - processors.add(new DefaultsProcessor(this.plugin, overrideWildcards, op)); + processors.add(new DefaultPermissionMapProcessor(this.plugin, op)); + processors.add(new PermissionMapProcessor(this.plugin, overrideWildcards, op)); } if (op) { diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/ChildProcessor.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/ChildProcessor.java index 8ee84610b..22422fedd 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/ChildProcessor.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/ChildProcessor.java @@ -26,9 +26,9 @@ package me.lucko.luckperms.bukkit.calculator; import me.lucko.luckperms.bukkit.LPBukkitPlugin; -import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; +import me.lucko.luckperms.common.calculator.processor.AbstractSourceBasedProcessor; import me.lucko.luckperms.common.calculator.processor.PermissionProcessor; -import me.lucko.luckperms.common.calculator.result.TristateResult; import net.luckperms.api.util.Tristate; @@ -40,7 +40,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * Permission Processor for Bukkits "child" permission system. */ -public class ChildProcessor extends AbstractPermissionProcessor implements PermissionProcessor { +public class ChildProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor { private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(ChildProcessor.class); private final LPBukkitPlugin plugin; @@ -62,10 +62,10 @@ public class ChildProcessor extends AbstractPermissionProcessor implements Permi @Override public void refresh() { Map childPermissions = new HashMap<>(); - this.sourceMap.forEach((key, value) -> { - Map children = this.plugin.getPermissionMap().getChildPermissions(key, value); + this.sourceMap.forEach((key, node) -> { + Map children = this.plugin.getPermissionMap().getChildPermissions(key, node.getValue()); children.forEach((childKey, childValue) -> { - childPermissions.put(childKey, RESULT_FACTORY.result(Tristate.of(childValue), "parent: " + key)); + childPermissions.put(childKey, RESULT_FACTORY.resultWithOverride(node, Tristate.of(childValue))); }); }); this.childPermissions = childPermissions; diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/DefaultPermissionMapProcessor.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/DefaultPermissionMapProcessor.java new file mode 100644 index 000000000..9144500ac --- /dev/null +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/DefaultPermissionMapProcessor.java @@ -0,0 +1,58 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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; + } +} diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/DefaultsProcessor.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/DefaultsProcessor.java deleted file mode 100644 index 4f0a6a846..000000000 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/DefaultsProcessor.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * 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))); - } -} diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/OpProcessor.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/OpProcessor.java index a4b06a18d..c552dd5cf 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/OpProcessor.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/OpProcessor.java @@ -25,8 +25,9 @@ package me.lucko.luckperms.bukkit.calculator; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; +import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor; import me.lucko.luckperms.common.calculator.processor.PermissionProcessor; -import me.lucko.luckperms.common.calculator.result.TristateResult; import net.luckperms.api.util.Tristate; @@ -34,7 +35,7 @@ import net.luckperms.api.util.Tristate; * Permission Processor which is added for opped users, to simply return true if * no other processors match. */ -public final class OpProcessor implements PermissionProcessor { +public final class OpProcessor extends AbstractPermissionProcessor implements PermissionProcessor { private static final TristateResult TRUE_RESULT = new TristateResult.Factory(OpProcessor.class).result(Tristate.TRUE); public static final OpProcessor INSTANCE = new OpProcessor(); @@ -44,10 +45,7 @@ public final class OpProcessor implements PermissionProcessor { } @Override - public TristateResult hasPermission(TristateResult prev, String permission) { - if (prev != TristateResult.UNDEFINED) { - return prev; - } + public TristateResult hasPermission(String permission) { return TRUE_RESULT; } } diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/PermissionMapProcessor.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/PermissionMapProcessor.java new file mode 100644 index 000000000..4f6ac96c5 --- /dev/null +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculator/PermissionMapProcessor.java @@ -0,0 +1,60 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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))); + } +} diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LuckPermsPermissible.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LuckPermsPermissible.java index 164b8d658..3b4c7bc0d 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LuckPermsPermissible.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LuckPermsPermissible.java @@ -29,13 +29,13 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import me.lucko.luckperms.bukkit.LPBukkitPlugin; -import me.lucko.luckperms.bukkit.calculator.DefaultsProcessor; import me.lucko.luckperms.bukkit.calculator.OpProcessor; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.bukkit.calculator.PermissionMapProcessor; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.context.manager.QueryOptionsCache; import me.lucko.luckperms.common.model.User; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.query.QueryOptions; import net.luckperms.api.util.Tristate; @@ -143,13 +143,13 @@ public class LuckPermsPermissible extends PermissibleBase { } QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); - TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK); + TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET); if (result.result() == Tristate.UNDEFINED) { return false; } // ignore matches made from looking up in the permission map (replicate bukkit behaviour) - if (result.processorClass() == DefaultsProcessor.class && "permission map".equals(result.cause())) { + if (result.processorClass() == PermissionMapProcessor.class) { return false; } @@ -173,7 +173,7 @@ public class LuckPermsPermissible extends PermissibleBase { } QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); - return this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK).result().asBoolean(); + return this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result().asBoolean(); } @Override @@ -183,7 +183,7 @@ public class LuckPermsPermissible extends PermissibleBase { } QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); - TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission.getName(), PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK); + TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission.getName(), CheckOrigin.PLATFORM_API_HAS_PERMISSION); // override default op handling using the Permission class we have if (result.processorClass() == OpProcessor.class && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) { diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/MonitoredPermissibleBase.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/MonitoredPermissibleBase.java index e3c4f57c5..45258c93e 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/MonitoredPermissibleBase.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/MonitoredPermissibleBase.java @@ -25,12 +25,12 @@ package me.lucko.luckperms.bukkit.inject.permissible; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.verbose.VerboseCheckTarget; import me.lucko.luckperms.common.verbose.VerboseHandler; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.util.Tristate; @@ -69,8 +69,8 @@ public class MonitoredPermissibleBase extends PermissibleBase { this.initialised = true; } - private void logCheck(PermissionCheckEvent.Origin origin, String permission, boolean result) { - this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(Tristate.of(result))); + private void logCheck(CheckOrigin origin, String permission, boolean result) { + this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(Tristate.of(result))); this.plugin.getPermissionRegistry().offer(permission); } @@ -85,7 +85,7 @@ public class MonitoredPermissibleBase extends PermissibleBase { } final boolean result = this.delegate.isPermissionSet(permission); - logCheck(PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK, permission, result); + logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, permission, result); return result; } @@ -96,7 +96,7 @@ public class MonitoredPermissibleBase extends PermissibleBase { } final boolean result = this.delegate.isPermissionSet(permission); - logCheck(PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK, permission.getName(), result); + logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, permission.getName(), result); return result; } @@ -107,7 +107,7 @@ public class MonitoredPermissibleBase extends PermissibleBase { } final boolean result = this.delegate.hasPermission(permission); - logCheck(PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK, permission, result); + logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION, permission, result); return result; } @@ -118,7 +118,7 @@ public class MonitoredPermissibleBase extends PermissibleBase { } final boolean result = this.delegate.hasPermission(permission); - logCheck(PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK, permission.getName(), result); + logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION, permission.getName(), result); return result; } diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/LuckPermsVaultChat.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/LuckPermsVaultChat.java index c77d3016c..cc5e80150 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/LuckPermsVaultChat.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/LuckPermsVaultChat.java @@ -30,6 +30,7 @@ import com.google.common.base.Strings; import me.lucko.luckperms.bukkit.LPBukkitPlugin; import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator; import me.lucko.luckperms.common.cacheddata.type.MetaCache; +import me.lucko.luckperms.common.cacheddata.type.MonitoredMetaCache; import me.lucko.luckperms.common.context.ImmutableContextSetImpl; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.PermissionHolder; @@ -37,7 +38,7 @@ import me.lucko.luckperms.common.node.types.Meta; import me.lucko.luckperms.common.node.types.Prefix; import me.lucko.luckperms.common.node.types.Suffix; import me.lucko.luckperms.common.query.QueryOptionsImpl; -import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.context.DefaultContextKeys; import net.luckperms.api.context.ImmutableContextSet; @@ -97,7 +98,7 @@ public class LuckPermsVaultChat extends AbstractVaultChat { PermissionHolder user = this.vaultPermission.lookupUser(uuid); QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world); MetaCache metaData = user.getCachedData().getMetaData(queryOptions); - return Strings.nullToEmpty(metaData.getPrefix(MetaCheckEvent.Origin.THIRD_PARTY_API)); + return Strings.nullToEmpty(metaData.getPrefix(CheckOrigin.THIRD_PARTY_API).result()); } @Override @@ -107,7 +108,7 @@ public class LuckPermsVaultChat extends AbstractVaultChat { PermissionHolder user = this.vaultPermission.lookupUser(uuid); QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world); MetaCache metaData = user.getCachedData().getMetaData(queryOptions); - return Strings.nullToEmpty(metaData.getSuffix(MetaCheckEvent.Origin.THIRD_PARTY_API)); + return Strings.nullToEmpty(metaData.getSuffix(CheckOrigin.THIRD_PARTY_API).result()); } @Override @@ -139,8 +140,8 @@ public class LuckPermsVaultChat extends AbstractVaultChat { PermissionHolder user = this.vaultPermission.lookupUser(uuid); QueryOptions queryOptions = this.vaultPermission.getQueryOptions(uuid, world); - MetaCache metaData = user.getCachedData().getMetaData(queryOptions); - return metaData.getMetaValue(key, MetaCheckEvent.Origin.THIRD_PARTY_API); + MonitoredMetaCache metaData = user.getCachedData().getMetaData(queryOptions); + return metaData.getMetaValue(key, CheckOrigin.THIRD_PARTY_API).result(); } @Override @@ -158,21 +159,21 @@ public class LuckPermsVaultChat extends AbstractVaultChat { @Override public String getGroupChatPrefix(String world, String name) { Objects.requireNonNull(name, "name"); - MetaCache metaData = getGroupMetaCache(name, world); + MonitoredMetaCache metaData = getGroupMetaCache(name, world); if (metaData == null) { return null; } - return Strings.nullToEmpty(metaData.getPrefix(MetaCheckEvent.Origin.THIRD_PARTY_API)); + return Strings.nullToEmpty(metaData.getPrefix(CheckOrigin.THIRD_PARTY_API).result()); } @Override public String getGroupChatSuffix(String world, String name) { Objects.requireNonNull(name, "name"); - MetaCache metaData = getGroupMetaCache(name, world); + MonitoredMetaCache metaData = getGroupMetaCache(name, world); if (metaData == null) { return null; } - return Strings.nullToEmpty(metaData.getSuffix(MetaCheckEvent.Origin.THIRD_PARTY_API)); + return Strings.nullToEmpty(metaData.getSuffix(CheckOrigin.THIRD_PARTY_API).result()); } @Override @@ -199,11 +200,11 @@ public class LuckPermsVaultChat extends AbstractVaultChat { public String getGroupMeta(String world, String name, String key) { Objects.requireNonNull(name, "name"); Objects.requireNonNull(key, "key"); - MetaCache metaData = getGroupMetaCache(name, world); + MonitoredMetaCache metaData = getGroupMetaCache(name, world); if (metaData == null) { return null; } - return metaData.getMetaValue(key, MetaCheckEvent.Origin.THIRD_PARTY_API); + return metaData.getMetaValue(key, CheckOrigin.THIRD_PARTY_API).result(); } @Override @@ -223,7 +224,7 @@ public class LuckPermsVaultChat extends AbstractVaultChat { return this.plugin.getGroupManager().getByDisplayName(name); } - private MetaCache getGroupMetaCache(String name, String world) { + private MonitoredMetaCache getGroupMetaCache(String name, String world) { Group group = getGroup(name); if (group == null) { return null; diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/LuckPermsVaultPermission.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/LuckPermsVaultPermission.java index 345fda82d..8c189c5ac 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/LuckPermsVaultPermission.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/LuckPermsVaultPermission.java @@ -29,10 +29,10 @@ import com.google.common.base.Preconditions; import me.lucko.luckperms.bukkit.LPBukkitPlugin; import me.lucko.luckperms.bukkit.context.BukkitContextManager; -import me.lucko.luckperms.common.cacheddata.type.MetaCache; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.type.MonitoredMetaCache; import me.lucko.luckperms.common.cacheddata.type.PermissionCache; import me.lucko.luckperms.common.calculator.processor.DirectProcessor; -import me.lucko.luckperms.common.calculator.result.TristateResult; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.HolderType; @@ -44,8 +44,7 @@ import me.lucko.luckperms.common.node.types.Inheritance; import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.util.UniqueIdType; import me.lucko.luckperms.common.util.Uuids; -import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.context.ContextSet; import net.luckperms.api.context.DefaultContextKeys; @@ -175,7 +174,7 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission { PermissionHolder user = lookupUser(uuid); QueryOptions queryOptions = getQueryOptions(uuid, world); PermissionCache permissionData = user.getCachedData().getPermissionData(queryOptions); - return permissionData.checkPermission(permission, PermissionCheckEvent.Origin.THIRD_PARTY_API).result().asBoolean(); + return permissionData.checkPermission(permission, CheckOrigin.THIRD_PARTY_API).result().asBoolean(); } @Override @@ -211,7 +210,7 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission { QueryOptions queryOptions = getQueryOptions(uuid, world); PermissionCache permissionData = user.getCachedData().getPermissionData(queryOptions); - TristateResult result = permissionData.checkPermission(Inheritance.key(rewriteGroupName(group)), PermissionCheckEvent.Origin.THIRD_PARTY_API); + TristateResult result = permissionData.checkPermission(Inheritance.key(rewriteGroupName(group)), CheckOrigin.THIRD_PARTY_API); return result.processorClass() == DirectProcessor.class && result.result().asBoolean(); } @@ -254,8 +253,8 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission { } QueryOptions queryOptions = getQueryOptions(uuid, world); - MetaCache metaData = user.getCachedData().getMetaData(queryOptions); - String value = metaData.getPrimaryGroup(MetaCheckEvent.Origin.THIRD_PARTY_API); + MonitoredMetaCache metaData = user.getCachedData().getMetaData(queryOptions); + String value = metaData.getPrimaryGroup(CheckOrigin.THIRD_PARTY_API); if (value == null) { return null; } @@ -276,7 +275,7 @@ public class LuckPermsVaultPermission extends AbstractVaultPermission { QueryOptions queryOptions = getQueryOptions(null, world); PermissionCache permissionData = group.getCachedData().getPermissionData(queryOptions); - return permissionData.checkPermission(permission, PermissionCheckEvent.Origin.THIRD_PARTY_API).result().asBoolean(); + return permissionData.checkPermission(permission, CheckOrigin.THIRD_PARTY_API).result().asBoolean(); } @Override diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/listeners/BungeePermissionCheckListener.java b/bungee/src/main/java/me/lucko/luckperms/bungee/listeners/BungeePermissionCheckListener.java index 18ddad379..e0d0119bb 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/listeners/BungeePermissionCheckListener.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/listeners/BungeePermissionCheckListener.java @@ -27,12 +27,12 @@ package me.lucko.luckperms.bungee.listeners; import me.lucko.luckperms.bungee.LPBungeePlugin; import me.lucko.luckperms.bungee.event.TristateCheckEvent; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.verbose.VerboseCheckTarget; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent.Origin; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.query.QueryOptions; import net.luckperms.api.util.Tristate; @@ -72,7 +72,7 @@ public class BungeePermissionCheckListener implements Listener { } QueryOptions queryOptions = this.plugin.getContextManager().getQueryOptions(player); - Tristate result = user.getCachedData().getPermissionData(queryOptions).checkPermission(e.getPermission(), Origin.PLATFORM_PERMISSION_CHECK).result(); + Tristate result = user.getCachedData().getPermissionData(queryOptions).checkPermission(e.getPermission(), CheckOrigin.PLATFORM_API_HAS_PERMISSION).result(); if (result == Tristate.UNDEFINED && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUNGEE_CONFIG_PERMISSIONS)) { return; // just use the result provided by the proxy when the event was created } @@ -101,7 +101,7 @@ public class BungeePermissionCheckListener implements Listener { } QueryOptions queryOptions = this.plugin.getContextManager().getQueryOptions(player); - Tristate result = user.getCachedData().getPermissionData(queryOptions).checkPermission(e.getPermission(), Origin.PLATFORM_LOOKUP_CHECK).result(); + Tristate result = user.getCachedData().getPermissionData(queryOptions).checkPermission(e.getPermission(), CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET).result(); if (result == Tristate.UNDEFINED && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUNGEE_CONFIG_PERMISSIONS)) { return; // just use the result provided by the proxy when the event was created } @@ -122,7 +122,7 @@ public class BungeePermissionCheckListener implements Listener { Tristate result = Tristate.of(e.hasPermission()); VerboseCheckTarget target = VerboseCheckTarget.internal(e.getSender().getName()); - this.plugin.getVerboseHandler().offerPermissionCheckEvent(Origin.PLATFORM_PERMISSION_CHECK, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(result)); + this.plugin.getVerboseHandler().offerPermissionCheckEvent(CheckOrigin.PLATFORM_API_HAS_PERMISSION, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(result)); this.plugin.getPermissionRegistry().offer(permission); } @@ -139,7 +139,7 @@ public class BungeePermissionCheckListener implements Listener { Tristate result = e.getResult(); VerboseCheckTarget target = VerboseCheckTarget.internal(e.getSender().getName()); - this.plugin.getVerboseHandler().offerPermissionCheckEvent(Origin.PLATFORM_LOOKUP_CHECK, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(result)); + this.plugin.getVerboseHandler().offerPermissionCheckEvent(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(result)); this.plugin.getPermissionRegistry().offer(permission); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiUser.java b/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiUser.java index 113ce698b..52e8c8961 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiUser.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiUser.java @@ -30,7 +30,7 @@ import com.google.common.base.Preconditions; import me.lucko.luckperms.common.cacheddata.UserCachedDataManager; import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.node.types.Inheritance; -import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.model.data.DataMutateResult; import net.luckperms.api.model.data.DataType; @@ -72,7 +72,7 @@ public class ApiUser extends ApiPermissionHolder implements net.luckperms.api.mo @Override public @NonNull String getPrimaryGroup() { - String value = this.handle.getCachedData().getMetaData(this.handle.getQueryOptions()).getPrimaryGroup(MetaCheckEvent.Origin.LUCKPERMS_API); + String value = this.handle.getCachedData().getMetaData(this.handle.getQueryOptions()).getPrimaryGroup(CheckOrigin.LUCKPERMS_API); Objects.requireNonNull(value, "value"); // assert nonnull return value; } diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java index ccf2a0c4a..581c11663 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java @@ -27,7 +27,7 @@ package me.lucko.luckperms.common.cacheddata; import me.lucko.luckperms.common.cache.LoadingMap; import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator; -import me.lucko.luckperms.common.cacheddata.type.MetaCache; +import me.lucko.luckperms.common.cacheddata.type.MonitoredMetaCache; import me.lucko.luckperms.common.cacheddata.type.PermissionCache; import me.lucko.luckperms.common.calculator.CalculatorFactory; import me.lucko.luckperms.common.calculator.PermissionCalculator; @@ -40,6 +40,7 @@ import net.luckperms.api.cacheddata.CachedMetaData; import net.luckperms.api.cacheddata.CachedPermissionData; import net.luckperms.api.metastacking.MetaStackDefinition; import net.luckperms.api.node.ChatMetaType; +import net.luckperms.api.node.Node; import net.luckperms.api.query.QueryOptions; import org.checkerframework.checker.nullness.qual.NonNull; @@ -59,7 +60,7 @@ import java.util.function.IntFunction; public abstract class AbstractCachedDataManager implements CachedDataManager { private final LuckPermsPlugin plugin; private final AbstractContainer permission; - private final AbstractContainer meta; + private final AbstractContainer meta; protected AbstractCachedDataManager(LuckPermsPlugin plugin) { this.plugin = plugin; @@ -87,7 +88,7 @@ public abstract class AbstractCachedDataManager implements CachedDataManager { } @Override - public @NonNull MetaCache getMetaData(@NonNull QueryOptions queryOptions) { + public @NonNull MonitoredMetaCache getMetaData(@NonNull QueryOptions queryOptions) { return this.meta.get(queryOptions); } @@ -97,7 +98,7 @@ public abstract class AbstractCachedDataManager implements CachedDataManager { } @Override - public @NonNull MetaCache getMetaData() { + public @NonNull MonitoredMetaCache getMetaData() { return getMetaData(getQueryOptions()); } @@ -139,7 +140,7 @@ public abstract class AbstractCachedDataManager implements CachedDataManager { * @param the map type * @return the resolved permissions */ - protected abstract > M resolvePermissions(IntFunction mapFactory, QueryOptions queryOptions); + protected abstract > M resolvePermissions(IntFunction mapFactory, QueryOptions queryOptions); /** * Resolves the owners meta data for the given {@link QueryOptions}. @@ -153,18 +154,18 @@ public abstract class AbstractCachedDataManager implements CachedDataManager { Objects.requireNonNull(queryOptions, "queryOptions"); CacheMetadata metadata = getMetadataForQueryOptions(queryOptions); - ConcurrentHashMap sourcePermissions = resolvePermissions(ConcurrentHashMap::new, queryOptions); + ConcurrentHashMap sourcePermissions = resolvePermissions(ConcurrentHashMap::new, queryOptions); return new PermissionCache(queryOptions, metadata, getCalculatorFactory(), sourcePermissions); } - private MetaCache calculateMeta(QueryOptions queryOptions) { + private MonitoredMetaCache calculateMeta(QueryOptions queryOptions) { Objects.requireNonNull(queryOptions, "queryOptions"); CacheMetadata metadata = getMetadataForQueryOptions(queryOptions); MetaAccumulator accumulator = newAccumulator(queryOptions); resolveMeta(accumulator, queryOptions); - return new MetaCache(this.plugin, queryOptions, metadata, accumulator); + return new MonitoredMetaCache(this.plugin, queryOptions, metadata, accumulator); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/HolderCachedDataManager.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/HolderCachedDataManager.java index 6938e7651..ca48561ac 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/HolderCachedDataManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/HolderCachedDataManager.java @@ -32,6 +32,7 @@ import me.lucko.luckperms.common.model.PermissionHolder; import net.luckperms.api.metastacking.MetaStackDefinition; import net.luckperms.api.node.ChatMetaType; +import net.luckperms.api.node.Node; import net.luckperms.api.query.QueryOptions; import java.util.Map; @@ -75,7 +76,7 @@ public abstract class HolderCachedDataManager extend } @Override - protected > M resolvePermissions(IntFunction mapFactory, QueryOptions queryOptions) { + protected > M resolvePermissions(IntFunction mapFactory, QueryOptions queryOptions) { return this.holder.exportPermissions(mapFactory, queryOptions, true, getPlugin().getConfiguration().get(ConfigKeys.APPLYING_SHORTHAND)); } diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/Result.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/Result.java new file mode 100644 index 000000000..be4294eea --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/Result.java @@ -0,0 +1,60 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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 the result type + */ +public interface Result { + + /** + * 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 overriddenResult(); + +} diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/StringResult.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/StringResult.java new file mode 100644 index 000000000..8efaff7f5 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/StringResult.java @@ -0,0 +1,107 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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 the node type + */ +public final class StringResult implements Result { + + /** 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 overriddenResult; + + public StringResult(String result, N node, StringResult 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 overriddenResult() { + return this.overriddenResult; + } + + public void setOverriddenResult(StringResult overriddenResult) { + this.overriddenResult = overriddenResult; + } + + public StringResult 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 StringResult nullResult() { + return (StringResult) NULL_RESULT; + } + + public static StringResult of(String result) { + return new StringResult<>(result, null, null); + } + + public static StringResult of(MetaNode node) { + return new StringResult<>(node.getMetaValue(), node, null); + } + + public static StringResult> of(ChatMetaNode node) { + return new StringResult<>(node.getMetaValue(), node, null); + } + + public static StringResult> of(String result, ChatMetaNode node) { + return new StringResult<>(result, node, null); + } +} diff --git a/common/src/main/java/me/lucko/luckperms/common/calculator/result/TristateResult.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/TristateResult.java similarity index 50% rename from common/src/main/java/me/lucko/luckperms/common/calculator/result/TristateResult.java rename to common/src/main/java/me/lucko/luckperms/common/cacheddata/result/TristateResult.java index 931b801a7..bbdb0dd97 100644 --- a/common/src/main/java/me/lucko/luckperms/common/calculator/result/TristateResult.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/TristateResult.java @@ -23,78 +23,110 @@ * SOFTWARE. */ -package me.lucko.luckperms.common.calculator.result; +package me.lucko.luckperms.common.cacheddata.result; import me.lucko.luckperms.common.calculator.PermissionCalculator; import me.lucko.luckperms.common.calculator.processor.PermissionProcessor; +import net.luckperms.api.node.Node; import net.luckperms.api.util.Tristate; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Represents the result of a {@link PermissionCalculator} lookup. */ -public final class TristateResult { +public final class TristateResult implements Result { - private static final Factory NULL_FACTORY = new Factory(null, null); - public static final TristateResult UNDEFINED = new TristateResult(Tristate.UNDEFINED, null, null); - - public static TristateResult of(Tristate result) { - return NULL_FACTORY.result(result); - } - + /** The result */ private final Tristate result; + /** The node that caused the result */ + private final Node node; + /** The permission processor that provided the result */ private final Class processorClass; - private final String cause; + /** A reference to another result that this one overrides */ + private TristateResult overriddenResult; - private TristateResult(Tristate result, Class processorClass, String cause) { + private TristateResult(Tristate result, Node node, Class processorClass) { this.result = result; + this.node = node; this.processorClass = processorClass; - this.cause = cause; } - public Tristate result() { + @Override + public @NonNull Tristate result() { return this.result; } - public Class processorClass() { + @Override + public @Nullable Node node() { + return this.node; + } + + public @Nullable Class processorClass() { return this.processorClass; } - public String cause() { - return this.cause; + public @Nullable String processorClassFriendly() { + if (this.processorClass == null) { + return null; + } else if (this.processorClass.getName().startsWith("me.lucko.luckperms.")) { + String simpleName = this.processorClass.getSimpleName(); + String platform = this.processorClass.getName().split("\\.")[3]; + return platform + "." + simpleName; + } else { + return this.processorClass.getName(); + } + } + + @Override + public @Nullable TristateResult overriddenResult() { + return this.overriddenResult; + } + + public void setOverriddenResult(TristateResult overriddenResult) { + this.overriddenResult = overriddenResult; } @Override public String toString() { return "TristateResult(" + "result=" + this.result + ", " + + "node=" + this.node + ", " + "processorClass=" + this.processorClass + ", " + - "cause=" + this.cause + ')'; + "overriddenResult=" + this.overriddenResult + ')'; + } + + private static final TristateResult TRUE = new TristateResult(Tristate.TRUE, null,null); + private static final TristateResult FALSE = new TristateResult(Tristate.FALSE, null,null); + public static final TristateResult UNDEFINED = new TristateResult(Tristate.UNDEFINED, null,null); + + public static TristateResult forMonitoredResult(Tristate result) { + switch (result) { + case TRUE: + return TRUE; + case FALSE: + return FALSE; + case UNDEFINED: + return UNDEFINED; + default: + throw new AssertionError(); + } } public static final class Factory { private final Class processorClass; - private final TristateResult trueResult; - private final TristateResult falseResult; - - public Factory(Class 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 processorClass) { - this(processorClass, null); + this.processorClass = processorClass; } public TristateResult result(Tristate result) { switch (result) { case TRUE: - return this.trueResult; case FALSE: - return this.falseResult; + return new TristateResult(result, null, this.processorClass); case UNDEFINED: return UNDEFINED; default: @@ -102,11 +134,12 @@ public final class TristateResult { } } - public TristateResult result(Tristate result, String cause) { - if (result == Tristate.UNDEFINED) { - return UNDEFINED; - } - return new TristateResult(result, this.processorClass, cause); + public TristateResult result(@NonNull Node node) { + return new TristateResult(Tristate.of(node.getValue()), node, this.processorClass); + } + + public TristateResult resultWithOverride(@NonNull Node node, Tristate result) { + return new TristateResult(result, node, this.processorClass); } } } diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaAccumulator.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaAccumulator.java index fd6dfa8b9..2252387c8 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaAccumulator.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaAccumulator.java @@ -28,6 +28,7 @@ package me.lucko.luckperms.common.cacheddata.type; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; +import me.lucko.luckperms.common.cacheddata.result.StringResult; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.node.types.Weight; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; @@ -35,6 +36,7 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import net.luckperms.api.metastacking.MetaStackDefinition; import net.luckperms.api.node.ChatMetaType; import net.luckperms.api.node.Node; +import net.luckperms.api.node.types.ChatMetaNode; import net.luckperms.api.node.types.MetaNode; import net.luckperms.api.node.types.PrefixNode; import net.luckperms.api.node.types.SuffixNode; @@ -75,9 +77,9 @@ public class MetaAccumulator { private final AtomicReference state = new AtomicReference<>(State.ACCUMULATING); - private final ListMultimap meta; - private final SortedMap prefixes; - private final SortedMap suffixes; + private final ListMultimap> meta; + private final SortedMap>> prefixes; + private final SortedMap>> suffixes; private int weight = 0; private String primaryGroup; @@ -119,10 +121,10 @@ public class MetaAccumulator { // perform final changes if (!this.meta.containsKey(Weight.NODE_KEY) && this.weight != 0) { - this.meta.put(Weight.NODE_KEY, String.valueOf(this.weight)); + this.meta.put(Weight.NODE_KEY, StringResult.of(String.valueOf(this.weight))); } if (this.primaryGroup != null && !this.meta.containsKey("primarygroup")) { - this.meta.put("primarygroup", this.primaryGroup); + this.meta.put("primarygroup", StringResult.of(this.primaryGroup)); } this.seenNodeKeys = null; // free up for GC @@ -146,27 +148,22 @@ public class MetaAccumulator { if (n instanceof MetaNode) { MetaNode mn = (MetaNode) n; - this.meta.put(mn.getMetaKey(), mn.getMetaValue()); + this.meta.put(mn.getMetaKey(), StringResult.of(mn)); } if (n instanceof PrefixNode) { PrefixNode pn = (PrefixNode) n; - this.prefixes.putIfAbsent(pn.getPriority(), pn.getMetaValue()); + this.prefixes.putIfAbsent(pn.getPriority(), StringResult.of(pn)); this.prefixAccumulator.offer(pn); } if (n instanceof SuffixNode) { SuffixNode pn = (SuffixNode) n; - this.suffixes.putIfAbsent(pn.getPriority(), pn.getMetaValue()); + this.suffixes.putIfAbsent(pn.getPriority(), StringResult.of(pn)); this.suffixAccumulator.offer(pn); } } - public void accumulateMeta(String key, String value) { - ensureState(State.ACCUMULATING); - this.meta.put(key, value); - } - public void accumulateWeight(int weight) { ensureState(State.ACCUMULATING); this.weight = Math.max(this.weight, weight); @@ -179,22 +176,22 @@ public class MetaAccumulator { // read methods - public ListMultimap getMeta() { + public ListMultimap> getMeta() { ensureState(State.COMPLETE); return this.meta; } - public Map getChatMeta(ChatMetaType type) { + public Map>> getChatMeta(ChatMetaType type) { ensureState(State.COMPLETE); return type == ChatMetaType.PREFIX ? this.prefixes : this.suffixes; } - public SortedMap getPrefixes() { + public SortedMap>> getPrefixes() { ensureState(State.COMPLETE); return this.prefixes; } - public SortedMap getSuffixes() { + public SortedMap>> getSuffixes() { ensureState(State.COMPLETE); return this.suffixes; } @@ -219,14 +216,14 @@ public class MetaAccumulator { return this.suffixDefinition; } - public String getPrefix() { + public StringResult> getPrefix() { ensureState(State.COMPLETE); - return this.prefixAccumulator.toFormattedString(); + return this.prefixAccumulator.toResult(); } - public String getSuffix() { + public StringResult> getSuffix() { ensureState(State.COMPLETE); - return this.suffixAccumulator.toFormattedString(); + return this.suffixAccumulator.toResult(); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaCache.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaCache.java index f65b7678a..cfde15f96 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaCache.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaCache.java @@ -26,102 +26,196 @@ package me.lucko.luckperms.common.cacheddata.type; import com.google.common.collect.ForwardingMap; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSortedMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimaps; -import me.lucko.luckperms.common.cacheddata.CacheMetadata; -import me.lucko.luckperms.common.node.types.Prefix; -import me.lucko.luckperms.common.node.types.Suffix; +import me.lucko.luckperms.common.cacheddata.UsageTracked; +import me.lucko.luckperms.common.cacheddata.result.StringResult; +import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; -import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.cacheddata.CachedMetaData; +import net.luckperms.api.metastacking.MetaStackDefinition; +import net.luckperms.api.node.types.ChatMetaNode; +import net.luckperms.api.node.types.MetaNode; import net.luckperms.api.query.QueryOptions; +import net.luckperms.api.query.meta.MetaValueSelector; +import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.Objects; +import java.util.SortedMap; /** * Holds cached meta for a given context */ -public class MetaCache extends SimpleMetaCache implements CachedMetaData { +public class MetaCache extends UsageTracked implements CachedMetaData { - /** The plugin instance */ private final LuckPermsPlugin plugin; - /** The metadata for this cache */ - private final CacheMetadata metadata; + /** The query options this container is holding data for */ + private final QueryOptions queryOptions; - public MetaCache(LuckPermsPlugin plugin, QueryOptions queryOptions, CacheMetadata metadata, MetaAccumulator sourceMeta) { - super(plugin, queryOptions, sourceMeta); + /* The data */ + private final Map>> meta; + private final Map> flattenedMeta; + private final SortedMap>> prefixes; + private final SortedMap>> suffixes; + private final int weight; + private final String primaryGroup; + private final MetaStackDefinition prefixDefinition; + private final MetaStackDefinition suffixDefinition; + private final StringResult> prefix; + private final StringResult> suffix; + + public MetaCache(LuckPermsPlugin plugin, QueryOptions queryOptions, MetaAccumulator sourceMeta) { this.plugin = plugin; - this.metadata = metadata; + this.queryOptions = queryOptions; + + Map>> 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> builder = ImmutableMap.builder(); + for (Map.Entry>> 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 getMetaValue(String key, CheckOrigin origin) { + Objects.requireNonNull(key, "key"); + return this.flattenedMeta.getOrDefault(key.toLowerCase(Locale.ROOT), StringResult.nullResult()); } @Override - public String getMetaValue(String key, MetaCheckEvent.Origin origin) { - String value = super.getMetaValue(key, origin); - this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), key, String.valueOf(value)); - return value; + public final @Nullable String getMetaValue(@NonNull String key) { + return getMetaValue(key, CheckOrigin.LUCKPERMS_API).result(); + } + + public @NonNull StringResult> getPrefix(CheckOrigin origin) { + return this.prefix; } @Override - public String getPrefix(MetaCheckEvent.Origin origin) { - String value = super.getPrefix(origin); - this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Prefix.NODE_KEY, String.valueOf(value)); - return value; + public final @Nullable String getPrefix() { + return getPrefix(CheckOrigin.LUCKPERMS_API).result(); + } + + public @NonNull StringResult> getSuffix(CheckOrigin origin) { + return this.suffix; } @Override - public String getSuffix(MetaCheckEvent.Origin origin) { - String value = super.getSuffix(origin); - this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Suffix.NODE_KEY, String.valueOf(value)); - return value; + public final @Nullable String getSuffix() { + return getSuffix(CheckOrigin.LUCKPERMS_API).result(); + } + + protected Map>> getMetaResults(CheckOrigin origin) { + return this.meta; + } + + public final Map> getMeta(CheckOrigin origin) { + return Maps.transformValues(getMetaResults(origin), list -> Lists.transform(list, StringResult::result)); } @Override - public Map> getMeta(MetaCheckEvent.Origin origin) { - return new MonitoredMetaMap(super.getMeta(origin), origin); + public final @NonNull Map> getMeta() { + return getMeta(CheckOrigin.LUCKPERMS_API); } @Override - public int getWeight(MetaCheckEvent.Origin origin) { - int value = super.getWeight(origin); - this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), "weight", String.valueOf(value)); - return value; + public @NonNull SortedMap getPrefixes() { + return Maps.transformValues(this.prefixes, StringResult::result); } @Override - public @Nullable String getPrimaryGroup(MetaCheckEvent.Origin origin) { - String value = super.getPrimaryGroup(origin); - this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), "primarygroup", String.valueOf(value)); - return value; + public @NonNull SortedMap getSuffixes() { + return Maps.transformValues(this.suffixes, StringResult::result); } - private final class MonitoredMetaMap extends ForwardingMap> { - private final Map> delegate; - private final MetaCheckEvent.Origin origin; + public int getWeight(CheckOrigin origin) { + return this.weight; + } - private MonitoredMetaMap(Map> 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>> { + private final Map>> delegate; + + private LowerCaseMetaMap(Map>> delegate) { this.delegate = delegate; - this.origin = origin; } @Override - protected Map> delegate() { + protected Map>> delegate() { return this.delegate; } @Override - public List get(Object k) { + public List> get(Object k) { if (k == null) { return null; } String key = (String) k; - List values = super.get(key); - MetaCache.this.plugin.getVerboseHandler().offerMetaCheckEvent(this.origin, MetaCache.this.metadata.getVerboseCheckInfo(), MetaCache.this.metadata.getQueryOptions(), key, String.valueOf(values)); - return values; + return super.get(key.toLowerCase(Locale.ROOT)); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaStackAccumulator.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaStackAccumulator.java index 89caedbd2..124dd7ca1 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaStackAccumulator.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaStackAccumulator.java @@ -25,6 +25,8 @@ package me.lucko.luckperms.common.cacheddata.type; +import me.lucko.luckperms.common.cacheddata.result.StringResult; + import net.luckperms.api.metastacking.MetaStackDefinition; import net.luckperms.api.metastacking.MetaStackElement; import net.luckperms.api.node.ChatMetaType; @@ -36,6 +38,8 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; public class MetaStackAccumulator { private final MetaStackDefinition definition; @@ -57,6 +61,13 @@ public class MetaStackAccumulator { } } + public List> getElements() { + return this.entries.stream() + .map(Entry::getNode) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + public String toFormattedString() { List elements = new LinkedList<>(); for (Entry entry : this.entries) { @@ -94,6 +105,35 @@ public class MetaStackAccumulator { return sb.toString(); } + public StringResult> toResult() { + String formatted = toFormattedString(); + if (formatted == null) { + return StringResult.nullResult(); + } + + List> elements = getElements(); + + switch (elements.size()) { + case 0: + throw new AssertionError(); + case 1: + return StringResult.of(formatted, elements.get(0)); + default: { + Iterator> it = elements.iterator(); + StringResult> result = StringResult.of(formatted, it.next()); + + StringResult> root = result; + while (it.hasNext()) { + StringResult> nested = StringResult.of(it.next()); + root.setOverriddenResult(nested); + root = nested; + } + + return result; + } + } + } + private static final class Entry { private final MetaStackElement element; private final ChatMetaType type; diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MonitoredMetaCache.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MonitoredMetaCache.java new file mode 100644 index 000000000..fd014eecd --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MonitoredMetaCache.java @@ -0,0 +1,152 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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 getMetaValue(String key, CheckOrigin origin) { + StringResult value = super.getMetaValue(key, origin); + this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), key, value); + return value; + } + + @Override + @NonNull + public StringResult> getPrefix(CheckOrigin origin) { + StringResult> 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> getSuffix(CheckOrigin origin) { + StringResult> value = super.getSuffix(origin); + this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Suffix.NODE_KEY, value); + return value; + } + + @Override + protected Map>> 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>> { + private final Map>> delegate; + private final CheckOrigin origin; + + private MonitoredMetaMap(Map>> delegate, CheckOrigin origin) { + this.delegate = delegate; + this.origin = origin; + } + + @Override + protected Map>> delegate() { + return this.delegate; + } + + @Override + public List> get(Object k) { + if (k == null) { + return null; + } + + String key = (String) k; + List> 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> it = values.iterator(); + StringResult result = it.next().copy(); + + StringResult root = result; + while (it.hasNext()) { + StringResult 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; + } + } + +} diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/PermissionCache.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/PermissionCache.java index 652a46c9a..c26d5a4c4 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/PermissionCache.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/PermissionCache.java @@ -25,14 +25,17 @@ package me.lucko.luckperms.common.cacheddata.type; +import com.google.common.collect.Maps; + import me.lucko.luckperms.common.cacheddata.CacheMetadata; import me.lucko.luckperms.common.cacheddata.UsageTracked; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.calculator.CalculatorFactory; import me.lucko.luckperms.common.calculator.PermissionCalculator; -import me.lucko.luckperms.common.calculator.result.TristateResult; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.cacheddata.CachedPermissionData; +import net.luckperms.api.node.Node; import net.luckperms.api.query.QueryOptions; import net.luckperms.api.util.Tristate; @@ -55,12 +58,12 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat /** * The raw set of permission strings. */ - private final Map permissions; + private final Map permissions; /** - * An immutable copy of {@link #permissions} + * A string->boolean view of {@link #permissions} */ - private final Map permissionsUnmodifiable; + private final Map permissionsView; /** * The calculator instance responsible for resolving the raw permission strings in the permission map. @@ -69,10 +72,10 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat */ private final PermissionCalculator calculator; - public PermissionCache(QueryOptions queryOptions, CacheMetadata metadata, CalculatorFactory calculatorFactory, ConcurrentHashMap sourcePermissions) { + public PermissionCache(QueryOptions queryOptions, CacheMetadata metadata, CalculatorFactory calculatorFactory, ConcurrentHashMap sourcePermissions) { this.queryOptions = queryOptions; this.permissions = sourcePermissions; - this.permissionsUnmodifiable = Collections.unmodifiableMap(this.permissions); + this.permissionsView = Collections.unmodifiableMap(Maps.transformValues(this.permissions, Node::getValue)); this.calculator = calculatorFactory.build(queryOptions, metadata); this.calculator.setSourcePermissions(this.permissions); @@ -89,10 +92,10 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat @Override public @NonNull Map getPermissionMap() { - return this.permissionsUnmodifiable; + return this.permissionsView; } - public TristateResult checkPermission(String permission, PermissionCheckEvent.Origin origin) { + public TristateResult checkPermission(String permission, CheckOrigin origin) { if (permission == null) { throw new NullPointerException("permission"); } @@ -101,7 +104,7 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat @Override public @NonNull Tristate checkPermission(@NonNull String permission) { - return checkPermission(permission, PermissionCheckEvent.Origin.LUCKPERMS_API).result(); + return checkPermission(permission, CheckOrigin.LUCKPERMS_API).result(); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/SimpleMetaCache.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/SimpleMetaCache.java deleted file mode 100644 index 76e9c105a..000000000 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/SimpleMetaCache.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * 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> meta; - protected final Map flattenedMeta; - protected final SortedMap prefixes; - protected final SortedMap 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> 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 builder = ImmutableMap.builder(); - for (Map.Entry> 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> getMeta(MetaCheckEvent.Origin origin) { - return this.meta; - } - - @Override - public final @NonNull Map> getMeta() { - return getMeta(MetaCheckEvent.Origin.LUCKPERMS_API); - } - - @Override - public @NonNull SortedMap getPrefixes() { - return this.prefixes; - } - - @Override - public @NonNull SortedMap 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> { - private final Map> delegate; - - private LowerCaseMetaMap(Map> delegate) { - this.delegate = delegate; - } - - @Override - protected Map> delegate() { - return this.delegate; - } - - @Override - public List get(Object k) { - if (k == null) { - return null; - } - - String key = (String) k; - return super.get(key.toLowerCase(Locale.ROOT)); - } - } - -} diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/SimpleMetaValueSelector.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/SimpleMetaValueSelector.java index f7ed17485..c033dd41b 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/SimpleMetaValueSelector.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/SimpleMetaValueSelector.java @@ -25,6 +25,7 @@ package me.lucko.luckperms.common.cacheddata.type; +import net.luckperms.api.node.types.MetaNode; import net.luckperms.api.query.meta.MetaValueSelector; import org.checkerframework.checker.nullness.qual.NonNull; @@ -43,7 +44,7 @@ public class SimpleMetaValueSelector implements MetaValueSelector { } @Override - public @NonNull String selectValue(@NonNull String key, @NonNull List values) { + public @NonNull MetaNode selectValue(@NonNull String key, @NonNull List values) { switch (values.size()) { case 0: throw new IllegalArgumentException("values is empty"); @@ -57,7 +58,7 @@ public class SimpleMetaValueSelector implements MetaValueSelector { public enum Strategy { INHERITANCE { @Override - public String select(List values) { + public MetaNode select(List values) { return values.get(0); } }, @@ -65,7 +66,7 @@ public class SimpleMetaValueSelector implements MetaValueSelector { private final DoubleSelectionPredicate selection = (value, current) -> value > current; @Override - public String select(List values) { + public MetaNode select(List values) { return selectNumber(values, this.selection); } }, @@ -73,12 +74,12 @@ public class SimpleMetaValueSelector implements MetaValueSelector { private final DoubleSelectionPredicate selection = (value, current) -> value < current; @Override - public String select(List values) { + public MetaNode select(List values) { return selectNumber(values, this.selection); } }; - public abstract String select(List values); + public abstract MetaNode select(List values); public static Strategy parse(String s) { try { @@ -94,15 +95,16 @@ public class SimpleMetaValueSelector implements MetaValueSelector { boolean shouldSelect(double value, double current); } - private static String selectNumber(List values, DoubleSelectionPredicate selection) { + private static MetaNode selectNumber(List values, DoubleSelectionPredicate selection) { double current = 0; - String selected = null; + MetaNode selected = null; - for (String value : values) { + for (MetaNode node : values) { + String value = node.getMetaValue(); try { double parse = Double.parseDouble(value); if (selected == null || selection.shouldSelect(parse, current)) { - selected = value; + selected = node; current = parse; } } catch (NumberFormatException e) { diff --git a/common/src/main/java/me/lucko/luckperms/common/calculator/PermissionCalculator.java b/common/src/main/java/me/lucko/luckperms/common/calculator/PermissionCalculator.java index 1c1d73829..c3de5f829 100644 --- a/common/src/main/java/me/lucko/luckperms/common/calculator/PermissionCalculator.java +++ b/common/src/main/java/me/lucko/luckperms/common/calculator/PermissionCalculator.java @@ -27,10 +27,12 @@ package me.lucko.luckperms.common.calculator; import me.lucko.luckperms.common.cache.LoadingMap; import me.lucko.luckperms.common.cacheddata.CacheMetadata; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.calculator.processor.PermissionProcessor; -import me.lucko.luckperms.common.calculator.result.TristateResult; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; + +import net.luckperms.api.node.Node; import org.checkerframework.checker.nullness.qual.NonNull; @@ -71,7 +73,7 @@ public class PermissionCalculator implements Function { * @param origin marks where this check originated from * @return the result */ - public TristateResult checkPermission(String permission, PermissionCheckEvent.Origin origin) { + public TristateResult checkPermission(String permission, CheckOrigin origin) { // get the result TristateResult result = this.lookupCache.get(permission); @@ -106,7 +108,7 @@ public class PermissionCalculator implements Function { * * @param sourceMap the source map */ - public synchronized void setSourcePermissions(Map sourceMap) { + public synchronized void setSourcePermissions(Map sourceMap) { for (PermissionProcessor processor : this.processors) { processor.setSource(sourceMap); processor.refresh(); diff --git a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractOverrideWildcardProcessor.java b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractOverrideWildcardProcessor.java new file mode 100644 index 000000000..e8546ea42 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractOverrideWildcardProcessor.java @@ -0,0 +1,58 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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; + } + +} diff --git a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractPermissionProcessor.java b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractPermissionProcessor.java index 198a7b69d..05fb3f705 100644 --- a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractPermissionProcessor.java +++ b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractPermissionProcessor.java @@ -25,26 +25,28 @@ package me.lucko.luckperms.common.calculator.processor; -import me.lucko.luckperms.common.calculator.result.TristateResult; - -import java.util.Collections; -import java.util.Map; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; +/** + * Abstract implementation of {@link PermissionProcessor} that splits behaviour for normal + * permission checks and override checks into two separate methods. + */ public abstract class AbstractPermissionProcessor implements PermissionProcessor { - protected Map sourceMap = Collections.emptyMap(); @Override - public void setSource(Map sourceMap) { - this.sourceMap = sourceMap; - } - - @Override - public TristateResult hasPermission(TristateResult prev, String permission) { + public final TristateResult hasPermission(TristateResult prev, String permission) { if (prev != TristateResult.UNDEFINED) { - return prev; + return hasPermissionOverride(prev, permission); } return hasPermission(permission); } - public abstract TristateResult hasPermission(String permission); + // Performs a regular permission check + protected abstract TristateResult hasPermission(String permission); + + // Performs an override permission check + protected TristateResult hasPermissionOverride(TristateResult prev, String permission) { + return prev; + } + } diff --git a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractSourceBasedProcessor.java b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractSourceBasedProcessor.java new file mode 100644 index 000000000..8b50500a3 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/AbstractSourceBasedProcessor.java @@ -0,0 +1,41 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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 sourceMap = Collections.emptyMap(); + + @Override + public void setSource(Map sourceMap) { + this.sourceMap = sourceMap; + } + +} diff --git a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/DirectProcessor.java b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/DirectProcessor.java index 2a19212d5..f2ab6828d 100644 --- a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/DirectProcessor.java +++ b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/DirectProcessor.java @@ -25,16 +25,14 @@ package me.lucko.luckperms.common.calculator.processor; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; -import net.luckperms.api.util.Tristate; - -public class DirectProcessor extends AbstractPermissionProcessor implements PermissionProcessor { +public class DirectProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor { private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(DirectProcessor.class); @Override public TristateResult hasPermission(String permission) { - return RESULT_FACTORY.result(Tristate.of(this.sourceMap.get(permission))); + return RESULT_FACTORY.result(this.sourceMap.get(permission)); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/PermissionProcessor.java b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/PermissionProcessor.java index 0bca9d5e4..9920c74ce 100644 --- a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/PermissionProcessor.java +++ b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/PermissionProcessor.java @@ -25,8 +25,10 @@ package me.lucko.luckperms.common.calculator.processor; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.calculator.PermissionCalculator; -import me.lucko.luckperms.common.calculator.result.TristateResult; + +import net.luckperms.api.node.Node; import java.util.Map; @@ -52,7 +54,7 @@ public interface PermissionProcessor { * * @param sourceMap the source map */ - default void setSource(Map sourceMap) { + default void setSource(Map sourceMap) { } diff --git a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/RegexProcessor.java b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/RegexProcessor.java index ae844f57c..d6a32505a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/RegexProcessor.java +++ b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/RegexProcessor.java @@ -28,17 +28,17 @@ package me.lucko.luckperms.common.calculator.processor; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.node.types.RegexPermission; -import net.luckperms.api.util.Tristate; +import net.luckperms.api.node.Node; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.regex.Pattern; -public class RegexProcessor extends AbstractPermissionProcessor implements PermissionProcessor { +public class RegexProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor { private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(RegexProcessor.class); private List> regexPermissions = Collections.emptyList(); @@ -56,7 +56,7 @@ public class RegexProcessor extends AbstractPermissionProcessor implements Permi @Override public void refresh() { ImmutableList.Builder> builder = ImmutableList.builder(); - for (Map.Entry e : this.sourceMap.entrySet()) { + for (Map.Entry e : this.sourceMap.entrySet()) { RegexPermission.Builder regexPerm = RegexPermission.parse(e.getKey()); if (regexPerm == null) { continue; @@ -67,7 +67,7 @@ public class RegexProcessor extends AbstractPermissionProcessor implements Permi continue; } - TristateResult value = RESULT_FACTORY.result(Tristate.of(e.getValue()), "pattern: " + pattern.pattern()); + TristateResult value = RESULT_FACTORY.result(e.getValue()); builder.add(Maps.immutableEntry(pattern, value)); } this.regexPermissions = builder.build(); diff --git a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/SpongeWildcardProcessor.java b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/SpongeWildcardProcessor.java index 382f29611..01c8fbb8d 100644 --- a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/SpongeWildcardProcessor.java +++ b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/SpongeWildcardProcessor.java @@ -25,12 +25,12 @@ package me.lucko.luckperms.common.calculator.processor; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.node.AbstractNode; -import net.luckperms.api.util.Tristate; +import net.luckperms.api.node.Node; -public class SpongeWildcardProcessor extends AbstractPermissionProcessor implements PermissionProcessor { +public class SpongeWildcardProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor { private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(SpongeWildcardProcessor.class); @Override @@ -45,9 +45,9 @@ public class SpongeWildcardProcessor extends AbstractPermissionProcessor impleme node = node.substring(0, endIndex); if (!node.isEmpty()) { - Tristate t = Tristate.of(this.sourceMap.get(node)); - if (t != Tristate.UNDEFINED) { - return RESULT_FACTORY.result(t, "match: " + node); + Node n = this.sourceMap.get(node); + if (n != null) { + return RESULT_FACTORY.result(n); } } } diff --git a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/WildcardProcessor.java b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/WildcardProcessor.java index fbb0faab9..d1d08b2f9 100644 --- a/common/src/main/java/me/lucko/luckperms/common/calculator/processor/WildcardProcessor.java +++ b/common/src/main/java/me/lucko/luckperms/common/calculator/processor/WildcardProcessor.java @@ -27,15 +27,16 @@ package me.lucko.luckperms.common.calculator.processor; import com.google.common.collect.ImmutableMap; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.node.AbstractNode; +import net.luckperms.api.node.Node; import net.luckperms.api.util.Tristate; import java.util.Collections; import java.util.Map; -public class WildcardProcessor extends AbstractPermissionProcessor implements PermissionProcessor { +public class WildcardProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor { private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(WildcardProcessor.class); public static final String WILDCARD_SUFFIX = ".*"; @@ -78,22 +79,22 @@ public class WildcardProcessor extends AbstractPermissionProcessor implements Pe @Override public void refresh() { ImmutableMap.Builder builder = ImmutableMap.builder(); - for (Map.Entry e : this.sourceMap.entrySet()) { + for (Map.Entry e : this.sourceMap.entrySet()) { String key = e.getKey(); if (!key.endsWith(WILDCARD_SUFFIX) || key.length() <= 2) { continue; } key = key.substring(0, key.length() - 2); - TristateResult value = RESULT_FACTORY.result(Tristate.of(e.getValue()), "match: " + key); + TristateResult value = RESULT_FACTORY.result(e.getValue()); builder.put(key, value); } this.wildcardPermissions = builder.build(); - Tristate state = Tristate.of(this.sourceMap.get(ROOT_WILDCARD)); - if (state == Tristate.UNDEFINED) { - state = Tristate.of(this.sourceMap.get(ROOT_WILDCARD_WITH_QUOTES)); + Node rootWildcard = this.sourceMap.get(ROOT_WILDCARD); + if (rootWildcard == null) { + rootWildcard = this.sourceMap.get(ROOT_WILDCARD_WITH_QUOTES); } - this.rootWildcardState = RESULT_FACTORY.result(state, "root"); + this.rootWildcardState = rootWildcard == null ? TristateResult.UNDEFINED : RESULT_FACTORY.result(rootWildcard); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/command/access/ArgumentPermissions.java b/common/src/main/java/me/lucko/luckperms/common/command/access/ArgumentPermissions.java index 1e04ce33d..b6b678f05 100644 --- a/common/src/main/java/me/lucko/luckperms/common/command/access/ArgumentPermissions.java +++ b/common/src/main/java/me/lucko/luckperms/common/command/access/ArgumentPermissions.java @@ -25,9 +25,9 @@ package me.lucko.luckperms.common.command.access; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.cacheddata.type.PermissionCache; import me.lucko.luckperms.common.calculator.processor.DirectProcessor; -import me.lucko.luckperms.common.calculator.result.TristateResult; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.HolderType; @@ -38,7 +38,7 @@ import me.lucko.luckperms.common.node.types.Inheritance; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.sender.Sender; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.context.Context; import net.luckperms.api.context.ContextSet; @@ -305,7 +305,7 @@ public final class ArgumentPermissions { } PermissionCache permissionData = user.getCachedData().getPermissionData(QueryOptionsImpl.DEFAULT_CONTEXTUAL.toBuilder().context(contextSet).build()); - TristateResult result = permissionData.checkPermission(Inheritance.key(targetGroupName), PermissionCheckEvent.Origin.INTERNAL); + TristateResult result = permissionData.checkPermission(Inheritance.key(targetGroupName), CheckOrigin.INTERNAL); return result.result() != Tristate.TRUE || result.processorClass() != DirectProcessor.class; } diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheck.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheck.java index f56f69b0a..679f93d4d 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheck.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheck.java @@ -25,8 +25,8 @@ package me.lucko.luckperms.common.commands.generic.permission; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.calculator.processor.WildcardProcessor; -import me.lucko.luckperms.common.calculator.result.TristateResult; import me.lucko.luckperms.common.command.abstraction.CommandException; import me.lucko.luckperms.common.command.abstraction.GenericChildCommand; import me.lucko.luckperms.common.command.access.ArgumentPermissions; @@ -43,7 +43,7 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.util.Predicates; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.kyori.adventure.text.Component; import net.luckperms.api.context.ImmutableContextSet; @@ -123,29 +123,13 @@ public class PermissionCheck extends GenericChildCommand { // perform a "real" check QueryOptions queryOptions = target.getQueryOptions(); - TristateResult checkResult = target.getCachedData().getPermissionData(queryOptions).checkPermission(node, PermissionCheckEvent.Origin.INTERNAL); + TristateResult checkResult = target.getCachedData().getPermissionData(queryOptions).checkPermission(node, CheckOrigin.INTERNAL); Tristate result = checkResult.result(); - String processor; - String cause; + String processor = checkResult.processorClassFriendly(); + Node cause = checkResult.node(); ImmutableContextSet context = queryOptions.context(); - if (result != Tristate.UNDEFINED) { - Class processorClass = checkResult.processorClass(); - if (processorClass.getName().startsWith("me.lucko.luckperms.")) { - String simpleName = processorClass.getSimpleName(); - String platform = processorClass.getName().split("\\.")[3]; - processor = platform + "." + simpleName; - } else { - processor = processorClass.getName(); - } - - cause = checkResult.cause(); - } else { - processor = null; - cause = null; - } - // send results Message.PERMISSION_CHECK_RESULT.send(sender, node, result, processor, cause, context); } diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupInfo.java index 21566678d..213fd587e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupInfo.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupInfo.java @@ -25,7 +25,7 @@ package me.lucko.luckperms.common.commands.group; -import me.lucko.luckperms.common.cacheddata.type.MetaCache; +import me.lucko.luckperms.common.cacheddata.type.MonitoredMetaCache; import me.lucko.luckperms.common.command.abstraction.ChildCommand; import me.lucko.luckperms.common.command.access.ArgumentPermissions; import me.lucko.luckperms.common.command.access.CommandPermission; @@ -36,7 +36,7 @@ import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.util.Predicates; -import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.node.Node; import net.luckperms.api.node.types.InheritanceNode; @@ -85,10 +85,10 @@ public class GroupInfo extends ChildCommand { } QueryOptions queryOptions = plugin.getContextManager().getStaticQueryOptions(); - MetaCache data = target.getCachedData().getMetaData(queryOptions); - String prefix = data.getPrefix(MetaCheckEvent.Origin.INTERNAL); - String suffix = data.getSuffix(MetaCheckEvent.Origin.INTERNAL); - Map> meta = data.getMeta(MetaCheckEvent.Origin.INTERNAL); + MonitoredMetaCache data = target.getCachedData().getMetaData(queryOptions); + String prefix = data.getPrefix(CheckOrigin.INTERNAL).result(); + String suffix = data.getSuffix(CheckOrigin.INTERNAL).result(); + Map> meta = data.getMeta(CheckOrigin.INTERNAL); Message.GROUP_INFO_CONTEXTUAL_DATA.send(sender, prefix, suffix, meta); } diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java index 41a8cc7d2..5b20cf8ae 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java @@ -25,7 +25,7 @@ package me.lucko.luckperms.common.commands.user; -import me.lucko.luckperms.common.cacheddata.type.MetaCache; +import me.lucko.luckperms.common.cacheddata.type.MonitoredMetaCache; import me.lucko.luckperms.common.command.abstraction.ChildCommand; import me.lucko.luckperms.common.command.access.ArgumentPermissions; import me.lucko.luckperms.common.command.access.CommandPermission; @@ -37,7 +37,7 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.util.Predicates; import me.lucko.luckperms.common.util.UniqueIdType; -import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.context.ContextSet; import net.luckperms.api.node.Node; @@ -100,11 +100,11 @@ public class UserInfo extends ChildCommand { } ContextSet contextSet = queryOptions.context(); - MetaCache data = target.getCachedData().getMetaData(queryOptions); - String prefix = data.getPrefix(MetaCheckEvent.Origin.INTERNAL); - String suffix = data.getSuffix(MetaCheckEvent.Origin.INTERNAL); - String primaryGroup = data.getPrimaryGroup(MetaCheckEvent.Origin.INTERNAL); - Map> meta = data.getMeta(MetaCheckEvent.Origin.INTERNAL); + MonitoredMetaCache data = target.getCachedData().getMetaData(queryOptions); + String prefix = data.getPrefix(CheckOrigin.INTERNAL).result(); + String suffix = data.getSuffix(CheckOrigin.INTERNAL).result(); + String primaryGroup = data.getPrimaryGroup(CheckOrigin.INTERNAL); + Map> meta = data.getMeta(CheckOrigin.INTERNAL); Message.USER_INFO_CONTEXTUAL_DATA.send(sender, active, contextSet, prefix, suffix, primaryGroup, meta); } diff --git a/common/src/main/java/me/lucko/luckperms/common/locale/Message.java b/common/src/main/java/me/lucko/luckperms/common/locale/Message.java index 6976bd500..9ddf461c3 100644 --- a/common/src/main/java/me/lucko/luckperms/common/locale/Message.java +++ b/common/src/main/java/me/lucko/luckperms/common/locale/Message.java @@ -338,6 +338,108 @@ public interface Message { .append(text(result, GRAY)) ); + Args1 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 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 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 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 VERBOSE_LOG_HOVER_CONTEXT = set -> translatable() + // "&bContext: {}" + .key("luckperms.logs.verbose.hover.context-key") + .color(AQUA) + .append(text(": ")) + .append(formatContextSet(set)) + .build(); + + Args1 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 VERBOSE_LOG_HOVER_TRACE_CONTENT = content -> text(content, GRAY); + + Args1 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 VERBOSE_LOG_HOVER_PROCESSOR = processor -> translatable() + .key("luckperms.logs.verbose.hover.processor-key") + .color(AQUA) + .append(text(": ")) + .append(text(processor, DARK_GREEN)) + .build(); + Args1 EXPORT_LOG = msg -> prefixed(text() // "&3EXPORT &3&l> &f{}" .append(translatable("luckperms.logs.export-prefix", DARK_AQUA)) @@ -1832,7 +1934,7 @@ public interface Message { ) ); - Args5 PERMISSION_CHECK_RESULT = (permission, result, processor, cause, context) -> join(newline(), + Args5 PERMISSION_CHECK_RESULT = (permission, result, processor, causeNode, context) -> join(newline(), // &aPermission check for &b{}&a: // &3Result: {} // &3Processor: &f{} @@ -1867,10 +1969,22 @@ public interface Message { .append(translatable("luckperms.command.generic.permission.check.result.cause-key")) .append(text(": ")) .apply(builder -> { - if (cause == null) { + if (causeNode == null) { builder.append(translatable("luckperms.command.misc.none", AQUA)); } else { - builder.append(text(cause, WHITE)); + String origin = causeNode.getMetadata(InheritanceOriginMetadata.KEY) + .map(o -> o.getOrigin().getName()).orElse("?"); + + builder.append(translatable() + .key("luckperms.command.generic.permission.check.info.directly") + .color(GRAY) + .args( + text().color(AQUA).content(origin), + text(causeNode.getKey(), AQUA), + formatBoolean(causeNode.getValue()), + formatContextSet(causeNode.getContexts()) + ) + ); } })), prefixed(text() diff --git a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java index 4583261f0..948d1b1e7 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java @@ -354,19 +354,19 @@ public abstract class PermissionHolder { return (List) inheritanceTree; } - public > M exportPermissions(IntFunction mapFactory, QueryOptions queryOptions, boolean convertToLowercase, boolean resolveShorthand) { + public > M exportPermissions(IntFunction mapFactory, QueryOptions queryOptions, boolean convertToLowercase, boolean resolveShorthand) { List entries = resolveInheritedNodes(queryOptions); M map = mapFactory.apply(entries.size()); processExportedPermissions(map, entries, convertToLowercase, resolveShorthand); return map; } - private static void processExportedPermissions(Map accumulator, List entries, boolean convertToLowercase, boolean resolveShorthand) { + private static void processExportedPermissions(Map accumulator, List entries, boolean convertToLowercase, boolean resolveShorthand) { for (Node node : entries) { if (convertToLowercase) { - accumulator.putIfAbsent(node.getKey().toLowerCase(Locale.ROOT), node.getValue()); + accumulator.putIfAbsent(node.getKey().toLowerCase(Locale.ROOT), node); } else { - accumulator.putIfAbsent(node.getKey(), node.getValue()); + accumulator.putIfAbsent(node.getKey(), node); } } @@ -375,9 +375,9 @@ public abstract class PermissionHolder { Collection shorthand = node.resolveShorthand(); for (String s : shorthand) { if (convertToLowercase) { - accumulator.putIfAbsent(s.toLowerCase(Locale.ROOT), node.getValue()); + accumulator.putIfAbsent(s.toLowerCase(Locale.ROOT), node); } else { - accumulator.putIfAbsent(s, node.getValue()); + accumulator.putIfAbsent(s, node); } } } diff --git a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolderIdentifier.java b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolderIdentifier.java index 36f7f8101..c8d58f720 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolderIdentifier.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolderIdentifier.java @@ -40,6 +40,11 @@ public final class PermissionHolderIdentifier implements Identifier { this.name = name; } + public PermissionHolderIdentifier(String type, String name) { + this.type = type; + this.name = name; + } + @Override public @NonNull String getName() { return this.name; diff --git a/common/src/main/java/me/lucko/luckperms/common/model/manager/user/AbstractUserManager.java b/common/src/main/java/me/lucko/luckperms/common/model/manager/user/AbstractUserManager.java index 53a647f34..451fe11bb 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/manager/user/AbstractUserManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/manager/user/AbstractUserManager.java @@ -32,7 +32,7 @@ import me.lucko.luckperms.common.model.manager.AbstractManager; import me.lucko.luckperms.common.model.manager.group.GroupManager; import me.lucko.luckperms.common.node.types.Inheritance; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; -import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.model.data.DataType; import net.luckperms.api.node.Node; @@ -86,7 +86,7 @@ public abstract class AbstractUserManager extends AbstractManage // check that they are actually a member of their primary group, otherwise remove it if (this.plugin.getConfiguration().get(ConfigKeys.PRIMARY_GROUP_CALCULATION_METHOD).equals("stored")) { - String primaryGroup = user.getCachedData().getMetaData(this.plugin.getConfiguration().get(ConfigKeys.GLOBAL_QUERY_OPTIONS)).getPrimaryGroup(MetaCheckEvent.Origin.INTERNAL); + String primaryGroup = user.getCachedData().getMetaData(this.plugin.getConfiguration().get(ConfigKeys.GLOBAL_QUERY_OPTIONS)).getPrimaryGroup(CheckOrigin.INTERNAL); boolean memberOfPrimaryGroup = false; for (InheritanceNode node : globalGroups) { diff --git a/common/src/main/java/me/lucko/luckperms/common/node/utils/NodeJsonSerializer.java b/common/src/main/java/me/lucko/luckperms/common/node/utils/NodeJsonSerializer.java index 138bc55ea..cc532060a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/utils/NodeJsonSerializer.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/utils/NodeJsonSerializer.java @@ -34,6 +34,7 @@ import me.lucko.luckperms.common.node.factory.NodeBuilders; import net.luckperms.api.node.Node; import net.luckperms.api.node.NodeBuilder; +import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata; import java.time.Instant; import java.util.Collection; @@ -47,54 +48,81 @@ public class NodeJsonSerializer { } + public static JsonObject serializeNode(Node node, boolean includeInheritanceOrigin) { + JsonObject attributes = new JsonObject(); + + attributes.addProperty("type", node.getType().name().toLowerCase(Locale.ROOT)); + attributes.addProperty("key", node.getKey()); + attributes.addProperty("value", node.getValue()); + + Instant expiry = node.getExpiry(); + if (expiry != null) { + attributes.addProperty("expiry", expiry.getEpochSecond()); + } + + if (!node.getContexts().isEmpty()) { + attributes.add("context", ContextSetJsonSerializer.serialize(node.getContexts())); + } + + if (includeInheritanceOrigin) { + InheritanceOriginMetadata origin = node.getMetadata(InheritanceOriginMetadata.KEY).orElse(null); + if (origin != null) { + JsonObject metadata = new JsonObject(); + metadata.add("inheritanceOrigin", serializeInheritanceOrigin(origin)); + attributes.add("metadata", metadata); + } + } + + return attributes; + } + + private static JsonObject serializeInheritanceOrigin(InheritanceOriginMetadata origin) { + JsonObject obj = new JsonObject(); + obj.addProperty("type", origin.getOrigin().getType()); + obj.addProperty("name", origin.getOrigin().getName()); + return obj; + } + public static JsonArray serializeNodes(Collection nodes) { JsonArray arr = new JsonArray(); for (Node node : nodes) { - JsonObject attributes = new JsonObject(); - - attributes.addProperty("type", node.getType().name().toLowerCase(Locale.ROOT)); - attributes.addProperty("key", node.getKey()); - attributes.addProperty("value", node.getValue()); - - Instant expiry = node.getExpiry(); - if (expiry != null) { - attributes.addProperty("expiry", expiry.getEpochSecond()); - } - - if (!node.getContexts().isEmpty()) { - attributes.add("context", ContextSetJsonSerializer.serialize(node.getContexts())); - } - - arr.add(attributes); + arr.add(serializeNode(node, false)); } return arr; } + public static Node deserializeNode(JsonElement ent) { + JsonObject attributes = ent.getAsJsonObject(); + + String key = attributes.get("key").getAsString(); + + if (key.isEmpty()) { + return null; // skip + } + + NodeBuilder builder = NodeBuilders.determineMostApplicable(key); + + boolean value = attributes.get("value").getAsBoolean(); + builder.value(value); + + if (attributes.has("expiry")) { + builder.expiry(attributes.get("expiry").getAsLong()); + } + + if (attributes.has("context")) { + builder.context(ContextSetJsonSerializer.deserialize(attributes.get("context"))); + } + + return builder.build(); + } + public static Set deserializeNodes(JsonArray arr) { Set nodes = new HashSet<>(); for (JsonElement ent : arr) { - JsonObject attributes = ent.getAsJsonObject(); - - String key = attributes.get("key").getAsString(); - - if (key.isEmpty()) { - continue; // skip + Node node = deserializeNode(ent); + if (node != null) { + nodes.add(node); } - - NodeBuilder builder = NodeBuilders.determineMostApplicable(key); - - boolean value = attributes.get("value").getAsBoolean(); - builder.value(value); - - if (attributes.has("expiry")) { - builder.expiry(attributes.get("expiry").getAsLong()); - } - - if (attributes.has("context")) { - builder.context(ContextSetJsonSerializer.deserialize(attributes.get("context"))); - } - - nodes.add(builder.build()); } return nodes; } diff --git a/common/src/main/java/me/lucko/luckperms/common/treeview/TreeView.java b/common/src/main/java/me/lucko/luckperms/common/treeview/TreeView.java index ee2feaa69..732460494 100644 --- a/common/src/main/java/me/lucko/luckperms/common/treeview/TreeView.java +++ b/common/src/main/java/me/lucko/luckperms/common/treeview/TreeView.java @@ -36,7 +36,7 @@ import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.util.gson.GsonProvider; import me.lucko.luckperms.common.util.gson.JObject; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -161,7 +161,7 @@ public class TreeView { checks = new JObject(); for (Map.Entry node : this.view.getNodeEndings()) { String permission = prefix + node.getValue(); - checks.add(permission, checker.checkPermission(permission, PermissionCheckEvent.Origin.INTERNAL).result().name().toLowerCase(Locale.ROOT)); + checks.add(permission, checker.checkPermission(permission, CheckOrigin.INTERNAL).result().name().toLowerCase(Locale.ROOT)); } } else { checks = null; diff --git a/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseHandler.java b/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseHandler.java index 98a09042f..4e489e6d3 100644 --- a/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseHandler.java +++ b/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseHandler.java @@ -25,10 +25,12 @@ package me.lucko.luckperms.common.verbose; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.StringResult; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter; import me.lucko.luckperms.common.plugin.scheduler.SchedulerTask; import me.lucko.luckperms.common.sender.Sender; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; import me.lucko.luckperms.common.verbose.event.VerboseEvent; @@ -74,7 +76,7 @@ public class VerboseHandler implements AutoCloseable { * @param permission the permission which was checked for * @param result the result of the permission check */ - public void offerPermissionCheckEvent(PermissionCheckEvent.Origin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, String permission, TristateResult result) { + public void offerPermissionCheckEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, String permission, TristateResult result) { // don't bother even processing the check if there are no listeners registered if (!this.listening) { return; @@ -100,7 +102,7 @@ public class VerboseHandler implements AutoCloseable { * @param key the meta key which was checked for * @param result the result of the meta check */ - public void offerMetaCheckEvent(MetaCheckEvent.Origin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, String key, String result) { + public void offerMetaCheckEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, String key, StringResult result) { // don't bother even processing the check if there are no listeners registered if (!this.listening) { return; diff --git a/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseListener.java b/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseListener.java index 8d942b90b..ef7fd4acb 100644 --- a/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseListener.java +++ b/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseListener.java @@ -27,7 +27,8 @@ package me.lucko.luckperms.common.verbose; import com.google.gson.JsonObject; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.Result; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.http.AbstractHttpClient; import me.lucko.luckperms.common.http.BytebinClient; import me.lucko.luckperms.common.http.UnsuccessfulRequestException; @@ -38,6 +39,7 @@ import me.lucko.luckperms.common.util.StackTracePrinter; import me.lucko.luckperms.common.util.gson.GsonProvider; import me.lucko.luckperms.common.util.gson.JArray; import me.lucko.luckperms.common.util.gson.JObject; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; import me.lucko.luckperms.common.verbose.event.VerboseEvent; @@ -45,7 +47,8 @@ import me.lucko.luckperms.common.verbose.event.VerboseEvent; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.text.event.HoverEvent; -import net.kyori.adventure.text.format.NamedTextColor; +import net.luckperms.api.node.Node; +import net.luckperms.api.node.types.MetaNode; import net.luckperms.api.query.QueryMode; import java.io.ByteArrayOutputStream; @@ -150,28 +153,6 @@ public class VerboseListener { } private void sendNotification(VerboseEvent event) { - if (this.notifiedSender.isConsole()) { - // just send as a raw message - if (event instanceof PermissionCheckEvent) { - PermissionCheckEvent permissionEvent = (PermissionCheckEvent) event; - Message.VERBOSE_LOG_PERMISSION.send(this.notifiedSender, - permissionEvent.getCheckTarget().describe(), - permissionEvent.getPermission(), - permissionEvent.getResult().result() - ); - } else if (event instanceof MetaCheckEvent) { - MetaCheckEvent metaEvent = (MetaCheckEvent) event; - Message.VERBOSE_LOG_META.send(this.notifiedSender, - metaEvent.getCheckTarget().describe(), - metaEvent.getKey(), - metaEvent.getResult() - ); - } else { - throw new IllegalArgumentException("Unknown event type: " + event); - } - return; - } - // form a text component from the check trace Component component; if (event instanceof PermissionCheckEvent) { @@ -186,69 +167,52 @@ public class VerboseListener { component = Message.VERBOSE_LOG_META.build( metaEvent.getCheckTarget().describe(), metaEvent.getKey(), - metaEvent.getResult() + String.valueOf(metaEvent.getResult().result()) ); } else { throw new IllegalArgumentException("Unknown event type: " + event); } + // just send as a raw message + if (this.notifiedSender.isConsole()) { + this.notifiedSender.sendMessage(component); + return; + } + // build the hover text List hover = new ArrayList<>(); - if (event instanceof PermissionCheckEvent) { - PermissionCheckEvent permissionEvent = (PermissionCheckEvent) event; - hover.add(Component.text() - .append(Component.text("Type: ", NamedTextColor.GREEN)) - .append(Component.text("permission", NamedTextColor.DARK_GREEN)) - ); - hover.add(Component.text() - .append(Component.text("Origin: ", NamedTextColor.AQUA)) - .append(Component.text(permissionEvent.getOrigin().name(), NamedTextColor.DARK_GREEN)) - ); + hover.add(Message.VERBOSE_LOG_HOVER_TYPE.build(event.getType().toString())); + hover.add(Message.VERBOSE_LOG_HOVER_ORIGIN.build(event.getOrigin().name())); - TristateResult result = permissionEvent.getResult(); - if (result.processorClass() != null) { - hover.add(Component.text() - .append(Component.text("Processor: ", NamedTextColor.AQUA)) - .append(Component.text(result.processorClass().getName(), NamedTextColor.DARK_GREEN)) - ); - } - if (result.cause() != null) { - hover.add(Component.text() - .append(Component.text("Cause: ", NamedTextColor.AQUA)) - .append(Component.text(result.cause(), NamedTextColor.DARK_GREEN)) - ); + Result result = event.getResult(); + + if (result instanceof TristateResult) { + TristateResult tristateResult = (TristateResult) result; + + if (tristateResult.processorClass() != null) { + hover.add(Message.VERBOSE_LOG_HOVER_PROCESSOR.build(tristateResult.processorClassFriendly())); } } - if (event instanceof MetaCheckEvent) { - MetaCheckEvent metaEvent = (MetaCheckEvent) event; - hover.add(Component.text() - .append(Component.text("Type: ", NamedTextColor.GREEN)) - .append(Component.text("meta", NamedTextColor.DARK_GREEN)) - ); - hover.add(Component.text() - .append(Component.text("Origin: ", NamedTextColor.AQUA)) - .append(Component.text(metaEvent.getOrigin().name(), NamedTextColor.DARK_GREEN)) - ); + + Node node = result.node(); + if (node != null) { + if (node instanceof MetaNode) { + hover.add(Message.VERBOSE_LOG_HOVER_CAUSE_META.build((MetaNode) node)); + } else { + hover.add(Message.VERBOSE_LOG_HOVER_CAUSE.build(node)); + } } if (event.getCheckQueryOptions().mode() == QueryMode.CONTEXTUAL) { - hover.add(Component.text() - .append(Component.text("Context: ", NamedTextColor.AQUA)) - .append(Message.formatContextSet(event.getCheckQueryOptions().context())) - ); + hover.add(Message.VERBOSE_LOG_HOVER_CONTEXT.build(event.getCheckQueryOptions().context())); } - hover.add(Component.text() - .append(Component.text("Thread: ", NamedTextColor.AQUA)) - .append(Component.text(event.getCheckThread(), NamedTextColor.WHITE)) - ); + hover.add(Message.VERBOSE_LOG_HOVER_THREAD.build(event.getCheckThread())); - hover.add(Component.text() - .append(Component.text("Trace: ", NamedTextColor.AQUA)) - ); + hover.add(Message.VERBOSE_LOG_HOVER_TRACE_TITLE.build()); - Consumer printer = StackTracePrinter.elementToString(str -> hover.add(Component.text(str, NamedTextColor.GRAY))); + Consumer printer = StackTracePrinter.elementToString(str -> hover.add(Message.VERBOSE_LOG_HOVER_TRACE_CONTENT.build(str))); int overflow; if (shouldFilterStackTrace(event)) { overflow = CHAT_FILTERED_PRINTER.process(event.getCheckTrace(), printer); @@ -256,7 +220,7 @@ public class VerboseListener { overflow = CHAT_UNFILTERED_PRINTER.process(event.getCheckTrace(), printer); } if (overflow != 0) { - hover.add(Component.text("... and " + overflow + " more", NamedTextColor.WHITE)); + hover.add(Message.VERBOSE_LOG_HOVER_TRACE_OVERFLOW.build(overflow)); } // send the message @@ -267,8 +231,8 @@ public class VerboseListener { private static boolean shouldFilterStackTrace(VerboseEvent event) { if (event instanceof PermissionCheckEvent) { PermissionCheckEvent permissionEvent = (PermissionCheckEvent) event; - return permissionEvent.getOrigin() == PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK || - permissionEvent.getOrigin() == PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK; + return permissionEvent.getOrigin() == CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET || + permissionEvent.getOrigin() == CheckOrigin.PLATFORM_API_HAS_PERMISSION; } return false; } @@ -302,8 +266,8 @@ public class VerboseListener { .add("truncated", truncated); JArray data = new JArray(); - for (VerboseEvent events : this.results) { - data.add(events.toJson(shouldFilterStackTrace(events) ? WEB_FILTERED_PRINTER : WEB_UNFILTERED_PRINTER)); + for (VerboseEvent event : this.results) { + data.add(event.toJson(shouldFilterStackTrace(event) ? WEB_FILTERED_PRINTER : WEB_UNFILTERED_PRINTER)); } this.results.clear(); diff --git a/common/src/main/java/me/lucko/luckperms/common/verbose/event/CheckOrigin.java b/common/src/main/java/me/lucko/luckperms/common/verbose/event/CheckOrigin.java new file mode 100644 index 000000000..6064f0b00 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/verbose/event/CheckOrigin.java @@ -0,0 +1,63 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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 + +} diff --git a/common/src/main/java/me/lucko/luckperms/common/verbose/event/MetaCheckEvent.java b/common/src/main/java/me/lucko/luckperms/common/verbose/event/MetaCheckEvent.java index bcfa2114a..eba966d96 100644 --- a/common/src/main/java/me/lucko/luckperms/common/verbose/event/MetaCheckEvent.java +++ b/common/src/main/java/me/lucko/luckperms/common/verbose/event/MetaCheckEvent.java @@ -25,6 +25,10 @@ package me.lucko.luckperms.common.verbose.event; +import com.google.gson.JsonArray; + +import me.lucko.luckperms.common.cacheddata.result.StringResult; +import me.lucko.luckperms.common.node.utils.NodeJsonSerializer; import me.lucko.luckperms.common.util.gson.JObject; import me.lucko.luckperms.common.verbose.VerboseCheckTarget; @@ -34,11 +38,6 @@ import java.util.Locale; public class MetaCheckEvent extends VerboseEvent { - /** - * The origin of the check - */ - private final Origin origin; - /** * The meta key which was checked for */ @@ -47,33 +46,59 @@ public class MetaCheckEvent extends VerboseEvent { /** * The result of the meta check */ - private final String result; + private final StringResult result; - public MetaCheckEvent(Origin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread, String key, String result) { - super(checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread); - this.origin = origin; + public MetaCheckEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread, String key, StringResult result) { + super(origin, checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread); this.key = key; this.result = result; } - public Origin getOrigin() { - return this.origin; - } - public String getKey() { return this.key; } - public String getResult() { + @Override + public StringResult getResult() { return this.result; } + @Override + public VerboseEventType getType() { + return VerboseEventType.META; + } + @Override protected void serializeTo(JObject object) { - object.add("type", "meta") - .add("key", this.key) - .add("result", this.result) - .add("origin", this.origin.name().toLowerCase(Locale.ROOT)); + object.add("key", this.key); + + object.add("result", String.valueOf(this.result.result())); + if (this.result != StringResult.nullResult()) { + object.add("resultInfo", serializeResult(this.result)); + } + } + + private static JObject serializeResult(StringResult result) { + JObject object = new JObject(); + object.add("result", String.valueOf(result.result())); + + if (result.node() != null) { + object.add("node", NodeJsonSerializer.serializeNode(result.node(), true)); + } + + if (result.overriddenResult() != null) { + JsonArray overridden = new JsonArray(); + + StringResult next = result.overriddenResult(); + while (next != null) { + overridden.add(serializeResult(next).toJson()); + next = next.overriddenResult(); + } + + object.add("overridden", overridden); + } + + return object; } @Override @@ -81,33 +106,7 @@ public class MetaCheckEvent extends VerboseEvent { return variable.equals("meta") || getCheckTarget().describe().equalsIgnoreCase(variable) || getKey().toLowerCase(Locale.ROOT).startsWith(variable.toLowerCase(Locale.ROOT)) || - getResult().equalsIgnoreCase(variable); + String.valueOf(getResult().result()).equalsIgnoreCase(variable); } - /** - * Represents the origin of a meta check - */ - public enum Origin { - - /** - * Indicates the check was caused by a lookup in a platform API - */ - PLATFORM_API, - - /** - * Indicates the check was caused by a 3rd party API call - */ - THIRD_PARTY_API, - - /** - * Indicates the check was caused by a LuckPerms API call - */ - LUCKPERMS_API, - - /** - * Indicates the check was caused by a LuckPerms internal - */ - INTERNAL - - } } diff --git a/common/src/main/java/me/lucko/luckperms/common/verbose/event/PermissionCheckEvent.java b/common/src/main/java/me/lucko/luckperms/common/verbose/event/PermissionCheckEvent.java index a646aa079..f047de036 100644 --- a/common/src/main/java/me/lucko/luckperms/common/verbose/event/PermissionCheckEvent.java +++ b/common/src/main/java/me/lucko/luckperms/common/verbose/event/PermissionCheckEvent.java @@ -25,7 +25,10 @@ package me.lucko.luckperms.common.verbose.event; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import com.google.gson.JsonArray; + +import me.lucko.luckperms.common.cacheddata.result.TristateResult; +import me.lucko.luckperms.common.node.utils.NodeJsonSerializer; import me.lucko.luckperms.common.util.gson.JObject; import me.lucko.luckperms.common.verbose.VerboseCheckTarget; @@ -35,11 +38,6 @@ import java.util.Locale; public class PermissionCheckEvent extends VerboseEvent { - /** - * The origin of the check - */ - private final Origin origin; - /** * The permission which was checked for */ @@ -50,43 +48,60 @@ public class PermissionCheckEvent extends VerboseEvent { */ private final TristateResult result; - public PermissionCheckEvent(Origin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread, String permission, TristateResult result) { - super(checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread); - this.origin = origin; + public PermissionCheckEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread, String permission, TristateResult result) { + super(origin, checkTarget, checkQueryOptions, checkTime, checkTrace, checkThread); this.permission = permission; this.result = result; } - public Origin getOrigin() { - return this.origin; - } - public String getPermission() { return this.permission; } + @Override public TristateResult getResult() { return this.result; } + @Override + public VerboseEventType getType() { + return VerboseEventType.PERMISSION; + } + @Override protected void serializeTo(JObject object) { - object.add("type", "permission"); object.add("permission", this.permission); object.add("result", this.result.result().name().toLowerCase(Locale.ROOT)); - if (this.result.processorClass() != null || this.result.cause() != null) { - JObject resultInfo = new JObject(); - if (this.result.processorClass() != null) { - resultInfo.add("processorClass", this.result.processorClass().getName()); - } - if (this.result.cause() != null) { - resultInfo.add("cause", this.result.cause()); - } - object.add("resultInfo", resultInfo); + if (this.result != TristateResult.UNDEFINED) { + object.add("resultInfo", serializeResult(this.result)); + } + } + + private static JObject serializeResult(TristateResult result) { + JObject object = new JObject(); + object.add("result", result.result().name().toLowerCase(Locale.ROOT)); + + if (result.processorClass() != null) { + object.add("processorClass", result.processorClass().getName()); + } + if (result.node() != null) { + object.add("node", NodeJsonSerializer.serializeNode(result.node(), true)); } - object.add("origin", this.origin.name().toLowerCase(Locale.ROOT)); + if (result.overriddenResult() != null) { + JsonArray overridden = new JsonArray(); + + TristateResult next = result.overriddenResult(); + while (next != null) { + overridden.add(serializeResult(next).toJson()); + next = next.overriddenResult(); + } + + object.add("overridden", overridden); + } + + return object; } @Override @@ -97,35 +112,4 @@ public class PermissionCheckEvent extends VerboseEvent { getResult().result().name().equalsIgnoreCase(variable); } - /** - * Represents the origin of a permission check - */ - public enum Origin { - - /** - * Indicates the check was caused by a 'hasPermission' check on the platform - */ - PLATFORM_PERMISSION_CHECK, - - /** - * Indicates the check was caused by a 'hasPermissionSet' type check on the platform - */ - PLATFORM_LOOKUP_CHECK, - - /** - * Indicates the check was caused by a 3rd party API call - */ - THIRD_PARTY_API, - - /** - * Indicates the check was caused by an LuckPerms API call - */ - LUCKPERMS_API, - - /** - * Indicates the check was caused by a LuckPerms internal - */ - INTERNAL - - } } diff --git a/common/src/main/java/me/lucko/luckperms/common/verbose/event/VerboseEvent.java b/common/src/main/java/me/lucko/luckperms/common/verbose/event/VerboseEvent.java index 577d1fab0..14f500e06 100644 --- a/common/src/main/java/me/lucko/luckperms/common/verbose/event/VerboseEvent.java +++ b/common/src/main/java/me/lucko/luckperms/common/verbose/event/VerboseEvent.java @@ -27,6 +27,7 @@ package me.lucko.luckperms.common.verbose.event; import com.google.gson.JsonObject; +import me.lucko.luckperms.common.cacheddata.result.Result; import me.lucko.luckperms.common.util.StackTracePrinter; import me.lucko.luckperms.common.util.gson.JArray; import me.lucko.luckperms.common.util.gson.JObject; @@ -46,6 +47,11 @@ import java.util.UUID; */ public abstract class VerboseEvent implements VariableEvaluator { + /** + * The origin of the check + */ + private final CheckOrigin origin; + /** * The name of the entity which was checked */ @@ -71,7 +77,8 @@ public abstract class VerboseEvent implements VariableEvaluator { */ private final String checkThread; - protected VerboseEvent(VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread) { + protected VerboseEvent(CheckOrigin origin, VerboseCheckTarget checkTarget, QueryOptions checkQueryOptions, long checkTime, Throwable checkTrace, String checkThread) { + this.origin = origin; this.checkTarget = checkTarget; this.checkQueryOptions = checkQueryOptions; this.checkTime = checkTime; @@ -79,10 +86,16 @@ public abstract class VerboseEvent implements VariableEvaluator { this.checkThread = checkThread; } + public CheckOrigin getOrigin() { + return this.origin; + } + public VerboseCheckTarget getCheckTarget() { return this.checkTarget; } + public abstract Result getResult(); + public QueryOptions getCheckQueryOptions() { return this.checkQueryOptions; } @@ -99,10 +112,14 @@ public abstract class VerboseEvent implements VariableEvaluator { return this.checkThread; } + public abstract VerboseEventType getType(); + protected abstract void serializeTo(JObject object); public JsonObject toJson(StackTracePrinter tracePrinter) { return new JObject() + .add("type", getType().toString()) + .add("origin", this.origin.name().toLowerCase(Locale.ROOT)) .add("who", new JObject() .add("identifier", this.checkTarget.describe()) .add("type", this.checkTarget.getType()) diff --git a/common/src/main/java/me/lucko/luckperms/common/verbose/event/VerboseEventType.java b/common/src/main/java/me/lucko/luckperms/common/verbose/event/VerboseEventType.java new file mode 100644 index 000000000..367262962 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/verbose/event/VerboseEventType.java @@ -0,0 +1,46 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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); + } +} diff --git a/common/src/main/java/me/lucko/luckperms/common/webeditor/WebEditorRequest.java b/common/src/main/java/me/lucko/luckperms/common/webeditor/WebEditorRequest.java index 24ddbb252..ab4a75a2f 100644 --- a/common/src/main/java/me/lucko/luckperms/common/webeditor/WebEditorRequest.java +++ b/common/src/main/java/me/lucko/luckperms/common/webeditor/WebEditorRequest.java @@ -46,7 +46,7 @@ import me.lucko.luckperms.common.storage.misc.NodeEntry; import me.lucko.luckperms.common.util.gson.GsonProvider; import me.lucko.luckperms.common.util.gson.JArray; import me.lucko.luckperms.common.util.gson.JObject; -import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.node.Node; @@ -233,7 +233,7 @@ public class WebEditorRequest { users.values().stream() .sorted(Comparator // sort firstly by the users relative weight (depends on the groups they inherit) - .comparingInt(u -> u.getCachedData().getMetaData(QueryOptions.nonContextual()).getWeight(MetaCheckEvent.Origin.INTERNAL)).reversed() + .comparingInt(u -> u.getCachedData().getMetaData(QueryOptions.nonContextual()).getWeight(CheckOrigin.INTERNAL)).reversed() // then, prioritise users we actually have a username for .thenComparing(u -> u.getUsername().isPresent(), ((Comparator) Boolean::compare).reversed()) // then sort according to their username diff --git a/common/src/main/resources/luckperms_en.properties b/common/src/main/resources/luckperms_en.properties index 69300a4db..220e48017 100644 --- a/common/src/main/resources/luckperms_en.properties +++ b/common/src/main/resources/luckperms_en.properties @@ -1,5 +1,13 @@ luckperms.logs.actionlog-prefix=LOG luckperms.logs.verbose-prefix=VB +luckperms.logs.verbose.hover.type-key=Type +luckperms.logs.verbose.hover.origin-key=Origin +luckperms.logs.verbose.hover.cause-key=Cause +luckperms.logs.verbose.hover.context-key=Context +luckperms.logs.verbose.hover.thread-key=Thread +luckperms.logs.verbose.hover.trace-key=Trace +luckperms.logs.verbose.hover.processor-key=Processor +luckperms.logs.verbose.hover.overflow=and {0} more luckperms.logs.export-prefix=EXPORT luckperms.commandsystem.available-commands=Use {0} to view available commands luckperms.commandsystem.command-not-recognised=Command not recognised diff --git a/fabric/src/main/java/me/lucko/luckperms/fabric/FabricCalculatorFactory.java b/fabric/src/main/java/me/lucko/luckperms/fabric/FabricCalculatorFactory.java index 3c78fa39e..00080670a 100644 --- a/fabric/src/main/java/me/lucko/luckperms/fabric/FabricCalculatorFactory.java +++ b/fabric/src/main/java/me/lucko/luckperms/fabric/FabricCalculatorFactory.java @@ -69,7 +69,7 @@ public class FabricCalculatorFactory implements CalculatorFactory { boolean integratedOwner = queryOptions.option(FabricContextManager.INTEGRATED_SERVER_OWNER).orElse(false); if (integratedOwner && this.plugin.getConfiguration().get(ConfigKeys.FABRIC_INTEGRATED_SERVER_OWNER_BYPASSES_CHECKS)) { - processors.add(new ServerOwnerProcessor()); + processors.add(ServerOwnerProcessor.INSTANCE); } return new PermissionCalculator(this.plugin, metadata, processors); diff --git a/fabric/src/main/java/me/lucko/luckperms/fabric/calculator/ServerOwnerProcessor.java b/fabric/src/main/java/me/lucko/luckperms/fabric/calculator/ServerOwnerProcessor.java index 61519020b..9426e7675 100644 --- a/fabric/src/main/java/me/lucko/luckperms/fabric/calculator/ServerOwnerProcessor.java +++ b/fabric/src/main/java/me/lucko/luckperms/fabric/calculator/ServerOwnerProcessor.java @@ -25,8 +25,9 @@ package me.lucko.luckperms.fabric.calculator; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.calculator.processor.PermissionProcessor; import net.luckperms.api.util.Tristate; @@ -34,9 +35,15 @@ import net.luckperms.api.util.Tristate; * Permission processor which is added to the owner of an Integrated server to * simply return true if no other processors match. */ -public class ServerOwnerProcessor extends AbstractPermissionProcessor { +public class ServerOwnerProcessor extends AbstractPermissionProcessor implements PermissionProcessor { private static final TristateResult TRUE_RESULT = new TristateResult.Factory(ServerOwnerProcessor.class).result(Tristate.TRUE); + public static final ServerOwnerProcessor INSTANCE = new ServerOwnerProcessor(); + + private ServerOwnerProcessor() { + + } + @Override public TristateResult hasPermission(String permission) { return TRUE_RESULT; diff --git a/fabric/src/main/java/me/lucko/luckperms/fabric/listeners/PermissionCheckListener.java b/fabric/src/main/java/me/lucko/luckperms/fabric/listeners/PermissionCheckListener.java index 515bd5d7b..cfef3c0f6 100644 --- a/fabric/src/main/java/me/lucko/luckperms/fabric/listeners/PermissionCheckListener.java +++ b/fabric/src/main/java/me/lucko/luckperms/fabric/listeners/PermissionCheckListener.java @@ -26,10 +26,10 @@ package me.lucko.luckperms.fabric.listeners; import me.lucko.fabric.api.permissions.v0.PermissionCheckEvent; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.verbose.VerboseCheckTarget; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent.Origin; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import me.lucko.luckperms.fabric.LPFabricPlugin; import me.lucko.luckperms.fabric.model.MixinUser; @@ -83,7 +83,7 @@ public class PermissionCheckListener { String name = ((ServerCommandSource) source).getName(); VerboseCheckTarget target = VerboseCheckTarget.internal(name); - this.plugin.getVerboseHandler().offerPermissionCheckEvent(Origin.PLATFORM_PERMISSION_CHECK, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.UNDEFINED); + this.plugin.getVerboseHandler().offerPermissionCheckEvent(CheckOrigin.PLATFORM_API_HAS_PERMISSION, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.UNDEFINED); this.plugin.getPermissionRegistry().offer(permission); } diff --git a/fabric/src/main/java/me/lucko/luckperms/fabric/mixin/ServerPlayerEntityMixin.java b/fabric/src/main/java/me/lucko/luckperms/fabric/mixin/ServerPlayerEntityMixin.java index 3232599ee..2ee381204 100644 --- a/fabric/src/main/java/me/lucko/luckperms/fabric/mixin/ServerPlayerEntityMixin.java +++ b/fabric/src/main/java/me/lucko/luckperms/fabric/mixin/ServerPlayerEntityMixin.java @@ -29,7 +29,7 @@ import me.lucko.luckperms.common.cacheddata.type.PermissionCache; import me.lucko.luckperms.common.context.manager.QueryOptionsCache; import me.lucko.luckperms.common.locale.TranslationManager; import me.lucko.luckperms.common.model.User; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import me.lucko.luckperms.fabric.context.FabricContextManager; import me.lucko.luckperms.fabric.event.PlayerChangeWorldCallback; import me.lucko.luckperms.fabric.model.MixinUser; @@ -133,7 +133,7 @@ public abstract class ServerPlayerEntityMixin implements MixinUser { } PermissionCache data = user.getCachedData().getPermissionData(queryOptions); - return data.checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK).result(); + return data.checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result(); } diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/ChildProcessor.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/ChildProcessor.java index 75a2f63d0..53c479ded 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/ChildProcessor.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/ChildProcessor.java @@ -25,9 +25,9 @@ package me.lucko.luckperms.nukkit.calculator; -import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; +import me.lucko.luckperms.common.calculator.processor.AbstractSourceBasedProcessor; import me.lucko.luckperms.common.calculator.processor.PermissionProcessor; -import me.lucko.luckperms.common.calculator.result.TristateResult; import me.lucko.luckperms.nukkit.LPNukkitPlugin; import net.luckperms.api.util.Tristate; @@ -40,7 +40,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * Permission Processor for Nukkits "child" permission system. */ -public class ChildProcessor extends AbstractPermissionProcessor implements PermissionProcessor { +public class ChildProcessor extends AbstractSourceBasedProcessor implements PermissionProcessor { private static final TristateResult.Factory RESULT_FACTORY = new TristateResult.Factory(ChildProcessor.class); private final LPNukkitPlugin plugin; @@ -62,10 +62,10 @@ public class ChildProcessor extends AbstractPermissionProcessor implements Permi @Override public void refresh() { Map childPermissions = new HashMap<>(); - this.sourceMap.forEach((key, value) -> { - Map children = this.plugin.getPermissionMap().getChildPermissions(key, value); + this.sourceMap.forEach((key, node) -> { + Map children = this.plugin.getPermissionMap().getChildPermissions(key, node.getValue()); children.forEach((childKey, childValue) -> { - childPermissions.put(childKey, RESULT_FACTORY.result(Tristate.of(childValue), "parent: " + key)); + childPermissions.put(childKey, RESULT_FACTORY.resultWithOverride(node, Tristate.of(childValue))); }); }); this.childPermissions = childPermissions; diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/DefaultPermissionMapProcessor.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/DefaultPermissionMapProcessor.java new file mode 100644 index 000000000..2e7a9c398 --- /dev/null +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/DefaultPermissionMapProcessor.java @@ -0,0 +1,58 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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; + } +} diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/DefaultsProcessor.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/DefaultsProcessor.java deleted file mode 100644 index b619f3c1b..000000000 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/DefaultsProcessor.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * 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))); - } -} diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/NukkitCalculatorFactory.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/NukkitCalculatorFactory.java index 564282c3c..e2a5aad76 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/NukkitCalculatorFactory.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/NukkitCalculatorFactory.java @@ -52,7 +52,7 @@ public class NukkitCalculatorFactory implements CalculatorFactory { @Override public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) { - List processors = new ArrayList<>(7); + List processors = new ArrayList<>(8); processors.add(new DirectProcessor()); @@ -75,7 +75,8 @@ public class NukkitCalculatorFactory implements CalculatorFactory { boolean op = queryOptions.option(NukkitContextManager.OP_OPTION).orElse(false); if (metadata.getHolderType() == HolderType.USER && this.plugin.getConfiguration().get(ConfigKeys.APPLY_NUKKIT_DEFAULT_PERMISSIONS)) { boolean overrideWildcards = this.plugin.getConfiguration().get(ConfigKeys.APPLY_DEFAULT_NEGATIONS_BEFORE_WILDCARDS); - processors.add(new DefaultsProcessor(this.plugin, overrideWildcards, op)); + processors.add(new DefaultPermissionMapProcessor(this.plugin, op)); + processors.add(new PermissionMapProcessor(this.plugin, overrideWildcards, op)); } if (op) { diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/OpProcessor.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/OpProcessor.java index de22d9575..c2c9b61e3 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/OpProcessor.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/OpProcessor.java @@ -25,8 +25,9 @@ package me.lucko.luckperms.nukkit.calculator; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; +import me.lucko.luckperms.common.calculator.processor.AbstractPermissionProcessor; import me.lucko.luckperms.common.calculator.processor.PermissionProcessor; -import me.lucko.luckperms.common.calculator.result.TristateResult; import net.luckperms.api.util.Tristate; @@ -34,7 +35,7 @@ import net.luckperms.api.util.Tristate; * Permission Processor which is added for opped users, to simply return true if * no other processors match. */ -public final class OpProcessor implements PermissionProcessor { +public final class OpProcessor extends AbstractPermissionProcessor implements PermissionProcessor { private static final TristateResult TRUE_RESULT = new TristateResult.Factory(OpProcessor.class).result(Tristate.TRUE); public static final OpProcessor INSTANCE = new OpProcessor(); @@ -44,10 +45,7 @@ public final class OpProcessor implements PermissionProcessor { } @Override - public TristateResult hasPermission(TristateResult prev, String permission) { - if (prev != TristateResult.UNDEFINED) { - return prev; - } + public TristateResult hasPermission(String permission) { return TRUE_RESULT; } } diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/PermissionMapProcessor.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/PermissionMapProcessor.java new file mode 100644 index 000000000..d287c647d --- /dev/null +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/calculator/PermissionMapProcessor.java @@ -0,0 +1,59 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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))); + } +} diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LuckPermsPermissible.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LuckPermsPermissible.java index b7296a4b6..81db6d90d 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LuckPermsPermissible.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LuckPermsPermissible.java @@ -28,14 +28,14 @@ package me.lucko.luckperms.nukkit.inject.permissible; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.context.manager.QueryOptionsCache; import me.lucko.luckperms.common.model.User; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import me.lucko.luckperms.nukkit.LPNukkitPlugin; -import me.lucko.luckperms.nukkit.calculator.DefaultsProcessor; import me.lucko.luckperms.nukkit.calculator.OpProcessor; +import me.lucko.luckperms.nukkit.calculator.PermissionMapProcessor; import me.lucko.luckperms.nukkit.inject.PermissionDefault; import net.luckperms.api.query.QueryOptions; @@ -144,13 +144,13 @@ public class LuckPermsPermissible extends PermissibleBase { } QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); - TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK); + TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET); if (result.result() == Tristate.UNDEFINED) { return false; } // ignore matches made from looking up in the permission map (replicate nukkit behaviour) - if (result.processorClass() == DefaultsProcessor.class && "permission map".equals(result.cause())) { + if (result.processorClass() == PermissionMapProcessor.class) { return false; } @@ -174,7 +174,7 @@ public class LuckPermsPermissible extends PermissibleBase { } QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); - return this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK).result().asBoolean(); + return this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result().asBoolean(); } @Override @@ -184,7 +184,7 @@ public class LuckPermsPermissible extends PermissibleBase { } QueryOptions queryOptions = this.queryOptionsSupplier.getQueryOptions(); - TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission.getName(), PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK); + TristateResult result = this.user.getCachedData().getPermissionData(queryOptions).checkPermission(permission.getName(), CheckOrigin.PLATFORM_API_HAS_PERMISSION); // override default op handling using the Permission class we have if (result.processorClass() == OpProcessor.class && this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) { diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/MonitoredPermissibleBase.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/MonitoredPermissibleBase.java index d728d4014..f74bdd9e4 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/MonitoredPermissibleBase.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/MonitoredPermissibleBase.java @@ -25,12 +25,12 @@ package me.lucko.luckperms.nukkit.inject.permissible; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.verbose.VerboseCheckTarget; import me.lucko.luckperms.common.verbose.VerboseHandler; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.util.Tristate; @@ -68,8 +68,8 @@ public class MonitoredPermissibleBase extends PermissibleBase { this.initialised = true; } - private void logCheck(PermissionCheckEvent.Origin origin, String permission, boolean result) { - this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(Tristate.of(result))); + private void logCheck(CheckOrigin origin, String permission, boolean result) { + this.plugin.getVerboseHandler().offerPermissionCheckEvent(origin, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(Tristate.of(result))); this.plugin.getPermissionRegistry().offer(permission); } @@ -84,7 +84,7 @@ public class MonitoredPermissibleBase extends PermissibleBase { } final boolean result = this.delegate.isPermissionSet(permission); - logCheck(PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK, permission, result); + logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, permission, result); return result; } @@ -95,7 +95,7 @@ public class MonitoredPermissibleBase extends PermissibleBase { } final boolean result = this.delegate.isPermissionSet(permission); - logCheck(PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK, permission.getName(), result); + logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, permission.getName(), result); return result; } @@ -106,7 +106,7 @@ public class MonitoredPermissibleBase extends PermissibleBase { } final boolean result = this.delegate.hasPermission(permission); - logCheck(PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK, permission, result); + logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION, permission, result); return result; } @@ -117,7 +117,7 @@ public class MonitoredPermissibleBase extends PermissibleBase { } final boolean result = this.delegate.hasPermission(permission); - logCheck(PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK, permission.getName(), result); + logCheck(CheckOrigin.PLATFORM_API_HAS_PERMISSION, permission.getName(), result); return result; } diff --git a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectCollectionProxy.java b/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectCollectionProxy.java index 660be87ea..fe66e8df7 100644 --- a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectCollectionProxy.java +++ b/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectCollectionProxy.java @@ -80,7 +80,7 @@ public final class SubjectCollectionProxy implements SubjectCollection, ProxiedS @Override public @NonNull CompletableFuture> loadSubjects(@NonNull Set 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 diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubject.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubject.java index 153fb7531..41df403a6 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubject.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubject.java @@ -28,6 +28,7 @@ package me.lucko.luckperms.sponge.service.model; import com.google.common.collect.ImmutableList; import net.luckperms.api.context.ImmutableContextSet; +import net.luckperms.api.model.PermissionHolder; import net.luckperms.api.query.QueryOptions; import net.luckperms.api.util.Tristate; @@ -45,7 +46,7 @@ public interface LPSubject { LPPermissionService getService(); - String getIdentifier(); + PermissionHolder.Identifier getIdentifier(); default LPSubjectReference toReference() { return getService().getReferenceFactory().obtain(this); diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/SubjectReferenceFactory.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/SubjectReferenceFactory.java index 87566a65c..9efa6d95b 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/SubjectReferenceFactory.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/SubjectReferenceFactory.java @@ -79,7 +79,7 @@ public final class SubjectReferenceFactory { public LPSubjectReference obtain(LPSubject subject) { Objects.requireNonNull(subject, "subject"); - LPSubjectReference reference = obtain(subject.getParentCollection().getIdentifier(), subject.getIdentifier()); + LPSubjectReference reference = obtain(subject.getParentCollection().getIdentifier(), subject.getIdentifier().getName()); ((CachedSubjectReference) reference).fillCache(subject); return reference; } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/DefaultsProcessor.java b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/DefaultsProcessor.java deleted file mode 100644 index 0a5bd8f9a..000000000 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/DefaultsProcessor.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * 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; - } -} diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/FixedDefaultsProcessor.java b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/FixedTypeDefaultsProcessor.java similarity index 88% rename from sponge/src/main/java/me/lucko/luckperms/sponge/calculator/FixedDefaultsProcessor.java rename to sponge/src/main/java/me/lucko/luckperms/sponge/calculator/FixedTypeDefaultsProcessor.java index 7fb466d22..7846e6d82 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/FixedDefaultsProcessor.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/FixedTypeDefaultsProcessor.java @@ -30,10 +30,10 @@ import me.lucko.luckperms.sponge.service.model.LPSubject; import net.luckperms.api.query.QueryOptions; -public class FixedDefaultsProcessor extends DefaultsProcessor { +public class FixedTypeDefaultsProcessor extends TypeDefaultsProcessor { private final LPSubject defaultsSubject; - public FixedDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, LPSubject defaultsSubject, boolean overrideWildcards) { + public FixedTypeDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, LPSubject defaultsSubject, boolean overrideWildcards) { super(service, queryOptions, overrideWildcards); this.defaultsSubject = defaultsSubject; } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/GroupDefaultsProcessor.java b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/GroupTypeDefaultsProcessor.java similarity index 88% rename from sponge/src/main/java/me/lucko/luckperms/sponge/calculator/GroupDefaultsProcessor.java rename to sponge/src/main/java/me/lucko/luckperms/sponge/calculator/GroupTypeDefaultsProcessor.java index 8a4fb8050..830162893 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/GroupDefaultsProcessor.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/GroupTypeDefaultsProcessor.java @@ -31,8 +31,8 @@ import me.lucko.luckperms.sponge.service.model.LPSubject; import net.luckperms.api.query.QueryOptions; -public class GroupDefaultsProcessor extends DefaultsProcessor implements PermissionProcessor { - public GroupDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) { +public class GroupTypeDefaultsProcessor extends TypeDefaultsProcessor implements PermissionProcessor { + public GroupTypeDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) { super(service, queryOptions, overrideWildcards); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/RootDefaultsProcessor.java b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/RootDefaultsProcessor.java new file mode 100644 index 000000000..0d8aac0e6 --- /dev/null +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/RootDefaultsProcessor.java @@ -0,0 +1,57 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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; + } +} diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/SpongeCalculatorFactory.java b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/SpongeCalculatorFactory.java index 89ade487a..f55d15745 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/SpongeCalculatorFactory.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/SpongeCalculatorFactory.java @@ -70,10 +70,11 @@ public class SpongeCalculatorFactory implements CalculatorFactory { if (this.plugin.getConfiguration().get(ConfigKeys.APPLY_SPONGE_DEFAULT_SUBJECTS)) { boolean overrideWildcards = this.plugin.getConfiguration().get(ConfigKeys.APPLY_DEFAULT_NEGATIONS_BEFORE_WILDCARDS); if (metadata.getHolderType() == HolderType.USER) { - processors.add(new UserDefaultsProcessor(this.plugin.getService(), queryOptions, overrideWildcards)); + processors.add(new UserTypeDefaultsProcessor(this.plugin.getService(), queryOptions, overrideWildcards)); } else if (metadata.getHolderType() == HolderType.GROUP) { - processors.add(new GroupDefaultsProcessor(this.plugin.getService(), queryOptions, overrideWildcards)); + processors.add(new GroupTypeDefaultsProcessor(this.plugin.getService(), queryOptions, overrideWildcards)); } + processors.add(new RootDefaultsProcessor(this.plugin.getService(), queryOptions, overrideWildcards)); } return new PermissionCalculator(this.plugin, metadata, processors); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/TypeDefaultsProcessor.java b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/TypeDefaultsProcessor.java new file mode 100644 index 000000000..99af378ca --- /dev/null +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/TypeDefaultsProcessor.java @@ -0,0 +1,60 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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; + } +} diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/UserDefaultsProcessor.java b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/UserTypeDefaultsProcessor.java similarity index 88% rename from sponge/src/main/java/me/lucko/luckperms/sponge/calculator/UserDefaultsProcessor.java rename to sponge/src/main/java/me/lucko/luckperms/sponge/calculator/UserTypeDefaultsProcessor.java index 30e02cd4e..de5d7da3c 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/UserDefaultsProcessor.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/calculator/UserTypeDefaultsProcessor.java @@ -31,8 +31,8 @@ import me.lucko.luckperms.sponge.service.model.LPSubject; import net.luckperms.api.query.QueryOptions; -public class UserDefaultsProcessor extends DefaultsProcessor implements PermissionProcessor { - public UserDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) { +public class UserTypeDefaultsProcessor extends TypeDefaultsProcessor implements PermissionProcessor { + public UserTypeDefaultsProcessor(LPPermissionService service, QueryOptions queryOptions, boolean overrideWildcards) { super(service, queryOptions, overrideWildcards); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentAdd.java b/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentAdd.java index f42a5e092..fd21a9e92 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentAdd.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentAdd.java @@ -66,7 +66,7 @@ public class ParentAdd extends ChildCommand { if (subjectData.addParent(contextSet, subject.toReference()).join()) { SpongeCommandUtils.sendPrefixed(sender, "&aAdded parent &b" + subject.getParentCollection().getIdentifier() + - "&a/&b" + subject.getIdentifier() + "&a in context " + SpongeCommandUtils.contextToString(contextSet)); + "&a/&b" + subject.getIdentifier().getName() + "&a in context " + SpongeCommandUtils.contextToString(contextSet)); } else { SpongeCommandUtils.sendPrefixed(sender, "Unable to add parent. Does the Subject already have it added?"); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentRemove.java b/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentRemove.java index a3d3ece54..f1126f9d1 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentRemove.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentRemove.java @@ -66,7 +66,7 @@ public class ParentRemove extends ChildCommand { if (subjectData.removeParent(contextSet, subject.toReference()).join()) { SpongeCommandUtils.sendPrefixed(sender, "&aRemoved parent &b" + subject.getParentCollection().getIdentifier() + - "&a/&b" + subject.getIdentifier() + "&a in context " + SpongeCommandUtils.contextToString(contextSet)); + "&a/&b" + subject.getIdentifier().getName() + "&a in context " + SpongeCommandUtils.contextToString(contextSet)); } else { SpongeCommandUtils.sendPrefixed(sender, "Unable to remove parent. Are you sure the Subject has it added?"); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/commands/SpongeParentCommand.java b/sponge/src/main/java/me/lucko/luckperms/sponge/commands/SpongeParentCommand.java index 3eaf93df1..12df23de3 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/commands/SpongeParentCommand.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/commands/SpongeParentCommand.java @@ -111,7 +111,7 @@ public class SpongeParentCommand extends Command { if (args.size() < 2) { List subjects = collection.getLoadedSubjects().stream() - .map(LPSubject::getIdentifier) + .map(lpSubject -> lpSubject.getIdentifier().getName()) .collect(Collectors.toList()); if (subjects.size() > 50) { diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubject.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubject.java index e8870b80d..3f8864096 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubject.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubject.java @@ -28,16 +28,18 @@ package me.lucko.luckperms.sponge.service.model.calculated; import com.google.common.collect.ImmutableList; import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator; +import me.lucko.luckperms.common.cacheddata.type.MetaCache; import me.lucko.luckperms.common.graph.TraversalAlgorithm; import me.lucko.luckperms.common.query.QueryOptionsImpl; -import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import me.lucko.luckperms.sponge.LPSpongePlugin; import me.lucko.luckperms.sponge.service.inheritance.SubjectInheritanceGraph; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectReference; import net.luckperms.api.context.ImmutableContextSet; +import net.luckperms.api.node.Node; +import net.luckperms.api.node.types.MetaNode; import net.luckperms.api.query.QueryOptions; import net.luckperms.api.util.Tristate; @@ -67,9 +69,9 @@ public abstract class CalculatedSubject implements LPSubject { @Override public abstract CalculatedSubjectData getTransientSubjectData(); - public Map getCombinedPermissions(QueryOptions filter) { - Map permissions; - Map merging; + public Map getCombinedPermissions(QueryOptions filter) { + Map permissions; + Map merging; switch (getParentCollection().getResolutionOrder()) { case TRANSIENT_FIRST: permissions = getTransientSubjectData().resolvePermissions(filter); @@ -83,18 +85,18 @@ public abstract class CalculatedSubject implements LPSubject { throw new AssertionError(); } - for (Map.Entry entry : merging.entrySet()) { + for (Map.Entry entry : merging.entrySet()) { permissions.putIfAbsent(entry.getKey(), entry.getValue()); } return permissions; } - public void resolveAllPermissions(Map accumulator, QueryOptions filter) { + public void resolveAllPermissions(Map accumulator, QueryOptions filter) { SubjectInheritanceGraph graph = new SubjectInheritanceGraph(filter); Iterable traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this); for (CalculatedSubject subject : traversal) { - for (Map.Entry entry : subject.getCombinedPermissions(filter).entrySet()) { + for (Map.Entry entry : subject.getCombinedPermissions(filter).entrySet()) { accumulator.putIfAbsent(entry.getKey(), entry.getValue()); } } @@ -132,9 +134,9 @@ public abstract class CalculatedSubject implements LPSubject { return result; } - public Map getCombinedOptions(QueryOptions filter) { - Map options; - Map merging; + public Map getCombinedOptions(QueryOptions filter) { + Map options; + Map merging; switch (getParentCollection().getResolutionOrder()) { case TRANSIENT_FIRST: options = getTransientSubjectData().resolveOptions(filter); @@ -148,7 +150,7 @@ public abstract class CalculatedSubject implements LPSubject { throw new AssertionError(); } - for (Map.Entry entry : merging.entrySet()) { + for (Map.Entry entry : merging.entrySet()) { options.putIfAbsent(entry.getKey(), entry.getValue()); } return options; @@ -160,8 +162,8 @@ public abstract class CalculatedSubject implements LPSubject { Iterable traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this); for (CalculatedSubject subject : traversal) { - for (Map.Entry entry : subject.getCombinedOptions(filter).entrySet()) { - result.putIfAbsent(entry.getKey(), entry.getValue()); + for (MetaNode entry : subject.getCombinedOptions(filter).values()) { + result.putIfAbsent(entry.getMetaKey(), entry.getMetaValue()); } } @@ -170,18 +172,20 @@ public abstract class CalculatedSubject implements LPSubject { public void resolveAllOptions(MetaAccumulator accumulator, QueryOptions filter) { SubjectInheritanceGraph graph = new SubjectInheritanceGraph(filter); + Iterable traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this); for (CalculatedSubject subject : traversal) { - for (Map.Entry entry : subject.getCombinedOptions(filter).entrySet()) { - accumulator.accumulateMeta(entry.getKey(), entry.getValue()); + for (MetaNode entry : subject.getCombinedOptions(filter).values()) { + accumulator.accumulateNode(entry); } } + accumulator.complete(); } @Override public Tristate getPermissionValue(QueryOptions options, String permission) { - return this.cachedData.getPermissionData(options).checkPermission(permission, PermissionCheckEvent.Origin.INTERNAL).result(); + return this.cachedData.getPermissionData(options).checkPermission(permission, CheckOrigin.INTERNAL).result(); } @Override @@ -201,7 +205,7 @@ public abstract class CalculatedSubject implements LPSubject { @Override public Optional 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 diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubjectCachedDataManager.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubjectCachedDataManager.java index eb03ca20a..9172dd839 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubjectCachedDataManager.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubjectCachedDataManager.java @@ -40,11 +40,13 @@ import me.lucko.luckperms.common.metastacking.SimpleMetaStackDefinition; import me.lucko.luckperms.common.metastacking.StandardStackElements; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.verbose.VerboseCheckTarget; -import me.lucko.luckperms.sponge.calculator.FixedDefaultsProcessor; +import me.lucko.luckperms.sponge.calculator.FixedTypeDefaultsProcessor; +import me.lucko.luckperms.sponge.calculator.RootDefaultsProcessor; import net.luckperms.api.metastacking.DuplicateRemovalFunction; import net.luckperms.api.metastacking.MetaStackDefinition; import net.luckperms.api.node.ChatMetaType; +import net.luckperms.api.node.Node; import net.luckperms.api.query.QueryOptions; import java.util.ArrayList; @@ -68,7 +70,7 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage @Override protected CacheMetadata getMetadataForQueryOptions(QueryOptions queryOptions) { - VerboseCheckTarget target = VerboseCheckTarget.of(this.subject.getParentCollection().getIdentifier(), this.subject.getIdentifier()); + VerboseCheckTarget target = VerboseCheckTarget.of(this.subject.getParentCollection().getIdentifier(), this.subject.getIdentifier().getName()); return new CacheMetadata(null, target, queryOptions); } @@ -88,7 +90,7 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage } @Override - protected > M resolvePermissions(IntFunction mapFactory, QueryOptions queryOptions) { + protected > M resolvePermissions(IntFunction mapFactory, QueryOptions queryOptions) { M map = mapFactory.apply(16); this.subject.resolveAllPermissions(map, queryOptions); return map; @@ -101,13 +103,14 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage @Override public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) { - List processors = new ArrayList<>(4); + List processors = new ArrayList<>(5); processors.add(new DirectProcessor()); processors.add(new SpongeWildcardProcessor()); processors.add(new WildcardProcessor()); if (!this.subject.getParentCollection().isDefaultsCollection()) { - processors.add(new FixedDefaultsProcessor(this.subject.getService(), queryOptions, this.subject.getDefaults(), true)); + processors.add(new FixedTypeDefaultsProcessor(this.subject.getService(), queryOptions, this.subject.getDefaults(), true)); + processors.add(new RootDefaultsProcessor(this.subject.getService(), queryOptions, true)); } return new PermissionCalculator(getPlugin(), metadata, processors); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubjectData.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubjectData.java index 74e6b881c..9637e2160 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubjectData.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/calculated/CalculatedSubjectData.java @@ -31,6 +31,9 @@ import com.google.common.collect.ImmutableSet; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.context.comparator.ContextSetComparator; +import me.lucko.luckperms.common.model.InheritanceOrigin; +import me.lucko.luckperms.common.node.types.Meta; +import me.lucko.luckperms.common.node.types.Permission; import me.lucko.luckperms.sponge.service.ProxyFactory; import me.lucko.luckperms.sponge.service.model.LPPermissionService; import me.lucko.luckperms.sponge.service.model.LPSubject; @@ -40,6 +43,10 @@ import me.lucko.luckperms.sponge.service.model.LPSubjectReference; import net.luckperms.api.context.ContextSatisfyMode; import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.model.data.DataType; +import net.luckperms.api.node.Node; +import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata; +import net.luckperms.api.node.types.MetaNode; +import net.luckperms.api.node.types.PermissionNode; import net.luckperms.api.query.QueryOptions; import net.luckperms.api.util.Tristate; @@ -134,21 +141,32 @@ public class CalculatedSubjectData implements LPSubjectData { return ImmutableMap.copyOf(this.permissions.getOrDefault(contexts, ImmutableMap.of())); } - public Map resolvePermissions(QueryOptions filter) { + public Map resolvePermissions(QueryOptions filter) { // get relevant entries - SortedMap> sorted = new TreeMap<>(ContextSetComparator.reverse()); + SortedMap> sorted = new TreeMap<>(ContextSetComparator.reverse()); for (Map.Entry> entry : this.permissions.entrySet()) { if (!filter.satisfies(entry.getKey(), defaultSatisfyMode())) { continue; } - sorted.put(entry.getKey(), entry.getValue()); + Map nodeMap = new HashMap<>(); + entry.getValue().forEach((key, value) -> { + PermissionNode node = Permission.builder() + .permission(key) + .value(value) + .context(entry.getKey()) + .withMetadata(InheritanceOriginMetadata.KEY, new InheritanceOrigin(this.parentSubject.getIdentifier())) + .build(); + nodeMap.put(key, node); + }); + + sorted.put(entry.getKey(), nodeMap); } // flatten - Map result = new HashMap<>(); - for (Map map : sorted.values()) { - for (Map.Entry e : map.entrySet()) { + Map result = new HashMap<>(); + for (Map map : sorted.values()) { + for (Map.Entry e : map.entrySet()) { result.putIfAbsent(e.getKey(), e.getValue()); } } @@ -288,21 +306,32 @@ public class CalculatedSubjectData implements LPSubjectData { return ImmutableMap.copyOf(this.options.getOrDefault(contexts, ImmutableMap.of())); } - public Map resolveOptions(QueryOptions filter) { + public Map resolveOptions(QueryOptions filter) { // get relevant entries - SortedMap> sorted = new TreeMap<>(ContextSetComparator.reverse()); + SortedMap> sorted = new TreeMap<>(ContextSetComparator.reverse()); for (Map.Entry> entry : this.options.entrySet()) { if (!filter.satisfies(entry.getKey(), defaultSatisfyMode())) { continue; } - sorted.put(entry.getKey(), entry.getValue()); + Map nodeMap = new HashMap<>(); + entry.getValue().forEach((key, value) -> { + MetaNode node = Meta.builder() + .key(key) + .value(value) + .context(entry.getKey()) + .withMetadata(InheritanceOriginMetadata.KEY, new InheritanceOrigin(this.parentSubject.getIdentifier())) + .build(); + nodeMap.put(key, node); + }); + + sorted.put(entry.getKey(), nodeMap); } // flatten - Map result = new HashMap<>(); - for (Map map : sorted.values()) { - for (Map.Entry e : map.entrySet()) { + Map result = new HashMap<>(); + for (Map map : sorted.values()) { + for (Map.Entry e : map.entrySet()) { result.putIfAbsent(e.getKey(), e.getValue()); } } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/GroupSubject.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/GroupSubject.java index e70d68dbc..b3fa83b37 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/GroupSubject.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/GroupSubject.java @@ -30,6 +30,8 @@ import me.lucko.luckperms.sponge.model.SpongeGroup; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; +import net.luckperms.api.model.PermissionHolder; + import org.spongepowered.api.command.CommandSource; import java.util.Optional; @@ -43,8 +45,8 @@ public class GroupSubject extends PermissionHolderSubject implement } @Override - public String getIdentifier() { - return this.parent.getObjectName(); + public PermissionHolder.Identifier getIdentifier() { + return this.parent.getIdentifier(); } @Override diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubject.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubject.java index 341147e9f..40d3dd50c 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubject.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubject.java @@ -35,8 +35,7 @@ import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.node.types.Inheritance; import me.lucko.luckperms.common.node.types.Prefix; import me.lucko.luckperms.common.node.types.Suffix; -import me.lucko.luckperms.common.verbose.event.MetaCheckEvent; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import me.lucko.luckperms.sponge.LPSpongePlugin; import me.lucko.luckperms.sponge.model.SpongeGroup; import me.lucko.luckperms.sponge.service.LuckPermsService; @@ -113,7 +112,7 @@ public abstract class PermissionHolderSubject implem @Override public Tristate getPermissionValue(QueryOptions options, String permission) { - return this.parent.getCachedData().getPermissionData(options).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK).result(); + return this.parent.getCachedData().getPermissionData(options).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET).result(); } @Override @@ -148,20 +147,20 @@ public abstract class PermissionHolderSubject implem public Optional getOption(ImmutableContextSet contexts, String s) { MetaCache data = this.parent.getCachedData().getMetaData(this.plugin.getContextManager().formQueryOptions(contexts)); if (s.equalsIgnoreCase(Prefix.NODE_KEY)) { - String prefix = data.getPrefix(MetaCheckEvent.Origin.PLATFORM_API); + String prefix = data.getPrefix(CheckOrigin.PLATFORM_API).result(); if (prefix != null) { return Optional.of(prefix); } } if (s.equalsIgnoreCase(Suffix.NODE_KEY)) { - String suffix = data.getSuffix(MetaCheckEvent.Origin.PLATFORM_API); + String suffix = data.getSuffix(CheckOrigin.PLATFORM_API).result(); if (suffix != null) { return Optional.of(suffix); } } - String val = data.getMetaValue(s, MetaCheckEvent.Origin.PLATFORM_API); + String val = data.getMetaValue(s, CheckOrigin.PLATFORM_API).result(); if (val != null) { return Optional.of(val); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/UserSubject.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/UserSubject.java index 8648e0e12..bc6fa3fb4 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/UserSubject.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/UserSubject.java @@ -30,6 +30,8 @@ import me.lucko.luckperms.sponge.model.SpongeUser; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; +import net.luckperms.api.model.PermissionHolder; + import org.spongepowered.api.Sponge; import org.spongepowered.api.command.CommandSource; @@ -46,8 +48,8 @@ public final class UserSubject extends PermissionHolderSubject imple } @Override - public String getIdentifier() { - return this.parent.getUniqueId().toString(); + public PermissionHolder.Identifier getIdentifier() { + return this.parent.getIdentifier(); } @Override diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedSubject.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedSubject.java index 2c6a05c0e..6c6675a71 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedSubject.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedSubject.java @@ -26,6 +26,7 @@ package me.lucko.luckperms.sponge.service.model.persisted; import me.lucko.luckperms.common.cache.BufferedRequest; +import me.lucko.luckperms.common.model.PermissionHolderIdentifier; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.ProxyFactory; @@ -37,6 +38,7 @@ import me.lucko.luckperms.sponge.service.model.calculated.CalculatedSubject; import me.lucko.luckperms.sponge.service.model.calculated.CalculatedSubjectData; import me.lucko.luckperms.sponge.service.model.calculated.MonitoredSubjectData; +import net.luckperms.api.model.PermissionHolder; import net.luckperms.api.model.data.DataType; import org.spongepowered.api.command.CommandSource; @@ -54,7 +56,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject { /** * The subjects identifier */ - private final String identifier; + private final PermissionHolderIdentifier identifier; /** * The parent collection @@ -81,7 +83,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject { super(service.getPlugin()); this.service = service; this.parentCollection = parentCollection; - this.identifier = identifier; + this.identifier = new PermissionHolderIdentifier(parentCollection.getIdentifier(), identifier); this.subjectData = new PersistedSubjectData(this, DataType.NORMAL, service) { @Override @@ -156,7 +158,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject { } @Override - public String getIdentifier() { + public PermissionHolder.Identifier getIdentifier() { return this.identifier; } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/SubjectStorage.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/SubjectStorage.java index 6eb811c37..717c9cd05 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/SubjectStorage.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/SubjectStorage.java @@ -110,7 +110,7 @@ public class SubjectStorage { * @throws IOException if the write fails */ public void saveToFile(PersistedSubject subject) throws IOException { - Path subjectFile = resolveFile(subject.getParentCollection().getIdentifier(), subject.getIdentifier()); + Path subjectFile = resolveFile(subject.getParentCollection().getIdentifier(), subject.getIdentifier().getName()); saveToFile(SubjectDataContainer.copyOf(subject.getSubjectData()), subjectFile); } diff --git a/velocity/src/main/java/me/lucko/luckperms/velocity/listeners/MonitoringPermissionCheckListener.java b/velocity/src/main/java/me/lucko/luckperms/velocity/listeners/MonitoringPermissionCheckListener.java index 81db28ec4..730f5b875 100644 --- a/velocity/src/main/java/me/lucko/luckperms/velocity/listeners/MonitoringPermissionCheckListener.java +++ b/velocity/src/main/java/me/lucko/luckperms/velocity/listeners/MonitoringPermissionCheckListener.java @@ -33,10 +33,10 @@ import com.velocitypowered.api.permission.PermissionProvider; import com.velocitypowered.api.permission.PermissionSubject; import com.velocitypowered.api.proxy.Player; -import me.lucko.luckperms.common.calculator.result.TristateResult; +import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.verbose.VerboseCheckTarget; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import me.lucko.luckperms.velocity.LPVelocityPlugin; import me.lucko.luckperms.velocity.service.CompatibilityUtil; @@ -91,7 +91,7 @@ public class MonitoringPermissionCheckListener { // report result Tristate result = CompatibilityUtil.convertTristate(setting); - MonitoringPermissionCheckListener.this.plugin.getVerboseHandler().offerPermissionCheckEvent(PermissionCheckEvent.Origin.PLATFORM_LOOKUP_CHECK, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.of(result)); + MonitoringPermissionCheckListener.this.plugin.getVerboseHandler().offerPermissionCheckEvent(CheckOrigin.PLATFORM_API_HAS_PERMISSION_SET, this.verboseCheckTarget, QueryOptionsImpl.DEFAULT_CONTEXTUAL, permission, TristateResult.forMonitoredResult(result)); MonitoringPermissionCheckListener.this.plugin.getPermissionRegistry().offer(permission); return setting; diff --git a/velocity/src/main/java/me/lucko/luckperms/velocity/service/PlayerPermissionProvider.java b/velocity/src/main/java/me/lucko/luckperms/velocity/service/PlayerPermissionProvider.java index 5287f04db..b1756f389 100644 --- a/velocity/src/main/java/me/lucko/luckperms/velocity/service/PlayerPermissionProvider.java +++ b/velocity/src/main/java/me/lucko/luckperms/velocity/service/PlayerPermissionProvider.java @@ -34,7 +34,7 @@ import com.velocitypowered.api.proxy.Player; import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier; import me.lucko.luckperms.common.model.User; -import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; +import me.lucko.luckperms.common.verbose.event.CheckOrigin; import org.checkerframework.checker.nullness.qual.NonNull; @@ -57,6 +57,6 @@ public class PlayerPermissionProvider implements PermissionProvider, PermissionF @Override public @NonNull Tristate getPermissionValue(@NonNull String permission) { - return CompatibilityUtil.convertTristate(this.user.getCachedData().getPermissionData(this.queryOptionsSupplier.getQueryOptions()).checkPermission(permission, PermissionCheckEvent.Origin.PLATFORM_PERMISSION_CHECK).result()); + return CompatibilityUtil.convertTristate(this.user.getCachedData().getPermissionData(this.queryOptionsSupplier.getQueryOptions()).checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result()); } }