Update LuckPermsProvider to v5.

This commit is contained in:
bloodshot 2019-12-28 12:23:50 -05:00
parent cad082bdcd
commit 772a8d077e
18 changed files with 343 additions and 426 deletions

View File

@ -115,6 +115,7 @@ dependencies {
compileOnly "net.ess3:EssentialsX:2.17.1" compileOnly "net.ess3:EssentialsX:2.17.1"
compileOnly "net.milkbowl.vault:VaultAPI:1.7" compileOnly "net.milkbowl.vault:VaultAPI:1.7"
compileOnly "us.dynmap:dynmap-api:3.0-SNAPSHOT" compileOnly "us.dynmap:dynmap-api:3.0-SNAPSHOT"
compileOnly "net.luckperms:api:5.0"
// Libs // Libs
compileOnly "aopalliance:aopalliance:1.0" compileOnly "aopalliance:aopalliance:1.0"
compileOnly "co.aikar:acf-core:0.5.0-SNAPSHOT" compileOnly "co.aikar:acf-core:0.5.0-SNAPSHOT"
@ -133,7 +134,6 @@ dependencies {
compileOnly "commons-io:commons-io:2.6" compileOnly "commons-io:commons-io:2.6"
compileOnly "it.unimi.dsi:fastutil:8.2.3" compileOnly "it.unimi.dsi:fastutil:8.2.3"
compileOnly "me.lucko:jar-relocator:1.3" compileOnly "me.lucko:jar-relocator:1.3"
compileOnly "me.lucko.luckperms:luckperms-api:4.4"
compileOnly "net.jodah:expiringmap:0.5.9" compileOnly "net.jodah:expiringmap:0.5.9"
compileOnly "org.apache.commons:commons-lang3:3.9" compileOnly "org.apache.commons:commons-lang3:3.9"
compileOnly "org.checkerframework:checker:2.8.2" compileOnly "org.checkerframework:checker:2.8.2"

View File

@ -29,47 +29,31 @@
import com.griefdefender.GDPlayerData; import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.permission.GDPermissionUser;
import me.lucko.luckperms.api.PermissionHolder; import net.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.User; import net.luckperms.api.context.ContextConsumer;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.MutableContextSet;
public class ClaimContextCalculator implements ContextCalculator<PermissionHolder> { public class ClaimContextCalculator implements ContextCalculator<Player> {
@Override @Override
public @NonNull MutableContextSet giveApplicableContext(@NonNull PermissionHolder holder, @NonNull MutableContextSet contextSet) { public void calculate(@NonNull Player player, @NonNull ContextConsumer contextSet) {
if (!(holder instanceof User)) { final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getPlayerData(player.getWorld(), player.getUniqueId());
return contextSet;
}
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(holder.getObjectName());
if (user == null || user.getOnlinePlayer() == null) {
return contextSet;
}
final Player player = user.getOnlinePlayer();
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getPlayerData(player.getWorld(), player.getUniqueId());
if (playerData.ignoreActiveContexts) { if (playerData.ignoreActiveContexts) {
playerData.ignoreActiveContexts = false; playerData.ignoreActiveContexts = false;
return contextSet; return;
} }
GDClaim sourceClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation()); GDClaim sourceClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (sourceClaim != null) { if (sourceClaim != null) {
if (playerData == null || playerData.canIgnoreClaim(sourceClaim)) { if (playerData == null || playerData.canIgnoreClaim(sourceClaim)) {
return contextSet; return;
} }
if (sourceClaim.parent != null && sourceClaim.getData().doesInheritParent()) { if (sourceClaim.parent != null && sourceClaim.getData().doesInheritParent()) {
contextSet.add(sourceClaim.parent.getContext()); contextSet.accept(sourceClaim.parent.getContext().getKey(), sourceClaim.parent.getContext().getValue());
} else { } else {
contextSet.add(sourceClaim.getContext()); contextSet.accept(sourceClaim.getContext().getKey(), sourceClaim.getContext().getValue());
} }
} }
return contextSet;
} }
} }

View File

@ -27,15 +27,16 @@
import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.PermissionHolderCache; import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionHolder;
import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.event.group.GroupDataRecalculateEvent; import net.luckperms.api.LuckPerms;
import me.lucko.luckperms.api.event.user.UserDataRecalculateEvent; import net.luckperms.api.event.group.GroupDataRecalculateEvent;
import net.luckperms.api.event.user.UserDataRecalculateEvent;
public class LuckPermsEventHandler { public class LuckPermsEventHandler {
private final LuckPermsApi luckPermsApi; private final LuckPerms luckPermsApi;
public LuckPermsEventHandler(LuckPermsApi luckPermsApi) { public LuckPermsEventHandler(LuckPerms luckPermsApi) {
this.luckPermsApi = luckPermsApi; this.luckPermsApi = luckPermsApi;
this.luckPermsApi.getEventBus().subscribe(GroupDataRecalculateEvent.class, this::onGroupDataRecalculate); this.luckPermsApi.getEventBus().subscribe(GroupDataRecalculateEvent.class, this::onGroupDataRecalculate);
this.luckPermsApi.getEventBus().subscribe(UserDataRecalculateEvent.class, this::onUserDataRecalculate); this.luckPermsApi.getEventBus().subscribe(UserDataRecalculateEvent.class, this::onUserDataRecalculate);
@ -47,7 +48,7 @@ public void onGroupDataRecalculate(GroupDataRecalculateEvent event) {
} }
public void onUserDataRecalculate(UserDataRecalculateEvent event) { public void onUserDataRecalculate(UserDataRecalculateEvent event) {
final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateUser(event.getUser().getUuid()); final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateUser(event.getUser().getUniqueId());
PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll(); PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll();
PermissionHolderCache.getInstance().getOrCreatePermissionCache(GriefDefenderPlugin.DEFAULT_HOLDER).invalidateAll(); PermissionHolderCache.getInstance().getOrCreatePermissionCache(GriefDefenderPlugin.DEFAULT_HOLDER).invalidateAll();
} }

View File

@ -26,7 +26,6 @@
import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.griefdefender.GDPlayerData; import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.GriefDefenderPlugin;
@ -44,20 +43,29 @@
import com.griefdefender.permission.GDPermissionResult; import com.griefdefender.permission.GDPermissionResult;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import me.lucko.luckperms.api.Contexts; import net.luckperms.api.LuckPerms;
import me.lucko.luckperms.api.DataMutateResult; import net.luckperms.api.cacheddata.CachedMetaData;
import me.lucko.luckperms.api.Group; import net.luckperms.api.cacheddata.CachedPermissionData;
import me.lucko.luckperms.api.LuckPermsApi; import net.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.Node; import net.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.PermissionHolder; import net.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.api.User; import net.luckperms.api.model.PermissionHolder;
import me.lucko.luckperms.api.caching.MetaData; import net.luckperms.api.model.PermissionHolder.Identifier;
import me.lucko.luckperms.api.caching.PermissionData; import net.luckperms.api.model.data.DataMutateResult;
import me.lucko.luckperms.api.context.ContextSet; import net.luckperms.api.model.data.DataType;
import me.lucko.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.model.group.Group;
import me.lucko.luckperms.api.context.MutableContextSet; import net.luckperms.api.model.user.User;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.NodeType;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.node.types.PermissionNode;
import net.luckperms.api.query.QueryMode;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.query.dataorder.DataQueryOrder;
import net.luckperms.api.query.dataorder.DataQueryOrderFunction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -95,13 +103,14 @@ public int compare(Set<Context> s1, Set<Context> s2) {
} }
}; };
private final LuckPermsApi luckPermsApi; private final LuckPerms luckPermsApi;
private final static DefaultDataQueryOrderFunction DEFAULT_DATA_QUERY_ORDER = new DefaultDataQueryOrderFunction();
public LuckPermsProvider() { public LuckPermsProvider() {
this.luckPermsApi = Bukkit.getServicesManager().getRegistration(LuckPermsApi.class).getProvider(); this.luckPermsApi = Bukkit.getServicesManager().getRegistration(LuckPerms.class).getProvider();
} }
public LuckPermsApi getApi() { public LuckPerms getApi() {
return this.luckPermsApi; return this.luckPermsApi;
} }
@ -112,7 +121,7 @@ public boolean hasGroupSubject(String identifier) {
public PermissionHolder getLuckPermsHolder(GDPermissionHolder holder) { public PermissionHolder getLuckPermsHolder(GDPermissionHolder holder) {
if (holder.getIdentifier().equalsIgnoreCase("default")) { if (holder.getIdentifier().equalsIgnoreCase("default")) {
return this.luckPermsApi.getGroup("default"); return this.luckPermsApi.getGroupManager().getGroup("default");
} }
if (holder instanceof GDPermissionUser) { if (holder instanceof GDPermissionUser) {
return this.getLuckPermsUser(holder.getIdentifier()); return this.getLuckPermsUser(holder.getIdentifier());
@ -140,7 +149,7 @@ public User getLuckPermsUser(String identifier) {
} }
if (user == null) { if (user == null) {
user = this.luckPermsApi.getUser(identifier); user = this.luckPermsApi.getUserManager().getUser(identifier);
} }
if (user != null) { if (user != null) {
this.userCache.put(identifier, user); this.userCache.put(identifier, user);
@ -151,14 +160,14 @@ public User getLuckPermsUser(String identifier) {
public Group getLuckPermsGroup(String identifier) { public Group getLuckPermsGroup(String identifier) {
if (identifier.equalsIgnoreCase("default")) { if (identifier.equalsIgnoreCase("default")) {
return this.luckPermsApi.getGroup("default"); return this.luckPermsApi.getGroupManager().getGroup("default");
} }
Group group = this.groupCache.getIfPresent(identifier); Group group = this.groupCache.getIfPresent(identifier);
if (group != null) { if (group != null) {
return group; return group;
} }
group = this.luckPermsApi.getGroup(identifier); group = this.luckPermsApi.getGroupManager().getGroup(identifier);
if (group != null) { if (group != null) {
this.groupCache.put(identifier, group); this.groupCache.put(identifier, group);
} }
@ -202,7 +211,7 @@ public Group getGroupSubject(String identifier) {
public UUID lookupUserUniqueId(String name) { public UUID lookupUserUniqueId(String name) {
final User user = this.getLuckPermsUser(name); final User user = this.getLuckPermsUser(name);
if (user != null) { if (user != null) {
return user.getUuid(); return user.getUniqueId();
} }
return null; return null;
} }
@ -229,7 +238,7 @@ public User getUserSubject(UUID uuid) {
public List<String> getAllLoadedPlayerNames() { public List<String> getAllLoadedPlayerNames() {
List<String> subjectList = new ArrayList<>(); List<String> subjectList = new ArrayList<>();
for (User user : this.luckPermsApi.getUserManager().getLoadedUsers()) { for (User user : this.luckPermsApi.getUserManager().getLoadedUsers()) {
final String name = user.getName(); final String name = user.getUsername();
if (name != null) { if (name != null) {
subjectList.add(name); subjectList.add(name);
} }
@ -268,7 +277,7 @@ public void addActiveContexts(Set<Context> contexts, GDPermissionHolder permissi
return; return;
} }
ImmutableContextSet contextSet = this.luckPermsApi.getContextManager().lookupApplicableContext((User) luckPermsHolder).orElse(null); ImmutableContextSet contextSet = this.luckPermsApi.getContextManager().getContext((User) luckPermsHolder).orElse(null);
if (contextSet == null) { if (contextSet == null) {
contextSet = this.luckPermsApi.getContextManager().getStaticContext(); contextSet = this.luckPermsApi.getContextManager().getStaticContext();
} }
@ -314,8 +323,8 @@ public void clearPermissions(GDPermissionHolder holder, Set<Context> contexts) {
return; return;
} }
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
permissionHolder.clearNodes(set); permissionHolder.data().clear(set);
this.savePermissionHolder(permissionHolder); this.savePermissionHolder(permissionHolder);
} }
@ -325,29 +334,37 @@ public boolean holderHasPermission(GDPermissionHolder holder, String permission)
return false; return false;
} }
return permissionHolder.getCachedData().getPermissionData(Contexts.allowAll()).getPermissionValue(permission) == me.lucko.luckperms.api.Tristate.TRUE; final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).build();
return permissionHolder.getCachedData().getPermissionData(query).checkPermission(permission).asBoolean();
} }
public Map<String, Boolean> getPermissions(GDPermissionHolder holder, Set<Context> contexts) { public Map<String, Boolean> getPermissions(GDPermissionHolder holder, Set<Context> contexts) {
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
Contexts context = Contexts.global().setContexts(set);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return new HashMap<>(); return new HashMap<>();
} }
PermissionData cachedData = permissionHolder.getCachedData().getPermissionData(context);
return cachedData.getImmutableBacking(); final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).context(set).build();
CachedPermissionData cachedData = permissionHolder.getCachedData().getPermissionData(query);
return cachedData.getPermissionMap();
} }
public Map<String, String> getOptions(GDPermissionHolder holder, Set<Context> contexts) { public Map<String, String> getOptions(GDPermissionHolder holder, Set<Context> contexts) {
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
Contexts context = Contexts.global().setContexts(set);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return new HashMap<>(); return new HashMap<>();
} }
MetaData cachedData = permissionHolder.getCachedData().getMetaData(context);
return cachedData.getMeta(); final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).context(set).build();
CachedMetaData cachedData = permissionHolder.getCachedData().getMetaData(query);
// TODO
Map<String, String> metaMap = new HashMap<>();
for (Map.Entry<String, List<String>> mapEntry : cachedData.getMeta().entrySet()) {
metaMap.put(mapEntry.getKey(), mapEntry.getValue().get(0));
}
return metaMap;
} }
public Map<Set<Context>, Map<String, Boolean>> getPermanentPermissions(GDPermissionHolder holder) { public Map<Set<Context>, Map<String, Boolean>> getPermanentPermissions(GDPermissionHolder holder) {
@ -356,33 +373,23 @@ public Map<Set<Context>, Map<String, Boolean>> getPermanentPermissions(GDPermiss
return new HashMap<>(); return new HashMap<>();
} }
final ImmutableCollection<Node> nodes = permissionHolder.getNodes().values(); //final @NonNull Collection<Node> nodes = permissionHolder.resolveInheritedNodes(QueryOptions.nonContextual());
final Collection<Node> nodes = permissionHolder.data().toCollection();
Map<Set<Context>, Map<String, Boolean>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR); Map<Set<Context>, Map<String, Boolean>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR);
for (Node node : nodes) { for (Node node : nodes) {
if (node.isMeta()) { if (node.getType() != NodeType.PERMISSION) {
continue; continue;
} }
String serverName = node.getServer().orElse(null); final PermissionNode permissionNode = (PermissionNode) node;
final String worldName = node.getWorld().orElse(null); final Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && serverName.equalsIgnoreCase("global")) {
serverName = null;
}
Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && !serverName.equalsIgnoreCase("undefined")) {
contexts.add(new Context("server", serverName));
}
if (worldName != null) {
contexts.add(new Context("world", worldName.toLowerCase()));
}
Map<String, Boolean> permissionEntry = permanentPermissionMap.get(contexts); Map<String, Boolean> permissionEntry = permanentPermissionMap.get(contexts);
if (permissionEntry == null) { if (permissionEntry == null) {
permissionEntry = new HashMap<>(); permissionEntry = new HashMap<>();
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(permissionNode.getPermission(), node.getValue());
permanentPermissionMap.put(contexts, permissionEntry); permanentPermissionMap.put(contexts, permissionEntry);
} else { } else {
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(permissionNode.getPermission(), node.getValue());
} }
} }
@ -395,33 +402,22 @@ public Map<Set<Context>, Map<String, Boolean>> getTransientPermissions(GDPermiss
return new HashMap<>(); return new HashMap<>();
} }
final Set<? extends Node> nodes = permissionHolder.getTransientPermissions(); final Collection<Node> nodes = permissionHolder.transientData().toCollection();
Map<Set<Context>, Map<String, Boolean>> transientPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR); Map<Set<Context>, Map<String, Boolean>> transientPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR);
for (Node node : nodes) { for (Node node : nodes) {
if (node.isMeta()) { if (node.getType() != NodeType.PERMISSION) {
continue; continue;
} }
String serverName = node.getServer().orElse(null); final PermissionNode permissionNode = (PermissionNode) node;
final String worldName = node.getWorld().orElse(null); final Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && serverName.equalsIgnoreCase("global")) {
serverName = null;
}
Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && !serverName.equalsIgnoreCase("undefined")) {
contexts.add(new Context("server", serverName));
}
if (worldName != null) {
contexts.add(new Context("world", worldName.toLowerCase()));
}
Map<String, Boolean> permissionEntry = transientPermissionMap.get(contexts); Map<String, Boolean> permissionEntry = transientPermissionMap.get(contexts);
if (permissionEntry == null) { if (permissionEntry == null) {
permissionEntry = new HashMap<>(); permissionEntry = new HashMap<>();
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(permissionNode.getPermission(), node.getValue());
transientPermissionMap.put(contexts, permissionEntry); transientPermissionMap.put(contexts, permissionEntry);
} else { } else {
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(permissionNode.getPermission(), node.getValue());
} }
} }
return transientPermissionMap; return transientPermissionMap;
@ -433,32 +429,22 @@ public Map<Set<Context>, Map<String, String>> getPermanentOptions(GDPermissionHo
return new HashMap<>(); return new HashMap<>();
} }
final ImmutableCollection<Node> nodes = permissionHolder.getNodes().values(); final Collection<Node> nodes = permissionHolder.data().toCollection();
Map<Set<Context>, Map<String, String>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, String>>(CONTEXT_COMPARATOR); Map<Set<Context>, Map<String, String>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, String>>(CONTEXT_COMPARATOR);
for (Node node : nodes) { for (Node node : nodes) {
if (!node.isMeta()) { if (node.getType() != NodeType.META) {
continue; continue;
} }
String serverName = node.getServer().orElse(null);
final String worldName = node.getWorld().orElse(null);
if (serverName != null && serverName.equalsIgnoreCase("global")) {
serverName = null;
}
Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && !serverName.equalsIgnoreCase("undefined")) {
contexts.add(new Context("server", serverName));
}
if (worldName != null) {
contexts.add(new Context("world", worldName.toLowerCase()));
}
final MetaNode metaNode = (MetaNode) node;
final Set<Context> contexts = getGPContexts(node.getContexts());
Map<String, String> metaEntry = permanentPermissionMap.get(contexts); Map<String, String> metaEntry = permanentPermissionMap.get(contexts);
if (metaEntry == null) { if (metaEntry == null) {
metaEntry = new HashMap<>(); metaEntry = new HashMap<>();
metaEntry.put(node.getMeta().getKey(), node.getMeta().getValue()); metaEntry.put(metaNode.getMetaKey(), metaNode.getMetaValue());
permanentPermissionMap.put(contexts, metaEntry); permanentPermissionMap.put(contexts, metaEntry);
} else { } else {
metaEntry.put(node.getMeta().getKey(), node.getMeta().getValue()); metaEntry.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} }
} }
return permanentPermissionMap; return permanentPermissionMap;
@ -470,32 +456,22 @@ public Map<Set<Context>, Map<String, String>> getTransientOptions(GDPermissionHo
return new HashMap<>(); return new HashMap<>();
} }
final Set<? extends Node> nodes = permissionHolder.getTransientPermissions(); final Collection<Node> nodes = permissionHolder.transientData().toCollection();
Map<Set<Context>, Map<String, String>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, String>>(CONTEXT_COMPARATOR); Map<Set<Context>, Map<String, String>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, String>>(CONTEXT_COMPARATOR);
for (Node node : nodes) { for (Node node : nodes) {
if (!node.isMeta()) { if (node.getType() != NodeType.META) {
continue; continue;
} }
String serverName = node.getServer().orElse(null);
final String worldName = node.getWorld().orElse(null);
if (serverName != null && serverName.equalsIgnoreCase("global")) {
serverName = null;
}
Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && !serverName.equalsIgnoreCase("undefined")) {
contexts.add(new Context("server", serverName));
}
if (worldName != null) {
contexts.add(new Context("world", worldName.toLowerCase()));
}
final MetaNode metaNode = (MetaNode) node;
final Set<Context> contexts = getGPContexts(node.getContexts());
Map<String, String> metaEntry = permanentPermissionMap.get(contexts); Map<String, String> metaEntry = permanentPermissionMap.get(contexts);
if (metaEntry == null) { if (metaEntry == null) {
metaEntry = new HashMap<>(); metaEntry = new HashMap<>();
metaEntry.put(node.getMeta().getKey(), node.getMeta().getValue()); metaEntry.put(metaNode.getMetaKey(), metaNode.getMetaValue());
permanentPermissionMap.put(contexts, metaEntry); permanentPermissionMap.put(contexts, metaEntry);
} else { } else {
metaEntry.put(node.getMeta().getKey(), node.getMeta().getValue()); metaEntry.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} }
} }
return permanentPermissionMap; return permanentPermissionMap;
@ -507,17 +483,18 @@ public Map<String, String> getPermanentOptions(GDPermissionHolder holder, Set<Co
return new HashMap<>(); return new HashMap<>();
} }
final Set<? extends Node> nodes = permissionHolder.getPermissions(); final Collection<Node> nodes = permissionHolder.data().toCollection();
final Map<String, String> options = new HashMap<>(); final Map<String, String> options = new HashMap<>();
for (Node node : nodes) { for (Node node : nodes) {
if (!node.isMeta()) { if (node.getType() != NodeType.META) {
continue; continue;
} }
final MetaNode metaNode = (MetaNode) node;
if (contexts == null) { if (contexts == null) {
options.put(node.getMeta().getKey(), node.getMeta().getValue()); options.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} else if (getGPContexts(node.getContexts()).containsAll(contexts)) { } else if (getGPContexts(node.getContexts()).containsAll(contexts)) {
options.put(node.getMeta().getKey(), node.getMeta().getValue()); options.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} }
} }
return options; return options;
@ -529,17 +506,18 @@ public Map<String, String> getTransientOptions(GDPermissionHolder holder, Set<Co
return new HashMap<>(); return new HashMap<>();
} }
final Set<? extends Node> nodes = permissionHolder.getTransientPermissions(); final Collection<Node> nodes = permissionHolder.transientData().toCollection();
final Map<String, String> options = new HashMap<>(); final Map<String, String> options = new HashMap<>();
for (Node node : nodes) { for (Node node : nodes) {
if (!node.isMeta()) { if (node.getType() != NodeType.META) {
continue; continue;
} }
final MetaNode metaNode = (MetaNode) node;
if (contexts == null) { if (contexts == null) {
options.put(node.getMeta().getKey(), node.getMeta().getValue()); options.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} else if (getGPContexts(node.getContexts()).containsAll(contexts)) { } else if (getGPContexts(node.getContexts()).containsAll(contexts)) {
options.put(node.getMeta().getKey(), node.getMeta().getValue()); options.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} }
} }
return options; return options;
@ -551,7 +529,7 @@ public Map<Set<Context>, Map<String, Boolean>> getAllPermissions(GDPermissionHol
return new HashMap<>(); return new HashMap<>();
} }
final Set<? extends Node> nodes = permissionHolder.getAllNodes(); final Collection<Node> nodes = permissionHolder.getNodes();
Map<Set<Context>, Map<String, Boolean>> permissionMap = new HashMap<>(); Map<Set<Context>, Map<String, Boolean>> permissionMap = new HashMap<>();
Map<ContextSet, Set<Context>> contextMap = new HashMap<>(); Map<ContextSet, Set<Context>> contextMap = new HashMap<>();
for (Node node : nodes) { for (Node node : nodes) {
@ -565,10 +543,10 @@ public Map<Set<Context>, Map<String, Boolean>> getAllPermissions(GDPermissionHol
Map<String, Boolean> permissionEntry = permissionMap.get(contexts); Map<String, Boolean> permissionEntry = permissionMap.get(contexts);
if (permissionEntry == null) { if (permissionEntry == null) {
permissionEntry = new HashMap<>(); permissionEntry = new HashMap<>();
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(node.getKey(), node.getValue());
permissionMap.put(contexts, permissionEntry); permissionMap.put(contexts, permissionEntry);
} else { } else {
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(node.getKey(), node.getValue());
} }
} }
return permissionMap; return permissionMap;
@ -576,16 +554,16 @@ public Map<Set<Context>, Map<String, Boolean>> getAllPermissions(GDPermissionHol
public Set<Context> getGPContexts(ContextSet contextSet) { public Set<Context> getGPContexts(ContextSet contextSet) {
final Set<Context> gpContexts = new HashSet<>(); final Set<Context> gpContexts = new HashSet<>();
for (Map.Entry<String, String> mapEntry : contextSet.toSet()) { for (net.luckperms.api.context.Context context : contextSet.toSet()) {
if (mapEntry.getKey().startsWith("gd_") || mapEntry.getKey().equals("used_item") if (context.getKey().startsWith("gd_") || context.getKey().equals("used_item")
|| mapEntry.getKey().equals("source") || mapEntry.getKey().equals("target") || context.getKey().equals("source") || context.getKey().equals("target")
|| mapEntry.getKey().equals("world") || mapEntry.getKey().equals("server") || context.getKey().equals("world") || context.getKey().equals("server")
|| mapEntry.getKey().equals("state")) { || context.getKey().equals("state")) {
if (contextSet.containsKey(ContextKeys.CLAIM) && mapEntry.getKey().equals("server")) { if (contextSet.containsKey(ContextKeys.CLAIM) && context.getKey().equals("server")) {
continue; continue;
} }
gpContexts.add(new Context(mapEntry.getKey(), mapEntry.getValue())); gpContexts.add(new Context(context.getKey(), context.getValue()));
} }
} }
return gpContexts; return gpContexts;
@ -598,11 +576,11 @@ public Tristate getPermissionValue(GDPermissionHolder holder, String permission)
public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, MutableContextSet contexts) { public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, MutableContextSet contexts) {
return getPermissionValue(claim, holder, permission, this.getGDContexts(contexts)); return this.getPermissionValue(claim, holder, permission, this.getGDContexts(contexts));
} }
public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, Set<Context> contexts) { public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, Set<Context> contexts) {
return getPermissionValue(claim, holder, permission, contexts, true); return this.getPermissionValue(holder, permission, contexts);
} }
public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, Set<Context> contexts, boolean checkTransient) { public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, Set<Context> contexts, boolean checkTransient) {
@ -711,58 +689,52 @@ public Tristate getPermissionValueWithRequiredContexts(GDClaim claim, GDPermissi
} }
public Tristate getPermissionValue(GDPermissionHolder holder, String permission, Set<Context> contexts) { public Tristate getPermissionValue(GDPermissionHolder holder, String permission, Set<Context> contexts) {
ImmutableContextSet contextSet = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet contextSet = this.getLPContexts(contexts).immutableCopy();
return this.getPermissionValue(holder, permission, contextSet); return this.getPermissionValue(holder, permission, contextSet);
} }
public Tristate getPermissionValue(GDPermissionHolder holder, String permission, ContextSet contexts) { public Tristate getPermissionValue(GDPermissionHolder holder, String permission, ContextSet contexts) {
Contexts context = Contexts.global().setContexts(contexts);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return Tristate.UNDEFINED; return Tristate.UNDEFINED;
} }
PermissionData cachedData = permissionHolder.getCachedData().getPermissionData(context); final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).context(contexts).build();
return getGDTristate(cachedData.getPermissionValue(permission)); CachedPermissionData cachedData = permissionHolder.getCachedData().getPermissionData(query);
return getGDTristate(cachedData.checkPermission(permission));
} }
// To set options, pass "meta.option". // To set options, pass "meta.option".
@Override @Override
public String getOptionValue(GDPermissionHolder holder, Option option, Set<Context> contexts) { public String getOptionValue(GDPermissionHolder holder, Option option, Set<Context> contexts) {
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
Contexts context = Contexts.global().setContexts(set);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return null; return null;
} }
MetaData metaData = permissionHolder.getCachedData().getMetaData(context); final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).context(set).build();
return metaData.getMeta().get(option.getPermission()); CachedMetaData metaData = permissionHolder.getCachedData().getMetaData(query);
return metaData.getMetaValue(option.getPermission());
} }
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) { public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
DataMutateResult result = null; DataMutateResult result = null;
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
Contexts context = Contexts.global().setContexts(set);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return new GDPermissionResult(ResultTypes.FAILURE); return new GDPermissionResult(ResultTypes.FAILURE);
} }
MetaData metaData = permissionHolder.getCachedData().getMetaData(context);
for (Map.Entry<String, String> mapEntry : metaData.getMeta().entrySet()) {
if (mapEntry.getKey().equalsIgnoreCase(permission)) {
// Always unset existing meta first // Always unset existing meta first
final Node node = this.luckPermsApi.getNodeFactory().makeMetaNode(permission, mapEntry.getValue()).withExtraContext(set).build(); final Node currentNode = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).context(set).build();
result = permissionHolder.unsetPermission(node); result = permissionHolder.data().remove(currentNode);
}
}
final Node node = this.luckPermsApi.getNodeFactory().makeMetaNode(permission, value).withExtraContext(set).build(); final Node node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).value(value).context(set).build();
if (!value.equalsIgnoreCase("undefined")) { if (!value.equalsIgnoreCase("undefined")) {
result = permissionHolder.setPermission(node); result = permissionHolder.data().add(node);
} }
if (result != null && result.wasSuccess()) { if (result != null && result.wasSuccessful()) {
this.savePermissionHolder(permissionHolder); this.savePermissionHolder(permissionHolder);
return new GDPermissionResult(ResultTypes.SUCCESS); return new GDPermissionResult(ResultTypes.SUCCESS);
} }
@ -779,25 +751,25 @@ public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag,
public boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) { public boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
DataMutateResult result = null; DataMutateResult result = null;
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final Node node = this.luckPermsApi.getNodeFactory().newBuilder(permission).setValue(value.asBoolean()).withExtraContext(set).build(); final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return false; return false;
} }
if (value == Tristate.UNDEFINED) { if (value == Tristate.UNDEFINED) {
result = permissionHolder.unsetPermission(node); result = permissionHolder.data().remove(node);
} else { } else {
result = permissionHolder.setPermission(node); result = permissionHolder.data().add(node);
} }
if (result.wasSuccess()) { if (result.wasSuccessful()) {
if (permissionHolder instanceof Group) { if (permissionHolder instanceof Group) {
final Group group = (Group) permissionHolder; final Group group = (Group) permissionHolder;
group.refreshCachedData(); group.getCachedData().invalidate();
for (User user :this.luckPermsApi.getUserManager().getLoadedUsers()) { for (User user :this.luckPermsApi.getUserManager().getLoadedUsers()) {
user.refreshCachedData(); user.getCachedData().invalidate();
} }
// If a group is changed, we invalidate all cache // If a group is changed, we invalidate all cache
PermissionHolderCache.getInstance().invalidateAllPermissionCache(); PermissionHolderCache.getInstance().invalidateAllPermissionCache();
@ -808,29 +780,29 @@ public boolean setPermissionValue(GDPermissionHolder holder, String permission,
this.savePermissionHolder(permissionHolder); this.savePermissionHolder(permissionHolder);
} }
return result.wasSuccess(); return result.wasSuccessful();
} }
public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) { public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
MutableContextSet contextSet = MutableContextSet.fromEntries(contexts); MutableContextSet contextSet = this.getLPContexts(contexts);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return; return;
} }
final Node node = this.luckPermsApi.getNodeFactory().makeMetaNode(permission, value).withExtraContext(contextSet).build(); final Node node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).value(value).context(contextSet).build();
permissionHolder.setTransientPermission(node); permissionHolder.transientData().add(node);
} }
public void setTransientPermission(GDPermissionHolder holder, String permission, Boolean value, Set<Context> contexts) { public void setTransientPermission(GDPermissionHolder holder, String permission, Boolean value, Set<Context> contexts) {
MutableContextSet contextSet = MutableContextSet.fromEntries(contexts); MutableContextSet contextSet = this.getLPContexts(contexts);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return; return;
} }
final Node node = this.luckPermsApi.getNodeFactory().newBuilder(permission).setValue(value).withExtraContext(contextSet).build(); final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value).context(contextSet).build();
permissionHolder.setTransientPermission(node); permissionHolder.transientData().add(node);
} }
public void savePermissionHolder(PermissionHolder holder) { public void savePermissionHolder(PermissionHolder holder) {
@ -846,25 +818,46 @@ public void refreshCachedData(GDPermissionHolder holder) {
if (permissionHolder == null) { if (permissionHolder == null) {
return; return;
} }
permissionHolder.refreshCachedData(); permissionHolder.getCachedData().invalidate();
} }
public Set<Context> getGDContexts(ContextSet contextSet) { public Set<Context> getGDContexts(ContextSet contexts) {
final Set<Context> gdContexts = new HashSet<>(); final Set<Context> gdContexts = new HashSet<>();
contextSet.forEach(entry -> { contexts.forEach(entry -> {
gdContexts.add(new Context(entry.getKey(), entry.getValue())); gdContexts.add(new Context(entry.getKey(), entry.getValue()));
}); });
return gdContexts; return gdContexts;
} }
public Tristate getGDTristate(me.lucko.luckperms.api.Tristate state) { public MutableContextSet getLPContexts(Set<Context> contexts) {
if (state == me.lucko.luckperms.api.Tristate.TRUE) { MutableContextSet lpContexts = MutableContextSet.create();
contexts.forEach(entry -> {
lpContexts.add(entry.getKey(), entry.getValue());
});
return lpContexts;
}
public Tristate getGDTristate(net.luckperms.api.util.Tristate state) {
if (state == net.luckperms.api.util.Tristate.TRUE) {
return Tristate.TRUE; return Tristate.TRUE;
} }
if (state == me.lucko.luckperms.api.Tristate.FALSE) { if (state == net.luckperms.api.util.Tristate.FALSE) {
return Tristate.FALSE; return Tristate.FALSE;
} }
return Tristate.UNDEFINED; return Tristate.UNDEFINED;
} }
private static class DefaultDataQueryOrderFunction implements DataQueryOrderFunction {
@Override
public Comparator<DataType> getOrderComparator(Identifier identifier) {
if (identifier.getType() == Identifier.GROUP_TYPE && identifier.getName().equalsIgnoreCase("default")) {
return DataQueryOrder.TRANSIENT_LAST;
}
return DataQueryOrder.TRANSIENT_FIRST;
}
}
} }

View File

@ -124,13 +124,6 @@
"relocate": "okio:okio", "relocate": "okio:okio",
"url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar" "url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
}, },
{
"name": "me.lucko.luckperms:luckperms-api:4.4",
"sha1": "e0356ab83e426ff5e51b3c596ffac8750905af64",
"path": "me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar",
"relocate": "me.lucko:lucko",
"url": "https://repo1.maven.org/maven2/me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar"
},
{ {
"name": "com.github.ben-manes.caffeine:caffeine:2.7.0", "name": "com.github.ben-manes.caffeine:caffeine:2.7.0",
"sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a", "sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a",

View File

@ -130,13 +130,6 @@
"relocate": "okio:okio", "relocate": "okio:okio",
"url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar" "url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
}, },
{
"name": "me.lucko.luckperms:luckperms-api:4.4",
"sha1": "e0356ab83e426ff5e51b3c596ffac8750905af64",
"path": "me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar",
"relocate": "me.lucko:lucko",
"url": "https://repo1.maven.org/maven2/me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar"
},
{ {
"name": "com.github.ben-manes.caffeine:caffeine:2.7.0", "name": "com.github.ben-manes.caffeine:caffeine:2.7.0",
"sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a", "sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a",

View File

@ -130,13 +130,6 @@
"relocate": "okio:okio", "relocate": "okio:okio",
"url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar" "url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
}, },
{
"name": "me.lucko.luckperms:luckperms-api:4.4",
"sha1": "e0356ab83e426ff5e51b3c596ffac8750905af64",
"path": "me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar",
"relocate": "me.lucko:lucko",
"url": "https://repo1.maven.org/maven2/me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar"
},
{ {
"name": "com.github.ben-manes.caffeine:caffeine:2.7.0", "name": "com.github.ben-manes.caffeine:caffeine:2.7.0",
"sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a", "sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a",

View File

@ -130,13 +130,6 @@
"relocate": "okio:okio", "relocate": "okio:okio",
"url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar" "url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
}, },
{
"name": "me.lucko.luckperms:luckperms-api:4.4",
"sha1": "e0356ab83e426ff5e51b3c596ffac8750905af64",
"path": "me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar",
"relocate": "me.lucko:lucko",
"url": "https://repo1.maven.org/maven2/me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar"
},
{ {
"name": "com.github.ben-manes.caffeine:caffeine:2.7.0", "name": "com.github.ben-manes.caffeine:caffeine:2.7.0",
"sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a", "sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a",

View File

@ -130,13 +130,6 @@
"relocate": "okio:okio", "relocate": "okio:okio",
"url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar" "url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
}, },
{
"name": "me.lucko.luckperms:luckperms-api:4.4",
"sha1": "e0356ab83e426ff5e51b3c596ffac8750905af64",
"path": "me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar",
"relocate": "me.lucko:lucko",
"url": "https://repo1.maven.org/maven2/me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar"
},
{ {
"name": "com.github.ben-manes.caffeine:caffeine:2.7.0", "name": "com.github.ben-manes.caffeine:caffeine:2.7.0",
"sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a", "sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a",

View File

@ -130,13 +130,6 @@
"relocate": "okio:okio", "relocate": "okio:okio",
"url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar" "url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
}, },
{
"name": "me.lucko.luckperms:luckperms-api:4.4",
"sha1": "e0356ab83e426ff5e51b3c596ffac8750905af64",
"path": "me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar",
"relocate": "me.lucko:lucko",
"url": "https://repo1.maven.org/maven2/me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar"
},
{ {
"name": "com.github.ben-manes.caffeine:caffeine:2.7.0", "name": "com.github.ben-manes.caffeine:caffeine:2.7.0",
"sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a", "sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a",

View File

@ -124,13 +124,6 @@
"relocate": "okio:okio", "relocate": "okio:okio",
"url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar" "url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
}, },
{
"name": "me.lucko.luckperms:luckperms-api:4.4",
"sha1": "e0356ab83e426ff5e51b3c596ffac8750905af64",
"path": "me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar",
"relocate": "me.lucko:lucko",
"url": "https://repo1.maven.org/maven2/me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar"
},
{ {
"name": "com.github.ben-manes.caffeine:caffeine:2.7.0", "name": "com.github.ben-manes.caffeine:caffeine:2.7.0",
"sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a", "sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a",

View File

@ -108,6 +108,7 @@ dependencies {
} }
compile "com.github.bloodmc:mcclans-api:develop-SNAPSHOT" compile "com.github.bloodmc:mcclans-api:develop-SNAPSHOT"
compileOnly "com.sk89q.worldedit:worldedit-core:6.1.4-SNAPSHOT" compileOnly "com.sk89q.worldedit:worldedit-core:6.1.4-SNAPSHOT"
compileOnly "net.luckperms:api:5.0"
// required for bootstrap // required for bootstrap
compile "com.googlecode.json-simple:json-simple:1.1.1" compile "com.googlecode.json-simple:json-simple:1.1.1"
@ -125,7 +126,6 @@ dependencies {
compileOnly "it.unimi.dsi:fastutil:8.2.3" compileOnly "it.unimi.dsi:fastutil:8.2.3"
compileOnly "javax.inject:javax.inject:1" compileOnly "javax.inject:javax.inject:1"
compileOnly "me.lucko:jar-relocator:1.3" compileOnly "me.lucko:jar-relocator:1.3"
compileOnly "me.lucko.luckperms:luckperms-api:4.4"
compileOnly "net.jodah:expiringmap:0.5.9" compileOnly "net.jodah:expiringmap:0.5.9"
compileOnly "org.apache.commons:commons-lang3:3.9" compileOnly "org.apache.commons:commons-lang3:3.9"
compileOnly "org.checkerframework:checker:2.8.2" compileOnly "org.checkerframework:checker:2.8.2"

View File

@ -67,7 +67,7 @@ public void accumulateContexts(Subject calculable, Set<Context> accumulator) {
@Override @Override
public boolean matches(Context context, Subject subject) { public boolean matches(Context context, Subject subject) {
if (context.equals("gd_claim")) { if (context.getKey().equals("gd_claim")) {
if (subject.getCommandSource().isPresent() && subject.getCommandSource().get() instanceof Player) { if (subject.getCommandSource().isPresent() && subject.getCommandSource().get() instanceof Player) {
Player player = (Player) subject.getCommandSource().get(); Player player = (Player) subject.getCommandSource().get();
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getPlayerData(player.getWorld(), player.getUniqueId()); GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getPlayerData(player.getWorld(), player.getUniqueId());

View File

@ -27,15 +27,15 @@
import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.PermissionHolderCache; import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionHolder;
import me.lucko.luckperms.api.LuckPermsApi; import net.luckperms.api.LuckPerms;
import me.lucko.luckperms.api.event.group.GroupDataRecalculateEvent; import net.luckperms.api.event.group.GroupDataRecalculateEvent;
import me.lucko.luckperms.api.event.user.UserDataRecalculateEvent; import net.luckperms.api.event.user.UserDataRecalculateEvent;
public class LuckPermsEventHandler { public class LuckPermsEventHandler {
private final LuckPermsApi luckPermsApi; private final LuckPerms luckPermsApi;
public LuckPermsEventHandler(LuckPermsApi luckPermsApi) { public LuckPermsEventHandler(LuckPerms luckPermsApi) {
this.luckPermsApi = luckPermsApi; this.luckPermsApi = luckPermsApi;
this.luckPermsApi.getEventBus().subscribe(GroupDataRecalculateEvent.class, this::onGroupDataRecalculate); this.luckPermsApi.getEventBus().subscribe(GroupDataRecalculateEvent.class, this::onGroupDataRecalculate);
this.luckPermsApi.getEventBus().subscribe(UserDataRecalculateEvent.class, this::onUserDataRecalculate); this.luckPermsApi.getEventBus().subscribe(UserDataRecalculateEvent.class, this::onUserDataRecalculate);
@ -47,7 +47,7 @@ public void onGroupDataRecalculate(GroupDataRecalculateEvent event) {
} }
public void onUserDataRecalculate(UserDataRecalculateEvent event) { public void onUserDataRecalculate(UserDataRecalculateEvent event) {
final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateUser(event.getUser().getUuid()); final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateUser(event.getUser().getUniqueId());
PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll(); PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll();
PermissionHolderCache.getInstance().getOrCreatePermissionCache(GriefDefenderPlugin.DEFAULT_HOLDER).invalidateAll(); PermissionHolderCache.getInstance().getOrCreatePermissionCache(GriefDefenderPlugin.DEFAULT_HOLDER).invalidateAll();
} }

View File

@ -26,7 +26,6 @@
import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.griefdefender.GDPlayerData; import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.GriefDefenderPlugin;
@ -37,28 +36,38 @@
import com.griefdefender.api.permission.PermissionResult; import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.ResultTypes; import com.griefdefender.api.permission.ResultTypes;
import com.griefdefender.api.permission.flag.Flag; import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Option; import com.griefdefender.api.permission.option.Option;
import com.griefdefender.cache.PermissionHolderCache; import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim; import com.griefdefender.claim.GDClaim;
import com.griefdefender.listener.LuckPermsEventHandler;
import com.griefdefender.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionResult; import com.griefdefender.permission.GDPermissionResult;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import me.lucko.luckperms.LuckPerms;
import me.lucko.luckperms.api.Contexts; import net.luckperms.api.LuckPerms;
import me.lucko.luckperms.api.DataMutateResult; import net.luckperms.api.cacheddata.CachedMetaData;
import me.lucko.luckperms.api.Group; import net.luckperms.api.cacheddata.CachedPermissionData;
import me.lucko.luckperms.api.LuckPermsApi; import net.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.Node; import net.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.PermissionHolder; import net.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.api.User; import net.luckperms.api.model.PermissionHolder;
import me.lucko.luckperms.api.caching.MetaData; import net.luckperms.api.model.PermissionHolder.Identifier;
import me.lucko.luckperms.api.caching.PermissionData; import net.luckperms.api.model.data.DataMutateResult;
import me.lucko.luckperms.api.context.ContextSet; import net.luckperms.api.model.data.DataType;
import me.lucko.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.model.group.Group;
import me.lucko.luckperms.api.context.MutableContextSet; import net.luckperms.api.model.user.User;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.NodeType;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.node.types.PermissionNode;
import net.luckperms.api.query.QueryMode;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.query.dataorder.DataQueryOrder;
import net.luckperms.api.query.dataorder.DataQueryOrderFunction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -73,6 +82,8 @@
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.service.ProviderRegistration;
public class LuckPermsProvider implements PermissionProvider { public class LuckPermsProvider implements PermissionProvider {
@ -94,14 +105,15 @@ public int compare(Set<Context> s1, Set<Context> s2) {
} }
}; };
private final LuckPermsApi luckPermsApi; private final LuckPerms luckPermsApi;
private final static DefaultDataQueryOrderFunction DEFAULT_DATA_QUERY_ORDER = new DefaultDataQueryOrderFunction();
public LuckPermsProvider() { public LuckPermsProvider() {
this.luckPermsApi = LuckPerms.getApi(); final ProviderRegistration<LuckPerms> service = Sponge.getServiceManager().getRegistration(LuckPerms.class).orElse(null);
//new LuckPermsEventHandler(this.luckPermsApi); this.luckPermsApi = service.getProvider();
} }
public LuckPermsApi getApi() { public LuckPerms getApi() {
return this.luckPermsApi; return this.luckPermsApi;
} }
@ -112,7 +124,7 @@ public boolean hasGroupSubject(String identifier) {
public PermissionHolder getLuckPermsHolder(GDPermissionHolder holder) { public PermissionHolder getLuckPermsHolder(GDPermissionHolder holder) {
if (holder.getIdentifier().equalsIgnoreCase("default")) { if (holder.getIdentifier().equalsIgnoreCase("default")) {
return this.luckPermsApi.getGroup("default"); return this.luckPermsApi.getGroupManager().getGroup("default");
} }
if (holder instanceof GDPermissionUser) { if (holder instanceof GDPermissionUser) {
return this.getLuckPermsUser(holder.getIdentifier()); return this.getLuckPermsUser(holder.getIdentifier());
@ -140,7 +152,7 @@ public User getLuckPermsUser(String identifier) {
} }
if (user == null) { if (user == null) {
user = this.luckPermsApi.getUser(identifier); user = this.luckPermsApi.getUserManager().getUser(identifier);
} }
if (user != null) { if (user != null) {
this.userCache.put(identifier, user); this.userCache.put(identifier, user);
@ -151,14 +163,14 @@ public User getLuckPermsUser(String identifier) {
public Group getLuckPermsGroup(String identifier) { public Group getLuckPermsGroup(String identifier) {
if (identifier.equalsIgnoreCase("default")) { if (identifier.equalsIgnoreCase("default")) {
return this.luckPermsApi.getGroup("default"); return this.luckPermsApi.getGroupManager().getGroup("default");
} }
Group group = this.groupCache.getIfPresent(identifier); Group group = this.groupCache.getIfPresent(identifier);
if (group != null) { if (group != null) {
return group; return group;
} }
group = this.luckPermsApi.getGroup(identifier); group = this.luckPermsApi.getGroupManager().getGroup(identifier);
if (group != null) { if (group != null) {
this.groupCache.put(identifier, group); this.groupCache.put(identifier, group);
} }
@ -202,7 +214,7 @@ public Group getGroupSubject(String identifier) {
public UUID lookupUserUniqueId(String name) { public UUID lookupUserUniqueId(String name) {
final User user = this.getLuckPermsUser(name); final User user = this.getLuckPermsUser(name);
if (user != null) { if (user != null) {
return user.getUuid(); return user.getUniqueId();
} }
return null; return null;
} }
@ -229,7 +241,7 @@ public User getUserSubject(UUID uuid) {
public List<String> getAllLoadedPlayerNames() { public List<String> getAllLoadedPlayerNames() {
List<String> subjectList = new ArrayList<>(); List<String> subjectList = new ArrayList<>();
for (User user : this.luckPermsApi.getUserManager().getLoadedUsers()) { for (User user : this.luckPermsApi.getUserManager().getLoadedUsers()) {
final String name = user.getName(); final String name = user.getUsername();
if (name != null) { if (name != null) {
subjectList.add(name); subjectList.add(name);
} }
@ -268,7 +280,7 @@ public void addActiveContexts(Set<Context> contexts, GDPermissionHolder permissi
return; return;
} }
ImmutableContextSet contextSet = this.luckPermsApi.getContextManager().lookupApplicableContext((User) luckPermsHolder).orElse(null); ImmutableContextSet contextSet = this.luckPermsApi.getContextManager().getContext((User) luckPermsHolder).orElse(null);
if (contextSet == null) { if (contextSet == null) {
contextSet = this.luckPermsApi.getContextManager().getStaticContext(); contextSet = this.luckPermsApi.getContextManager().getStaticContext();
} }
@ -309,8 +321,8 @@ public void clearPermissions(GDPermissionHolder holder, Set<Context> contexts) {
return; return;
} }
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
permissionHolder.clearNodes(set); permissionHolder.data().clear(set);
this.savePermissionHolder(permissionHolder); this.savePermissionHolder(permissionHolder);
} }
@ -320,29 +332,37 @@ public boolean holderHasPermission(GDPermissionHolder holder, String permission)
return false; return false;
} }
return permissionHolder.getCachedData().getPermissionData(Contexts.allowAll()).getPermissionValue(permission) == me.lucko.luckperms.api.Tristate.TRUE; final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).build();
return permissionHolder.getCachedData().getPermissionData(query).checkPermission(permission).asBoolean();
} }
public Map<String, Boolean> getPermissions(GDPermissionHolder holder, Set<Context> contexts) { public Map<String, Boolean> getPermissions(GDPermissionHolder holder, Set<Context> contexts) {
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
Contexts context = Contexts.global().setContexts(set);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return new HashMap<>(); return new HashMap<>();
} }
PermissionData cachedData = permissionHolder.getCachedData().getPermissionData(context);
return cachedData.getImmutableBacking(); final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).context(set).build();
CachedPermissionData cachedData = permissionHolder.getCachedData().getPermissionData(query);
return cachedData.getPermissionMap();
} }
public Map<String, String> getOptions(GDPermissionHolder holder, Set<Context> contexts) { public Map<String, String> getOptions(GDPermissionHolder holder, Set<Context> contexts) {
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
Contexts context = Contexts.global().setContexts(set);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return new HashMap<>(); return new HashMap<>();
} }
MetaData cachedData = permissionHolder.getCachedData().getMetaData(context);
return cachedData.getMeta(); final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).context(set).build();
CachedMetaData cachedData = permissionHolder.getCachedData().getMetaData(query);
// TODO
Map<String, String> metaMap = new HashMap<>();
for (Map.Entry<String, List<String>> mapEntry : cachedData.getMeta().entrySet()) {
metaMap.put(mapEntry.getKey(), mapEntry.getValue().get(0));
}
return metaMap;
} }
public Map<Set<Context>, Map<String, Boolean>> getPermanentPermissions(GDPermissionHolder holder) { public Map<Set<Context>, Map<String, Boolean>> getPermanentPermissions(GDPermissionHolder holder) {
@ -351,33 +371,22 @@ public Map<Set<Context>, Map<String, Boolean>> getPermanentPermissions(GDPermiss
return new HashMap<>(); return new HashMap<>();
} }
final ImmutableCollection<Node> nodes = permissionHolder.getNodes().values(); final Collection<Node> nodes = permissionHolder.data().toCollection();
Map<Set<Context>, Map<String, Boolean>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR); Map<Set<Context>, Map<String, Boolean>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR);
for (Node node : nodes) { for (Node node : nodes) {
if (node.isMeta()) { if (node.getType() != NodeType.PERMISSION) {
continue; continue;
} }
String serverName = node.getServer().orElse(null); final PermissionNode permissionNode = (PermissionNode) node;
final String worldName = node.getWorld().orElse(null); final Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && serverName.equalsIgnoreCase("global")) {
serverName = null;
}
Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && !serverName.equalsIgnoreCase("undefined")) {
contexts.add(new Context("server", serverName));
}
if (worldName != null) {
contexts.add(new Context("world", worldName.toLowerCase()));
}
Map<String, Boolean> permissionEntry = permanentPermissionMap.get(contexts); Map<String, Boolean> permissionEntry = permanentPermissionMap.get(contexts);
if (permissionEntry == null) { if (permissionEntry == null) {
permissionEntry = new HashMap<>(); permissionEntry = new HashMap<>();
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(permissionNode.getPermission(), node.getValue());
permanentPermissionMap.put(contexts, permissionEntry); permanentPermissionMap.put(contexts, permissionEntry);
} else { } else {
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(permissionNode.getPermission(), node.getValue());
} }
} }
@ -390,33 +399,22 @@ public Map<Set<Context>, Map<String, Boolean>> getTransientPermissions(GDPermiss
return new HashMap<>(); return new HashMap<>();
} }
final Set<? extends Node> nodes = permissionHolder.getTransientPermissions(); final Collection<Node> nodes = permissionHolder.transientData().toCollection();
Map<Set<Context>, Map<String, Boolean>> transientPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR); Map<Set<Context>, Map<String, Boolean>> transientPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR);
for (Node node : nodes) { for (Node node : nodes) {
if (node.isMeta()) { if (node.getType() != NodeType.PERMISSION) {
continue; continue;
} }
String serverName = node.getServer().orElse(null); final PermissionNode permissionNode = (PermissionNode) node;
final String worldName = node.getWorld().orElse(null); final Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && serverName.equalsIgnoreCase("global")) {
serverName = null;
}
Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && !serverName.equalsIgnoreCase("undefined")) {
contexts.add(new Context("server", serverName));
}
if (worldName != null) {
contexts.add(new Context("world", worldName.toLowerCase()));
}
Map<String, Boolean> permissionEntry = transientPermissionMap.get(contexts); Map<String, Boolean> permissionEntry = transientPermissionMap.get(contexts);
if (permissionEntry == null) { if (permissionEntry == null) {
permissionEntry = new HashMap<>(); permissionEntry = new HashMap<>();
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(permissionNode.getPermission(), node.getValue());
transientPermissionMap.put(contexts, permissionEntry); transientPermissionMap.put(contexts, permissionEntry);
} else { } else {
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(permissionNode.getPermission(), node.getValue());
} }
} }
return transientPermissionMap; return transientPermissionMap;
@ -428,32 +426,22 @@ public Map<Set<Context>, Map<String, String>> getPermanentOptions(GDPermissionHo
return new HashMap<>(); return new HashMap<>();
} }
final ImmutableCollection<Node> nodes = permissionHolder.getNodes().values(); final Collection<Node> nodes = permissionHolder.data().toCollection();
Map<Set<Context>, Map<String, String>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, String>>(CONTEXT_COMPARATOR); Map<Set<Context>, Map<String, String>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, String>>(CONTEXT_COMPARATOR);
for (Node node : nodes) { for (Node node : nodes) {
if (!node.isMeta()) { if (node.getType() != NodeType.META) {
continue; continue;
} }
String serverName = node.getServer().orElse(null);
final String worldName = node.getWorld().orElse(null);
if (serverName != null && serverName.equalsIgnoreCase("global")) {
serverName = null;
}
Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && !serverName.equalsIgnoreCase("undefined")) {
contexts.add(new Context("server", serverName));
}
if (worldName != null) {
contexts.add(new Context("world", worldName.toLowerCase()));
}
final MetaNode metaNode = (MetaNode) node;
final Set<Context> contexts = getGPContexts(node.getContexts());
Map<String, String> metaEntry = permanentPermissionMap.get(contexts); Map<String, String> metaEntry = permanentPermissionMap.get(contexts);
if (metaEntry == null) { if (metaEntry == null) {
metaEntry = new HashMap<>(); metaEntry = new HashMap<>();
metaEntry.put(node.getMeta().getKey(), node.getMeta().getValue()); metaEntry.put(metaNode.getMetaKey(), metaNode.getMetaValue());
permanentPermissionMap.put(contexts, metaEntry); permanentPermissionMap.put(contexts, metaEntry);
} else { } else {
metaEntry.put(node.getMeta().getKey(), node.getMeta().getValue()); metaEntry.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} }
} }
return permanentPermissionMap; return permanentPermissionMap;
@ -465,32 +453,22 @@ public Map<Set<Context>, Map<String, String>> getTransientOptions(GDPermissionHo
return new HashMap<>(); return new HashMap<>();
} }
final Set<? extends Node> nodes = permissionHolder.getTransientPermissions(); final Collection<Node> nodes = permissionHolder.transientData().toCollection();
Map<Set<Context>, Map<String, String>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, String>>(CONTEXT_COMPARATOR); Map<Set<Context>, Map<String, String>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, String>>(CONTEXT_COMPARATOR);
for (Node node : nodes) { for (Node node : nodes) {
if (!node.isMeta()) { if (node.getType() != NodeType.META) {
continue; continue;
} }
String serverName = node.getServer().orElse(null);
final String worldName = node.getWorld().orElse(null);
if (serverName != null && serverName.equalsIgnoreCase("global")) {
serverName = null;
}
Set<Context> contexts = getGPContexts(node.getContexts());
if (serverName != null && !serverName.equalsIgnoreCase("undefined")) {
contexts.add(new Context("server", serverName));
}
if (worldName != null) {
contexts.add(new Context("world", worldName.toLowerCase()));
}
final MetaNode metaNode = (MetaNode) node;
final Set<Context> contexts = getGPContexts(node.getContexts());
Map<String, String> metaEntry = permanentPermissionMap.get(contexts); Map<String, String> metaEntry = permanentPermissionMap.get(contexts);
if (metaEntry == null) { if (metaEntry == null) {
metaEntry = new HashMap<>(); metaEntry = new HashMap<>();
metaEntry.put(node.getMeta().getKey(), node.getMeta().getValue()); metaEntry.put(metaNode.getMetaKey(), metaNode.getMetaValue());
permanentPermissionMap.put(contexts, metaEntry); permanentPermissionMap.put(contexts, metaEntry);
} else { } else {
metaEntry.put(node.getMeta().getKey(), node.getMeta().getValue()); metaEntry.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} }
} }
return permanentPermissionMap; return permanentPermissionMap;
@ -502,17 +480,18 @@ public Map<String, String> getPermanentOptions(GDPermissionHolder holder, Set<Co
return new HashMap<>(); return new HashMap<>();
} }
final Set<? extends Node> nodes = permissionHolder.getPermissions(); final Collection<Node> nodes = permissionHolder.data().toCollection();
final Map<String, String> options = new HashMap<>(); final Map<String, String> options = new HashMap<>();
for (Node node : nodes) { for (Node node : nodes) {
if (!node.isMeta()) { if (node.getType() != NodeType.META) {
continue; continue;
} }
final MetaNode metaNode = (MetaNode) node;
if (contexts == null) { if (contexts == null) {
options.put(node.getMeta().getKey(), node.getMeta().getValue()); options.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} else if (getGPContexts(node.getContexts()).containsAll(contexts)) { } else if (getGPContexts(node.getContexts()).containsAll(contexts)) {
options.put(node.getMeta().getKey(), node.getMeta().getValue()); options.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} }
} }
return options; return options;
@ -524,17 +503,18 @@ public Map<String, String> getTransientOptions(GDPermissionHolder holder, Set<Co
return new HashMap<>(); return new HashMap<>();
} }
final Set<? extends Node> nodes = permissionHolder.getTransientPermissions(); final Collection<Node> nodes = permissionHolder.transientData().toCollection();
final Map<String, String> options = new HashMap<>(); final Map<String, String> options = new HashMap<>();
for (Node node : nodes) { for (Node node : nodes) {
if (!node.isMeta()) { if (node.getType() != NodeType.META) {
continue; continue;
} }
final MetaNode metaNode = (MetaNode) node;
if (contexts == null) { if (contexts == null) {
options.put(node.getMeta().getKey(), node.getMeta().getValue()); options.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} else if (getGPContexts(node.getContexts()).containsAll(contexts)) { } else if (getGPContexts(node.getContexts()).containsAll(contexts)) {
options.put(node.getMeta().getKey(), node.getMeta().getValue()); options.put(metaNode.getMetaKey(), metaNode.getMetaValue());
} }
} }
return options; return options;
@ -546,7 +526,7 @@ public Map<Set<Context>, Map<String, Boolean>> getAllPermissions(GDPermissionHol
return new HashMap<>(); return new HashMap<>();
} }
final Set<? extends Node> nodes = permissionHolder.getAllNodes(); final Collection<Node> nodes = permissionHolder.getNodes();
Map<Set<Context>, Map<String, Boolean>> permissionMap = new HashMap<>(); Map<Set<Context>, Map<String, Boolean>> permissionMap = new HashMap<>();
Map<ContextSet, Set<Context>> contextMap = new HashMap<>(); Map<ContextSet, Set<Context>> contextMap = new HashMap<>();
for (Node node : nodes) { for (Node node : nodes) {
@ -560,10 +540,10 @@ public Map<Set<Context>, Map<String, Boolean>> getAllPermissions(GDPermissionHol
Map<String, Boolean> permissionEntry = permissionMap.get(contexts); Map<String, Boolean> permissionEntry = permissionMap.get(contexts);
if (permissionEntry == null) { if (permissionEntry == null) {
permissionEntry = new HashMap<>(); permissionEntry = new HashMap<>();
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(node.getKey(), node.getValue());
permissionMap.put(contexts, permissionEntry); permissionMap.put(contexts, permissionEntry);
} else { } else {
permissionEntry.put(node.getPermission(), node.getValue()); permissionEntry.put(node.getKey(), node.getValue());
} }
} }
return permissionMap; return permissionMap;
@ -571,16 +551,16 @@ public Map<Set<Context>, Map<String, Boolean>> getAllPermissions(GDPermissionHol
public Set<Context> getGPContexts(ContextSet contextSet) { public Set<Context> getGPContexts(ContextSet contextSet) {
final Set<Context> gpContexts = new HashSet<>(); final Set<Context> gpContexts = new HashSet<>();
for (Map.Entry<String, String> mapEntry : contextSet.toSet()) { for (net.luckperms.api.context.Context context : contextSet.toSet()) {
if (mapEntry.getKey().startsWith("gd_") || mapEntry.getKey().equals("used_item") if (context.getKey().startsWith("gd_") || context.getKey().equals("used_item")
|| mapEntry.getKey().equals("source") || mapEntry.getKey().equals("target") || context.getKey().equals("source") || context.getKey().equals("target")
|| mapEntry.getKey().equals("world") || mapEntry.getKey().equals("server") || context.getKey().equals("world") || context.getKey().equals("server")
|| mapEntry.getKey().equals("state")) { || context.getKey().equals("state")) {
if (contextSet.containsKey(ContextKeys.CLAIM) && mapEntry.getKey().equals("server")) { if (contextSet.containsKey(ContextKeys.CLAIM) && context.getKey().equals("server")) {
continue; continue;
} }
gpContexts.add(new Context(mapEntry.getKey(), mapEntry.getValue())); gpContexts.add(new Context(context.getKey(), context.getValue()));
} }
} }
return gpContexts; return gpContexts;
@ -593,11 +573,11 @@ public Tristate getPermissionValue(GDPermissionHolder holder, String permission)
public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, MutableContextSet contexts) { public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, MutableContextSet contexts) {
return getPermissionValue(claim, holder, permission, this.getGDContexts(contexts)); return this.getPermissionValue(claim, holder, permission, this.getGDContexts(contexts));
} }
public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, Set<Context> contexts) { public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, Set<Context> contexts) {
return getPermissionValue(claim, holder, permission, contexts, true); return this.getPermissionValue(holder, permission, contexts);
} }
public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, Set<Context> contexts, boolean checkTransient) { public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, Set<Context> contexts, boolean checkTransient) {
@ -706,58 +686,52 @@ public Tristate getPermissionValueWithRequiredContexts(GDClaim claim, GDPermissi
} }
public Tristate getPermissionValue(GDPermissionHolder holder, String permission, Set<Context> contexts) { public Tristate getPermissionValue(GDPermissionHolder holder, String permission, Set<Context> contexts) {
ImmutableContextSet contextSet = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet contextSet = this.getLPContexts(contexts).immutableCopy();
return this.getPermissionValue(holder, permission, contextSet); return this.getPermissionValue(holder, permission, contextSet);
} }
public Tristate getPermissionValue(GDPermissionHolder holder, String permission, ContextSet contexts) { public Tristate getPermissionValue(GDPermissionHolder holder, String permission, ContextSet contexts) {
Contexts context = Contexts.global().setContexts(contexts);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return Tristate.UNDEFINED; return Tristate.UNDEFINED;
} }
PermissionData cachedData = permissionHolder.getCachedData().getPermissionData(context); final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).context(contexts).build();
return getGDTristate(cachedData.getPermissionValue(permission)); CachedPermissionData cachedData = permissionHolder.getCachedData().getPermissionData(query);
return getGDTristate(cachedData.checkPermission(permission));
} }
// To set options, pass "meta.option". // To set options, pass "meta.option".
@Override @Override
public String getOptionValue(GDPermissionHolder holder, Option option, Set<Context> contexts) { public String getOptionValue(GDPermissionHolder holder, Option option, Set<Context> contexts) {
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
Contexts context = Contexts.global().setContexts(set);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return null; return null;
} }
MetaData metaData = permissionHolder.getCachedData().getMetaData(context); final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).context(set).build();
return metaData.getMeta().get(option.getPermission()); CachedMetaData metaData = permissionHolder.getCachedData().getMetaData(query);
return metaData.getMetaValue(option.getPermission());
} }
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) { public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
DataMutateResult result = null; DataMutateResult result = null;
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
Contexts context = Contexts.global().setContexts(set);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return new GDPermissionResult(ResultTypes.FAILURE); return new GDPermissionResult(ResultTypes.FAILURE);
} }
MetaData metaData = permissionHolder.getCachedData().getMetaData(context);
for (Map.Entry<String, String> mapEntry : metaData.getMeta().entrySet()) {
if (mapEntry.getKey().equalsIgnoreCase(permission)) {
// Always unset existing meta first // Always unset existing meta first
final Node node = this.luckPermsApi.getNodeFactory().makeMetaNode(permission, mapEntry.getValue()).withExtraContext(set).build(); final Node currentNode = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).context(set).build();
result = permissionHolder.unsetPermission(node); result = permissionHolder.data().remove(currentNode);
}
}
final Node node = this.luckPermsApi.getNodeFactory().makeMetaNode(permission, value).withExtraContext(set).build(); final Node node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).value(value).context(set).build();
if (!value.equalsIgnoreCase("undefined")) { if (!value.equalsIgnoreCase("undefined")) {
result = permissionHolder.setPermission(node); result = permissionHolder.data().add(node);
} }
if (result != null && result.wasSuccess()) { if (result != null && result.wasSuccessful()) {
this.savePermissionHolder(permissionHolder); this.savePermissionHolder(permissionHolder);
return new GDPermissionResult(ResultTypes.SUCCESS); return new GDPermissionResult(ResultTypes.SUCCESS);
} }
@ -774,25 +748,25 @@ public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag,
public boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) { public boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
DataMutateResult result = null; DataMutateResult result = null;
ImmutableContextSet set = ImmutableContextSet.fromEntries(contexts); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final Node node = this.luckPermsApi.getNodeFactory().newBuilder(permission).setValue(value.asBoolean()).withExtraContext(set).build(); final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return false; return false;
} }
if (value == Tristate.UNDEFINED) { if (value == Tristate.UNDEFINED) {
result = permissionHolder.unsetPermission(node); result = permissionHolder.data().remove(node);
} else { } else {
result = permissionHolder.setPermission(node); result = permissionHolder.data().add(node);
} }
if (result.wasSuccess()) { if (result.wasSuccessful()) {
if (permissionHolder instanceof Group) { if (permissionHolder instanceof Group) {
final Group group = (Group) permissionHolder; final Group group = (Group) permissionHolder;
group.refreshCachedData(); group.getCachedData().invalidate();
for (User user :this.luckPermsApi.getUserManager().getLoadedUsers()) { for (User user :this.luckPermsApi.getUserManager().getLoadedUsers()) {
user.refreshCachedData(); user.getCachedData().invalidate();
} }
// If a group is changed, we invalidate all cache // If a group is changed, we invalidate all cache
PermissionHolderCache.getInstance().invalidateAllPermissionCache(); PermissionHolderCache.getInstance().invalidateAllPermissionCache();
@ -803,29 +777,29 @@ public boolean setPermissionValue(GDPermissionHolder holder, String permission,
this.savePermissionHolder(permissionHolder); this.savePermissionHolder(permissionHolder);
} }
return result.wasSuccess(); return result.wasSuccessful();
} }
public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) { public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
MutableContextSet contextSet = MutableContextSet.fromEntries(contexts); MutableContextSet contextSet = this.getLPContexts(contexts);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return; return;
} }
final Node node = this.luckPermsApi.getNodeFactory().makeMetaNode(permission, value).withExtraContext(contextSet).build(); final Node node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).value(value).context(contextSet).build();
permissionHolder.setTransientPermission(node); permissionHolder.transientData().add(node);
} }
public void setTransientPermission(GDPermissionHolder holder, String permission, Boolean value, Set<Context> contexts) { public void setTransientPermission(GDPermissionHolder holder, String permission, Boolean value, Set<Context> contexts) {
MutableContextSet contextSet = MutableContextSet.fromEntries(contexts); MutableContextSet contextSet = this.getLPContexts(contexts);
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return; return;
} }
final Node node = this.luckPermsApi.getNodeFactory().newBuilder(permission).setValue(value).withExtraContext(contextSet).build(); final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value).context(contextSet).build();
permissionHolder.setTransientPermission(node); permissionHolder.transientData().add(node);
} }
public void savePermissionHolder(PermissionHolder holder) { public void savePermissionHolder(PermissionHolder holder) {
@ -841,25 +815,46 @@ public void refreshCachedData(GDPermissionHolder holder) {
if (permissionHolder == null) { if (permissionHolder == null) {
return; return;
} }
permissionHolder.refreshCachedData(); permissionHolder.getCachedData().invalidate();
} }
public Set<Context> getGDContexts(ContextSet contextSet) { public Set<Context> getGDContexts(ContextSet contexts) {
final Set<Context> gdContexts = new HashSet<>(); final Set<Context> gdContexts = new HashSet<>();
contextSet.forEach(entry -> { contexts.forEach(entry -> {
gdContexts.add(new Context(entry.getKey(), entry.getValue())); gdContexts.add(new Context(entry.getKey(), entry.getValue()));
}); });
return gdContexts; return gdContexts;
} }
public Tristate getGDTristate(me.lucko.luckperms.api.Tristate state) { public MutableContextSet getLPContexts(Set<Context> contexts) {
if (state == me.lucko.luckperms.api.Tristate.TRUE) { MutableContextSet lpContexts = MutableContextSet.create();
contexts.forEach(entry -> {
lpContexts.add(entry.getKey(), entry.getValue());
});
return lpContexts;
}
public Tristate getGDTristate(net.luckperms.api.util.Tristate state) {
if (state == net.luckperms.api.util.Tristate.TRUE) {
return Tristate.TRUE; return Tristate.TRUE;
} }
if (state == me.lucko.luckperms.api.Tristate.FALSE) { if (state == net.luckperms.api.util.Tristate.FALSE) {
return Tristate.FALSE; return Tristate.FALSE;
} }
return Tristate.UNDEFINED; return Tristate.UNDEFINED;
} }
private static class DefaultDataQueryOrderFunction implements DataQueryOrderFunction {
@Override
public Comparator<DataType> getOrderComparator(Identifier identifier) {
if (identifier.getType() == Identifier.GROUP_TYPE && identifier.getName().equalsIgnoreCase("default")) {
return DataQueryOrder.TRANSIENT_LAST;
}
return DataQueryOrder.TRANSIENT_FIRST;
}
}
} }

View File

@ -376,7 +376,8 @@ public void setDefaultGlobalPermissions() {
this.setDefaultFlags(contexts, globalDefaultFlags); this.setDefaultFlags(contexts, globalDefaultFlags);
final Map<String, String> globalDefaultOptions = activeConfig.getConfig().permissionCategory.getUserOptionDefaults(); final Map<String, String> globalDefaultOptions = activeConfig.getConfig().permissionCategory.getUserOptionDefaults();
this.setDefaultOptions(ClaimContexts.GLOBAL_DEFAULT_CONTEXT.getName(), contexts, new HashMap<>(globalDefaultOptions)); this.setDefaultOptions(ClaimContexts.GLOBAL_DEFAULT_CONTEXT.getName(), contexts, new HashMap<>(globalDefaultOptions));
GriefDefenderPlugin.getInstance().getPermissionProvider().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, "griefdefender", false, new HashSet<>()); // TODO - does not work with LP v5
//GriefDefenderPlugin.getInstance().getPermissionProvider().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, "griefdefender", false, new HashSet<>());
activeConfig.save(); activeConfig.save();
} }

View File

@ -1,9 +1,9 @@
package com.griefdefender.util; package com.griefdefender.util;
import com.griefdefender.api.Tristate; import com.griefdefender.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet;
import net.kyori.text.Component; import net.kyori.text.Component;
import net.kyori.text.serializer.gson.GsonComponentSerializer; import net.kyori.text.serializer.gson.GsonComponentSerializer;
import net.luckperms.api.context.ContextSet;
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 org.spongepowered.api.text.Text; import org.spongepowered.api.text.Text;
@ -12,7 +12,6 @@
import org.spongepowered.api.text.serializer.TextSerializers; import org.spongepowered.api.text.serializer.TextSerializers;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
public class SpongeUtil { public class SpongeUtil {
@ -23,7 +22,7 @@ public static org.spongepowered.api.service.context.Context getSpongeContext(com
public static org.spongepowered.api.service.context.Context getSpongeContext(ContextSet context) { public static org.spongepowered.api.service.context.Context getSpongeContext(ContextSet context) {
Context spongeContext = null; Context spongeContext = null;
for (Map.Entry<String, String> mapEntry : context) { for (net.luckperms.api.context.Context mapEntry : context) {
spongeContext = new Context(mapEntry.getKey(), mapEntry.getValue()); spongeContext = new Context(mapEntry.getKey(), mapEntry.getValue());
break; break;
} }
@ -55,7 +54,7 @@ public static Set<Context> getSpongeContexts(Set<com.griefdefender.api.permissio
public static Set<Context> getSpongeContexts(ContextSet contexts) { public static Set<Context> getSpongeContexts(ContextSet contexts) {
final Set<Context> spongeContexts = new HashSet<>(); final Set<Context> spongeContexts = new HashSet<>();
for (Map.Entry<String, String> mapEntry : contexts) { for (net.luckperms.api.context.Context mapEntry : contexts) {
spongeContexts.add(new Context(mapEntry.getKey(), mapEntry.getValue())); spongeContexts.add(new Context(mapEntry.getKey(), mapEntry.getValue()));
} }

View File

@ -109,13 +109,6 @@
"relocate": "okio:okio", "relocate": "okio:okio",
"url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar" "url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
}, },
{
"name": "me.lucko.luckperms:luckperms-api:4.4",
"sha1": "e0356ab83e426ff5e51b3c596ffac8750905af64",
"path": "me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar",
"relocate": "me.lucko:lucko",
"url": "https://repo1.maven.org/maven2/me/lucko/luckperms/luckperms-api/4.4/luckperms-api-4.4.jar"
},
{ {
"name": "com.github.ben-manes.caffeine:caffeine:2.7.0", "name": "com.github.ben-manes.caffeine:caffeine:2.7.0",
"sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a", "sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a",