diff --git a/api/src/main/java/me/lucko/luckperms/api/Contexts.java b/api/src/main/java/me/lucko/luckperms/api/Contexts.java
index d21fe7b1..287464ae 100644
--- a/api/src/main/java/me/lucko/luckperms/api/Contexts.java
+++ b/api/src/main/java/me/lucko/luckperms/api/Contexts.java
@@ -25,22 +25,46 @@
package me.lucko.luckperms.api;
+import com.google.common.base.Preconditions;
+
import me.lucko.luckperms.api.context.ContextSet;
+import me.lucko.luckperms.api.context.ImmutableContextSet;
import javax.annotation.Nonnull;
/**
- * Context and options for a permission lookup.
+ * Encapsulates the options and settings for a permission lookup.
*
- *
All values are immutable.
+ * This class is immutable.
*
* @since 2.11
*/
public class Contexts {
+
+ /**
+ * The context key used to denote the subjects server
+ */
public static final String SERVER_KEY = "server";
+
+ /**
+ * The context key used to denote the subjects world
+ */
public static final String WORLD_KEY = "world";
- private static final Contexts GLOBAL = new Contexts(ContextSet.empty(), true, true, true, true, true, false);
+ /**
+ * A 'global' or default contexts instance.
+ *
+ * Simply passes an empty context set, with all accumulation settings set to true.
+ */
+ private static final Contexts GLOBAL = new Contexts(
+ ContextSet.empty(),
+ true,
+ true,
+ true,
+ true,
+ true,
+ false
+ );
/**
* Gets the {@link FullySatisfiedContexts} instance.
@@ -69,12 +93,12 @@ public class Contexts {
/**
* The contexts that apply for this lookup
- * The keys for servers and worlds are defined as static values.
*/
- private final ContextSet context;
+ private final ImmutableContextSet context;
/**
- * The mode to parse defaults on Bukkit
+ * If the target subject is OP. This is used to parse defaults on Bukkit,
+ * and is ignored on all other platforms.
*
* @since 2.12
*/
@@ -105,18 +129,18 @@ public class Contexts {
*/
private final boolean applyGlobalWorldGroups;
- public Contexts(@Nonnull ContextSet context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
- if (context == null) {
- throw new NullPointerException("context");
- }
+ // cache hashcode - this class is immutable, and is used as an index in the permission cache.
+ private final int hashCode;
- this.context = context.makeImmutable();
+ public Contexts(@Nonnull ContextSet context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
+ this.context = Preconditions.checkNotNull(context, "context").makeImmutable();
this.includeGlobal = includeGlobal;
this.includeGlobalWorld = includeGlobalWorld;
this.applyGroups = applyGroups;
this.applyGlobalGroups = applyGlobalGroups;
this.applyGlobalWorldGroups = applyGlobalWorldGroups;
this.op = op;
+ this.hashCode = calculateHashCode();
}
/**
@@ -131,7 +155,8 @@ public class Contexts {
}
/**
- * Gets if OP defaults should be included
+ * Gets if the target subject is OP. This is used to parse defaults on Bukkit,
+ * and is ignored on all other platforms.
*
* @return true if op defaults should be included
*/
@@ -198,10 +223,6 @@ public class Contexts {
")";
}
- /*
- * Ugly auto-generated lombok code
- */
-
@Override
public boolean equals(Object o) {
if (o == this) return true;
@@ -218,8 +239,7 @@ public class Contexts {
this.isApplyGlobalWorldGroups() == other.isApplyGlobalWorldGroups();
}
- @Override
- public int hashCode() {
+ private int calculateHashCode() {
final int PRIME = 59;
int result = 1;
final Object contexts = this.getContexts();
@@ -233,4 +253,8 @@ public class Contexts {
return result;
}
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
}
diff --git a/api/src/main/java/me/lucko/luckperms/api/DataMutateResult.java b/api/src/main/java/me/lucko/luckperms/api/DataMutateResult.java
index a5b42114..1850213f 100644
--- a/api/src/main/java/me/lucko/luckperms/api/DataMutateResult.java
+++ b/api/src/main/java/me/lucko/luckperms/api/DataMutateResult.java
@@ -55,7 +55,7 @@ public enum DataMutateResult {
*/
FAIL(false, RuntimeException::new);
- private boolean value;
+ private final boolean value;
private final Supplier extends Exception> exceptionSupplier;
DataMutateResult(boolean value, Supplier extends Exception> exceptionSupplier) {
@@ -104,6 +104,7 @@ public enum DataMutateResult {
sneakyThrow0(t);
}
+ @SuppressWarnings("unchecked")
private static void sneakyThrow0(Throwable t) throws T {
throw (T) t;
}
diff --git a/api/src/main/java/me/lucko/luckperms/api/FullySatisfiedContexts.java b/api/src/main/java/me/lucko/luckperms/api/FullySatisfiedContexts.java
index f2205b09..d0146679 100644
--- a/api/src/main/java/me/lucko/luckperms/api/FullySatisfiedContexts.java
+++ b/api/src/main/java/me/lucko/luckperms/api/FullySatisfiedContexts.java
@@ -48,6 +48,8 @@ import javax.annotation.Nonnull;
* @since 3.3
*/
public final class FullySatisfiedContexts extends Contexts {
+
+ // singleton
private static final FullySatisfiedContexts INSTANCE = new FullySatisfiedContexts();
@Nonnull
@@ -62,16 +64,18 @@ public final class FullySatisfiedContexts extends Contexts {
@Nonnull
@Override
public String toString() {
- return "FullySatisfiedContexts";
+ return "FullySatisfiedContexts()";
}
@Override
public boolean equals(Object o) {
+ // this class is a singleton, so we can use object comparison to check equality.
return o == this;
}
@Override
public int hashCode() {
+ // just use the system hashcode - we need to override the hashcode impl in super
return System.identityHashCode(this);
}
}
diff --git a/api/src/main/java/me/lucko/luckperms/api/LogEntry.java b/api/src/main/java/me/lucko/luckperms/api/LogEntry.java
index 864698e9..d22f1a07 100644
--- a/api/src/main/java/me/lucko/luckperms/api/LogEntry.java
+++ b/api/src/main/java/me/lucko/luckperms/api/LogEntry.java
@@ -426,8 +426,8 @@ public class LogEntry implements Comparable {
* @param the log builder type
*/
public static abstract class AbstractLogEntryBuilder> {
- private T obj;
- private B thisObj;
+ private final T obj;
+ private final B thisObj;
public AbstractLogEntryBuilder() {
obj = createEmptyLog();
diff --git a/api/src/main/java/me/lucko/luckperms/api/PermissionHolder.java b/api/src/main/java/me/lucko/luckperms/api/PermissionHolder.java
index 8b66c66d..81bb7dc1 100644
--- a/api/src/main/java/me/lucko/luckperms/api/PermissionHolder.java
+++ b/api/src/main/java/me/lucko/luckperms/api/PermissionHolder.java
@@ -48,6 +48,7 @@ import javax.annotation.Nullable;
* Any changes made to permission holding objects will be lost unless the
* instance is saved back to the {@link Storage}.
*/
+@SuppressWarnings("RedundantThrows")
public interface PermissionHolder {
/**
diff --git a/api/src/main/java/me/lucko/luckperms/api/Track.java b/api/src/main/java/me/lucko/luckperms/api/Track.java
index aa26ecb6..b1cccd2a 100644
--- a/api/src/main/java/me/lucko/luckperms/api/Track.java
+++ b/api/src/main/java/me/lucko/luckperms/api/Track.java
@@ -36,6 +36,7 @@ import javax.annotation.Nullable;
/**
* An ordered chain of {@link Group}s.
*/
+@SuppressWarnings("RedundantThrows")
public interface Track {
/**
diff --git a/api/src/main/java/me/lucko/luckperms/api/caching/MetaContexts.java b/api/src/main/java/me/lucko/luckperms/api/caching/MetaContexts.java
index 9538ec97..946e98b4 100644
--- a/api/src/main/java/me/lucko/luckperms/api/caching/MetaContexts.java
+++ b/api/src/main/java/me/lucko/luckperms/api/caching/MetaContexts.java
@@ -58,6 +58,9 @@ public final class MetaContexts {
private final MetaStackDefinition prefixStackDefinition;
private final MetaStackDefinition suffixStackDefinition;
+ // cache hashcode - this class is immutable, and is used as an index in the permission cache.
+ private final int hashCode;
+
/**
* Creates a new meta contexts instance
*
@@ -69,6 +72,7 @@ public final class MetaContexts {
this.contexts = Preconditions.checkNotNull(contexts, "contexts");
this.prefixStackDefinition = Preconditions.checkNotNull(prefixStackDefinition, "prefixStackDefinition");
this.suffixStackDefinition = Preconditions.checkNotNull(suffixStackDefinition, "suffixStackDefinition");
+ this.hashCode = calculateHashCode();
}
@Nonnull
@@ -106,8 +110,7 @@ public final class MetaContexts {
this.getSuffixStackDefinition().equals(other.getSuffixStackDefinition());
}
- @Override
- public int hashCode() {
+ private int calculateHashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.getContexts().hashCode();
@@ -115,4 +118,9 @@ public final class MetaContexts {
result = result * PRIME + this.getSuffixStackDefinition().hashCode();
return result;
}
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
}
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitScheduler.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitScheduler.java
index 95c23e3c..de30b0a6 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitScheduler.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitScheduler.java
@@ -59,7 +59,7 @@ public class LPBukkitScheduler implements LuckPermsScheduler {
@Setter
private boolean useBukkitAsync = false;
- private Set tasks = ConcurrentHashMap.newKeySet();
+ private final Set tasks = ConcurrentHashMap.newKeySet();
public LPBukkitScheduler(LPBukkitPlugin plugin) {
this.plugin = plugin;
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 60bc18ae..dc998184 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
@@ -55,15 +55,17 @@ public class Injector {
*
* This field is where the permissible is stored on a HumanEntity.
*/
- private static Field humanEntityPermissibleField;
+ private static final Field HUMAN_ENTITY_PERMISSIBLE_FIELD;
/**
* The field where attachments are stored on a permissible base.
*/
- private static Field permissibleBaseAttachmentsField;
+ private static final Field PERMISSIBLE_BASE_ATTACHMENTS_FIELD;
- private static Throwable cachedThrowable = null;
static {
+ Field humanEntityPermissibleField;
+ Field permissibleBaseAttachmentsField;
+
try {
// Catch all. If this setup doesn't fully complete without
// exceptions, then the Injector will not work.
@@ -85,9 +87,11 @@ public class Injector {
permissibleBaseAttachmentsField.setAccessible(true);
} catch (Throwable t) {
- cachedThrowable = t;
- t.printStackTrace();
+ throw new RuntimeException("Injector did not init successfully.", t);
}
+
+ HUMAN_ENTITY_PERMISSIBLE_FIELD = humanEntityPermissibleField;
+ PERMISSIBLE_BASE_ATTACHMENTS_FIELD = permissibleBaseAttachmentsField;
}
/**
@@ -99,13 +103,8 @@ public class Injector {
*/
public static void inject(Player player, LPPermissible newPermissible) throws Exception {
- // make sure the class inited without errors, otherwise, print a trace
- if (cachedThrowable != null) {
- throw new RuntimeException("Injector did not init successfully.", cachedThrowable);
- }
-
// get the existing PermissibleBase held by the player
- PermissibleBase oldPermissible = (PermissibleBase) humanEntityPermissibleField.get(player);
+ PermissibleBase oldPermissible = (PermissibleBase) HUMAN_ENTITY_PERMISSIBLE_FIELD.get(player);
// seems we have already injected into this player.
if (oldPermissible instanceof LPPermissible) {
@@ -115,7 +114,7 @@ public class Injector {
// Move attachments over from the old permissible
//noinspection unchecked
- List attachments = (List) permissibleBaseAttachmentsField.get(oldPermissible);
+ List attachments = (List) PERMISSIBLE_BASE_ATTACHMENTS_FIELD.get(oldPermissible);
newPermissible.addAttachments(attachments);
attachments.clear();
@@ -128,7 +127,7 @@ public class Injector {
newPermissible.updateSubscriptionsAsync();
// inject the new instance
- humanEntityPermissibleField.set(player, newPermissible);
+ HUMAN_ENTITY_PERMISSIBLE_FIELD.set(player, newPermissible);
// register the injection with the map
INJECTED_PERMISSIBLES.put(player.getUniqueId(), newPermissible);
@@ -143,13 +142,9 @@ public class Injector {
* @throws Exception propagates any exceptions which were thrown during uninjection
*/
public static void unInject(Player player, boolean dummy, boolean unsubscribe) throws Exception {
- // make sure the class inited without errors, otherwise, print a trace
- if (cachedThrowable != null) {
- throw new RuntimeException("Injector did not init successfully.", cachedThrowable);
- }
// gets the players current permissible.
- PermissibleBase permissible = (PermissibleBase) humanEntityPermissibleField.get(player);
+ PermissibleBase permissible = (PermissibleBase) HUMAN_ENTITY_PERMISSIBLE_FIELD.get(player);
// only uninject if the permissible was a luckperms one.
if (permissible instanceof LPPermissible) {
@@ -169,7 +164,7 @@ public class Injector {
// handle the replacement permissible.
if (dummy) {
// just inject a dummy class. this is used when we know the player is about to quit the server.
- humanEntityPermissibleField.set(player, new DummyPermissibleBase());
+ HUMAN_ENTITY_PERMISSIBLE_FIELD.set(player, new DummyPermissibleBase());
} else {
// otherwise, inject the permissible they had when we first injected.
@@ -182,11 +177,11 @@ public class Injector {
}
//noinspection unchecked
- List newPbAttachments = (List) permissibleBaseAttachmentsField.get(newPb);
+ List newPbAttachments = (List) PERMISSIBLE_BASE_ATTACHMENTS_FIELD.get(newPb);
newPbAttachments.addAll(lpAttachments);
lpAttachments.clear();
- humanEntityPermissibleField.set(player, newPb);
+ HUMAN_ENTITY_PERMISSIBLE_FIELD.set(player, newPb);
}
}
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/processors/ChildProcessor.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/processors/ChildProcessor.java
index 80ff8542..6a1ba488 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/processors/ChildProcessor.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/processors/ChildProcessor.java
@@ -41,7 +41,7 @@ import java.util.concurrent.ConcurrentHashMap;
@RequiredArgsConstructor
public class ChildProcessor implements PermissionProcessor {
private final ChildPermissionProvider provider;
- private Map childPermissions = new ConcurrentHashMap<>();
+ private final Map childPermissions = new ConcurrentHashMap<>();
@Override
public Tristate hasPermission(String permission) {
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java
index c3821ead..1f7d873b 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java
@@ -32,7 +32,6 @@ import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.caching.MetaData;
import me.lucko.luckperms.common.caching.MetaAccumulator;
-import me.lucko.luckperms.common.contexts.ExtractedContexts;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
@@ -284,7 +283,7 @@ public class VaultChatHook extends Chat {
holder.removeIf(type::matches);
// find the max inherited priority & add 10
- MetaAccumulator metaAccumulator = holder.accumulateMeta(null, null, ExtractedContexts.generate(perms.createContextForWorldSet(finalWorld)));
+ MetaAccumulator metaAccumulator = holder.accumulateMeta(null, null, perms.createContextForWorldSet(finalWorld));
int priority = (type == ChatMetaType.PREFIX ? metaAccumulator.getPrefixes() : metaAccumulator.getSuffixes()).keySet().stream()
.mapToInt(e -> e).max().orElse(0) + 10;
@@ -355,8 +354,8 @@ public class VaultChatHook extends Chat {
int priority = Integer.MIN_VALUE;
String meta = null;
- ExtractedContexts ec = ExtractedContexts.generate(Contexts.of(perms.createContextForWorldLookup(world).getContexts(), perms.isIncludeGlobal(), true, true, true, true, false));
- for (Node n : group.getAllNodes(ec)) {
+ Contexts contexts = Contexts.of(perms.createContextForWorldLookup(world).getContexts(), perms.isIncludeGlobal(), true, true, true, true, false);
+ for (Node n : group.getAllNodes(contexts)) {
if (!n.getValuePrimitive()) continue;
if (type.shouldIgnore(n)) continue;
if (!n.shouldApplyWithContext(perms.createContextForWorldLookup(world).getContexts())) continue;
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java
index 57f7368d..8ecba55f 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java
@@ -37,7 +37,6 @@ import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.caching.PermissionCache;
import me.lucko.luckperms.common.config.ConfigKeys;
-import me.lucko.luckperms.common.contexts.ExtractedContexts;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
@@ -226,7 +225,7 @@ public class VaultPermissionHook extends Permission {
if (group == null) return false;
// This is a nasty call. Groups aren't cached. :(
- Map permissions = group.exportNodesAndShorthand(ExtractedContexts.generate(createContextForWorldLookup(world)), true);
+ Map permissions = group.exportNodesAndShorthand(createContextForWorldLookup(world), true);
return permissions.containsKey(permission.toLowerCase()) && permissions.get(permission.toLowerCase());
}
diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeeScheduler.java b/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeeScheduler.java
index 9754e477..2e2497b5 100644
--- a/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeeScheduler.java
+++ b/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeeScheduler.java
@@ -37,8 +37,8 @@ import java.util.concurrent.TimeUnit;
public class LPBungeeScheduler implements LuckPermsScheduler {
private final LPBungeePlugin plugin;
- private Executor asyncExecutor;
- private Set tasks = ConcurrentHashMap.newKeySet();
+ private final Executor asyncExecutor;
+ private final Set tasks = ConcurrentHashMap.newKeySet();
public LPBungeeScheduler(LPBungeePlugin plugin) {
this.plugin = plugin;
diff --git a/common/src/main/java/me/lucko/luckperms/common/api/ApiProvider.java b/common/src/main/java/me/lucko/luckperms/common/api/ApiProvider.java
index 26087465..3babfac5 100644
--- a/common/src/main/java/me/lucko/luckperms/common/api/ApiProvider.java
+++ b/common/src/main/java/me/lucko/luckperms/common/api/ApiProvider.java
@@ -151,7 +151,7 @@ public class ApiProvider implements LuckPermsApi {
@Override
public Set getUsers() {
- return plugin.getUserManager().getAll().values().stream().map(u -> u.getDelegate()).collect(Collectors.toSet());
+ return plugin.getUserManager().getAll().values().stream().map(me.lucko.luckperms.common.model.User::getDelegate).collect(Collectors.toSet());
}
@Override
@@ -177,7 +177,7 @@ public class ApiProvider implements LuckPermsApi {
@Override
public Set getGroups() {
- return plugin.getGroupManager().getAll().values().stream().map(g -> g.getDelegate()).collect(Collectors.toSet());
+ return plugin.getGroupManager().getAll().values().stream().map(me.lucko.luckperms.common.model.Group::getDelegate).collect(Collectors.toSet());
}
@Override
@@ -198,7 +198,7 @@ public class ApiProvider implements LuckPermsApi {
@Override
public Set