From e68fc7c55831558dd3cec18a8f81fdf9a06ddc1d Mon Sep 17 00:00:00 2001 From: Luck Date: Tue, 4 Apr 2017 15:22:25 +0100 Subject: [PATCH] Improve performance of resolve methods in PermissionHolder, other cleanup --- .../java/me/lucko/luckperms/api/Node.java | 14 ++ .../luckperms/bukkit/model/Injector.java | 2 +- .../luckperms/bukkit/model/LPPermissible.java | 6 +- .../caching/handlers/UserReference.java | 2 +- .../commands/sender/AbstractSender.java | 2 +- .../common/commands/utils/ArgumentUtils.java | 8 ++ .../common/core/InheritanceInfo.java | 2 +- .../luckperms/common/core/UserIdentifier.java | 2 +- .../common/core/model/ImmutableNode.java | 7 +- .../common/core/model/PermissionHolder.java | 130 ++++++++++-------- .../storage/backing/utils/NodeDataHolder.java | 2 +- .../storage/holder/NodeHeldPermission.java | 2 +- .../lucko/luckperms/common/utils/Buffer.java | 2 +- .../common/utils/ImmutableLocalizedNode.java | 2 +- .../sponge/service/LuckPermsService.java | 4 +- .../service/calculated/OptionLookup.java | 2 +- .../service/calculated/PermissionLookup.java | 2 +- .../SubjectCollectionReference.java | 2 +- .../service/references/SubjectReference.java | 2 +- 19 files changed, 120 insertions(+), 75 deletions(-) diff --git a/api/src/main/java/me/lucko/luckperms/api/Node.java b/api/src/main/java/me/lucko/luckperms/api/Node.java index 99dcc2d3..8c3b1177 100644 --- a/api/src/main/java/me/lucko/luckperms/api/Node.java +++ b/api/src/main/java/me/lucko/luckperms/api/Node.java @@ -114,6 +114,20 @@ public interface Node extends Map.Entry { */ boolean hasSpecificContext(); + /** + * Returns if this node is able to apply in the given context + * + * @param includeGlobal if global server values should apply + * @param includeGlobalWorld if global world values should apply + * @param server the server being checked against, or null + * @param world the world being checked against, or null + * @param context the context being checked against, or null + * @param applyRegex if regex should be applied + * @return true if the node should apply, otherwise false + * @since 3.1 + */ + boolean shouldApply(boolean includeGlobal, boolean includeGlobalWorld, String server, String world, ContextSet context, boolean applyRegex); + /** * If this node should apply on a specific server * diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/Injector.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/Injector.java index 96494ed9..620be2f7 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/Injector.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/Injector.java @@ -74,7 +74,7 @@ public class Injector { existing.clearPermissions(); lpPermissible.getActive().set(true); - lpPermissible.recalculatePermissions(); + lpPermissible.recalculatePermissions(false); lpPermissible.setOldPermissible(existing); lpPermissible.updateSubscriptionsAsync(); diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/LPPermissible.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/LPPermissible.java index eaceb72f..04323781 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/LPPermissible.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/LPPermissible.java @@ -271,6 +271,10 @@ public class LPPermissible extends PermissibleBase { @Override public void recalculatePermissions() { + recalculatePermissions(true); + } + + public void recalculatePermissions(boolean invalidate) { if (attachmentPermissions == null) { return; } @@ -281,7 +285,7 @@ public class LPPermissible extends PermissibleBase { calculateChildPermissions(attachment.getPermissions(), false, attachment); } - if (hasData()) { + if (hasData() && invalidate) { user.getUserData().invalidatePermissionCalculators(); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/caching/handlers/UserReference.java b/common/src/main/java/me/lucko/luckperms/common/caching/handlers/UserReference.java index 13bb83e9..376bd71d 100644 --- a/common/src/main/java/me/lucko/luckperms/common/caching/handlers/UserReference.java +++ b/common/src/main/java/me/lucko/luckperms/common/caching/handlers/UserReference.java @@ -38,7 +38,7 @@ import java.util.function.Consumer; @ToString @EqualsAndHashCode @AllArgsConstructor(staticName = "of") -public class UserReference implements HolderReference { +public final class UserReference implements HolderReference { private final UserIdentifier id; @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/sender/AbstractSender.java b/common/src/main/java/me/lucko/luckperms/common/commands/sender/AbstractSender.java index c0d0ca47..e11cd023 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/sender/AbstractSender.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/sender/AbstractSender.java @@ -41,7 +41,7 @@ import java.util.UUID; */ @Getter @EqualsAndHashCode(of = "uuid") -public class AbstractSender implements Sender { +public final class AbstractSender implements Sender { private final LuckPermsPlugin platform; private final SenderFactory factory; private final WeakReference ref; diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/utils/ArgumentUtils.java b/common/src/main/java/me/lucko/luckperms/common/commands/utils/ArgumentUtils.java index f1a13e65..fbc0181a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/utils/ArgumentUtils.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/utils/ArgumentUtils.java @@ -171,6 +171,14 @@ public class ArgumentUtils { set.add(key, value); } + // remove any potential "global" context mappings + set.remove("server", "global"); + set.remove("world", "global"); + set.remove("server", "null"); + set.remove("world", "null"); + set.remove("server", "*"); + set.remove("world", "*"); + // remove excess entries from the set. // (it can only have one server and one world.) List servers = new ArrayList<>(set.getValues("server")); diff --git a/common/src/main/java/me/lucko/luckperms/common/core/InheritanceInfo.java b/common/src/main/java/me/lucko/luckperms/common/core/InheritanceInfo.java index dbca7e0a..2454ba8c 100644 --- a/common/src/main/java/me/lucko/luckperms/common/core/InheritanceInfo.java +++ b/common/src/main/java/me/lucko/luckperms/common/core/InheritanceInfo.java @@ -40,7 +40,7 @@ import java.util.Optional; @ToString @EqualsAndHashCode @AllArgsConstructor(access = AccessLevel.PRIVATE) -public class InheritanceInfo { +public final class InheritanceInfo { public static InheritanceInfo of(@NonNull LocalizedNode node) { return new InheritanceInfo(node.getTristate(), node.getLocation()); } diff --git a/common/src/main/java/me/lucko/luckperms/common/core/UserIdentifier.java b/common/src/main/java/me/lucko/luckperms/common/core/UserIdentifier.java index 5a1b80e2..eb648fd3 100644 --- a/common/src/main/java/me/lucko/luckperms/common/core/UserIdentifier.java +++ b/common/src/main/java/me/lucko/luckperms/common/core/UserIdentifier.java @@ -36,7 +36,7 @@ import java.util.UUID; @ToString @EqualsAndHashCode(of = "uuid") @AllArgsConstructor(access = AccessLevel.PRIVATE) -public class UserIdentifier implements Identifiable { +public final class UserIdentifier implements Identifiable { public static UserIdentifier of(UUID uuid, String username) { return new UserIdentifier(uuid, username); } diff --git a/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java b/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java index 832258a0..9ea00d6a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java +++ b/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java @@ -57,7 +57,7 @@ import java.util.stream.Collectors; @SuppressWarnings("OptionalGetWithoutIsPresent") @ToString(of = {"permission", "value", "override", "server", "world", "expireAt", "contexts"}) @EqualsAndHashCode(of = {"permission", "value", "override", "server", "world", "expireAt", "contexts"}) -public class ImmutableNode implements Node { +public final class ImmutableNode implements Node { private static boolean shouldApply(String str, boolean applyRegex, String thisStr) { if (str.equalsIgnoreCase(thisStr)) { @@ -389,6 +389,11 @@ public class ImmutableNode implements Node { return suffix; } + @Override + public boolean shouldApply(boolean includeGlobal, boolean includeGlobalWorld, String server, String world, ContextSet context, boolean applyRegex) { + return shouldApplyOnServer(server, includeGlobal, applyRegex) && shouldApplyOnWorld(world, includeGlobalWorld, applyRegex) && shouldApplyWithContext(context, false); + } + @Override public boolean shouldApplyOnServer(String server, boolean includeGlobal, boolean applyRegex) { if (server == null || server.equals("") || server.equalsIgnoreCase("global")) { diff --git a/common/src/main/java/me/lucko/luckperms/common/core/model/PermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/core/model/PermissionHolder.java index aed698b9..72bb9b78 100644 --- a/common/src/main/java/me/lucko/luckperms/common/core/model/PermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/core/model/PermissionHolder.java @@ -117,10 +117,6 @@ public abstract class PermissionHolder { /** * The holders persistent nodes. * - *

These are nodes which are never stored or persisted to a file, and only - * last until the end of the objects lifetime. (for a group, that's when the server stops, and for a user, it's when - * they log out, or get unloaded.)

- * *

Nodes are mapped by the result of {@link Node#getFullContexts()}, and keys are sorted by the weight of the * ContextSet. ContextSets are ordered first by the presence of a server key, then by the presence of a world * key, and finally by the overall size of the set. Nodes are ordered according to the priority rules @@ -345,6 +341,25 @@ public abstract class PermissionHolder { } } + public LinkedHashSet flattenAndMergeNodes(ContextSet filter) { + LinkedHashSet set = new LinkedHashSet<>(); + synchronized (transientNodes) { + for (Map.Entry> e : transientNodes.asMap().entrySet()) { + if (e.getKey().isSatisfiedBy(filter)) { + set.addAll(e.getValue()); + } + } + } + synchronized (nodes) { + for (Map.Entry> e : nodes.asMap().entrySet()) { + if (e.getKey().isSatisfiedBy(filter)) { + set.addAll(e.getValue()); + } + } + } + return set; + } + public List flattenNodesToList() { synchronized (nodes) { return new ArrayList<>(nodes.values()); @@ -387,6 +402,25 @@ public abstract class PermissionHolder { } } + public List flattenAndMergeNodesToList(ContextSet filter) { + List set = new ArrayList<>(); + synchronized (transientNodes) { + for (Map.Entry> e : transientNodes.asMap().entrySet()) { + if (e.getKey().isSatisfiedBy(filter)) { + set.addAll(e.getValue()); + } + } + } + synchronized (nodes) { + for (Map.Entry> e : nodes.asMap().entrySet()) { + if (e.getKey().isSatisfiedBy(filter)) { + set.addAll(e.getValue()); + } + } + } + return set; + } + public boolean removeIf(Predicate predicate) { boolean result; ImmutableSet before = ImmutableSet.copyOf(flattenNodes()); @@ -439,28 +473,26 @@ public abstract class PermissionHolder { excludedGroups.add(getObjectName().toLowerCase()); } - // get the objects own nodes - flattenTransientNodesToList(context.getContextSet()).stream() - .map(n -> ImmutableLocalizedNode.of(n, getObjectName())) - .forEach(accumulator::add); - - flattenNodesToList(context.getContextSet()).stream() + // get and add the objects own nodes + List nodes = flattenAndMergeNodesToList(context.getContextSet()); + nodes.stream() .map(n -> ImmutableLocalizedNode.of(n, getObjectName())) .forEach(accumulator::add); Contexts contexts = context.getContexts(); - String server = context.getServer(); - String world = context.getWorld(); // screw effectively final Set finalExcludedGroups = excludedGroups; List finalAccumulator = accumulator; - mergePermissions().stream() + + // this allows you to negate parent permissions lower down the inheritance tree. + // there's no way to distinct the stream below based on a custom comparator. + NodeTools.removeIgnoreValue(nodes.iterator()); + + nodes.stream() .filter(Node::getValue) .filter(Node::isGroupNode) - .filter(n -> n.shouldApplyOnServer(server, contexts.isApplyGlobalGroups(), plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX))) - .filter(n -> n.shouldApplyOnWorld(world, contexts.isApplyGlobalWorldGroups(), plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX))) - .filter(n -> n.shouldApplyWithContext(contexts.getContexts(), false)) + .filter(n -> !(!contexts.isApplyGlobalGroups() && !n.isServerSpecific()) && !(!contexts.isApplyGlobalWorldGroups() && !n.isWorldSpecific())) .map(Node::getGroupName) .distinct() .map(n -> Optional.ofNullable(plugin.getGroupManager().getIfLoaded(n))) @@ -498,8 +530,6 @@ public abstract class PermissionHolder { public SortedSet getAllNodes(ExtractedContexts context) { Contexts contexts = context.getContexts(); - String server = context.getServer(); - String world = context.getWorld(); List entries; if (contexts.isApplyGroups()) { @@ -508,13 +538,12 @@ public abstract class PermissionHolder { entries = flattenNodesToList(context.getContextSet()).stream().map(n -> ImmutableLocalizedNode.of(n, getObjectName())).collect(Collectors.toList()); } - entries.removeIf(node -> - !node.isGroupNode() && ( - !node.shouldApplyOnServer(server, contexts.isIncludeGlobal(), plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX)) || - !node.shouldApplyOnWorld(world, contexts.isIncludeGlobalWorld(), plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX)) || - !node.shouldApplyWithContext(context.getContextSet(), false) - ) - ); + if (!contexts.isIncludeGlobal()) { + entries.removeIf(n -> !n.isGroupNode() && !n.isServerSpecific()); + } + if (!contexts.isApplyGlobalWorldGroups()) { + entries.removeIf(n -> !n.isGroupNode() && !n.isWorldSpecific()); + } NodeTools.removeSamePermission(entries.iterator()); SortedSet ret = new TreeSet<>(PriorityComparator.reverse()); @@ -524,8 +553,6 @@ public abstract class PermissionHolder { public Map exportNodes(ExtractedContexts context, boolean lowerCase) { Contexts contexts = context.getContexts(); - String server = context.getServer(); - String world = context.getWorld(); List entries; if (contexts.isApplyGroups()) { @@ -534,27 +561,22 @@ public abstract class PermissionHolder { entries = flattenNodesToList(context.getContextSet()); } - entries.removeIf(node -> - !node.isGroupNode() && ( - !node.shouldApplyOnServer(server, contexts.isIncludeGlobal(), plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX)) || - !node.shouldApplyOnWorld(world, contexts.isIncludeGlobalWorld(), plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX)) || - !node.shouldApplyWithContext(context.getContextSet(), false) - ) - ); + if (!contexts.isIncludeGlobal()) { + entries.removeIf(n -> !n.isGroupNode() && !n.isServerSpecific()); + } + if (!contexts.isApplyGlobalWorldGroups()) { + entries.removeIf(n -> !n.isGroupNode() && !n.isWorldSpecific()); + } Map perms = new HashMap<>(); - for (Node node : entries) { String perm = lowerCase ? node.getPermission().toLowerCase() : node.getPermission(); - if (!perms.containsKey(perm)) { - perms.put(perm, node.getValue()); + if (perms.putIfAbsent(perm, node.getValue()) == null) { if (plugin.getConfiguration().get(ConfigKeys.APPLYING_SHORTHAND)) { List sh = node.resolveShorthand(); if (!sh.isEmpty()) { - sh.stream().map(s -> lowerCase ? s.toLowerCase() : s) - .filter(s -> !perms.containsKey(s)) - .forEach(s -> perms.put(s, node.getValue())); + sh.stream().map(s -> lowerCase ? s.toLowerCase() : s).forEach(s -> perms.putIfAbsent(s, node.getValue())); } } } @@ -580,27 +602,17 @@ public abstract class PermissionHolder { } Contexts contexts = context.getContexts(); - String server = context.getServer(); - String world = context.getWorld(); // screw effectively final Set finalExcludedGroups = excludedGroups; MetaAccumulator finalAccumulator = accumulator; - flattenTransientNodesToList(context.getContextSet()).stream() + // get and add the objects own nodes + List nodes = flattenAndMergeNodesToList(context.getContextSet()); + nodes.stream() .filter(Node::getValue) .filter(n -> n.isMeta() || n.isPrefix() || n.isSuffix()) - .filter(n -> n.shouldApplyOnServer(server, contexts.isIncludeGlobal(), false)) - .filter(n -> n.shouldApplyOnWorld(world, contexts.isIncludeGlobalWorld(), false)) - .filter(n -> n.shouldApplyWithContext(context.getContextSet(), false)) - .forEach(n -> finalAccumulator.accumulateNode(ImmutableLocalizedNode.of(n, getObjectName()))); - - flattenNodesToList(context.getContextSet()).stream() - .filter(Node::getValue) - .filter(n -> n.isMeta() || n.isPrefix() || n.isSuffix()) - .filter(n -> n.shouldApplyOnServer(server, contexts.isIncludeGlobal(), false)) - .filter(n -> n.shouldApplyOnWorld(world, contexts.isIncludeGlobalWorld(), false)) - .filter(n -> n.shouldApplyWithContext(context.getContextSet(), false)) + .filter(n -> !(!contexts.isIncludeGlobal() && !n.isServerSpecific()) && !(!contexts.isIncludeGlobalWorld() && !n.isWorldSpecific())) .forEach(n -> finalAccumulator.accumulateNode(ImmutableLocalizedNode.of(n, getObjectName()))); OptionalInt w = getWeight(); @@ -608,12 +620,14 @@ public abstract class PermissionHolder { accumulator.accumulateWeight(w.getAsInt()); } - mergePermissions().stream() + // this allows you to negate parent permissions lower down the inheritance tree. + // there's no way to distinct the stream below based on a custom comparator. + NodeTools.removeIgnoreValue(nodes.iterator()); + + nodes.stream() .filter(Node::getValue) .filter(Node::isGroupNode) - .filter(n -> n.shouldApplyOnServer(server, contexts.isApplyGlobalGroups(), plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX))) - .filter(n -> n.shouldApplyOnWorld(world, contexts.isApplyGlobalWorldGroups(), plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX))) - .filter(n -> n.shouldApplyWithContext(contexts.getContexts(), false)) + .filter(n -> !(!contexts.isApplyGlobalGroups() && !n.isServerSpecific()) && !(!contexts.isApplyGlobalWorldGroups() && !n.isWorldSpecific())) .map(Node::getGroupName) .distinct() .map(n -> Optional.ofNullable(plugin.getGroupManager().getIfLoaded(n))) diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/backing/utils/NodeDataHolder.java b/common/src/main/java/me/lucko/luckperms/common/storage/backing/utils/NodeDataHolder.java index 7fcecef5..d3221aee 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/backing/utils/NodeDataHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/backing/utils/NodeDataHolder.java @@ -47,7 +47,7 @@ import java.util.Map; @ToString @EqualsAndHashCode @AllArgsConstructor(staticName = "of") -public class NodeDataHolder { +public final class NodeDataHolder { private static final Gson GSON = new Gson(); public static NodeDataHolder fromNode(Node node) { diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/holder/NodeHeldPermission.java b/common/src/main/java/me/lucko/luckperms/common/storage/holder/NodeHeldPermission.java index 9921678e..d9420914 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/holder/NodeHeldPermission.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/holder/NodeHeldPermission.java @@ -38,7 +38,7 @@ import java.util.OptionalLong; @Getter @EqualsAndHashCode @AllArgsConstructor(staticName = "of") -public class NodeHeldPermission implements HeldPermission { +public final class NodeHeldPermission implements HeldPermission { public static NodeHeldPermission of(T holder, NodeDataHolder nodeDataHolder) { return of(holder, nodeDataHolder.toNode()); } diff --git a/common/src/main/java/me/lucko/luckperms/common/utils/Buffer.java b/common/src/main/java/me/lucko/luckperms/common/utils/Buffer.java index 35af989b..26ee59e0 100644 --- a/common/src/main/java/me/lucko/luckperms/common/utils/Buffer.java +++ b/common/src/main/java/me/lucko/luckperms/common/utils/Buffer.java @@ -111,7 +111,7 @@ public abstract class Buffer implements Runnable { @Getter @EqualsAndHashCode(of = "object") @AllArgsConstructor - private static class BufferedObject { + private static final class BufferedObject { @Setter private long bufferTime; diff --git a/common/src/main/java/me/lucko/luckperms/common/utils/ImmutableLocalizedNode.java b/common/src/main/java/me/lucko/luckperms/common/utils/ImmutableLocalizedNode.java index 6ba821f5..5db9dc29 100644 --- a/common/src/main/java/me/lucko/luckperms/common/utils/ImmutableLocalizedNode.java +++ b/common/src/main/java/me/lucko/luckperms/common/utils/ImmutableLocalizedNode.java @@ -38,7 +38,7 @@ import me.lucko.luckperms.api.Node; @Getter @ToString @AllArgsConstructor(access = AccessLevel.PRIVATE) -public class ImmutableLocalizedNode implements LocalizedNode { +public final class ImmutableLocalizedNode implements LocalizedNode { public static ImmutableLocalizedNode of(@NonNull Node node, @NonNull String location) { return new ImmutableLocalizedNode(node, location); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/LuckPermsService.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/LuckPermsService.java index fff45c2a..4129199a 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/LuckPermsService.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/LuckPermsService.java @@ -311,7 +311,7 @@ public class LuckPermsService implements PermissionService { @RequiredArgsConstructor @EqualsAndHashCode @ToString - public static class DescriptionBuilder implements PermissionDescription.Builder { + public static final class DescriptionBuilder implements PermissionDescription.Builder { private final LuckPermsService service; private final PluginContainer container; private final Map roles = new HashMap<>(); @@ -365,7 +365,7 @@ public class LuckPermsService implements PermissionService { @AllArgsConstructor @EqualsAndHashCode @ToString - public static class Description implements PermissionDescription { + public static final class Description implements PermissionDescription { private final LuckPermsService service; private final PluginContainer owner; private final String id; diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/calculated/OptionLookup.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/calculated/OptionLookup.java index 0f69a9d3..40d4aaba 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/calculated/OptionLookup.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/calculated/OptionLookup.java @@ -33,7 +33,7 @@ import me.lucko.luckperms.api.context.ImmutableContextSet; @ToString @EqualsAndHashCode @AllArgsConstructor(staticName = "of") -public class OptionLookup { +public final class OptionLookup { private final String key; private final ImmutableContextSet contexts; diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/calculated/PermissionLookup.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/calculated/PermissionLookup.java index c249bf20..5cbf399a 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/calculated/PermissionLookup.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/calculated/PermissionLookup.java @@ -33,7 +33,7 @@ import me.lucko.luckperms.api.context.ImmutableContextSet; @ToString @EqualsAndHashCode @AllArgsConstructor(staticName = "of") -public class PermissionLookup { +public final class PermissionLookup { private final String node; private final ImmutableContextSet contexts; diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/references/SubjectCollectionReference.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/references/SubjectCollectionReference.java index 84854c47..b5640531 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/references/SubjectCollectionReference.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/references/SubjectCollectionReference.java @@ -35,7 +35,7 @@ import java.lang.ref.WeakReference; @ToString(of = "collection") @EqualsAndHashCode(of = "collection") @RequiredArgsConstructor(staticName = "of") -public class SubjectCollectionReference { +public final class SubjectCollectionReference { @Getter private final String collection; diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/references/SubjectReference.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/references/SubjectReference.java index f6a970ec..1fe2fdbc 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/references/SubjectReference.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/references/SubjectReference.java @@ -40,7 +40,7 @@ import java.util.List; @ToString(of = {"collection", "identifier"}) @EqualsAndHashCode(of = {"collection", "identifier"}) @RequiredArgsConstructor(staticName = "of") -public class SubjectReference { +public final class SubjectReference { public static SubjectReference deserialize(String s) { List parts = Splitter.on('/').limit(2).splitToList(s); return of(parts.get(0), parts.get(1));