Refactor contexts, expose cached data in the API & release 2.13
This commit is contained in:
@@ -69,7 +69,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public double getApiVersion() {
|
||||
return 2.12;
|
||||
return 2.13;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-3
@@ -25,6 +25,7 @@ package me.lucko.luckperms.common.api.internal;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
@@ -247,7 +248,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
if (world != null && !world.equals("")) {
|
||||
context.put("world", world);
|
||||
}
|
||||
return master.exportNodes(new Contexts(context, true, true, true, true, true), false);
|
||||
return master.exportNodes(new Contexts(ContextSet.fromMap(context), true, true, true, true, true, false), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -259,7 +260,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
if (world != null && !world.equals("")) {
|
||||
context.put("world", world);
|
||||
}
|
||||
return master.exportNodes(new Contexts(context, true, true, true, true, true), false);
|
||||
return master.exportNodes(new Contexts(ContextSet.fromMap(context), true, true, true, true, true, false), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -283,7 +284,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
if (world != null && !world.equals("")) {
|
||||
extraContext.put("world", world);
|
||||
}
|
||||
return master.exportNodes(new Contexts(extraContext, includeGlobal, includeGlobal, applyGroups, true, true), false);
|
||||
return master.exportNodes(new Contexts(ContextSet.fromMap(extraContext), includeGlobal, includeGlobal, applyGroups, true, true, false), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,10 +27,12 @@ import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.api.caching.UserData;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.*;
|
||||
@@ -82,6 +84,11 @@ public class UserLink extends PermissionHolderLink implements User {
|
||||
master.getRefreshBuffer().requestDirectly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UserData> getUserDataCache() {
|
||||
return Optional.ofNullable(master.getUserData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGroup(@NonNull Group group) {
|
||||
checkGroup(group);
|
||||
|
||||
+14
-5
@@ -28,6 +28,8 @@ import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.caching.MetaData;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -35,7 +37,7 @@ import java.util.*;
|
||||
* Holds a user's cached meta for a given context
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class MetaData {
|
||||
public class MetaCache implements MetaData {
|
||||
private final Contexts contexts;
|
||||
|
||||
private final SortedMap<Integer, String> prefixes = new TreeMap<>(Comparator.reverseOrder());
|
||||
@@ -46,9 +48,11 @@ public class MetaData {
|
||||
public void loadMeta(SortedSet<LocalizedNode> nodes) {
|
||||
invalidateCache();
|
||||
|
||||
Map<String, String> contexts = new HashMap<>(this.contexts.getContext());
|
||||
String server = contexts.remove("server");
|
||||
String world = contexts.remove("world");
|
||||
MutableContextSet contexts = MutableContextSet.fromSet(this.contexts.getContexts());
|
||||
String server = contexts.getValues("server").stream().findAny().orElse(null);
|
||||
String world = contexts.getValues("world").stream().findAny().orElse(null);
|
||||
contexts.removeAll("server");
|
||||
contexts.removeAll("world");
|
||||
|
||||
for (LocalizedNode ln : nodes) {
|
||||
Node n = ln.getNode();
|
||||
@@ -105,7 +109,7 @@ public class MetaData {
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
private void invalidateCache() {
|
||||
synchronized (meta) {
|
||||
meta.clear();
|
||||
}
|
||||
@@ -117,24 +121,28 @@ public class MetaData {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMeta() {
|
||||
synchronized (meta) {
|
||||
return ImmutableMap.copyOf(meta);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedMap<Integer, String> getPrefixes() {
|
||||
synchronized (prefixes) {
|
||||
return ImmutableSortedMap.copyOfSorted(prefixes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedMap<Integer, String> getSuffixes() {
|
||||
synchronized (suffixes) {
|
||||
return ImmutableSortedMap.copyOfSorted(suffixes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefix() {
|
||||
synchronized (prefixes) {
|
||||
if (prefixes.isEmpty()) {
|
||||
@@ -145,6 +153,7 @@ public class MetaData {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuffix() {
|
||||
synchronized (suffixes) {
|
||||
if (suffixes.isEmpty()) {
|
||||
+6
-2
@@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableMap;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.caching.PermissionData;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.calculators.PermissionCalculator;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
@@ -36,7 +37,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
/**
|
||||
* Holds a user's cached permissions for a given context
|
||||
*/
|
||||
public class PermissionData {
|
||||
public class PermissionCache implements PermissionData {
|
||||
|
||||
/**
|
||||
* The raw set of permission strings.
|
||||
@@ -50,11 +51,12 @@ public class PermissionData {
|
||||
*/
|
||||
private final PermissionCalculator calculator;
|
||||
|
||||
public PermissionData(Contexts contexts, User user, CalculatorFactory calculatorFactory) {
|
||||
public PermissionCache(Contexts contexts, User user, CalculatorFactory calculatorFactory) {
|
||||
permissions = new ConcurrentHashMap<>();
|
||||
calculator = calculatorFactory.build(contexts, user, permissions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCache() {
|
||||
calculator.invalidateCache();
|
||||
}
|
||||
@@ -71,10 +73,12 @@ public class PermissionData {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getImmutableBacking() {
|
||||
return ImmutableMap.copyOf(permissions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tristate getPermissionValue(@NonNull String permission) {
|
||||
return calculator.getPermissionValue(permission);
|
||||
}
|
||||
+34
-66
@@ -28,8 +28,12 @@ import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.caching.MetaData;
|
||||
import me.lucko.luckperms.api.caching.PermissionData;
|
||||
import me.lucko.luckperms.api.caching.UserData;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
|
||||
@@ -39,7 +43,7 @@ import java.util.Set;
|
||||
* Holds an easily accessible cache of a user's data in a number of contexts
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class UserData {
|
||||
public class UserCache implements UserData {
|
||||
|
||||
/**
|
||||
* The user whom this data instance is representing
|
||||
@@ -51,124 +55,87 @@ public class UserData {
|
||||
*/
|
||||
private final CalculatorFactory calculatorFactory;
|
||||
|
||||
private final LoadingCache<Contexts, PermissionData> permission = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<Contexts, PermissionData>() {
|
||||
private final LoadingCache<Contexts, PermissionCache> permission = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<Contexts, PermissionCache>() {
|
||||
@Override
|
||||
public PermissionData load(Contexts contexts) {
|
||||
public PermissionCache load(Contexts contexts) {
|
||||
return calculatePermissions(contexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<PermissionData> reload(Contexts contexts, PermissionData oldData) {
|
||||
public ListenableFuture<PermissionCache> reload(Contexts contexts, PermissionCache oldData) {
|
||||
oldData.comparePermissions(user.exportNodes(contexts, true));
|
||||
return Futures.immediateFuture(oldData);
|
||||
}
|
||||
});
|
||||
|
||||
private final LoadingCache<Contexts, MetaData> meta = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<Contexts, MetaData>() {
|
||||
private final LoadingCache<Contexts, MetaCache> meta = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<Contexts, MetaCache>() {
|
||||
@Override
|
||||
public MetaData load(Contexts contexts) {
|
||||
public MetaCache load(Contexts contexts) {
|
||||
return calculateMeta(contexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<MetaData> reload(Contexts contexts, MetaData oldData) {
|
||||
public ListenableFuture<MetaCache> reload(Contexts contexts, MetaCache oldData) {
|
||||
oldData.loadMeta(user.getAllNodes(null, contexts));
|
||||
return Futures.immediateFuture(oldData);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Gets PermissionData from the cache, given a specified context.
|
||||
* If the data is not cached, it is calculated. Therefore, this call could be costly.
|
||||
* @param contexts the contexts to get the permission data in
|
||||
* @return a permission data instance
|
||||
*/
|
||||
public PermissionData getPermissionData(Contexts contexts) {
|
||||
@Override
|
||||
public PermissionData getPermissionData(@NonNull Contexts contexts) {
|
||||
return permission.getUnchecked(contexts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets MetaData from the cache, given a specified context.
|
||||
* If the data is not cached, it is calculated. Therefore, this call could be costly.
|
||||
* @param contexts the contexts to get the permission data in
|
||||
* @return a meta data instance
|
||||
*/
|
||||
public MetaData getMetaData(Contexts contexts) {
|
||||
@Override
|
||||
public MetaData getMetaData(@NonNull Contexts contexts) {
|
||||
return meta.getUnchecked(contexts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates permission data, bypassing the cache.
|
||||
* @param contexts the contexts to get permission data in
|
||||
* @return a permission data instance
|
||||
*/
|
||||
public PermissionData calculatePermissions(Contexts contexts) {
|
||||
PermissionData data = new PermissionData(contexts, user, calculatorFactory);
|
||||
@Override
|
||||
public PermissionCache calculatePermissions(@NonNull Contexts contexts) {
|
||||
PermissionCache data = new PermissionCache(contexts, user, calculatorFactory);
|
||||
data.setPermissions(user.exportNodes(contexts, true));
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates meta data, bypassing the cache.
|
||||
* @param contexts the contexts to get meta data in
|
||||
* @return a meta data instance
|
||||
*/
|
||||
public MetaData calculateMeta(Contexts contexts) {
|
||||
MetaData data = new MetaData(contexts);
|
||||
@Override
|
||||
public MetaCache calculateMeta(@NonNull Contexts contexts) {
|
||||
MetaCache data = new MetaCache(contexts);
|
||||
data.loadMeta(user.getAllNodes(null, contexts));
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates permission data and stores it in the cache. If there is already data cached for the given contexts,
|
||||
* and if the resultant output is different, the cached value is updated.
|
||||
* @param contexts the contexts to recalculate in.
|
||||
*/
|
||||
public void recalculatePermissions(Contexts contexts) {
|
||||
@Override
|
||||
public void recalculatePermissions(@NonNull Contexts contexts) {
|
||||
permission.refresh(contexts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates meta data and stores it in the cache. If there is already data cached for the given contexts,
|
||||
* and if the resultant output is different, the cached value is updated.
|
||||
* @param contexts the contexts to recalculate in.
|
||||
*/
|
||||
public void recalculateMeta(Contexts contexts) {
|
||||
@Override
|
||||
public void recalculateMeta(@NonNull Contexts contexts) {
|
||||
meta.refresh(contexts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #recalculatePermissions(Contexts)} for all current loaded contexts
|
||||
*/
|
||||
@Override
|
||||
public void recalculatePermissions() {
|
||||
Set<Contexts> keys = ImmutableSet.copyOf(permission.asMap().keySet());
|
||||
keys.forEach(permission::refresh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #recalculateMeta(Contexts)} for all current loaded contexts
|
||||
*/
|
||||
@Override
|
||||
public void recalculateMeta() {
|
||||
Set<Contexts> keys = ImmutableSet.copyOf(meta.asMap().keySet());
|
||||
keys.forEach(meta::refresh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #preCalculate(Contexts)} for the given contexts
|
||||
* @param contexts a set of contexts
|
||||
*/
|
||||
public void preCalculate(Set<Contexts> contexts) {
|
||||
@Override
|
||||
public void preCalculate(@NonNull Set<Contexts> contexts) {
|
||||
contexts.forEach(this::preCalculate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that PermissionData and MetaData is cached for a context. If the cache does not contain any data for the
|
||||
* context, it will be calculated and saved.
|
||||
* @param contexts the contexts to pre-calculate for
|
||||
*/
|
||||
public void preCalculate(Contexts contexts) {
|
||||
@Override
|
||||
public void preCalculate(@NonNull Contexts contexts) {
|
||||
permission.getUnchecked(contexts);
|
||||
meta.getUnchecked(contexts);
|
||||
}
|
||||
@@ -178,6 +145,7 @@ public class UserData {
|
||||
meta.invalidateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidatePermissionCalculators() {
|
||||
permission.asMap().values().forEach(PermissionData::invalidateCache);
|
||||
}
|
||||
@@ -24,6 +24,7 @@ package me.lucko.luckperms.common.contexts;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import me.lucko.luckperms.api.context.IContextCalculator;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -47,7 +48,7 @@ public class ContextManager<T> {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public Map<String, String> giveApplicableContext(T subject, Map<String, String> accumulator) {
|
||||
public MutableContextSet giveApplicableContext(T subject, MutableContextSet accumulator) {
|
||||
for (IContextCalculator<T> calculator : calculators) {
|
||||
calculator.giveApplicableContext(subject, accumulator);
|
||||
}
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
|
||||
package me.lucko.luckperms.common.contexts;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.context.ContextCalculator;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -32,8 +34,8 @@ public class ServerCalculator<T> extends ContextCalculator<T> {
|
||||
private final String server;
|
||||
|
||||
@Override
|
||||
public Map<String, String> giveApplicableContext(T subject, Map<String, String> accumulator) {
|
||||
accumulator.put("server", server);
|
||||
public MutableContextSet giveApplicableContext(T subject, MutableContextSet accumulator) {
|
||||
accumulator.add(Maps.immutableEntry("server", server));
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,10 @@
|
||||
package me.lucko.luckperms.common.core;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import lombok.*;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.common.constants.Patterns;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
|
||||
@@ -60,7 +61,8 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
|
||||
private long expireAt = 0L;
|
||||
|
||||
private final Map<String, String> extraContexts;
|
||||
@Getter
|
||||
private final ContextSet contexts;
|
||||
|
||||
// Cache the state
|
||||
private Tristate isPrefix = Tristate.UNDEFINED;
|
||||
@@ -74,9 +76,9 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
* @param expireAt the time when the node will expire
|
||||
* @param server the server this node applies on
|
||||
* @param world the world this node applies on
|
||||
* @param extraContexts any additional contexts applying to this node
|
||||
* @param contexts any additional contexts applying to this node
|
||||
*/
|
||||
public Node(String permission, boolean value, boolean override, long expireAt, String server, String world, Map<String, String> extraContexts) {
|
||||
public Node(String permission, boolean value, boolean override, long expireAt, String server, String world, ContextSet contexts) {
|
||||
if (permission == null || permission.equals("")) {
|
||||
throw new IllegalArgumentException("Empty permission");
|
||||
}
|
||||
@@ -99,12 +101,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
this.expireAt = expireAt;
|
||||
this.server = server;
|
||||
this.world = world;
|
||||
|
||||
ImmutableMap.Builder<String, String> contexts = ImmutableMap.builder();
|
||||
if (extraContexts != null) {
|
||||
contexts.putAll(extraContexts);
|
||||
}
|
||||
this.extraContexts = contexts.build();
|
||||
this.contexts = contexts == null ? ContextSet.empty() : contexts.makeImmutable();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -176,11 +173,6 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
return isTemporary() && expireAt < (System.currentTimeMillis() / 1000L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getExtraContexts() {
|
||||
return ImmutableMap.copyOf(extraContexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGroupNode() {
|
||||
return getPermission().toLowerCase().startsWith("group.");
|
||||
@@ -316,31 +308,28 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyWithContext(Map<String, String> context, boolean worldAndServer) {
|
||||
if (extraContexts.isEmpty() && !isServerSpecific() && !isWorldSpecific()) {
|
||||
public boolean shouldApplyWithContext(ContextSet context, boolean worldAndServer) {
|
||||
if (contexts.isEmpty() && !isServerSpecific() && !isWorldSpecific()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (worldAndServer) {
|
||||
if (isWorldSpecific()) {
|
||||
if (context == null) return false;
|
||||
if (!context.containsKey("world")) return false;
|
||||
if (!context.get("world").equalsIgnoreCase(world)) return false;
|
||||
if (!context.hasIgnoreCase("world", world)) return false;
|
||||
}
|
||||
|
||||
if (isServerSpecific()) {
|
||||
if (context == null) return false;
|
||||
if (!context.containsKey("server")) return false;
|
||||
if (!context.get("server").equalsIgnoreCase(server)) return false;
|
||||
if (!context.hasIgnoreCase("server", server)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!extraContexts.isEmpty()) {
|
||||
if (!contexts.isEmpty()) {
|
||||
if (context == null) return false;
|
||||
|
||||
for (Map.Entry<String, String> c : extraContexts.entrySet()) {
|
||||
if (!context.containsKey(c.getKey())) return false;
|
||||
if (!context.get(c.getKey()).equalsIgnoreCase(c.getValue())) return false;
|
||||
for (Map.Entry<String, String> c : contexts.toSet()) {
|
||||
if (!context.hasIgnoreCase(c.getKey(), c.getValue())) return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,7 +337,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyWithContext(Map<String, String> context) {
|
||||
public boolean shouldApplyWithContext(ContextSet context) {
|
||||
return shouldApplyWithContext(context, true);
|
||||
}
|
||||
|
||||
@@ -478,9 +467,9 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
}
|
||||
}
|
||||
|
||||
if (!extraContexts.isEmpty()) {
|
||||
if (!contexts.isEmpty()) {
|
||||
builder.append("(");
|
||||
for (Map.Entry<String, String> entry : extraContexts.entrySet()) {
|
||||
for (Map.Entry<String, String> entry : contexts.toSet()) {
|
||||
builder.append(entry.getKey()).append("=").append(entry.getValue()).append(",");
|
||||
}
|
||||
|
||||
@@ -533,7 +522,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!other.getExtraContexts().equals(this.getExtraContexts())) {
|
||||
if (!other.getContexts().equals(this.getContexts())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -570,7 +559,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!other.getExtraContexts().equals(this.getExtraContexts())) {
|
||||
if (!other.getContexts().equals(this.getContexts())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -603,7 +592,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!other.getExtraContexts().equals(this.getExtraContexts())) {
|
||||
if (!other.getContexts().equals(this.getContexts())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -681,8 +670,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
private String server = null;
|
||||
private String world = null;
|
||||
private long expireAt = 0L;
|
||||
|
||||
private final Map<String, String> extraContexts = new HashMap<>();
|
||||
private final MutableContextSet extraContexts = new MutableContextSet();
|
||||
|
||||
Builder(String permission, boolean shouldConvertContexts) {
|
||||
if (!shouldConvertContexts) {
|
||||
@@ -696,7 +684,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
|
||||
this.permission = contextParts.get(1);
|
||||
try {
|
||||
extraContexts.putAll(Splitter.on(',').withKeyValueSeparator('=').split(contextParts.get(0)));
|
||||
extraContexts.addAll(Splitter.on(',').withKeyValueSeparator('=').split(contextParts.get(0)));
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -711,6 +699,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
this.server = other.getServer().orElse(null);
|
||||
this.world = other.getWorld().orElse(null);
|
||||
this.expireAt = other.isPermanent() ? 0L : other.getExpiryUnixTime();
|
||||
this.extraContexts.addAll(other.getContexts());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -760,7 +749,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
|
||||
@Override
|
||||
public me.lucko.luckperms.api.Node.Builder withExtraContext(@NonNull String key, @NonNull String value) {
|
||||
switch (key) {
|
||||
switch (key.toLowerCase()) {
|
||||
case "server":
|
||||
setServer(value);
|
||||
break;
|
||||
@@ -768,25 +757,37 @@ public class Node implements me.lucko.luckperms.api.Node {
|
||||
setWorld(value);
|
||||
break;
|
||||
default:
|
||||
this.extraContexts.put(key, value);
|
||||
this.extraContexts.add(key, value);
|
||||
break;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public me.lucko.luckperms.api.Node.Builder withExtraContext(Map<String, String> map) {
|
||||
map.entrySet().forEach(this::withExtraContext);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public me.lucko.luckperms.api.Node.Builder withExtraContext(Map.Entry<String, String> entry) {
|
||||
withExtraContext(entry.getKey(), entry.getValue());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public me.lucko.luckperms.api.Node.Builder withExtraContext(Map<String, String> map) {
|
||||
withExtraContext(ContextSet.fromMap(map));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public me.lucko.luckperms.api.Node.Builder withExtraContext(Set<Map.Entry<String, String>> context) {
|
||||
withExtraContext(ContextSet.fromEntries(context));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public me.lucko.luckperms.api.Node.Builder withExtraContext(ContextSet set) {
|
||||
set.toSet().forEach(this::withExtraContext);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public me.lucko.luckperms.api.Node build() {
|
||||
return new Node(permission, value, override, expireAt, server, world, extraContexts);
|
||||
|
||||
@@ -32,6 +32,7 @@ import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.api.event.events.*;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.api.internal.GroupLink;
|
||||
@@ -368,11 +369,11 @@ public abstract class PermissionHolder {
|
||||
.filter(Node::isGroupNode)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Map<String, String> contexts = new HashMap<>(context.getContext());
|
||||
String server = contexts.get("server");
|
||||
String world = contexts.get("world");
|
||||
contexts.remove("server");
|
||||
contexts.remove("world");
|
||||
MutableContextSet contexts = MutableContextSet.fromSet(context.getContexts());
|
||||
String server = contexts.getValues("server").stream().findAny().orElse(null);
|
||||
String world = contexts.getValues("world").stream().findAny().orElse(null);
|
||||
contexts.removeAll("server");
|
||||
contexts.removeAll("world");
|
||||
|
||||
parents.removeIf(node ->
|
||||
!node.shouldApplyOnServer(server, context.isApplyGlobalGroups(), plugin.getConfiguration().isApplyingRegex()) ||
|
||||
@@ -419,11 +420,11 @@ public abstract class PermissionHolder {
|
||||
allNodes = new TreeSet<>((SortedSet<LocalizedNode>) getPermissions(true));
|
||||
}
|
||||
|
||||
Map<String, String> contexts = new HashMap<>(context.getContext());
|
||||
String server = contexts.get("server");
|
||||
String world = contexts.get("world");
|
||||
contexts.remove("server");
|
||||
contexts.remove("world");
|
||||
MutableContextSet contexts = MutableContextSet.fromSet(context.getContexts());
|
||||
String server = contexts.getValues("server").stream().findAny().orElse(null);
|
||||
String world = contexts.getValues("world").stream().findAny().orElse(null);
|
||||
contexts.removeAll("server");
|
||||
contexts.removeAll("world");
|
||||
|
||||
allNodes.removeIf(node ->
|
||||
!node.shouldApplyOnServer(server, context.isIncludeGlobal(), plugin.getConfiguration().isApplyingRegex()) ||
|
||||
|
||||
@@ -26,10 +26,11 @@ import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import me.lucko.luckperms.api.caching.UserData;
|
||||
import me.lucko.luckperms.api.event.events.UserPermissionRefreshEvent;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.api.internal.UserLink;
|
||||
import me.lucko.luckperms.common.caching.UserData;
|
||||
import me.lucko.luckperms.common.caching.UserCache;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||
import me.lucko.luckperms.common.utils.Identifiable;
|
||||
@@ -61,7 +62,7 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
||||
private String primaryGroup = null;
|
||||
|
||||
@Getter
|
||||
private UserData userData = null;
|
||||
private UserCache userData = null;
|
||||
|
||||
@Getter
|
||||
private BufferedRequest<Void> refreshBuffer = new BufferedRequest<Void>(1000L, r -> getPlugin().doAsync(r)) {
|
||||
@@ -103,7 +104,7 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
||||
return;
|
||||
}
|
||||
|
||||
userData = new UserData(this, getPlugin().getCalculatorFactory());
|
||||
userData = new UserCache(this, getPlugin().getCalculatorFactory());
|
||||
userData.preCalculate(getPlugin().getPreProcessContexts(op));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,13 +23,8 @@
|
||||
package me.lucko.luckperms.common.utils;
|
||||
|
||||
import lombok.*;
|
||||
import lombok.experimental.Delegate;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Holds a Node and where it was inherited from
|
||||
@@ -38,11 +33,12 @@ import java.util.Optional;
|
||||
@ToString
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class LocalizedNode implements me.lucko.luckperms.api.LocalizedNode {
|
||||
public static LocalizedNode of(@NonNull me.lucko.luckperms.api.Node node, @NonNull String location) {
|
||||
public static LocalizedNode of(@NonNull Node node, @NonNull String location) {
|
||||
return new LocalizedNode(node, location);
|
||||
}
|
||||
|
||||
private final me.lucko.luckperms.api.Node node;
|
||||
@Delegate
|
||||
private final Node node;
|
||||
private final String location;
|
||||
|
||||
@Override
|
||||
@@ -54,204 +50,4 @@ public class LocalizedNode implements me.lucko.luckperms.api.LocalizedNode {
|
||||
public boolean equals(Object obj) {
|
||||
return node.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermission() {
|
||||
return node.getPermission();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return node.getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getValue() {
|
||||
return node.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean setValue(Boolean value) {
|
||||
return node.setValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tristate getTristate() {
|
||||
return node.getTristate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNegated() {
|
||||
return node.isNegated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverride() {
|
||||
return node.isOverride();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getServer() {
|
||||
return node.getServer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getWorld() {
|
||||
return node.getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServerSpecific() {
|
||||
return node.isServerSpecific();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWorldSpecific() {
|
||||
return node.isWorldSpecific();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyOnServer(String server, boolean includeGlobal, boolean applyRegex) {
|
||||
return node.shouldApplyOnServer(server, includeGlobal, applyRegex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyOnWorld(String world, boolean includeGlobal, boolean applyRegex) {
|
||||
return node.shouldApplyOnWorld(world, includeGlobal, applyRegex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyWithContext(Map<String, String> context, boolean worldAndServer) {
|
||||
return node.shouldApplyWithContext(context, worldAndServer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyWithContext(Map<String, String> context) {
|
||||
return node.shouldApplyWithContext(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyOnAnyServers(List<String> servers, boolean includeGlobal) {
|
||||
return node.shouldApplyOnAnyServers(servers, includeGlobal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyOnAnyWorlds(List<String> worlds, boolean includeGlobal) {
|
||||
return node.shouldApplyOnAnyWorlds(worlds, includeGlobal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> resolveWildcard(List<String> possibleNodes) {
|
||||
return node.resolveWildcard(possibleNodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> resolveShorthand() {
|
||||
return node.resolveShorthand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTemporary() {
|
||||
return node.isTemporary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermanent() {
|
||||
return node.isPermanent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getExpiryUnixTime() {
|
||||
return node.getExpiryUnixTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getExpiry() {
|
||||
return node.getExpiry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSecondsTilExpiry() {
|
||||
return node.getSecondsTilExpiry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasExpired() {
|
||||
return node.hasExpired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getExtraContexts() {
|
||||
return node.getExtraContexts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSerializedNode() {
|
||||
return node.toSerializedNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGroupNode() {
|
||||
return node.isGroupNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroupName() {
|
||||
return node.getGroupName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWildcard() {
|
||||
return node.isWildcard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWildcardLevel() {
|
||||
return node.getWildcardLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMeta() {
|
||||
return node.isMeta();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map.Entry<String, String> getMeta() {
|
||||
return node.getMeta();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrefix() {
|
||||
return node.isPrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map.Entry<Integer, String> getPrefix() {
|
||||
return node.getPrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuffix() {
|
||||
return node.isSuffix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map.Entry<Integer, String> getSuffix() {
|
||||
return node.getSuffix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equalsIgnoringValue(Node other) {
|
||||
return node.equalsIgnoringValue(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean almostEquals(Node other) {
|
||||
return node.almostEquals(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equalsIgnoringValueOrTemp(Node other) {
|
||||
return node.equalsIgnoringValueOrTemp(other);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user