mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-28 20:17:55 +01:00
Cleanup permission calculation
This commit is contained in:
parent
7b655d12df
commit
d113a92ce5
@ -44,10 +44,8 @@ public class AttachmentProcessor implements PermissionProcessor {
|
|||||||
return Tristate.UNDEFINED;
|
return Tristate.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m.containsKey(permission)) {
|
PermissionAttachmentInfo pai = m.get(permission);
|
||||||
return Tristate.fromBoolean(m.get(permission).getValue());
|
return pai == null ? Tristate.UNDEFINED : Tristate.fromBoolean(pai.getValue());
|
||||||
}
|
|
||||||
return Tristate.UNDEFINED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import me.lucko.luckperms.bukkit.inject.LPPermissible;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class AutoOPListener implements ContextListener<Player> {
|
public class AutoOPListener implements ContextListener<Player> {
|
||||||
|
|
||||||
@ -39,7 +40,7 @@ public class AutoOPListener implements ContextListener<Player> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Boolean> backing = permissible.getUser().getUserData().getPermissionData(permissible.calculateContexts()).getImmutableBacking();
|
Map<String, Boolean> backing = permissible.getUser().getUserData().getPermissionData(permissible.calculateContexts()).getImmutableBacking();
|
||||||
boolean op = backing.containsKey("luckperms.autoop") && backing.get("luckperms.autoop");
|
boolean op = Optional.ofNullable(backing.get("luckperms.autoop")).orElse(false);
|
||||||
subject.setOp(op);
|
subject.setOp(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,10 +41,6 @@ public class DefaultsProcessor implements PermissionProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Permission defPerm = Bukkit.getServer().getPluginManager().getPermission(permission);
|
Permission defPerm = Bukkit.getServer().getPluginManager().getPermission(permission);
|
||||||
if (defPerm != null) {
|
return defPerm == null ? Tristate.UNDEFINED : Tristate.fromBoolean(defPerm.getDefault().getValue(isOp));
|
||||||
return Tristate.fromBoolean(defPerm.getDefault().getValue(isOp));
|
|
||||||
} else {
|
|
||||||
return Tristate.UNDEFINED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,11 +97,9 @@ public class DefaultsProvider {
|
|||||||
|
|
||||||
public Tristate hasDefault(String permission, boolean isOp) {
|
public Tristate hasDefault(String permission, boolean isOp) {
|
||||||
Map<String, Boolean> map = isOp ? op : nonOp;
|
Map<String, Boolean> map = isOp ? op : nonOp;
|
||||||
if (!map.containsKey(permission)) {
|
|
||||||
return Tristate.UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Tristate.fromBoolean(map.get(permission));
|
Boolean b = map.get(permission);
|
||||||
|
return b == null ? Tristate.UNDEFINED : Tristate.fromBoolean(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -23,27 +23,25 @@
|
|||||||
package me.lucko.luckperms.common.caching;
|
package me.lucko.luckperms.common.caching;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import lombok.Getter;
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import me.lucko.luckperms.api.Contexts;
|
import me.lucko.luckperms.api.Contexts;
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
import me.lucko.luckperms.api.LocalizedNode;
|
||||||
import me.lucko.luckperms.api.Node;
|
import me.lucko.luckperms.api.Node;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.SortedSet;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds a user's cached meta for a given context
|
||||||
|
*/
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MetaData {
|
public class MetaData {
|
||||||
private final Contexts contexts;
|
private final Contexts contexts;
|
||||||
|
|
||||||
@Getter
|
private final SortedMap<Integer, String> prefixes = new TreeMap<>(Comparator.reverseOrder());
|
||||||
private String prefix = null;
|
private final SortedMap<Integer, String> suffixes = new TreeMap<>(Comparator.reverseOrder());
|
||||||
|
|
||||||
@Getter
|
private final Map<String, String> meta = new HashMap<>();
|
||||||
private String suffix = null;
|
|
||||||
private Map<String, String> meta = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public void loadMeta(SortedSet<LocalizedNode> nodes) {
|
public void loadMeta(SortedSet<LocalizedNode> nodes) {
|
||||||
invalidateCache();
|
invalidateCache();
|
||||||
@ -52,9 +50,6 @@ public class MetaData {
|
|||||||
String server = contexts.remove("server");
|
String server = contexts.remove("server");
|
||||||
String world = contexts.remove("world");
|
String world = contexts.remove("world");
|
||||||
|
|
||||||
int prefixPriority = Integer.MIN_VALUE;
|
|
||||||
int suffixPriority = Integer.MIN_VALUE;
|
|
||||||
|
|
||||||
for (LocalizedNode ln : nodes) {
|
for (LocalizedNode ln : nodes) {
|
||||||
Node n = ln.getNode();
|
Node n = ln.getNode();
|
||||||
|
|
||||||
@ -80,37 +75,84 @@ public class MetaData {
|
|||||||
|
|
||||||
if (n.isPrefix()) {
|
if (n.isPrefix()) {
|
||||||
Map.Entry<Integer, String> value = n.getPrefix();
|
Map.Entry<Integer, String> value = n.getPrefix();
|
||||||
if (value.getKey() > prefixPriority) {
|
synchronized (this.prefixes) {
|
||||||
this.prefix = value.getValue();
|
if (!this.prefixes.containsKey(value.getKey())) {
|
||||||
prefixPriority = value.getKey();
|
this.prefixes.put(value.getKey(), value.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n.isSuffix()) {
|
if (n.isSuffix()) {
|
||||||
Map.Entry<Integer, String> value = n.getSuffix();
|
Map.Entry<Integer, String> value = n.getSuffix();
|
||||||
if (value.getKey() > suffixPriority) {
|
synchronized (this.suffixes) {
|
||||||
this.suffix = value.getValue();
|
if (!this.suffixes.containsKey(value.getKey())) {
|
||||||
suffixPriority = value.getKey();
|
this.suffixes.put(value.getKey(), value.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n.isMeta()) {
|
if (n.isMeta()) {
|
||||||
Map.Entry<String, String> meta = n.getMeta();
|
Map.Entry<String, String> meta = n.getMeta();
|
||||||
|
synchronized (this.meta) {
|
||||||
|
if (!this.meta.containsKey(meta.getKey())) {
|
||||||
|
this.meta.put(meta.getKey(), meta.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
this.meta.put(meta.getKey(), meta.getValue());
|
this.meta.put(meta.getKey(), meta.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidateCache() {
|
public void invalidateCache() {
|
||||||
meta.clear();
|
synchronized (meta) {
|
||||||
prefix = null;
|
meta.clear();
|
||||||
suffix = null;
|
}
|
||||||
|
synchronized (prefixes) {
|
||||||
|
prefixes.clear();
|
||||||
|
}
|
||||||
|
synchronized (suffixes) {
|
||||||
|
suffixes.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getMeta() {
|
public Map<String, String> getMeta() {
|
||||||
return ImmutableMap.copyOf(meta);
|
synchronized (meta) {
|
||||||
|
return ImmutableMap.copyOf(meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SortedMap<Integer, String> getPrefixes() {
|
||||||
|
synchronized (prefixes) {
|
||||||
|
return ImmutableSortedMap.copyOfSorted(prefixes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SortedMap<Integer, String> getSuffixes() {
|
||||||
|
synchronized (suffixes) {
|
||||||
|
return ImmutableSortedMap.copyOfSorted(suffixes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrefix() {
|
||||||
|
synchronized (prefixes) {
|
||||||
|
if (prefixes.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prefixes.get(prefixes.firstKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSuffix() {
|
||||||
|
synchronized (suffixes) {
|
||||||
|
if (suffixes.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return suffixes.get(suffixes.firstKey());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,14 +33,24 @@ import me.lucko.luckperms.common.users.User;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds a user's cached permissions for a given context
|
||||||
|
*/
|
||||||
public class PermissionData {
|
public class PermissionData {
|
||||||
private final Contexts contexts;
|
|
||||||
|
/**
|
||||||
|
* The raw set of permission strings.
|
||||||
|
*/
|
||||||
private final Map<String, Boolean> permissions;
|
private final Map<String, Boolean> permissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The calculator instance responsible for resolving the raw permission strings in the permission map.
|
||||||
|
* This calculator will attempt to resolve all regex/wildcard permissions, as well as account for
|
||||||
|
* defaults & attachment permissions (if applicable.)
|
||||||
|
*/
|
||||||
private final PermissionCalculator calculator;
|
private final PermissionCalculator calculator;
|
||||||
|
|
||||||
public PermissionData(Contexts contexts, User user, CalculatorFactory calculatorFactory) {
|
public PermissionData(Contexts contexts, User user, CalculatorFactory calculatorFactory) {
|
||||||
this.contexts = contexts;
|
|
||||||
permissions = new ConcurrentHashMap<>();
|
permissions = new ConcurrentHashMap<>();
|
||||||
calculator = calculatorFactory.build(contexts, user, permissions);
|
calculator = calculatorFactory.build(contexts, user, permissions);
|
||||||
}
|
}
|
||||||
@ -56,20 +66,7 @@ public class PermissionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void comparePermissions(Map<String, Boolean> toApply) {
|
public void comparePermissions(Map<String, Boolean> toApply) {
|
||||||
boolean different = false;
|
if (!permissions.equals(toApply)) {
|
||||||
if (toApply.size() != permissions.size()) {
|
|
||||||
different = true;
|
|
||||||
} else {
|
|
||||||
for (Map.Entry<String, Boolean> e : permissions.entrySet()) {
|
|
||||||
if (toApply.containsKey(e.getKey()) && toApply.get(e.getKey()) == e.getValue()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
different = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (different) {
|
|
||||||
setPermissions(toApply);
|
setPermissions(toApply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,11 +76,6 @@ public class PermissionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Tristate getPermissionValue(@NonNull String permission) {
|
public Tristate getPermissionValue(@NonNull String permission) {
|
||||||
Tristate t = calculator.getPermissionValue(permission);
|
return calculator.getPermissionValue(permission);
|
||||||
if (t != Tristate.UNDEFINED) {
|
|
||||||
return Tristate.fromBoolean(t.asBoolean());
|
|
||||||
} else {
|
|
||||||
return Tristate.UNDEFINED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,28 +31,72 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds an easily accessible cache of a user's data in a number of contexts
|
||||||
|
*/
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class UserData {
|
public class UserData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user whom this data instance is representing
|
||||||
|
*/
|
||||||
private final User user;
|
private final User user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A provider of {@link me.lucko.luckperms.common.calculators.PermissionCalculator}s for the instance
|
||||||
|
*/
|
||||||
private final CalculatorFactory calculatorFactory;
|
private final CalculatorFactory calculatorFactory;
|
||||||
|
|
||||||
private final Map<Contexts, PermissionData> permission = new ConcurrentHashMap<>();
|
private final Map<Contexts, PermissionData> permission = new ConcurrentHashMap<>();
|
||||||
private final Map<Contexts, MetaData> meta = new ConcurrentHashMap<>();
|
private final Map<Contexts, MetaData> meta = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
public PermissionData getPermissionData(Contexts contexts) {
|
||||||
return permission.computeIfAbsent(contexts, this::calculatePermissions);
|
return permission.computeIfAbsent(contexts, this::calculatePermissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
public MetaData getMetaData(Contexts contexts) {
|
||||||
return meta.computeIfAbsent(contexts, this::calculateMeta);
|
return meta.computeIfAbsent(contexts, this::calculateMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
public PermissionData calculatePermissions(Contexts contexts) {
|
||||||
PermissionData data = new PermissionData(contexts, user, calculatorFactory);
|
PermissionData data = new PermissionData(contexts, user, calculatorFactory);
|
||||||
data.setPermissions(user.exportNodes(contexts, true));
|
data.setPermissions(user.exportNodes(contexts, true));
|
||||||
return data;
|
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);
|
||||||
|
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) {
|
public void recalculatePermissions(Contexts contexts) {
|
||||||
permission.compute(contexts, (c, data) -> {
|
permission.compute(contexts, (c, data) -> {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
@ -64,16 +108,11 @@ public class UserData {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void recalculatePermissions() {
|
/**
|
||||||
permission.keySet().forEach(this::recalculatePermissions);
|
* 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 MetaData calculateMeta(Contexts contexts) {
|
*/
|
||||||
MetaData data = new MetaData(contexts);
|
|
||||||
data.loadMeta(user.getAllNodes(null, contexts));
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void recalculateMeta(Contexts contexts) {
|
public void recalculateMeta(Contexts contexts) {
|
||||||
meta.compute(contexts, (c, data) -> {
|
meta.compute(contexts, (c, data) -> {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
@ -85,14 +124,33 @@ public class UserData {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link #recalculatePermissions(Contexts)} for all current loaded contexts
|
||||||
|
*/
|
||||||
|
public void recalculatePermissions() {
|
||||||
|
permission.keySet().forEach(this::recalculatePermissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link #recalculateMeta(Contexts)} for all current loaded contexts
|
||||||
|
*/
|
||||||
public void recalculateMeta() {
|
public void recalculateMeta() {
|
||||||
meta.keySet().forEach(this::recalculateMeta);
|
meta.keySet().forEach(this::recalculateMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link #preCalculate(Contexts)} for the given contexts
|
||||||
|
* @param contexts a set of contexts
|
||||||
|
*/
|
||||||
public void preCalculate(Set<Contexts> contexts) {
|
public void preCalculate(Set<Contexts> contexts) {
|
||||||
contexts.forEach(this::preCalculate);
|
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) {
|
public void preCalculate(Contexts contexts) {
|
||||||
getPermissionData(contexts);
|
getPermissionData(contexts);
|
||||||
getMetaData(contexts);
|
getMetaData(contexts);
|
||||||
|
@ -36,10 +36,7 @@ public class MapProcessor implements PermissionProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tristate hasPermission(String permission) {
|
public Tristate hasPermission(String permission) {
|
||||||
if (map.containsKey(permission)) {
|
Boolean b = map.get(permission);
|
||||||
return Tristate.fromBoolean(map.get(permission));
|
return b == null ? Tristate.UNDEFINED : Tristate.fromBoolean(b);
|
||||||
}
|
|
||||||
|
|
||||||
return Tristate.UNDEFINED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,43 +38,31 @@ public class WildcardProcessor implements PermissionProcessor {
|
|||||||
public Tristate hasPermission(String permission) {
|
public Tristate hasPermission(String permission) {
|
||||||
String node = permission;
|
String node = permission;
|
||||||
|
|
||||||
while (node.contains(".")) {
|
while (true) {
|
||||||
int endIndex = node.lastIndexOf('.');
|
int endIndex = node.lastIndexOf('.');
|
||||||
if (endIndex == -1) {
|
if (endIndex == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node.substring(0, endIndex);
|
node = node.substring(0, endIndex);
|
||||||
if (!isEmpty(node)) {
|
if (!node.isEmpty()) {
|
||||||
if (map.containsKey(node + ".*")) {
|
Boolean b = map.get(node + ".*");
|
||||||
return Tristate.fromBoolean(map.get(node + ".*"));
|
if (b != null) {
|
||||||
|
return Tristate.fromBoolean(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map.containsKey("'*'")) {
|
Boolean b = map.get("'*'");
|
||||||
return Tristate.fromBoolean(map.get("'*'"));
|
if (b != null) {
|
||||||
|
return Tristate.fromBoolean(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map.containsKey("*")) {
|
b = map.get("*");
|
||||||
return Tristate.fromBoolean(map.get("*"));
|
if (b != null) {
|
||||||
|
return Tristate.fromBoolean(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Tristate.UNDEFINED;
|
return Tristate.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isEmpty(String s) {
|
|
||||||
if (s.equals("")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] chars = s.toCharArray();
|
|
||||||
for (char c : chars) {
|
|
||||||
if (c != '.') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -41,12 +41,12 @@ public class DefaultsProcessor implements PermissionProcessor {
|
|||||||
public me.lucko.luckperms.api.Tristate hasPermission(String permission) {
|
public me.lucko.luckperms.api.Tristate hasPermission(String permission) {
|
||||||
Tristate t = service.getUserSubjects().getDefaults().getPermissionValue(contexts, permission);
|
Tristate t = service.getUserSubjects().getDefaults().getPermissionValue(contexts, permission);
|
||||||
if (t != Tristate.UNDEFINED) {
|
if (t != Tristate.UNDEFINED) {
|
||||||
return convertTristate(Tristate.fromBoolean(t.asBoolean()));
|
return convertTristate(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tristate t2 = service.getDefaults().getPermissionValue(contexts, permission);
|
Tristate t2 = service.getDefaults().getPermissionValue(contexts, permission);
|
||||||
if (t2 != Tristate.UNDEFINED) {
|
if (t2 != Tristate.UNDEFINED) {
|
||||||
return convertTristate(Tristate.fromBoolean(t.asBoolean()));
|
return convertTristate(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return me.lucko.luckperms.api.Tristate.UNDEFINED;
|
return me.lucko.luckperms.api.Tristate.UNDEFINED;
|
||||||
|
@ -24,6 +24,7 @@ package me.lucko.luckperms.sponge.calculators;
|
|||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -35,46 +36,24 @@ public class SpongeWildcardProcessor implements PermissionProcessor {
|
|||||||
private final Map<String, Boolean> map;
|
private final Map<String, Boolean> map;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public me.lucko.luckperms.api.Tristate hasPermission(String permission) {
|
public Tristate hasPermission(String permission) {
|
||||||
String node = permission;
|
String node = permission;
|
||||||
|
|
||||||
while (node.contains(".")) {
|
while (true) {
|
||||||
int endIndex = node.lastIndexOf('.');
|
int endIndex = node.lastIndexOf('.');
|
||||||
if (endIndex == -1) {
|
if (endIndex == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node.substring(0, endIndex);
|
node = node.substring(0, endIndex);
|
||||||
if (!isEmpty(node)) {
|
if (!node.isEmpty()) {
|
||||||
if (map.containsKey(node)) {
|
Boolean b = map.get(node);
|
||||||
return me.lucko.luckperms.api.Tristate.fromBoolean(map.get(node));
|
if (b != null) {
|
||||||
|
return Tristate.fromBoolean(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map.containsKey("'*'")) {
|
return Tristate.UNDEFINED;
|
||||||
return me.lucko.luckperms.api.Tristate.fromBoolean(map.get("'*'"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (map.containsKey("*")) {
|
|
||||||
return me.lucko.luckperms.api.Tristate.fromBoolean(map.get("*"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return me.lucko.luckperms.api.Tristate.UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isEmpty(String s) {
|
|
||||||
if (s.equals("")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] chars = s.toCharArray();
|
|
||||||
for (char c : chars) {
|
|
||||||
if (c != '.') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,12 @@ package me.lucko.luckperms.sponge.contexts;
|
|||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import me.lucko.luckperms.api.context.ContextCalculator;
|
import me.lucko.luckperms.api.context.ContextCalculator;
|
||||||
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
import org.spongepowered.api.service.context.Context;
|
import org.spongepowered.api.service.context.Context;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class SpongeCalculatorLink extends ContextCalculator<Subject> {
|
public class SpongeCalculatorLink extends ContextCalculator<Subject> {
|
||||||
@ -37,10 +37,11 @@ public class SpongeCalculatorLink extends ContextCalculator<Subject> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> giveApplicableContext(Subject subject, Map<String, String> accumulator) {
|
public Map<String, String> giveApplicableContext(Subject subject, Map<String, String> accumulator) {
|
||||||
Set<Context> contexts = accumulator.entrySet().stream().map(e -> new Context(e.getKey(), e.getValue())).collect(Collectors.toSet());
|
Set<Context> contexts = LuckPermsService.convertContexts(accumulator);
|
||||||
calculator.accumulateContexts(subject, contexts);
|
calculator.accumulateContexts(subject, contexts);
|
||||||
|
|
||||||
contexts.forEach(c -> accumulator.put(c.getKey(), c.getValue()));
|
accumulator.clear();
|
||||||
|
accumulator.putAll(LuckPermsService.convertContexts(contexts));
|
||||||
return accumulator;
|
return accumulator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user