mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-11-28 05:35:26 +01:00
WIP: Sponge service refactor
This commit is contained in:
parent
02ff4a4acb
commit
2b8bbc434f
@ -34,7 +34,6 @@ import me.lucko.luckperms.common.calculators.processors.WildcardProcessor;
|
|||||||
import me.lucko.luckperms.common.core.model.User;
|
import me.lucko.luckperms.common.core.model.User;
|
||||||
import me.lucko.luckperms.sponge.calculators.DefaultsProcessor;
|
import me.lucko.luckperms.sponge.calculators.DefaultsProcessor;
|
||||||
import me.lucko.luckperms.sponge.calculators.SpongeWildcardProcessor;
|
import me.lucko.luckperms.sponge.calculators.SpongeWildcardProcessor;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class SpongeCalculatorFactory extends AbstractCalculatorFactory {
|
public class SpongeCalculatorFactory extends AbstractCalculatorFactory {
|
||||||
@ -51,7 +50,7 @@ public class SpongeCalculatorFactory extends AbstractCalculatorFactory {
|
|||||||
if (plugin.getConfiguration().isApplyingRegex()) {
|
if (plugin.getConfiguration().isApplyingRegex()) {
|
||||||
processors.add(new RegexProcessor());
|
processors.add(new RegexProcessor());
|
||||||
}
|
}
|
||||||
processors.add(new DefaultsProcessor(plugin.getService(), LuckPermsService.convertContexts(contexts.getContexts())));
|
processors.add(new DefaultsProcessor(plugin.getService(), contexts.getContexts()));
|
||||||
|
|
||||||
return registerCalculator(new PermissionCalculator(plugin, user.getName(), processors.build()));
|
return registerCalculator(new PermissionCalculator(plugin, user.getName(), processors.build()));
|
||||||
}
|
}
|
||||||
|
@ -23,34 +23,31 @@
|
|||||||
package me.lucko.luckperms.sponge.calculators;
|
package me.lucko.luckperms.sponge.calculators;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
import org.spongepowered.api.service.context.Context;
|
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static me.lucko.luckperms.sponge.service.LuckPermsService.convertTristate;
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class DefaultsProcessor implements PermissionProcessor {
|
public class DefaultsProcessor implements PermissionProcessor {
|
||||||
private final LuckPermsService service;
|
private final LuckPermsService service;
|
||||||
private final Set<Context> contexts;
|
private final ContextSet contexts;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public me.lucko.luckperms.api.Tristate hasPermission(String permission) {
|
public Tristate hasPermission(String permission) {
|
||||||
Tristate t = service.getUserSubjects().getDefaults().getPermissionValue(contexts, permission);
|
Tristate t = service.getUserSubjects().getDefaultSubject().resolve(service).getPermissionValue(contexts, permission);
|
||||||
if (t != Tristate.UNDEFINED) {
|
if (t != Tristate.UNDEFINED) {
|
||||||
return convertTristate(t);
|
return 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(t);
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return me.lucko.luckperms.api.Tristate.UNDEFINED;
|
return Tristate.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,7 +25,7 @@ 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.api.context.MutableContextSet;
|
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.base.Util;
|
||||||
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;
|
||||||
|
|
||||||
@ -38,11 +38,11 @@ public class SpongeCalculatorLink extends ContextCalculator<Subject> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MutableContextSet giveApplicableContext(Subject subject, MutableContextSet accumulator) {
|
public MutableContextSet giveApplicableContext(Subject subject, MutableContextSet accumulator) {
|
||||||
Set<Context> contexts = LuckPermsService.convertContexts(accumulator);
|
Set<Context> contexts = Util.convertContexts(accumulator);
|
||||||
calculator.accumulateContexts(subject, contexts);
|
calculator.accumulateContexts(subject, contexts);
|
||||||
|
|
||||||
accumulator.clear();
|
accumulator.clear();
|
||||||
accumulator.addAll(LuckPermsService.convertContexts(contexts));
|
accumulator.addAll(Util.convertContexts(contexts));
|
||||||
return accumulator;
|
return accumulator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ import com.google.common.collect.ImmutableMap;
|
|||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.common.core.model.Group;
|
import me.lucko.luckperms.common.core.model.Group;
|
||||||
import me.lucko.luckperms.common.managers.GroupManager;
|
import me.lucko.luckperms.common.managers.GroupManager;
|
||||||
@ -38,18 +39,16 @@ import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
|||||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
import me.lucko.luckperms.sponge.model.SpongeGroup;
|
import me.lucko.luckperms.sponge.model.SpongeGroup;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubjectCollection;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import me.lucko.luckperms.sponge.timings.LPTiming;
|
import me.lucko.luckperms.sponge.timings.LPTiming;
|
||||||
import org.spongepowered.api.service.context.Context;
|
|
||||||
import org.spongepowered.api.service.permission.PermissionService;
|
import org.spongepowered.api.service.permission.PermissionService;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
|
||||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
|
||||||
import org.spongepowered.api.service.permission.SubjectData;
|
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class SpongeGroupManager implements GroupManager, SubjectCollection {
|
public class SpongeGroupManager implements GroupManager, LPSubjectCollection {
|
||||||
private final LPSpongePlugin plugin;
|
private final LPSpongePlugin plugin;
|
||||||
|
|
||||||
private final LoadingCache<String, SpongeGroup> objects = CacheBuilder.newBuilder()
|
private final LoadingCache<String, SpongeGroup> objects = CacheBuilder.newBuilder()
|
||||||
@ -120,7 +119,12 @@ public class SpongeGroupManager implements GroupManager, SubjectCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject get(@NonNull String id) {
|
public LuckPermsService getService() {
|
||||||
|
return plugin.getService();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LPSubject get(@NonNull String id) {
|
||||||
// Special Sponge method. This call will actually load the group from the datastore if not already present.
|
// Special Sponge method. This call will actually load the group from the datastore if not already present.
|
||||||
|
|
||||||
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_COLLECTION_GET)) {
|
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_COLLECTION_GET)) {
|
||||||
@ -159,26 +163,20 @@ public class SpongeGroupManager implements GroupManager, SubjectCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Subject> getAllSubjects() {
|
public Collection<LPSubject> getSubjects() {
|
||||||
return objects.asMap().values().stream().map(SpongeGroup::getSpongeData).collect(ImmutableCollectors.toImmutableList());
|
return objects.asMap().values().stream().map(SpongeGroup::getSpongeData).collect(ImmutableCollectors.toImmutableList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Subject, Boolean> getAllWithPermission(@NonNull String id) {
|
public Map<LPSubject, Boolean> getWithPermission(@NonNull ContextSet contexts, @NonNull String node) {
|
||||||
return getAllWithPermission(SubjectData.GLOBAL_CONTEXT, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
|
||||||
ContextSet cs = LuckPermsService.convertContexts(contexts);
|
|
||||||
return objects.asMap().values().stream()
|
return objects.asMap().values().stream()
|
||||||
.map(SpongeGroup::getSpongeData)
|
.map(SpongeGroup::getSpongeData)
|
||||||
.filter(sub -> sub.getPermissionValue(cs, node) != Tristate.UNDEFINED)
|
.filter(sub -> sub.getPermissionValue(contexts, node) != Tristate.UNDEFINED)
|
||||||
.collect(ImmutableCollectors.toImmutableMap(sub -> sub, sub -> sub.getPermissionValue(cs, node).asBoolean()));
|
.collect(ImmutableCollectors.toImmutableMap(sub -> sub, sub -> sub.getPermissionValue(contexts, node).asBoolean()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getDefaults() {
|
public SubjectReference getDefaultSubject() {
|
||||||
return plugin.getService().getDefaultSubjects().get(getIdentifier());
|
return SubjectReference.of("defaults", getIdentifier());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import com.google.common.collect.ImmutableMap;
|
|||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.common.commands.utils.Util;
|
import me.lucko.luckperms.common.commands.utils.Util;
|
||||||
import me.lucko.luckperms.common.core.UserIdentifier;
|
import me.lucko.luckperms.common.core.UserIdentifier;
|
||||||
@ -40,19 +41,18 @@ import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
|||||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
import me.lucko.luckperms.sponge.model.SpongeUser;
|
import me.lucko.luckperms.sponge.model.SpongeUser;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubjectCollection;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import me.lucko.luckperms.sponge.timings.LPTiming;
|
import me.lucko.luckperms.sponge.timings.LPTiming;
|
||||||
import org.spongepowered.api.service.context.Context;
|
|
||||||
import org.spongepowered.api.service.permission.PermissionService;
|
import org.spongepowered.api.service.permission.PermissionService;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
|
||||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
|
||||||
import org.spongepowered.api.service.permission.SubjectData;
|
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class SpongeUserManager implements UserManager, SubjectCollection {
|
public class SpongeUserManager implements UserManager, LPSubjectCollection {
|
||||||
private final LPSpongePlugin plugin;
|
private final LPSpongePlugin plugin;
|
||||||
|
|
||||||
private final LoadingCache<UserIdentifier, SpongeUser> objects = CacheBuilder.newBuilder()
|
private final LoadingCache<UserIdentifier, SpongeUser> objects = CacheBuilder.newBuilder()
|
||||||
@ -170,7 +170,12 @@ public class SpongeUserManager implements UserManager, SubjectCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject get(@NonNull String id) {
|
public LuckPermsService getService() {
|
||||||
|
return plugin.getService();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LPSubject get(@NonNull String id) {
|
||||||
// Special Sponge method. This call will actually load the user from the datastore if not already present.
|
// Special Sponge method. This call will actually load the user from the datastore if not already present.
|
||||||
|
|
||||||
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_COLLECTION_GET)) {
|
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_COLLECTION_GET)) {
|
||||||
@ -217,26 +222,20 @@ public class SpongeUserManager implements UserManager, SubjectCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Subject> getAllSubjects() {
|
public Collection<LPSubject> getSubjects() {
|
||||||
return objects.asMap().values().stream().map(SpongeUser::getSpongeData).collect(ImmutableCollectors.toImmutableList());
|
return objects.asMap().values().stream().map(SpongeUser::getSpongeData).collect(ImmutableCollectors.toImmutableList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Subject, Boolean> getAllWithPermission(@NonNull String id) {
|
public Map<LPSubject, Boolean> getWithPermission(@NonNull ContextSet contexts, @NonNull String node) {
|
||||||
return getAllWithPermission(SubjectData.GLOBAL_CONTEXT, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
|
||||||
ContextSet cs = LuckPermsService.convertContexts(contexts);
|
|
||||||
return objects.asMap().values().stream()
|
return objects.asMap().values().stream()
|
||||||
.map(SpongeUser::getSpongeData)
|
.map(SpongeUser::getSpongeData)
|
||||||
.filter(sub -> sub.getPermissionValue(cs, node) != Tristate.UNDEFINED)
|
.filter(sub -> sub.getPermissionValue(contexts, node) != Tristate.UNDEFINED)
|
||||||
.collect(ImmutableCollectors.toImmutableMap(sub -> sub, sub -> sub.getPermissionValue(cs, node).asBoolean()));
|
.collect(ImmutableCollectors.toImmutableMap(sub -> sub, sub -> sub.getPermissionValue(contexts, node).asBoolean()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getDefaults() {
|
public SubjectReference getDefaultSubject() {
|
||||||
return plugin.getService().getDefaultSubjects().get(getIdentifier());
|
return SubjectReference.of("defaults", getIdentifier());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import me.lucko.luckperms.common.core.NodeFactory;
|
|||||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.base.Util;
|
||||||
import org.spongepowered.api.service.context.Context;
|
import org.spongepowered.api.service.context.Context;
|
||||||
import org.spongepowered.api.service.permission.PermissionService;
|
import org.spongepowered.api.service.permission.PermissionService;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
@ -47,7 +47,7 @@ public class MigrationUtils {
|
|||||||
// Migrate permissions
|
// Migrate permissions
|
||||||
Map<Set<Context>, Map<String, Boolean>> perms = subject.getSubjectData().getAllPermissions();
|
Map<Set<Context>, Map<String, Boolean>> perms = subject.getSubjectData().getAllPermissions();
|
||||||
for (Map.Entry<Set<Context>, Map<String, Boolean>> e : perms.entrySet()) {
|
for (Map.Entry<Set<Context>, Map<String, Boolean>> e : perms.entrySet()) {
|
||||||
ContextSet context = LuckPermsService.convertContexts(e.getKey());
|
ContextSet context = Util.convertContexts(e.getKey());
|
||||||
|
|
||||||
ExtractedContexts extractedContexts = ExtractedContexts.generate(context);
|
ExtractedContexts extractedContexts = ExtractedContexts.generate(context);
|
||||||
ContextSet contexts = extractedContexts.getContextSet();
|
ContextSet contexts = extractedContexts.getContextSet();
|
||||||
@ -65,7 +65,7 @@ public class MigrationUtils {
|
|||||||
try {
|
try {
|
||||||
Map<Set<Context>, Map<String, String>> opts = subject.getSubjectData().getAllOptions();
|
Map<Set<Context>, Map<String, String>> opts = subject.getSubjectData().getAllOptions();
|
||||||
for (Map.Entry<Set<Context>, Map<String, String>> e : opts.entrySet()) {
|
for (Map.Entry<Set<Context>, Map<String, String>> e : opts.entrySet()) {
|
||||||
ContextSet context = LuckPermsService.convertContexts(e.getKey());
|
ContextSet context = Util.convertContexts(e.getKey());
|
||||||
|
|
||||||
ExtractedContexts extractedContexts = ExtractedContexts.generate(context);
|
ExtractedContexts extractedContexts = ExtractedContexts.generate(context);
|
||||||
ContextSet contexts = extractedContexts.getContextSet();
|
ContextSet contexts = extractedContexts.getContextSet();
|
||||||
@ -96,7 +96,7 @@ public class MigrationUtils {
|
|||||||
// Migrate parents
|
// Migrate parents
|
||||||
Map<Set<Context>, List<Subject>> parents = subject.getSubjectData().getAllParents();
|
Map<Set<Context>, List<Subject>> parents = subject.getSubjectData().getAllParents();
|
||||||
for (Map.Entry<Set<Context>, List<Subject>> e : parents.entrySet()) {
|
for (Map.Entry<Set<Context>, List<Subject>> e : parents.entrySet()) {
|
||||||
ContextSet context = LuckPermsService.convertContexts(e.getKey());
|
ContextSet context = Util.convertContexts(e.getKey());
|
||||||
|
|
||||||
ExtractedContexts extractedContexts = ExtractedContexts.generate(context);
|
ExtractedContexts extractedContexts = ExtractedContexts.generate(context);
|
||||||
ContextSet contexts = extractedContexts.getContextSet();
|
ContextSet contexts = extractedContexts.getContextSet();
|
||||||
|
@ -23,28 +23,30 @@
|
|||||||
package me.lucko.luckperms.sponge.model;
|
package me.lucko.luckperms.sponge.model;
|
||||||
|
|
||||||
import co.aikar.timings.Timing;
|
import co.aikar.timings.Timing;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
import me.lucko.luckperms.api.LocalizedNode;
|
||||||
import me.lucko.luckperms.api.MetaUtils;
|
import me.lucko.luckperms.api.MetaUtils;
|
||||||
import me.lucko.luckperms.api.Node;
|
import me.lucko.luckperms.api.Node;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.common.core.model.Group;
|
import me.lucko.luckperms.common.core.model.Group;
|
||||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsSubject;
|
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsSubjectData;
|
import me.lucko.luckperms.sponge.service.LuckPermsSubjectData;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.Util;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectCollectionReference;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import me.lucko.luckperms.sponge.timings.LPTiming;
|
import me.lucko.luckperms.sponge.timings.LPTiming;
|
||||||
import org.spongepowered.api.command.CommandSource;
|
import org.spongepowered.api.command.CommandSource;
|
||||||
import org.spongepowered.api.service.permission.NodeTree;
|
import org.spongepowered.api.service.permission.NodeTree;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
import org.spongepowered.api.service.permission.PermissionService;
|
||||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class SpongeGroup extends Group {
|
public class SpongeGroup extends Group {
|
||||||
@ -57,7 +59,7 @@ public class SpongeGroup extends Group {
|
|||||||
this.spongeData = new GroupSubject(plugin, this);
|
this.spongeData = new GroupSubject(plugin, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GroupSubject extends LuckPermsSubject {
|
public static class GroupSubject implements LPSubject {
|
||||||
private final SpongeGroup parent;
|
private final SpongeGroup parent;
|
||||||
private final LPSpongePlugin plugin;
|
private final LPSpongePlugin plugin;
|
||||||
|
|
||||||
@ -79,59 +81,71 @@ public class SpongeGroup extends Group {
|
|||||||
return parent.getObjectName();
|
return parent.getObjectName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getFriendlyIdentifier() {
|
||||||
|
return Optional.of(parent.getFriendlyName());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<CommandSource> getCommandSource() {
|
public Optional<CommandSource> getCommandSource() {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubjectCollection getContainingCollection() {
|
public SubjectCollectionReference getParentCollection() {
|
||||||
return plugin.getService().getGroupSubjects();
|
return plugin.getService().getGroupSubjects().toReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LuckPermsService getService() {
|
||||||
|
return plugin.getService();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tristate getPermissionValue(ContextSet contexts, String permission) {
|
public Tristate getPermissionValue(ContextSet contexts, String permission) {
|
||||||
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_GET_PERMISSION_VALUE)) {
|
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_GET_PERMISSION_VALUE)) {
|
||||||
|
// TODO move this away from NodeTree
|
||||||
Map<String, Boolean> permissions = parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream()
|
Map<String, Boolean> permissions = parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream()
|
||||||
.map(LocalizedNode::getNode)
|
.map(LocalizedNode::getNode)
|
||||||
.collect(Collectors.toMap(Node::getPermission, Node::getValue));
|
.collect(Collectors.toMap(Node::getPermission, Node::getValue));
|
||||||
|
|
||||||
Tristate t = NodeTree.of(permissions).get(permission);
|
Tristate t = Util.convertTristate(NodeTree.of(permissions).get(permission));
|
||||||
if (t != Tristate.UNDEFINED) {
|
if (t != Tristate.UNDEFINED) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = plugin.getService().getGroupSubjects().getDefaults().getPermissionValue(LuckPermsService.convertContexts(contexts), permission);
|
t = plugin.getService().getGroupSubjects().getDefaultSubject().resolve(getService()).getPermissionValue(contexts, permission);
|
||||||
if (t != Tristate.UNDEFINED) {
|
if (t != Tristate.UNDEFINED) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = plugin.getService().getDefaults().getPermissionValue(LuckPermsService.convertContexts(contexts), permission);
|
t = plugin.getService().getDefaults().getPermissionValue(contexts, permission);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChildOf(ContextSet contexts, Subject parent) {
|
public boolean isChildOf(ContextSet contexts, SubjectReference parent) {
|
||||||
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_IS_CHILD_OF)) {
|
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_IS_CHILD_OF)) {
|
||||||
return parent instanceof SpongeGroup && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
|
return parent.getCollection().equals(PermissionService.SUBJECTS_GROUP) && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Subject> getParents(ContextSet contexts) {
|
public Set<SubjectReference> getParents(ContextSet contexts) {
|
||||||
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_GET_PARENTS)) {
|
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_GET_PARENTS)) {
|
||||||
List<Subject> subjects = parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream()
|
Set<SubjectReference> subjects = parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream()
|
||||||
.map(LocalizedNode::getNode)
|
.map(LocalizedNode::getNode)
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.map(Node::getGroupName)
|
.map(Node::getGroupName)
|
||||||
.map(s -> plugin.getService().getGroupSubjects().get(s))
|
.map(s -> plugin.getService().getGroupSubjects().get(s))
|
||||||
.collect(Collectors.toList());
|
.map(LPSubject::toReference)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
subjects.addAll(plugin.getService().getGroupSubjects().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
|
subjects.addAll(plugin.getService().getGroupSubjects().getDefaultSubject().resolve(getService()).getParents(contexts));
|
||||||
subjects.addAll(plugin.getService().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
|
subjects.addAll(plugin.getService().getDefaults().getParents(contexts));
|
||||||
|
|
||||||
return ImmutableList.copyOf(subjects);
|
return ImmutableSet.copyOf(subjects);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,12 +167,12 @@ public class SpongeGroup extends Group {
|
|||||||
return option;
|
return option;
|
||||||
}
|
}
|
||||||
|
|
||||||
option = plugin.getService().getGroupSubjects().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
|
option = plugin.getService().getGroupSubjects().getDefaultSubject().resolve(getService()).getOption(contexts, s);
|
||||||
if (option.isPresent()) {
|
if (option.isPresent()) {
|
||||||
return option;
|
return option;
|
||||||
}
|
}
|
||||||
|
|
||||||
return plugin.getService().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
|
return plugin.getService().getDefaults().getOption(contexts, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,25 +23,26 @@
|
|||||||
package me.lucko.luckperms.sponge.model;
|
package me.lucko.luckperms.sponge.model;
|
||||||
|
|
||||||
import co.aikar.timings.Timing;
|
import co.aikar.timings.Timing;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.api.caching.MetaData;
|
import me.lucko.luckperms.api.caching.MetaData;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.common.core.model.User;
|
import me.lucko.luckperms.common.core.model.User;
|
||||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsSubject;
|
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsSubjectData;
|
import me.lucko.luckperms.sponge.service.LuckPermsSubjectData;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectCollectionReference;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import me.lucko.luckperms.sponge.timings.LPTiming;
|
import me.lucko.luckperms.sponge.timings.LPTiming;
|
||||||
import org.spongepowered.api.Sponge;
|
import org.spongepowered.api.Sponge;
|
||||||
import org.spongepowered.api.command.CommandSource;
|
import org.spongepowered.api.command.CommandSource;
|
||||||
import org.spongepowered.api.entity.living.player.Player;
|
import org.spongepowered.api.entity.living.player.Player;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
import org.spongepowered.api.service.permission.PermissionService;
|
||||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class SpongeUser extends User {
|
public class SpongeUser extends User {
|
||||||
@ -59,7 +60,7 @@ public class SpongeUser extends User {
|
|||||||
this.spongeData = new UserSubject(plugin, this);
|
this.spongeData = new UserSubject(plugin, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class UserSubject extends LuckPermsSubject {
|
public static class UserSubject implements LPSubject {
|
||||||
private final SpongeUser parent;
|
private final SpongeUser parent;
|
||||||
private final LPSpongePlugin plugin;
|
private final LPSpongePlugin plugin;
|
||||||
|
|
||||||
@ -98,8 +99,13 @@ public class SpongeUser extends User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubjectCollection getContainingCollection() {
|
public SubjectCollectionReference getParentCollection() {
|
||||||
return plugin.getService().getUserSubjects();
|
return plugin.getService().getUserSubjects().toReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LuckPermsService getService() {
|
||||||
|
return plugin.getService();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -109,21 +115,21 @@ public class SpongeUser extends User {
|
|||||||
return Tristate.UNDEFINED;
|
return Tristate.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return LuckPermsService.convertTristate(parent.getUserData().getPermissionData(plugin.getService().calculateContexts(contexts)).getPermissionValue(permission));
|
return parent.getUserData().getPermissionData(plugin.getService().calculateContexts(contexts)).getPermissionValue(permission);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChildOf(ContextSet contexts, Subject parent) {
|
public boolean isChildOf(ContextSet contexts, SubjectReference parent) {
|
||||||
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_IS_CHILD_OF)) {
|
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_IS_CHILD_OF)) {
|
||||||
return parent instanceof SpongeGroup && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
|
return parent.getCollection().equals(PermissionService.SUBJECTS_GROUP) && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Subject> getParents(ContextSet contexts) {
|
public Set<SubjectReference> getParents(ContextSet contexts) {
|
||||||
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_GET_PARENTS)) {
|
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_GET_PARENTS)) {
|
||||||
ImmutableList.Builder<Subject> subjects = ImmutableList.builder();
|
ImmutableSet.Builder<SubjectReference> subjects = ImmutableSet.builder();
|
||||||
|
|
||||||
if (hasData()) {
|
if (hasData()) {
|
||||||
for (String perm : parent.getUserData().getPermissionData(plugin.getService().calculateContexts(contexts)).getImmutableBacking().keySet()) {
|
for (String perm : parent.getUserData().getPermissionData(plugin.getService().calculateContexts(contexts)).getImmutableBacking().keySet()) {
|
||||||
@ -133,13 +139,13 @@ public class SpongeUser extends User {
|
|||||||
|
|
||||||
String groupName = perm.substring("group.".length());
|
String groupName = perm.substring("group.".length());
|
||||||
if (plugin.getGroupManager().isLoaded(groupName)) {
|
if (plugin.getGroupManager().isLoaded(groupName)) {
|
||||||
subjects.add(plugin.getService().getGroupSubjects().get(groupName));
|
subjects.add(plugin.getService().getGroupSubjects().get(groupName).toReference());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
subjects.addAll(plugin.getService().getUserSubjects().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
|
subjects.addAll(plugin.getService().getUserSubjects().getDefaultSubject().resolve(getService()).getParents(contexts));
|
||||||
subjects.addAll(plugin.getService().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
|
subjects.addAll(plugin.getService().getDefaults().getParents(contexts));
|
||||||
|
|
||||||
return subjects.build();
|
return subjects.build();
|
||||||
}
|
}
|
||||||
@ -167,12 +173,12 @@ public class SpongeUser extends User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<String> v = plugin.getService().getUserSubjects().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
|
Optional<String> v = plugin.getService().getUserSubjects().getDefaultSubject().resolve(getService()).getOption(contexts, s);
|
||||||
if (v.isPresent()) {
|
if (v.isPresent()) {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return plugin.getService().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
|
return plugin.getService().getDefaults().getOption(contexts, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,5 +190,4 @@ public class SpongeUser extends User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,31 +28,40 @@ import com.google.common.cache.CacheLoader;
|
|||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.MapMaker;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import me.lucko.luckperms.api.Contexts;
|
import me.lucko.luckperms.api.Contexts;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
|
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
import me.lucko.luckperms.sponge.contexts.SpongeCalculatorLink;
|
import me.lucko.luckperms.sponge.contexts.SpongeCalculatorLink;
|
||||||
import me.lucko.luckperms.sponge.managers.SpongeGroupManager;
|
import me.lucko.luckperms.sponge.managers.SpongeGroupManager;
|
||||||
import me.lucko.luckperms.sponge.managers.SpongeUserManager;
|
import me.lucko.luckperms.sponge.managers.SpongeUserManager;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubjectCollection;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubjectData;
|
||||||
|
import me.lucko.luckperms.sponge.service.calculated.OptionLookup;
|
||||||
|
import me.lucko.luckperms.sponge.service.calculated.PermissionLookup;
|
||||||
import me.lucko.luckperms.sponge.service.persisted.PersistedCollection;
|
import me.lucko.luckperms.sponge.service.persisted.PersistedCollection;
|
||||||
import me.lucko.luckperms.sponge.service.persisted.SubjectStorage;
|
import me.lucko.luckperms.sponge.service.persisted.SubjectStorage;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import me.lucko.luckperms.sponge.service.simple.SimpleCollection;
|
import me.lucko.luckperms.sponge.service.simple.SimpleCollection;
|
||||||
import me.lucko.luckperms.sponge.timings.LPTiming;
|
import me.lucko.luckperms.sponge.timings.LPTiming;
|
||||||
import org.spongepowered.api.plugin.PluginContainer;
|
import org.spongepowered.api.plugin.PluginContainer;
|
||||||
import org.spongepowered.api.service.context.Context;
|
import org.spongepowered.api.service.context.Context;
|
||||||
import org.spongepowered.api.service.context.ContextCalculator;
|
import org.spongepowered.api.service.context.ContextCalculator;
|
||||||
import org.spongepowered.api.service.permission.*;
|
import org.spongepowered.api.service.permission.PermissionDescription;
|
||||||
|
import org.spongepowered.api.service.permission.PermissionService;
|
||||||
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||||
import org.spongepowered.api.text.Text;
|
import org.spongepowered.api.text.Text;
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The LuckPerms implementation of the Sponge Permission Service
|
* The LuckPerms implementation of the Sponge Permission Service
|
||||||
@ -70,16 +79,20 @@ public class LuckPermsService implements PermissionService {
|
|||||||
private final PersistedCollection defaultSubjects;
|
private final PersistedCollection defaultSubjects;
|
||||||
private final Set<PermissionDescription> descriptionSet;
|
private final Set<PermissionDescription> descriptionSet;
|
||||||
|
|
||||||
|
private final Set<LoadingCache<PermissionLookup, Tristate>> localPermissionCaches;
|
||||||
|
private final Set<LoadingCache<Set<Context>, List<SubjectReference>>> localParentCaches;
|
||||||
|
private final Set<LoadingCache<OptionLookup, Optional<String>>> localOptionCaches;
|
||||||
|
|
||||||
@Getter(value = AccessLevel.NONE)
|
@Getter(value = AccessLevel.NONE)
|
||||||
private final LoadingCache<String, SubjectCollection> collections = CacheBuilder.newBuilder()
|
private final LoadingCache<String, LPSubjectCollection> collections = CacheBuilder.newBuilder()
|
||||||
.build(new CacheLoader<String, SubjectCollection>() {
|
.build(new CacheLoader<String, LPSubjectCollection>() {
|
||||||
@Override
|
@Override
|
||||||
public SubjectCollection load(String s) {
|
public LPSubjectCollection load(String s) {
|
||||||
return new SimpleCollection(LuckPermsService.this, s);
|
return new SimpleCollection(LuckPermsService.this, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<SubjectCollection> reload(String s, SubjectCollection collection) {
|
public ListenableFuture<LPSubjectCollection> reload(String s, LPSubjectCollection collection) {
|
||||||
return Futures.immediateFuture(collection); // Never needs to be refreshed.
|
return Futures.immediateFuture(collection); // Never needs to be refreshed.
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -87,6 +100,10 @@ public class LuckPermsService implements PermissionService {
|
|||||||
public LuckPermsService(LPSpongePlugin plugin) {
|
public LuckPermsService(LPSpongePlugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
localPermissionCaches = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap());
|
||||||
|
localParentCaches = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap());
|
||||||
|
localOptionCaches = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap());
|
||||||
|
|
||||||
storage = new SubjectStorage(new File(plugin.getDataFolder(), "local"));
|
storage = new SubjectStorage(new File(plugin.getDataFolder(), "local"));
|
||||||
|
|
||||||
userSubjects = plugin.getUserManager();
|
userSubjects = plugin.getUserManager();
|
||||||
@ -105,25 +122,30 @@ public class LuckPermsService implements PermissionService {
|
|||||||
descriptionSet = ConcurrentHashMap.newKeySet();
|
descriptionSet = ConcurrentHashMap.newKeySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubjectData getDefaultData() {
|
public LPSubjectData getDefaultData() {
|
||||||
return getDefaults().getSubjectData();
|
return getDefaults().getSubjectData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getDefaults() {
|
public LPSubject getDefaults() {
|
||||||
return getDefaultSubjects().get("default");
|
return getDefaultSubjects().get("default");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubjectCollection getSubjects(String s) {
|
public LPSubjectCollection getSubjects(String s) {
|
||||||
try (Timing ignored = plugin.getTimings().time(LPTiming.GET_SUBJECTS)) {
|
try (Timing ignored = plugin.getTimings().time(LPTiming.GET_SUBJECTS)) {
|
||||||
return collections.getUnchecked(s.toLowerCase());
|
return collections.getUnchecked(s.toLowerCase());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, LPSubjectCollection> getCollections() {
|
||||||
|
return ImmutableMap.copyOf(collections.asMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public Map<String, SubjectCollection> getKnownSubjects() {
|
public Map<String, SubjectCollection> getKnownSubjects() {
|
||||||
return ImmutableMap.copyOf(collections.asMap());
|
return getCollections().entrySet().stream().collect(ImmutableCollectors.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -169,36 +191,6 @@ public class LuckPermsService implements PermissionService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ContextSet convertContexts(Set<Context> contexts) {
|
|
||||||
return ContextSet.fromEntries(contexts.stream().map(c -> Maps.immutableEntry(c.getKey(), c.getValue())).collect(Collectors.toSet()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Set<Context> convertContexts(ContextSet contexts) {
|
|
||||||
return contexts.toSet().stream().map(e -> new Context(e.getKey(), e.getValue())).collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Tristate convertTristate(me.lucko.luckperms.api.Tristate tristate) {
|
|
||||||
switch (tristate) {
|
|
||||||
case TRUE:
|
|
||||||
return Tristate.TRUE;
|
|
||||||
case FALSE:
|
|
||||||
return Tristate.FALSE;
|
|
||||||
default:
|
|
||||||
return Tristate.UNDEFINED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static me.lucko.luckperms.api.Tristate convertTristate(Tristate tristate) {
|
|
||||||
switch (tristate) {
|
|
||||||
case TRUE:
|
|
||||||
return me.lucko.luckperms.api.Tristate.TRUE;
|
|
||||||
case FALSE:
|
|
||||||
return me.lucko.luckperms.api.Tristate.FALSE;
|
|
||||||
default:
|
|
||||||
return me.lucko.luckperms.api.Tristate.UNDEFINED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
@ToString
|
@ToString
|
||||||
@ -241,10 +233,10 @@ public class LuckPermsService implements PermissionService {
|
|||||||
service.getDescriptionSet().add(d);
|
service.getDescriptionSet().add(d);
|
||||||
|
|
||||||
// Set role-templates
|
// Set role-templates
|
||||||
SubjectCollection subjects = service.getSubjects(PermissionService.SUBJECTS_ROLE_TEMPLATE);
|
LPSubjectCollection subjects = service.getSubjects(PermissionService.SUBJECTS_ROLE_TEMPLATE);
|
||||||
for (Map.Entry<String, Tristate> assignment : roles.entrySet()) {
|
for (Map.Entry<String, Tristate> assignment : roles.entrySet()) {
|
||||||
Subject subject = subjects.get(assignment.getKey());
|
LPSubject subject = subjects.get(assignment.getKey());
|
||||||
subject.getTransientSubjectData().setPermission(SubjectData.GLOBAL_CONTEXT, id, assignment.getValue());
|
subject.getTransientSubjectData().setPermission(ContextSet.empty(), id, assignment.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
service.getPlugin().getPermissionCache().offer(id);
|
service.getPlugin().getPermissionCache().offer(id);
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package me.lucko.luckperms.sponge.service;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
|
||||||
import org.spongepowered.api.service.context.Context;
|
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public abstract class LuckPermsSubject implements Subject {
|
|
||||||
|
|
||||||
public abstract Tristate getPermissionValue(ContextSet contexts, String permission);
|
|
||||||
public abstract boolean isChildOf(ContextSet contexts, Subject parent);
|
|
||||||
public abstract List<Subject> getParents(ContextSet contexts);
|
|
||||||
public abstract Optional<String> getOption(ContextSet contexts, String s);
|
|
||||||
public abstract ContextSet getActiveContextSet();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String permission) {
|
|
||||||
return getPermissionValue(LuckPermsService.convertContexts(contexts), permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public boolean hasPermission(@NonNull Set<Context> contexts, @NonNull String permission) {
|
|
||||||
return getPermissionValue(LuckPermsService.convertContexts(contexts), permission).asBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public boolean hasPermission(@NonNull String permission) {
|
|
||||||
return getPermissionValue(getActiveContextSet(), permission).asBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject parent) {
|
|
||||||
return isChildOf(LuckPermsService.convertContexts(contexts), parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public boolean isChildOf(@NonNull Subject parent) {
|
|
||||||
return isChildOf(getActiveContextSet(), parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public List<Subject> getParents(@NonNull Set<Context> contexts) {
|
|
||||||
return getParents(LuckPermsService.convertContexts(contexts));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public List<Subject> getParents() {
|
|
||||||
return getParents(getActiveContextSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public Optional<String> getOption(@NonNull Set<Context> contexts, @NonNull String s) {
|
|
||||||
return getOption(LuckPermsService.convertContexts(contexts), s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public Optional<String> getOption(@NonNull String key) {
|
|
||||||
return getOption(getActiveContextSet(), key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public Set<Context> getActiveContexts() {
|
|
||||||
return ImmutableSet.copyOf(LuckPermsService.convertContexts(getActiveContextSet()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -23,14 +23,15 @@
|
|||||||
package me.lucko.luckperms.sponge.service;
|
package me.lucko.luckperms.sponge.service;
|
||||||
|
|
||||||
import co.aikar.timings.Timing;
|
import co.aikar.timings.Timing;
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import me.lucko.luckperms.api.Node;
|
import me.lucko.luckperms.api.Node;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
|
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||||
import me.lucko.luckperms.common.core.NodeBuilder;
|
import me.lucko.luckperms.common.core.NodeBuilder;
|
||||||
import me.lucko.luckperms.common.core.NodeFactory;
|
import me.lucko.luckperms.common.core.NodeFactory;
|
||||||
import me.lucko.luckperms.common.core.model.Group;
|
import me.lucko.luckperms.common.core.model.Group;
|
||||||
@ -39,18 +40,19 @@ import me.lucko.luckperms.common.core.model.User;
|
|||||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||||
import me.lucko.luckperms.sponge.model.SpongeGroup;
|
import me.lucko.luckperms.sponge.model.SpongeGroup;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubjectData;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import me.lucko.luckperms.sponge.timings.LPTiming;
|
import me.lucko.luckperms.sponge.timings.LPTiming;
|
||||||
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.PermissionService;
|
||||||
import org.spongepowered.api.service.permission.SubjectData;
|
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@SuppressWarnings({"OptionalGetWithoutIsPresent", "unused"})
|
@SuppressWarnings({"OptionalGetWithoutIsPresent", "unused"})
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class LuckPermsSubjectData implements SubjectData {
|
public class LuckPermsSubjectData implements LPSubjectData {
|
||||||
private final boolean enduring;
|
private final boolean enduring;
|
||||||
private final LuckPermsService service;
|
private final LuckPermsService service;
|
||||||
|
|
||||||
@ -69,12 +71,17 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Set<Context>, Map<String, Boolean>> getAllPermissions() {
|
public LPSubject getParentSubject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<ContextSet, Map<String, Boolean>> getPermissions() {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_PERMISSIONS)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_PERMISSIONS)) {
|
||||||
Map<Set<Context>, Map<String, Boolean>> perms = new HashMap<>();
|
Map<ContextSet, Map<String, Boolean>> perms = new HashMap<>();
|
||||||
|
|
||||||
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
||||||
Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
|
MutableContextSet contexts = MutableContextSet.fromSet(n.getContexts());
|
||||||
|
|
||||||
if (n.isServerSpecific()) {
|
if (n.isServerSpecific()) {
|
||||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||||
@ -85,41 +92,32 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!perms.containsKey(contexts)) {
|
if (!perms.containsKey(contexts)) {
|
||||||
perms.put(contexts, new HashMap<>());
|
perms.put(contexts.makeImmutable(), new HashMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
perms.get(contexts).put(n.getPermission(), n.getValue());
|
perms.get(contexts).put(n.getPermission(), n.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImmutableMap.Builder<Set<Context>, Map<String, Boolean>> map = ImmutableMap.builder();
|
ImmutableMap.Builder<ContextSet, Map<String, Boolean>> map = ImmutableMap.builder();
|
||||||
for (Map.Entry<Set<Context>, Map<String, Boolean>> e : perms.entrySet()) {
|
for (Map.Entry<ContextSet, Map<String, Boolean>> e : perms.entrySet()) {
|
||||||
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableMap.copyOf(e.getValue()));
|
map.put(e.getKey().makeImmutable(), ImmutableMap.copyOf(e.getValue()));
|
||||||
}
|
}
|
||||||
return map.build();
|
return map.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Boolean> getPermissions(@NonNull Set<Context> contexts) {
|
public boolean setPermission(@NonNull ContextSet contexts, @NonNull String permission, @NonNull Tristate tristate) {
|
||||||
return getAllPermissions().getOrDefault(contexts, ImmutableMap.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setPermission(@NonNull Set<Context> contexts, @NonNull String permission, @NonNull Tristate tristate) {
|
|
||||||
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_SET_PERMISSION)) {
|
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_SET_PERMISSION)) {
|
||||||
if (tristate == Tristate.UNDEFINED) {
|
if (tristate == Tristate.UNDEFINED) {
|
||||||
// Unset
|
// Unset
|
||||||
Node.Builder builder = new NodeBuilder(permission);
|
Node node = new NodeBuilder(permission).withExtraContext(contexts).build();
|
||||||
|
|
||||||
for (Context ct : contexts) {
|
|
||||||
builder.withExtraContext(ct.getKey(), ct.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (enduring) {
|
if (enduring) {
|
||||||
holder.unsetPermission(builder.build());
|
holder.unsetPermission(node);
|
||||||
} else {
|
} else {
|
||||||
holder.unsetTransientPermission(builder.build());
|
holder.unsetTransientPermission(node);
|
||||||
}
|
}
|
||||||
} catch (ObjectLacksException ignored) {}
|
} catch (ObjectLacksException ignored) {}
|
||||||
|
|
||||||
@ -127,14 +125,7 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node.Builder builder = new NodeBuilder(permission)
|
Node node = new NodeBuilder(permission).setValue(tristate.asBoolean()).withExtraContext(contexts).build();
|
||||||
.setValue(tristate.asBoolean());
|
|
||||||
|
|
||||||
for (Context ct : contexts) {
|
|
||||||
builder.withExtraContext(ct.getKey(), ct.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
Node node = builder.build();
|
|
||||||
|
|
||||||
// Workaround: unset the inverse, to allow false -> true, true -> false overrides.
|
// Workaround: unset the inverse, to allow false -> true, true -> false overrides.
|
||||||
try {
|
try {
|
||||||
@ -172,11 +163,11 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean clearPermissions(@NonNull Set<Context> c) {
|
public boolean clearPermissions(@NonNull ContextSet c) {
|
||||||
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_PERMISSIONS)) {
|
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_PERMISSIONS)) {
|
||||||
List<Node> toRemove = new ArrayList<>();
|
List<Node> toRemove = new ArrayList<>();
|
||||||
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
||||||
Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
|
MutableContextSet contexts = MutableContextSet.fromSet(n.getContexts());
|
||||||
|
|
||||||
if (n.isServerSpecific()) {
|
if (n.isServerSpecific()) {
|
||||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||||
@ -211,16 +202,16 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Set<Context>, List<Subject>> getAllParents() {
|
public Map<ContextSet, Set<SubjectReference>> getParents() {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_PARENTS)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_PARENTS)) {
|
||||||
Map<Set<Context>, List<Subject>> parents = new HashMap<>();
|
Map<ContextSet, Set<SubjectReference>> parents = new HashMap<>();
|
||||||
|
|
||||||
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
||||||
if (!n.isGroupNode()) {
|
if (!n.isGroupNode()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
|
MutableContextSet contexts = MutableContextSet.fromSet(n.getContexts());
|
||||||
|
|
||||||
if (n.isServerSpecific()) {
|
if (n.isServerSpecific()) {
|
||||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||||
@ -231,31 +222,25 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!parents.containsKey(contexts)) {
|
if (!parents.containsKey(contexts)) {
|
||||||
parents.put(contexts, new ArrayList<>());
|
parents.put(contexts.makeImmutable(), new HashSet<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
parents.get(contexts).add(service.getGroupSubjects().get(n.getGroupName()));
|
parents.get(contexts).add(service.getGroupSubjects().get(n.getGroupName()).toReference());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImmutableMap.Builder<Set<Context>, List<Subject>> map = ImmutableMap.builder();
|
ImmutableMap.Builder<ContextSet, Set<SubjectReference>> map = ImmutableMap.builder();
|
||||||
for (Map.Entry<Set<Context>, List<Subject>> e : parents.entrySet()) {
|
for (Map.Entry<ContextSet, Set<SubjectReference>> e : parents.entrySet()) {
|
||||||
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableList.copyOf(e.getValue()));
|
map.put(e.getKey().makeImmutable(), ImmutableSet.copyOf(e.getValue()));
|
||||||
}
|
}
|
||||||
return map.build();
|
return map.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Subject> getParents(@NonNull Set<Context> contexts) {
|
public boolean addParent(@NonNull ContextSet contexts, @NonNull SubjectReference subject) {
|
||||||
return getAllParents().getOrDefault(contexts, ImmutableList.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean addParent(@NonNull Set<Context> set, @NonNull Subject subject) {
|
|
||||||
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_ADD_PARENT)) {
|
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_ADD_PARENT)) {
|
||||||
if (subject instanceof SpongeGroup) {
|
if (subject.getCollection().equals(PermissionService.SUBJECTS_GROUP)) {
|
||||||
SpongeGroup permsSubject = ((SpongeGroup) subject);
|
SpongeGroup permsSubject = ((SpongeGroup) subject.resolve(service));
|
||||||
ContextSet contexts = LuckPermsService.convertContexts(set);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (enduring) {
|
if (enduring) {
|
||||||
@ -277,11 +262,10 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeParent(@NonNull Set<Context> set, @NonNull Subject subject) {
|
public boolean removeParent(@NonNull ContextSet contexts, @NonNull SubjectReference subject) {
|
||||||
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_REMOVE_PARENT)) {
|
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_REMOVE_PARENT)) {
|
||||||
if (subject instanceof SpongeGroup) {
|
if (subject.getCollection().equals(PermissionService.SUBJECTS_GROUP)) {
|
||||||
SpongeGroup permsSubject = ((SpongeGroup) subject);
|
SpongeGroup permsSubject = ((SpongeGroup) subject.resolve(service));
|
||||||
ContextSet contexts = LuckPermsService.convertContexts(set);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (enduring) {
|
if (enduring) {
|
||||||
@ -329,7 +313,7 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean clearParents(@NonNull Set<Context> set) {
|
public boolean clearParents(@NonNull ContextSet set) {
|
||||||
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_PARENTS)) {
|
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_PARENTS)) {
|
||||||
List<Node> toRemove = new ArrayList<>();
|
List<Node> toRemove = new ArrayList<>();
|
||||||
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
||||||
@ -337,7 +321,7 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
|
MutableContextSet contexts = MutableContextSet.fromSet(n.getContexts());
|
||||||
|
|
||||||
if (n.isServerSpecific()) {
|
if (n.isServerSpecific()) {
|
||||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||||
@ -372,11 +356,11 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Set<Context>, Map<String, String>> getAllOptions() {
|
public Map<ContextSet, Map<String, String>> getOptions() {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_OPTIONS)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_OPTIONS)) {
|
||||||
Map<Set<Context>, Map<String, String>> options = new HashMap<>();
|
Map<ContextSet, Map<String, String>> options = new HashMap<>();
|
||||||
Map<Set<Context>, Integer> minPrefixPriority = new HashMap<>();
|
Map<ContextSet, Integer> minPrefixPriority = new HashMap<>();
|
||||||
Map<Set<Context>, Integer> minSuffixPriority = new HashMap<>();
|
Map<ContextSet, Integer> minSuffixPriority = new HashMap<>();
|
||||||
|
|
||||||
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
||||||
if (!n.getValue()) {
|
if (!n.getValue()) {
|
||||||
@ -387,7 +371,7 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
|
MutableContextSet contexts = MutableContextSet.fromSet(n.getContexts());
|
||||||
|
|
||||||
if (n.isServerSpecific()) {
|
if (n.isServerSpecific()) {
|
||||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||||
@ -427,24 +411,17 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImmutableMap.Builder<Set<Context>, Map<String, String>> map = ImmutableMap.builder();
|
ImmutableMap.Builder<ContextSet, Map<String, String>> map = ImmutableMap.builder();
|
||||||
for (Map.Entry<Set<Context>, Map<String, String>> e : options.entrySet()) {
|
for (Map.Entry<ContextSet, Map<String, String>> e : options.entrySet()) {
|
||||||
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableMap.copyOf(e.getValue()));
|
map.put(e.getKey().makeImmutable(), ImmutableMap.copyOf(e.getValue()));
|
||||||
}
|
}
|
||||||
return map.build();
|
return map.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getOptions(@NonNull Set<Context> set) {
|
public boolean setOption(@NonNull ContextSet context, @NonNull String key, @NonNull String value) {
|
||||||
return getAllOptions().getOrDefault(set, ImmutableMap.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setOption(@NonNull Set<Context> set, @NonNull String key, @NonNull String value) {
|
|
||||||
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_SET_OPTION)) {
|
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_SET_OPTION)) {
|
||||||
ContextSet context = LuckPermsService.convertContexts(set);
|
|
||||||
|
|
||||||
List<Node> toRemove = holder.getNodes().stream()
|
List<Node> toRemove = holder.getNodes().stream()
|
||||||
.filter(n -> n.isMeta() && n.getMeta().getKey().equals(key))
|
.filter(n -> n.isMeta() && n.getMeta().getKey().equals(key))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@ -468,7 +445,25 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean clearOptions(@NonNull Set<Context> set) {
|
public boolean unsetOption(ContextSet contexts, String key) {
|
||||||
|
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_SET_OPTION)) {
|
||||||
|
List<Node> toRemove = holder.getNodes().stream()
|
||||||
|
.filter(n -> n.isMeta() && n.getMeta().getKey().equals(key))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
toRemove.forEach(n -> {
|
||||||
|
try {
|
||||||
|
holder.unsetPermission(n);
|
||||||
|
} catch (ObjectLacksException ignored) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
objectSave(holder);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean clearOptions(@NonNull ContextSet set) {
|
||||||
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_OPTIONS)) {
|
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_OPTIONS)) {
|
||||||
List<Node> toRemove = new ArrayList<>();
|
List<Node> toRemove = new ArrayList<>();
|
||||||
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
||||||
@ -476,7 +471,7 @@ public class LuckPermsSubjectData implements SubjectData {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
|
MutableContextSet contexts = MutableContextSet.fromSet(n.getContexts());
|
||||||
|
|
||||||
if (n.isServerSpecific()) {
|
if (n.isServerSpecific()) {
|
||||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||||
|
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.sponge.service.base;
|
||||||
|
|
||||||
|
import lombok.NonNull;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
|
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||||
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectCollectionReference;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
|
import org.spongepowered.api.command.CommandSource;
|
||||||
|
import org.spongepowered.api.service.context.Context;
|
||||||
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
import org.spongepowered.api.util.Tristate;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static me.lucko.luckperms.sponge.service.base.Util.convertContexts;
|
||||||
|
import static me.lucko.luckperms.sponge.service.base.Util.convertTristate;
|
||||||
|
|
||||||
|
public interface LPSubject extends Subject {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getIdentifier();
|
||||||
|
|
||||||
|
default Optional<String> getFriendlyIdentifier() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Optional<CommandSource> getCommandSource() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
SubjectCollectionReference getParentCollection();
|
||||||
|
|
||||||
|
LuckPermsService getService();
|
||||||
|
|
||||||
|
default SubjectReference toReference() {
|
||||||
|
return SubjectReference.of(getParentCollection().getCollection(), getIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LPSubjectData getSubjectData();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LPSubjectData getTransientSubjectData();
|
||||||
|
|
||||||
|
me.lucko.luckperms.api.Tristate getPermissionValue(ContextSet contexts, String permission);
|
||||||
|
|
||||||
|
boolean isChildOf(ContextSet contexts, SubjectReference parent);
|
||||||
|
|
||||||
|
Set<SubjectReference> getParents(ContextSet contexts);
|
||||||
|
|
||||||
|
Optional<String> getOption(ContextSet contexts, String key);
|
||||||
|
|
||||||
|
ContextSet getActiveContextSet();
|
||||||
|
|
||||||
|
|
||||||
|
/* Compat */
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default LPSubjectCollection getContainingCollection() {
|
||||||
|
return getParentCollection().resolve(getService());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default boolean hasPermission(@NonNull Set<Context> contexts, @NonNull String permission) {
|
||||||
|
return getPermissionValue(convertContexts(contexts), permission).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default boolean hasPermission(@NonNull String permission) {
|
||||||
|
return getPermissionValue(getActiveContextSet(), permission).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String permission) {
|
||||||
|
return convertTristate(getPermissionValue(convertContexts(contexts), permission));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default boolean isChildOf(@NonNull Subject parent) {
|
||||||
|
return isChildOf(getActiveContextSet(), SubjectReference.of(parent));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject parent) {
|
||||||
|
return isChildOf(convertContexts(contexts), SubjectReference.of(parent));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default List<Subject> getParents() {
|
||||||
|
return getParents(getActiveContextSet()).stream().map(s -> s.resolve(getService())).collect(ImmutableCollectors.toImmutableList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default List<Subject> getParents(@NonNull Set<Context> contexts) {
|
||||||
|
return getParents(convertContexts(contexts)).stream().map(s -> s.resolve(getService())).collect(ImmutableCollectors.toImmutableList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Optional<String> getOption(@NonNull String key) {
|
||||||
|
return getOption(getActiveContextSet(), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Optional<String> getOption(@NonNull Set<Context> contexts, @NonNull String key) {
|
||||||
|
return getOption(getActiveContextSet(), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Set<Context> getActiveContexts() {
|
||||||
|
return convertContexts(getActiveContextSet());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.sponge.service.base;
|
||||||
|
|
||||||
|
import lombok.NonNull;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
|
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||||
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectCollectionReference;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
|
import org.spongepowered.api.service.context.Context;
|
||||||
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static me.lucko.luckperms.sponge.service.base.Util.convertContexts;
|
||||||
|
|
||||||
|
public interface LPSubjectCollection extends SubjectCollection {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getIdentifier();
|
||||||
|
|
||||||
|
LuckPermsService getService();
|
||||||
|
|
||||||
|
default SubjectCollectionReference toReference() {
|
||||||
|
return SubjectCollectionReference.of(getIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LPSubject get(String identifier);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean hasRegistered(String identifier);
|
||||||
|
|
||||||
|
Collection<LPSubject> getSubjects();
|
||||||
|
|
||||||
|
default Map<LPSubject, Boolean> getWithPermission(String permission) {
|
||||||
|
return getWithPermission(ContextSet.empty(), permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<LPSubject, Boolean> getWithPermission(ContextSet contexts, String permission);
|
||||||
|
|
||||||
|
SubjectReference getDefaultSubject();
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Subject getDefaults() {
|
||||||
|
return getDefaultSubject().resolve(getService());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Iterable<Subject> getAllSubjects() {
|
||||||
|
return getSubjects().stream().collect(ImmutableCollectors.toImmutableList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Map<Subject, Boolean> getAllWithPermission(@NonNull String permission) {
|
||||||
|
return getWithPermission(permission).entrySet().stream().collect(ImmutableCollectors.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String permission) {
|
||||||
|
return getWithPermission(convertContexts(contexts), permission).entrySet().stream().collect(ImmutableCollectors.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.sponge.service.base;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
|
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
|
import org.spongepowered.api.service.context.Context;
|
||||||
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectData;
|
||||||
|
import org.spongepowered.api.util.Tristate;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static me.lucko.luckperms.sponge.service.base.Util.convertContexts;
|
||||||
|
import static me.lucko.luckperms.sponge.service.base.Util.convertTristate;
|
||||||
|
|
||||||
|
public interface LPSubjectData extends SubjectData {
|
||||||
|
|
||||||
|
LPSubject getParentSubject();
|
||||||
|
|
||||||
|
Map<ContextSet, Map<String, Boolean>> getPermissions();
|
||||||
|
|
||||||
|
default Map<String, Boolean> getPermissions(ContextSet contexts) {
|
||||||
|
return ImmutableMap.copyOf(getPermissions().getOrDefault(contexts, ImmutableMap.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean setPermission(ContextSet contexts, String permission, me.lucko.luckperms.api.Tristate value);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean clearPermissions();
|
||||||
|
|
||||||
|
boolean clearPermissions(ContextSet contexts);
|
||||||
|
|
||||||
|
Map<ContextSet, Set<SubjectReference>> getParents();
|
||||||
|
|
||||||
|
default Set<SubjectReference> getParents(ContextSet contexts) {
|
||||||
|
return ImmutableSet.copyOf(getParents().getOrDefault(contexts, ImmutableSet.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean addParent(ContextSet contexts, SubjectReference parent);
|
||||||
|
|
||||||
|
boolean removeParent(ContextSet contexts, SubjectReference parent);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean clearParents();
|
||||||
|
|
||||||
|
boolean clearParents(ContextSet contexts);
|
||||||
|
|
||||||
|
Map<ContextSet, Map<String, String>> getOptions();
|
||||||
|
|
||||||
|
default Map<String, String> getOptions(ContextSet contexts) {
|
||||||
|
return ImmutableMap.copyOf(getOptions().getOrDefault(contexts, ImmutableMap.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean setOption(ContextSet contexts, String key, String value);
|
||||||
|
|
||||||
|
boolean unsetOption(ContextSet contexts, String key);
|
||||||
|
|
||||||
|
boolean clearOptions(ContextSet contexts);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean clearOptions();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Compat */
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Map<Set<Context>, Map<String, Boolean>> getAllPermissions() {
|
||||||
|
return getPermissions().entrySet().stream()
|
||||||
|
.collect(ImmutableCollectors.toImmutableMap(
|
||||||
|
e -> convertContexts(e.getKey()),
|
||||||
|
e -> ImmutableMap.copyOf(e.getValue()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Map<String, Boolean> getPermissions(Set<Context> contexts) {
|
||||||
|
return ImmutableMap.copyOf(getPermissions(convertContexts(contexts)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default boolean setPermission(Set<Context> contexts, String permission, Tristate value) {
|
||||||
|
return setPermission(convertContexts(contexts), permission, convertTristate(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default boolean clearPermissions(Set<Context> contexts) {
|
||||||
|
return clearPermissions(convertContexts(contexts));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Map<Set<Context>, List<Subject>> getAllParents() {
|
||||||
|
return getParents().entrySet().stream()
|
||||||
|
.collect(ImmutableCollectors.toImmutableMap(
|
||||||
|
e -> convertContexts(e.getKey()),
|
||||||
|
e -> e.getValue().stream()
|
||||||
|
.map(s -> s.resolve(getParentSubject().getService()))
|
||||||
|
.collect(ImmutableCollectors.toImmutableList())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default List<Subject> getParents(Set<Context> contexts) {
|
||||||
|
return getParents(convertContexts(contexts)).stream().map(s -> s.resolve(getParentSubject().getService())).collect(ImmutableCollectors.toImmutableList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default boolean addParent(Set<Context> contexts, Subject parent) {
|
||||||
|
return addParent(convertContexts(contexts), SubjectReference.of(parent));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default boolean removeParent(Set<Context> contexts, Subject parent) {
|
||||||
|
return removeParent(convertContexts(contexts), SubjectReference.of(parent));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default boolean clearParents(Set<Context> contexts) {
|
||||||
|
return clearParents(convertContexts(contexts));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Map<Set<Context>, Map<String, String>> getAllOptions() {
|
||||||
|
return getOptions().entrySet().stream()
|
||||||
|
.collect(ImmutableCollectors.toImmutableMap(
|
||||||
|
e -> convertContexts(e.getKey()),
|
||||||
|
e -> ImmutableMap.copyOf(e.getValue()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default Map<String, String> getOptions(Set<Context> contexts) {
|
||||||
|
return ImmutableMap.copyOf(getOptions(convertContexts(contexts)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default boolean setOption(Set<Context> contexts, String key, @Nullable String value) {
|
||||||
|
return value == null ? unsetOption(convertContexts(contexts), key) : setOption(convertContexts(contexts), key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
default boolean clearOptions(Set<Context> contexts) {
|
||||||
|
return clearOptions(convertContexts(contexts));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.sponge.service.base;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
|
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||||
|
import org.spongepowered.api.service.context.Context;
|
||||||
|
import org.spongepowered.api.util.Tristate;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class Util {
|
||||||
|
|
||||||
|
public static ContextSet convertContexts(Set<Context> contexts) {
|
||||||
|
return ContextSet.fromEntries(contexts.stream().map(c -> Maps.immutableEntry(c.getKey(), c.getValue())).collect(Collectors.toSet()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<Context> convertContexts(ContextSet contexts) {
|
||||||
|
return contexts.toSet().stream().map(e -> new Context(e.getKey(), e.getValue())).collect(ImmutableCollectors.toImmutableSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tristate convertTristate(me.lucko.luckperms.api.Tristate tristate) {
|
||||||
|
switch (tristate) {
|
||||||
|
case TRUE:
|
||||||
|
return Tristate.TRUE;
|
||||||
|
case FALSE:
|
||||||
|
return Tristate.FALSE;
|
||||||
|
default:
|
||||||
|
return Tristate.UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static me.lucko.luckperms.api.Tristate convertTristate(Tristate tristate) {
|
||||||
|
switch (tristate) {
|
||||||
|
case TRUE:
|
||||||
|
return me.lucko.luckperms.api.Tristate.TRUE;
|
||||||
|
case FALSE:
|
||||||
|
return me.lucko.luckperms.api.Tristate.FALSE;
|
||||||
|
default:
|
||||||
|
return me.lucko.luckperms.api.Tristate.UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -20,7 +20,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.sponge.service.data;
|
package me.lucko.luckperms.sponge.service.calculated;
|
||||||
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
@ -31,32 +31,34 @@ import com.google.common.collect.ImmutableSet;
|
|||||||
import com.google.common.collect.ImmutableSortedMap;
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.common.calculators.PermissionCalculator;
|
import me.lucko.luckperms.common.calculators.PermissionCalculator;
|
||||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||||
import me.lucko.luckperms.common.calculators.processors.MapProcessor;
|
import me.lucko.luckperms.common.calculators.processors.MapProcessor;
|
||||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
|
||||||
import me.lucko.luckperms.sponge.calculators.SpongeWildcardProcessor;
|
import me.lucko.luckperms.sponge.calculators.SpongeWildcardProcessor;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
import org.spongepowered.api.service.context.Context;
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
import me.lucko.luckperms.sponge.service.base.LPSubjectData;
|
||||||
import org.spongepowered.api.service.permission.SubjectData;
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class CalculatedSubjectData implements SubjectData {
|
public class CalculatedSubjectData implements LPSubjectData {
|
||||||
private static final ContextComparator CONTEXT_COMPARATOR = new ContextComparator();
|
private static final ContextComparator CONTEXT_COMPARATOR = new ContextComparator();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final LPSubject parentSubject;
|
||||||
|
|
||||||
private final LuckPermsService service;
|
private final LuckPermsService service;
|
||||||
private final String calculatorDisplayName;
|
private final String calculatorDisplayName;
|
||||||
|
|
||||||
private final LoadingCache<Set<Context>, CalculatorHolder> permissionCache = CacheBuilder.newBuilder()
|
private final LoadingCache<ContextSet, CalculatorHolder> permissionCache = CacheBuilder.newBuilder()
|
||||||
.build(new CacheLoader<Set<Context>, CalculatorHolder>() {
|
.build(new CacheLoader<ContextSet, CalculatorHolder>() {
|
||||||
@Override
|
@Override
|
||||||
public CalculatorHolder load(Set<Context> contexts) {
|
public CalculatorHolder load(ContextSet contexts) {
|
||||||
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
|
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
|
||||||
processors.add(new MapProcessor());
|
processors.add(new MapProcessor());
|
||||||
processors.add(new SpongeWildcardProcessor());
|
processors.add(new SpongeWildcardProcessor());
|
||||||
@ -68,77 +70,69 @@ public class CalculatedSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
private final LoadingCache<Set<Context>, Map<String, String>> optionCache = CacheBuilder.newBuilder()
|
private final LoadingCache<ContextSet, Map<String, String>> optionCache = CacheBuilder.newBuilder()
|
||||||
.build(new CacheLoader<Set<Context>, Map<String, String>>() {
|
.build(new CacheLoader<ContextSet, Map<String, String>>() {
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> load(Set<Context> contexts) {
|
public Map<String, String> load(ContextSet contexts) {
|
||||||
return flattenMap(contexts, options);
|
return flattenMap(contexts, options);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
private final Map<Set<Context>, Map<String, Boolean>> permissions = new ConcurrentHashMap<>();
|
private final Map<ContextSet, Map<String, Boolean>> permissions = new ConcurrentHashMap<>();
|
||||||
private final Map<Set<Context>, Set<SubjectReference>> parents = new ConcurrentHashMap<>();
|
private final Map<ContextSet, Set<SubjectReference>> parents = new ConcurrentHashMap<>();
|
||||||
private final Map<Set<Context>, Map<String, String>> options = new ConcurrentHashMap<>();
|
private final Map<ContextSet, Map<String, String>> options = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public Tristate getPermissionValue(Set<Context> contexts, String permission) {
|
public Tristate getPermissionValue(ContextSet contexts, String permission) {
|
||||||
return LuckPermsService.convertTristate(permissionCache.getUnchecked(contexts).getCalculator().getPermissionValue(permission));
|
return permissionCache.getUnchecked(contexts).getCalculator().getPermissionValue(permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Set<Context>, Set<SubjectReference>> getParents() {
|
public void replacePermissions(Map<ContextSet, Map<String, Boolean>> map) {
|
||||||
ImmutableMap.Builder<Set<Context>, Set<SubjectReference>> map = ImmutableMap.builder();
|
|
||||||
for (Map.Entry<Set<Context>, Set<SubjectReference>> e : parents.entrySet()) {
|
|
||||||
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableSet.copyOf(e.getValue()));
|
|
||||||
}
|
|
||||||
return map.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void replacePermissions(Map<Set<Context>, Map<String, Boolean>> map) {
|
|
||||||
permissions.clear();
|
permissions.clear();
|
||||||
for (Map.Entry<Set<Context>, Map<String, Boolean>> e : map.entrySet()) {
|
for (Map.Entry<ContextSet, Map<String, Boolean>> e : map.entrySet()) {
|
||||||
permissions.put(ImmutableSet.copyOf(e.getKey()), new ConcurrentHashMap<>(e.getValue()));
|
permissions.put(e.getKey().makeImmutable(), new ConcurrentHashMap<>(e.getValue()));
|
||||||
}
|
}
|
||||||
permissionCache.invalidateAll();
|
permissionCache.invalidateAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void replaceParents(Map<Set<Context>, Set<SubjectReference>> map) {
|
public void replaceParents(Map<ContextSet, Set<SubjectReference>> map) {
|
||||||
parents.clear();
|
parents.clear();
|
||||||
for (Map.Entry<Set<Context>, Set<SubjectReference>> e : map.entrySet()) {
|
for (Map.Entry<ContextSet, Set<SubjectReference>> e : map.entrySet()) {
|
||||||
Set<SubjectReference> set = ConcurrentHashMap.newKeySet();
|
Set<SubjectReference> set = ConcurrentHashMap.newKeySet();
|
||||||
set.addAll(e.getValue());
|
set.addAll(e.getValue());
|
||||||
parents.put(ImmutableSet.copyOf(e.getKey()), set);
|
parents.put(e.getKey().makeImmutable(), set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void replaceOptions(Map<Set<Context>, Map<String, String>> map) {
|
public void replaceOptions(Map<ContextSet, Map<String, String>> map) {
|
||||||
options.clear();
|
options.clear();
|
||||||
for (Map.Entry<Set<Context>, Map<String, String>> e : map.entrySet()) {
|
for (Map.Entry<ContextSet, Map<String, String>> e : map.entrySet()) {
|
||||||
options.put(ImmutableSet.copyOf(e.getKey()), new ConcurrentHashMap<>(e.getValue()));
|
options.put(e.getKey().makeImmutable(), new ConcurrentHashMap<>(e.getValue()));
|
||||||
}
|
}
|
||||||
optionCache.invalidateAll();
|
optionCache.invalidateAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Set<Context>, Map<String, Boolean>> getAllPermissions() {
|
public Map<ContextSet, Map<String, Boolean>> getPermissions() {
|
||||||
ImmutableMap.Builder<Set<Context>, Map<String, Boolean>> map = ImmutableMap.builder();
|
ImmutableMap.Builder<ContextSet, Map<String, Boolean>> map = ImmutableMap.builder();
|
||||||
for (Map.Entry<Set<Context>, Map<String, Boolean>> e : permissions.entrySet()) {
|
for (Map.Entry<ContextSet, Map<String, Boolean>> e : permissions.entrySet()) {
|
||||||
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableMap.copyOf(e.getValue()));
|
map.put(e.getKey().makeImmutable(), ImmutableMap.copyOf(e.getValue()));
|
||||||
}
|
}
|
||||||
return map.build();
|
return map.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Boolean> getPermissions(Set<Context> contexts) {
|
public Map<String, Boolean> getPermissions(ContextSet contexts) {
|
||||||
return ImmutableMap.copyOf(permissions.getOrDefault(contexts, ImmutableMap.of()));
|
return ImmutableMap.copyOf(permissions.getOrDefault(contexts, ImmutableMap.of()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setPermission(Set<Context> contexts, String permission, Tristate value) {
|
public boolean setPermission(ContextSet contexts, String permission, Tristate value) {
|
||||||
boolean b;
|
boolean b;
|
||||||
if (value == Tristate.UNDEFINED) {
|
if (value == Tristate.UNDEFINED) {
|
||||||
Map<String, Boolean> perms = permissions.get(contexts);
|
Map<String, Boolean> perms = permissions.get(contexts);
|
||||||
b = perms != null && perms.remove(permission.toLowerCase()) != null;
|
b = perms != null && perms.remove(permission.toLowerCase()) != null;
|
||||||
} else {
|
} else {
|
||||||
Map<String, Boolean> perms = permissions.computeIfAbsent(ImmutableSet.copyOf(contexts), c -> new ConcurrentHashMap<>());
|
Map<String, Boolean> perms = permissions.computeIfAbsent(contexts.makeImmutable(), c -> new ConcurrentHashMap<>());
|
||||||
b = !Objects.equals(perms.put(permission.toLowerCase(), value.asBoolean()), value.asBoolean());
|
b = !Objects.equals(perms.put(permission.toLowerCase(), value.asBoolean()), value.asBoolean());
|
||||||
}
|
}
|
||||||
if (b) {
|
if (b) {
|
||||||
@ -159,7 +153,7 @@ public class CalculatedSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean clearPermissions(Set<Context> contexts) {
|
public boolean clearPermissions(ContextSet contexts) {
|
||||||
Map<String, Boolean> perms = permissions.get(contexts);
|
Map<String, Boolean> perms = permissions.get(contexts);
|
||||||
if (perms == null) {
|
if (perms == null) {
|
||||||
return false;
|
return false;
|
||||||
@ -174,34 +168,29 @@ public class CalculatedSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Set<Context>, List<Subject>> getAllParents() {
|
public Map<ContextSet, Set<SubjectReference>> getParents() {
|
||||||
ImmutableMap.Builder<Set<Context>, List<Subject>> map = ImmutableMap.builder();
|
ImmutableMap.Builder<ContextSet, Set<SubjectReference>> map = ImmutableMap.builder();
|
||||||
for (Map.Entry<Set<Context>, Set<SubjectReference>> e : parents.entrySet()) {
|
for (Map.Entry<ContextSet, Set<SubjectReference>> e : parents.entrySet()) {
|
||||||
map.put(
|
map.put(e.getKey().makeImmutable(), ImmutableSet.copyOf(e.getValue()));
|
||||||
ImmutableSet.copyOf(e.getKey()),
|
|
||||||
e.getValue().stream().map(s -> s.resolve(service)).collect(ImmutableCollectors.toImmutableList())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return map.build();
|
return map.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Subject> getParents(Set<Context> contexts) {
|
public Set<SubjectReference> getParents(ContextSet contexts) {
|
||||||
return parents.getOrDefault(contexts, ImmutableSet.of()).stream()
|
return ImmutableSet.copyOf(parents.getOrDefault(contexts, ImmutableSet.of()));
|
||||||
.map(s -> s.resolve(service))
|
|
||||||
.collect(ImmutableCollectors.toImmutableList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addParent(Set<Context> contexts, Subject parent) {
|
public boolean addParent(ContextSet contexts, SubjectReference parent) {
|
||||||
Set<SubjectReference> set = parents.computeIfAbsent(ImmutableSet.copyOf(contexts), c -> ConcurrentHashMap.newKeySet());
|
Set<SubjectReference> set = parents.computeIfAbsent(contexts.makeImmutable(), c -> ConcurrentHashMap.newKeySet());
|
||||||
return set.add(SubjectReference.of(parent));
|
return set.add(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeParent(Set<Context> contexts, Subject parent) {
|
public boolean removeParent(ContextSet contexts, SubjectReference parent) {
|
||||||
Set<SubjectReference> set = parents.get(contexts);
|
Set<SubjectReference> set = parents.get(contexts);
|
||||||
return set != null && set.remove(SubjectReference.of(parent));
|
return set != null && set.remove(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -215,7 +204,7 @@ public class CalculatedSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean clearParents(Set<Context> contexts) {
|
public boolean clearParents(ContextSet contexts) {
|
||||||
Set<SubjectReference> set = parents.get(contexts);
|
Set<SubjectReference> set = parents.get(contexts);
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
return false;
|
return false;
|
||||||
@ -226,29 +215,33 @@ public class CalculatedSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Set<Context>, Map<String, String>> getAllOptions() {
|
public Map<ContextSet, Map<String, String>> getOptions() {
|
||||||
ImmutableMap.Builder<Set<Context>, Map<String, String>> map = ImmutableMap.builder();
|
ImmutableMap.Builder<ContextSet, Map<String, String>> map = ImmutableMap.builder();
|
||||||
for (Map.Entry<Set<Context>, Map<String, String>> e : options.entrySet()) {
|
for (Map.Entry<ContextSet, Map<String, String>> e : options.entrySet()) {
|
||||||
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableMap.copyOf(e.getValue()));
|
map.put(e.getKey().makeImmutable(), ImmutableMap.copyOf(e.getValue()));
|
||||||
}
|
}
|
||||||
return map.build();
|
return map.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getOptions(Set<Context> contexts) {
|
public Map<String, String> getOptions(ContextSet contexts) {
|
||||||
return ImmutableMap.copyOf(options.getOrDefault(contexts, ImmutableMap.of()));
|
return ImmutableMap.copyOf(options.getOrDefault(contexts, ImmutableMap.of()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setOption(Set<Context> contexts, String key, @Nullable String value) {
|
public boolean setOption(ContextSet contexts, String key, String value) {
|
||||||
boolean b;
|
Map<String, String> options = this.options.computeIfAbsent(contexts.makeImmutable(), c -> new ConcurrentHashMap<>());
|
||||||
if (value == null) {
|
boolean b = !stringEquals(options.put(key.toLowerCase(), value), value);
|
||||||
Map<String, String> options = this.options.get(contexts);
|
if (b) {
|
||||||
b = options != null && options.remove(key.toLowerCase()) != null;
|
optionCache.invalidateAll();
|
||||||
} else {
|
|
||||||
Map<String, String> options = this.options.computeIfAbsent(ImmutableSet.copyOf(contexts), c -> new ConcurrentHashMap<>());
|
|
||||||
b = !stringEquals(options.put(key.toLowerCase(), value), value);
|
|
||||||
}
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean unsetOption(ContextSet contexts, String key) {
|
||||||
|
Map<String, String> options = this.options.get(contexts);
|
||||||
|
boolean b = options != null && options.remove(key.toLowerCase()) != null;
|
||||||
if (b) {
|
if (b) {
|
||||||
optionCache.invalidateAll();
|
optionCache.invalidateAll();
|
||||||
}
|
}
|
||||||
@ -267,7 +260,7 @@ public class CalculatedSubjectData implements SubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean clearOptions(Set<Context> contexts) {
|
public boolean clearOptions(ContextSet contexts) {
|
||||||
Map<String, String> map = options.get(contexts);
|
Map<String, String> map = options.get(contexts);
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
return false;
|
return false;
|
||||||
@ -281,10 +274,10 @@ public class CalculatedSubjectData implements SubjectData {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <V> Map<String, V> flattenMap(Set<Context> contexts, Map<Set<Context>, Map<String, V>> source) {
|
private static <V> Map<String, V> flattenMap(ContextSet contexts, Map<ContextSet, Map<String, V>> source) {
|
||||||
Map<String, V> map = new HashMap<>();
|
Map<String, V> map = new HashMap<>();
|
||||||
|
|
||||||
SortedMap<Set<Context>, Map<String, V>> ret = getRelevantEntries(contexts, source);
|
SortedMap<ContextSet, Map<String, V>> ret = getRelevantEntries(contexts, source);
|
||||||
for (Map<String, V> m : ret.values()) {
|
for (Map<String, V> m : ret.values()) {
|
||||||
for (Map.Entry<String, V> e : m.entrySet()) {
|
for (Map.Entry<String, V> e : m.entrySet()) {
|
||||||
if (!map.containsKey(e.getKey())) {
|
if (!map.containsKey(e.getKey())) {
|
||||||
@ -296,18 +289,19 @@ public class CalculatedSubjectData implements SubjectData {
|
|||||||
return ImmutableMap.copyOf(map);
|
return ImmutableMap.copyOf(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <K, V> SortedMap<Set<Context>, Map<K, V>> getRelevantEntries(Set<Context> set, Map<Set<Context>, Map<K, V>> map) {
|
private static <K, V> SortedMap<ContextSet, Map<K, V>> getRelevantEntries(ContextSet set, Map<ContextSet, Map<K, V>> map) {
|
||||||
ImmutableSortedMap.Builder<Set<Context>, Map<K, V>> perms = ImmutableSortedMap.orderedBy(CONTEXT_COMPARATOR);
|
ImmutableSortedMap.Builder<ContextSet, Map<K, V>> perms = ImmutableSortedMap.orderedBy(CONTEXT_COMPARATOR);
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
for (Map.Entry<Set<Context>, Map<K, V>> e : map.entrySet()) {
|
for (Map.Entry<ContextSet, Map<K, V>> e : map.entrySet()) {
|
||||||
for (Context c : e.getKey()) {
|
|
||||||
if (!set.contains(c)) {
|
for (Map.Entry<String, String> c : e.getKey().toSet()) {
|
||||||
|
if (!set.has(c.getKey(), c.getValue())) {
|
||||||
continue loop;
|
continue loop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
perms.put(ImmutableSet.copyOf(e.getKey()), ImmutableMap.copyOf(e.getValue()));
|
perms.put(e.getKey().makeImmutable(), ImmutableMap.copyOf(e.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return perms.build();
|
return perms.build();
|
||||||
@ -317,10 +311,10 @@ public class CalculatedSubjectData implements SubjectData {
|
|||||||
return a == null && b == null || a != null && b != null && a.equalsIgnoreCase(b);
|
return a == null && b == null || a != null && b != null && a.equalsIgnoreCase(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ContextComparator implements Comparator<Set<Context>> {
|
private static class ContextComparator implements Comparator<ContextSet> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(Set<Context> o1, Set<Context> o2) {
|
public int compare(ContextSet o1, ContextSet o2) {
|
||||||
int i = Integer.compare(o1.size(), o2.size());
|
int i = Integer.compare(o1.size(), o2.size());
|
||||||
return i == 0 ? 1 : i;
|
return i == 0 ? 1 : i;
|
||||||
}
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.sponge.service.calculated;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@AllArgsConstructor(staticName = "of")
|
||||||
|
public class OptionLookup {
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
private final ContextSet contexts;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.sponge.service.calculated;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@AllArgsConstructor(staticName = "of")
|
||||||
|
public class PermissionLookup {
|
||||||
|
|
||||||
|
private final String node;
|
||||||
|
private final ContextSet contexts;
|
||||||
|
|
||||||
|
}
|
@ -26,30 +26,31 @@ import com.google.common.cache.CacheBuilder;
|
|||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
import org.spongepowered.api.service.context.Context;
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
import me.lucko.luckperms.sponge.service.base.LPSubjectCollection;
|
||||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple persistable subject collection
|
* A simple persistable subject collection
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PersistedCollection implements SubjectCollection {
|
public class PersistedCollection implements LPSubjectCollection {
|
||||||
private final LuckPermsService service;
|
private final LuckPermsService service;
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final String identifier;
|
private final String identifier;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.NONE)
|
||||||
private final LoadingCache<String, PersistedSubject> subjects = CacheBuilder.newBuilder()
|
private final LoadingCache<String, PersistedSubject> subjects = CacheBuilder.newBuilder()
|
||||||
.build(new CacheLoader<String, PersistedSubject>() {
|
.build(new CacheLoader<String, PersistedSubject>() {
|
||||||
@Override
|
@Override
|
||||||
@ -77,19 +78,14 @@ public class PersistedCollection implements SubjectCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Subject> getAllSubjects() {
|
public Collection<LPSubject> getSubjects() {
|
||||||
return subjects.asMap().values().stream().map(s -> (Subject) s).collect(ImmutableCollectors.toImmutableList());
|
return subjects.asMap().values().stream().map(s -> (LPSubject) s).collect(ImmutableCollectors.toImmutableList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Subject, Boolean> getAllWithPermission(@NonNull String id) {
|
public Map<LPSubject, Boolean> getWithPermission(@NonNull ContextSet contexts, @NonNull String node) {
|
||||||
return getAllWithPermission(ImmutableSet.of(), id);
|
ImmutableMap.Builder<LPSubject, Boolean> m = ImmutableMap.builder();
|
||||||
}
|
for (LPSubject subject : subjects.asMap().values()) {
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
|
||||||
ImmutableMap.Builder<Subject, Boolean> m = ImmutableMap.builder();
|
|
||||||
for (Subject subject : subjects.asMap().values()) {
|
|
||||||
Tristate ts = subject.getPermissionValue(contexts, node);
|
Tristate ts = subject.getPermissionValue(contexts, node);
|
||||||
if (ts != Tristate.UNDEFINED) {
|
if (ts != Tristate.UNDEFINED) {
|
||||||
m.put(subject, ts.asBoolean());
|
m.put(subject, ts.asBoolean());
|
||||||
@ -100,7 +96,7 @@ public class PersistedCollection implements SubjectCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getDefaults() {
|
public SubjectReference getDefaultSubject() {
|
||||||
return service.getDefaultSubjects().get(identifier);
|
return SubjectReference.of("defaults", identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,22 +23,22 @@
|
|||||||
package me.lucko.luckperms.sponge.service.persisted;
|
package me.lucko.luckperms.sponge.service.persisted;
|
||||||
|
|
||||||
import co.aikar.timings.Timing;
|
import co.aikar.timings.Timing;
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
import me.lucko.luckperms.sponge.service.data.CalculatedSubjectData;
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.calculated.CalculatedSubjectData;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectCollectionReference;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import me.lucko.luckperms.sponge.timings.LPTiming;
|
import me.lucko.luckperms.sponge.timings.LPTiming;
|
||||||
import org.spongepowered.api.command.CommandSource;
|
import org.spongepowered.api.command.CommandSource;
|
||||||
import org.spongepowered.api.service.context.Context;
|
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -46,11 +46,12 @@ import java.util.Set;
|
|||||||
* A simple persistable Subject implementation
|
* A simple persistable Subject implementation
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
public class PersistedSubject implements Subject {
|
public class PersistedSubject implements LPSubject {
|
||||||
private final String identifier;
|
private final String identifier;
|
||||||
|
|
||||||
|
@Getter
|
||||||
private final LuckPermsService service;
|
private final LuckPermsService service;
|
||||||
private final PersistedCollection containingCollection;
|
private final SubjectCollectionReference parentCollection;
|
||||||
private final PersistedSubjectData subjectData;
|
private final PersistedSubjectData subjectData;
|
||||||
private final CalculatedSubjectData transientSubjectData;
|
private final CalculatedSubjectData transientSubjectData;
|
||||||
private final BufferedRequest<Void> saveBuffer = new BufferedRequest<Void>(1000L, r -> PersistedSubject.this.service.getPlugin().doAsync(r)) {
|
private final BufferedRequest<Void> saveBuffer = new BufferedRequest<Void>(1000L, r -> PersistedSubject.this.service.getPlugin().doAsync(r)) {
|
||||||
@ -70,9 +71,9 @@ public class PersistedSubject implements Subject {
|
|||||||
public PersistedSubject(String identifier, LuckPermsService service, PersistedCollection containingCollection) {
|
public PersistedSubject(String identifier, LuckPermsService service, PersistedCollection containingCollection) {
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
this.service = service;
|
this.service = service;
|
||||||
this.containingCollection = containingCollection;
|
this.parentCollection = containingCollection.toReference();
|
||||||
this.subjectData = new PersistedSubjectData(service, "local:" + containingCollection.getIdentifier() + "/" + identifier + "(p)", this);
|
this.subjectData = new PersistedSubjectData(service, "local:" + containingCollection.getIdentifier() + "/" + identifier + "(p)", this);
|
||||||
this.transientSubjectData = new CalculatedSubjectData(service, "local:" + containingCollection.getIdentifier() + "/" + identifier + "(t)");
|
this.transientSubjectData = new CalculatedSubjectData(this, service, "local:" + containingCollection.getIdentifier() + "/" + identifier + "(t)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadData(SubjectDataHolder dataHolder) {
|
public void loadData(SubjectDataHolder dataHolder) {
|
||||||
@ -91,12 +92,7 @@ public class PersistedSubject implements Subject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
public Tristate getPermissionValue(@NonNull ContextSet contexts, @NonNull String node) {
|
||||||
return getPermissionValue(contexts, node).asBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) {
|
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_PERMISSION_VALUE)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_PERMISSION_VALUE)) {
|
||||||
Tristate res = subjectData.getPermissionValue(contexts, node);
|
Tristate res = subjectData.getPermissionValue(contexts, node);
|
||||||
if (res != Tristate.UNDEFINED) {
|
if (res != Tristate.UNDEFINED) {
|
||||||
@ -108,18 +104,18 @@ public class PersistedSubject implements Subject {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Subject parent : getParents(contexts)) {
|
for (SubjectReference parent : getParents(contexts)) {
|
||||||
Tristate tempRes = parent.getPermissionValue(contexts, node);
|
Tristate tempRes = parent.resolve(service).getPermissionValue(contexts, node);
|
||||||
if (tempRes != Tristate.UNDEFINED) {
|
if (tempRes != Tristate.UNDEFINED) {
|
||||||
return tempRes;
|
return tempRes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
|
if (getParentCollection().resolve(service).getIdentifier().equalsIgnoreCase("defaults")) {
|
||||||
return Tristate.UNDEFINED;
|
return Tristate.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = service.getGroupSubjects().getDefaults().getPermissionValue(contexts, node);
|
res = service.getGroupSubjects().getDefaultSubject().resolve(service).getPermissionValue(contexts, node);
|
||||||
if (res != Tristate.UNDEFINED) {
|
if (res != Tristate.UNDEFINED) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -130,61 +126,61 @@ public class PersistedSubject implements Subject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject subject) {
|
public boolean isChildOf(@NonNull ContextSet contexts, @NonNull SubjectReference subject) {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_IS_CHILD_OF)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_IS_CHILD_OF)) {
|
||||||
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
|
if (getParentCollection().resolve(service).getIdentifier().equalsIgnoreCase("defaults")) {
|
||||||
return subjectData.getParents(contexts).contains(subject) ||
|
return subjectData.getParents(contexts).contains(subject) ||
|
||||||
transientSubjectData.getParents(contexts).contains(subject);
|
transientSubjectData.getParents(contexts).contains(subject);
|
||||||
} else {
|
} else {
|
||||||
return subjectData.getParents(contexts).contains(subject) ||
|
return subjectData.getParents(contexts).contains(subject) ||
|
||||||
transientSubjectData.getParents(contexts).contains(subject) ||
|
transientSubjectData.getParents(contexts).contains(subject) ||
|
||||||
getContainingCollection().getDefaults().getParents(contexts).contains(subject) ||
|
getParentCollection().resolve(service).getDefaultSubject().resolve(service).getParents(contexts).contains(subject) ||
|
||||||
service.getDefaults().getParents(contexts).contains(subject);
|
service.getDefaults().getParents(contexts).contains(subject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Subject> getParents(@NonNull Set<Context> contexts) {
|
public Set<SubjectReference> getParents(@NonNull ContextSet contexts) {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_PARENTS)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_PARENTS)) {
|
||||||
List<Subject> s = new ArrayList<>();
|
Set<SubjectReference> s = new HashSet<>();
|
||||||
s.addAll(subjectData.getParents(contexts));
|
s.addAll(subjectData.getParents(contexts));
|
||||||
s.addAll(transientSubjectData.getParents(contexts));
|
s.addAll(transientSubjectData.getParents(contexts));
|
||||||
|
|
||||||
if (!getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
|
if (!getParentCollection().resolve(service).getIdentifier().equalsIgnoreCase("defaults")) {
|
||||||
s.addAll(getContainingCollection().getDefaults().getParents(contexts));
|
s.addAll(getParentCollection().resolve(service).getDefaultSubject().resolve(service).getParents(contexts));
|
||||||
s.addAll(service.getDefaults().getParents(contexts));
|
s.addAll(service.getDefaults().getParents(contexts));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ImmutableList.copyOf(s);
|
return ImmutableSet.copyOf(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<String> getOption(Set<Context> set, String key) {
|
public Optional<String> getOption(ContextSet set, String key) {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_OPTION)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_OPTION)) {
|
||||||
Optional<String> res = Optional.ofNullable(subjectData.getOptions(getActiveContexts()).get(key));
|
Optional<String> res = Optional.ofNullable(subjectData.getOptions(getActiveContextSet()).get(key));
|
||||||
if (res.isPresent()) {
|
if (res.isPresent()) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = Optional.ofNullable(transientSubjectData.getOptions(getActiveContexts()).get(key));
|
res = Optional.ofNullable(transientSubjectData.getOptions(getActiveContextSet()).get(key));
|
||||||
if (res.isPresent()) {
|
if (res.isPresent()) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Subject parent : getParents(getActiveContexts())) {
|
for (SubjectReference parent : getParents(getActiveContextSet())) {
|
||||||
Optional<String> tempRes = parent.getOption(getActiveContexts(), key);
|
Optional<String> tempRes = parent.resolve(service).getOption(getActiveContextSet(), key);
|
||||||
if (tempRes.isPresent()) {
|
if (tempRes.isPresent()) {
|
||||||
return tempRes;
|
return tempRes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
|
if (getParentCollection().resolve(service).getIdentifier().equalsIgnoreCase("defaults")) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
res = getContainingCollection().getDefaults().getOption(set, key);
|
res = getParentCollection().resolve(service).getDefaultSubject().resolve(service).getOption(set, key);
|
||||||
if (res.isPresent()) {
|
if (res.isPresent()) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -194,9 +190,9 @@ public class PersistedSubject implements Subject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Context> getActiveContexts() {
|
public ContextSet getActiveContextSet() {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_ACTIVE_CONTEXTS)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_ACTIVE_CONTEXTS)) {
|
||||||
return ImmutableSet.copyOf(LuckPermsService.convertContexts(service.getPlugin().getContextManager().getApplicableContext(this)));
|
return service.getPlugin().getContextManager().getApplicableContext(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,14 +24,10 @@ package me.lucko.luckperms.sponge.service.persisted;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
import me.lucko.luckperms.sponge.service.data.CalculatedSubjectData;
|
import me.lucko.luckperms.sponge.service.calculated.CalculatedSubjectData;
|
||||||
import org.spongepowered.api.service.context.Context;
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension of MemorySubjectData which persists data when modified
|
* Extension of MemorySubjectData which persists data when modified
|
||||||
@ -44,7 +40,7 @@ public class PersistedSubjectData extends CalculatedSubjectData {
|
|||||||
private boolean save = true;
|
private boolean save = true;
|
||||||
|
|
||||||
public PersistedSubjectData(LuckPermsService service, String calculatorDisplayName, PersistedSubject subject) {
|
public PersistedSubjectData(LuckPermsService service, String calculatorDisplayName, PersistedSubject subject) {
|
||||||
super(service, calculatorDisplayName);
|
super(subject, service, calculatorDisplayName);
|
||||||
this.subject = subject;
|
this.subject = subject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +55,7 @@ public class PersistedSubjectData extends CalculatedSubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setPermission(Set<Context> contexts, String permission, Tristate value) {
|
public boolean setPermission(ContextSet contexts, String permission, me.lucko.luckperms.api.Tristate value) {
|
||||||
boolean r = super.setPermission(contexts, permission, value);
|
boolean r = super.setPermission(contexts, permission, value);
|
||||||
save();
|
save();
|
||||||
return r;
|
return r;
|
||||||
@ -73,21 +69,21 @@ public class PersistedSubjectData extends CalculatedSubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean clearPermissions(Set<Context> context) {
|
public boolean clearPermissions(ContextSet contexts) {
|
||||||
boolean r = super.clearPermissions(context);
|
boolean r = super.clearPermissions(contexts);
|
||||||
save();
|
save();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addParent(Set<Context> contexts, Subject parent) {
|
public boolean addParent(ContextSet contexts, SubjectReference parent) {
|
||||||
boolean r = super.addParent(contexts, parent);
|
boolean r = super.addParent(contexts, parent);
|
||||||
save();
|
save();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeParent(Set<Context> contexts, Subject parent) {
|
public boolean removeParent(ContextSet contexts, SubjectReference parent) {
|
||||||
boolean r = super.removeParent(contexts, parent);
|
boolean r = super.removeParent(contexts, parent);
|
||||||
save();
|
save();
|
||||||
return r;
|
return r;
|
||||||
@ -101,21 +97,28 @@ public class PersistedSubjectData extends CalculatedSubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean clearParents(Set<Context> contexts) {
|
public boolean clearParents(ContextSet contexts) {
|
||||||
boolean r = super.clearParents(contexts);
|
boolean r = super.clearParents(contexts);
|
||||||
save();
|
save();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setOption(Set<Context> contexts, String key, @Nullable String value) {
|
public boolean setOption(ContextSet contexts, String key, String value) {
|
||||||
boolean r = super.setOption(contexts, key, value);
|
boolean r = super.setOption(contexts, key, value);
|
||||||
save();
|
save();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean clearOptions(Set<Context> contexts) {
|
public boolean unsetOption(ContextSet contexts, String key) {
|
||||||
|
boolean r = super.unsetOption(contexts, key);
|
||||||
|
save();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean clearOptions(ContextSet contexts) {
|
||||||
boolean r = super.clearOptions(contexts);
|
boolean r = super.clearOptions(contexts);
|
||||||
save();
|
save();
|
||||||
return r;
|
return r;
|
||||||
|
@ -24,9 +24,8 @@ package me.lucko.luckperms.sponge.service.persisted;
|
|||||||
|
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.sponge.service.data.CalculatedSubjectData;
|
import me.lucko.luckperms.sponge.service.calculated.CalculatedSubjectData;
|
||||||
import me.lucko.luckperms.sponge.service.data.SubjectReference;
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import org.spongepowered.api.service.context.Context;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -34,8 +33,6 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static me.lucko.luckperms.sponge.service.LuckPermsService.convertContexts;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds SubjectData in a "gson friendly" format for serialization
|
* Holds SubjectData in a "gson friendly" format for serialization
|
||||||
*/
|
*/
|
||||||
@ -45,45 +42,45 @@ public class SubjectDataHolder {
|
|||||||
private final Map<Map<String, String>, Map<String, String>> options;
|
private final Map<Map<String, String>, Map<String, String>> options;
|
||||||
private final Map<Map<String, String>, List<String>> parents;
|
private final Map<Map<String, String>, List<String>> parents;
|
||||||
|
|
||||||
public SubjectDataHolder(Map<Set<Context>, Map<String, String>> options, Map<Set<Context>, Map<String, Boolean>> permissions, Map<Set<Context>, Set<SubjectReference>> parents) {
|
public SubjectDataHolder(Map<ContextSet, Map<String, String>> options, Map<ContextSet, Map<String, Boolean>> permissions, Map<ContextSet, Set<SubjectReference>> parents) {
|
||||||
this.options = new HashMap<>();
|
this.options = new HashMap<>();
|
||||||
for (Map.Entry<Set<Context>, Map<String, String>> e : options.entrySet()) {
|
for (Map.Entry<ContextSet, Map<String, String>> e : options.entrySet()) {
|
||||||
this.options.put(convertContexts(e.getKey()).toMap(), new HashMap<>(e.getValue()));
|
this.options.put(e.getKey().toMap(), new HashMap<>(e.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.permissions = new HashMap<>();
|
this.permissions = new HashMap<>();
|
||||||
for (Map.Entry<Set<Context>, Map<String, Boolean>> e : permissions.entrySet()) {
|
for (Map.Entry<ContextSet, Map<String, Boolean>> e : permissions.entrySet()) {
|
||||||
this.permissions.put(convertContexts(e.getKey()).toMap(), new HashMap<>(e.getValue()));
|
this.permissions.put(e.getKey().toMap(), new HashMap<>(e.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.parents = new HashMap<>();
|
this.parents = new HashMap<>();
|
||||||
for (Map.Entry<Set<Context>, Set<SubjectReference>> e : parents.entrySet()) {
|
for (Map.Entry<ContextSet, Set<SubjectReference>> e : parents.entrySet()) {
|
||||||
this.parents.put(convertContexts(e.getKey()).toMap(), e.getValue().stream().map(SubjectReference::serialize).collect(Collectors.toList()));
|
this.parents.put(e.getKey().toMap(), e.getValue().stream().map(SubjectReference::serialize).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubjectDataHolder(CalculatedSubjectData data) {
|
public SubjectDataHolder(CalculatedSubjectData data) {
|
||||||
this(data.getAllOptions(), data.getAllPermissions(), data.getParents());
|
this(data.getOptions(), data.getPermissions(), data.getParents());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyTo(CalculatedSubjectData subjectData) {
|
public void copyTo(CalculatedSubjectData subjectData) {
|
||||||
subjectData.replacePermissions(permissions.entrySet().stream()
|
subjectData.replacePermissions(permissions.entrySet().stream()
|
||||||
.collect(Collectors.toMap(
|
.collect(Collectors.toMap(
|
||||||
k -> convertContexts(ContextSet.fromMap(k.getKey())),
|
k -> ContextSet.fromMap(k.getKey()),
|
||||||
Map.Entry::getValue
|
Map.Entry::getValue
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
subjectData.replaceOptions(options.entrySet().stream()
|
subjectData.replaceOptions(options.entrySet().stream()
|
||||||
.collect(Collectors.toMap(
|
.collect(Collectors.toMap(
|
||||||
k -> convertContexts(ContextSet.fromMap(k.getKey())),
|
k -> ContextSet.fromMap(k.getKey()),
|
||||||
Map.Entry::getValue
|
Map.Entry::getValue
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
subjectData.replaceParents(parents.entrySet().stream()
|
subjectData.replaceParents(parents.entrySet().stream()
|
||||||
.collect(Collectors.toMap(
|
.collect(Collectors.toMap(
|
||||||
k -> convertContexts(ContextSet.fromMap(k.getKey())),
|
k -> ContextSet.fromMap(k.getKey()),
|
||||||
v -> v.getValue().stream().map(SubjectReference::deserialize).collect(Collectors.toSet())
|
v -> v.getValue().stream().map(SubjectReference::deserialize).collect(Collectors.toSet())
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.sponge.service.references;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubjectCollection;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@AllArgsConstructor(staticName = "of")
|
||||||
|
public class SubjectCollectionReference {
|
||||||
|
|
||||||
|
private final String collection;
|
||||||
|
|
||||||
|
public LPSubjectCollection resolve(LuckPermsService service) {
|
||||||
|
return service.getSubjects(collection);
|
||||||
|
}
|
||||||
|
}
|
@ -20,14 +20,16 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.sponge.service.data;
|
package me.lucko.luckperms.sponge.service.references;
|
||||||
|
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.spongepowered.api.service.permission.PermissionService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.base.LPSubjectCollection;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -49,10 +51,14 @@ public class SubjectReference {
|
|||||||
private final String collection;
|
private final String collection;
|
||||||
private final String identifier;
|
private final String identifier;
|
||||||
|
|
||||||
public Subject resolve(PermissionService service) {
|
public LPSubject resolve(LuckPermsService service) {
|
||||||
return service.getSubjects(collection).get(identifier);
|
return service.getSubjects(collection).get(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LPSubjectCollection resolveCollection(LuckPermsService service) {
|
||||||
|
return service.getSubjects(collection);
|
||||||
|
}
|
||||||
|
|
||||||
public String serialize() {
|
public String serialize() {
|
||||||
return collection + "/" + identifier;
|
return collection + "/" + identifier;
|
||||||
}
|
}
|
@ -26,30 +26,31 @@ import com.google.common.cache.CacheBuilder;
|
|||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
import org.spongepowered.api.service.context.Context;
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
import me.lucko.luckperms.sponge.service.base.LPSubjectCollection;
|
||||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Super simple SubjectCollection implementation
|
* Super simple SubjectCollection implementation
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SimpleCollection implements SubjectCollection {
|
public class SimpleCollection implements LPSubjectCollection {
|
||||||
private final LuckPermsService service;
|
private final LuckPermsService service;
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final String identifier;
|
private final String identifier;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.NONE)
|
||||||
private final LoadingCache<String, SimpleSubject> subjects = CacheBuilder.newBuilder()
|
private final LoadingCache<String, SimpleSubject> subjects = CacheBuilder.newBuilder()
|
||||||
.build(new CacheLoader<String, SimpleSubject>() {
|
.build(new CacheLoader<String, SimpleSubject>() {
|
||||||
@Override
|
@Override
|
||||||
@ -59,7 +60,7 @@ public class SimpleCollection implements SubjectCollection {
|
|||||||
});
|
});
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject get(@NonNull String id) {
|
public LPSubject get(@NonNull String id) {
|
||||||
return subjects.getUnchecked(id.toLowerCase());
|
return subjects.getUnchecked(id.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,19 +70,14 @@ public class SimpleCollection implements SubjectCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Subject> getAllSubjects() {
|
public Collection<LPSubject> getSubjects() {
|
||||||
return subjects.asMap().values().stream().map(s -> (Subject) s).collect(ImmutableCollectors.toImmutableList());
|
return subjects.asMap().values().stream().map(s -> (LPSubject) s).collect(ImmutableCollectors.toImmutableList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Subject, Boolean> getAllWithPermission(@NonNull String id) {
|
public Map<LPSubject, Boolean> getWithPermission(@NonNull ContextSet contexts, @NonNull String node) {
|
||||||
return getAllWithPermission(ImmutableSet.of(), id);
|
ImmutableMap.Builder<LPSubject, Boolean> m = ImmutableMap.builder();
|
||||||
}
|
for (LPSubject subject : subjects.asMap().values()) {
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
|
||||||
ImmutableMap.Builder<Subject, Boolean> m = ImmutableMap.builder();
|
|
||||||
for (Subject subject : subjects.asMap().values()) {
|
|
||||||
Tristate ts = subject.getPermissionValue(contexts, node);
|
Tristate ts = subject.getPermissionValue(contexts, node);
|
||||||
if (ts != Tristate.UNDEFINED) {
|
if (ts != Tristate.UNDEFINED) {
|
||||||
m.put(subject, ts.asBoolean());
|
m.put(subject, ts.asBoolean());
|
||||||
@ -92,7 +88,7 @@ public class SimpleCollection implements SubjectCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getDefaults() {
|
public SubjectReference getDefaultSubject() {
|
||||||
return service.getDefaultSubjects().get(identifier);
|
return SubjectReference.of("defaults", identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,20 +23,24 @@
|
|||||||
package me.lucko.luckperms.sponge.service.simple;
|
package me.lucko.luckperms.sponge.service.simple;
|
||||||
|
|
||||||
import co.aikar.timings.Timing;
|
import co.aikar.timings.Timing;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
import me.lucko.luckperms.sponge.service.data.CalculatedSubjectData;
|
import me.lucko.luckperms.sponge.service.base.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.calculated.CalculatedSubjectData;
|
||||||
|
import me.lucko.luckperms.sponge.service.calculated.OptionLookup;
|
||||||
|
import me.lucko.luckperms.sponge.service.calculated.PermissionLookup;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectCollectionReference;
|
||||||
|
import me.lucko.luckperms.sponge.service.references.SubjectReference;
|
||||||
import me.lucko.luckperms.sponge.timings.LPTiming;
|
import me.lucko.luckperms.sponge.timings.LPTiming;
|
||||||
import org.spongepowered.api.command.CommandSource;
|
|
||||||
import org.spongepowered.api.service.context.Context;
|
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -44,126 +48,153 @@ import java.util.Set;
|
|||||||
* Super simple Subject implementation.
|
* Super simple Subject implementation.
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
public class SimpleSubject implements Subject {
|
public class SimpleSubject implements LPSubject {
|
||||||
private final String identifier;
|
private final String identifier;
|
||||||
|
|
||||||
private final LuckPermsService service;
|
private final LuckPermsService service;
|
||||||
private final SimpleCollection containingCollection;
|
private final SubjectCollectionReference parentCollection;
|
||||||
private final CalculatedSubjectData subjectData;
|
private final CalculatedSubjectData subjectData;
|
||||||
private final CalculatedSubjectData transientSubjectData;
|
private final CalculatedSubjectData transientSubjectData;
|
||||||
|
|
||||||
|
private final LoadingCache<PermissionLookup, Tristate> permissionLookupCache = CacheBuilder.newBuilder()
|
||||||
|
.build(new CacheLoader<PermissionLookup, Tristate>() {
|
||||||
|
@Override
|
||||||
|
public Tristate load(PermissionLookup lookup) {
|
||||||
|
return lookupPermissionValue(lookup.getContexts(), lookup.getNode());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
private final LoadingCache<ContextSet, Set<SubjectReference>> parentLookupCache = CacheBuilder.newBuilder()
|
||||||
|
.build(new CacheLoader<ContextSet, Set<SubjectReference>>() {
|
||||||
|
@Override
|
||||||
|
public Set<SubjectReference> load(ContextSet contexts) {
|
||||||
|
return lookupParents(contexts);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
private final LoadingCache<OptionLookup, Optional<String>> optionLookupCache = CacheBuilder.newBuilder()
|
||||||
|
.build(new CacheLoader<OptionLookup, Optional<String>>() {
|
||||||
|
@Override
|
||||||
|
public Optional<String> load(OptionLookup lookup) {
|
||||||
|
return lookupOptionValue(lookup.getContexts(), lookup.getKey());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
public SimpleSubject(String identifier, LuckPermsService service, SimpleCollection containingCollection) {
|
public SimpleSubject(String identifier, LuckPermsService service, SimpleCollection containingCollection) {
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
this.service = service;
|
this.service = service;
|
||||||
this.containingCollection = containingCollection;
|
this.parentCollection = containingCollection.toReference();
|
||||||
this.subjectData = new CalculatedSubjectData(service, "local:" + containingCollection.getIdentifier() + "/" + identifier + "(p)");
|
this.subjectData = new CalculatedSubjectData(this, service, "local:" + containingCollection.getIdentifier() + "/" + identifier + "(p)");
|
||||||
this.transientSubjectData = new CalculatedSubjectData(service, "local:" + containingCollection.getIdentifier() + "/" + identifier + "(t)");
|
this.transientSubjectData = new CalculatedSubjectData(this, service, "local:" + containingCollection.getIdentifier() + "/" + identifier + "(t)");
|
||||||
|
service.getLocalPermissionCaches().add(permissionLookupCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private Tristate lookupPermissionValue(ContextSet contexts, String node) {
|
||||||
public Optional<CommandSource> getCommandSource() {
|
Tristate res = transientSubjectData.getPermissionValue(contexts, node);
|
||||||
return Optional.empty();
|
if (res != Tristate.UNDEFINED) {
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
|
||||||
return getPermissionValue(contexts, node).asBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) {
|
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_PERMISSION_VALUE)) {
|
|
||||||
Tristate res = transientSubjectData.getPermissionValue(contexts, node);
|
|
||||||
if (res != Tristate.UNDEFINED) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = subjectData.getPermissionValue(contexts, node);
|
|
||||||
if (res != Tristate.UNDEFINED) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Subject parent : getParents(contexts)) {
|
|
||||||
res = parent.getPermissionValue(contexts, node);
|
|
||||||
if (res != Tristate.UNDEFINED) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
|
|
||||||
return Tristate.UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = getContainingCollection().getDefaults().getPermissionValue(contexts, node);
|
|
||||||
if (res != Tristate.UNDEFINED) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = service.getDefaults().getPermissionValue(contexts, node);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res = subjectData.getPermissionValue(contexts, node);
|
||||||
|
if (res != Tristate.UNDEFINED) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SubjectReference parent : getParents(contexts)) {
|
||||||
|
res = parent.resolve(service).getPermissionValue(contexts, node);
|
||||||
|
if (res != Tristate.UNDEFINED) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getParentCollection().resolve(service).getIdentifier().equalsIgnoreCase("defaults")) {
|
||||||
|
return Tristate.UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = getParentCollection().resolve(service).getDefaultSubject().resolve(service).getPermissionValue(contexts, node);
|
||||||
|
if (res != Tristate.UNDEFINED) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = service.getDefaults().getPermissionValue(contexts, node);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<SubjectReference> lookupParents(ContextSet contexts) {
|
||||||
|
Set<SubjectReference> s = new HashSet<>();
|
||||||
|
s.addAll(subjectData.getParents(contexts));
|
||||||
|
|
||||||
|
if (!getParentCollection().resolve(service).getIdentifier().equalsIgnoreCase("defaults")){
|
||||||
|
s.addAll(getParentCollection().resolve(service).getDefaultSubject().resolve(service).getParents(contexts));
|
||||||
|
s.addAll(service.getDefaults().getParents(contexts));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImmutableSet.copyOf(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<String> lookupOptionValue(ContextSet contexts, String key) {
|
||||||
|
Optional<String> res = Optional.ofNullable(subjectData.getOptions(contexts).get(key));
|
||||||
|
if (res.isPresent()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SubjectReference parent : getParents(getActiveContextSet())) {
|
||||||
|
Optional<String> tempRes = parent.resolve(service).getOption(contexts, key);
|
||||||
|
if (tempRes.isPresent()) {
|
||||||
|
return tempRes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getParentCollection().resolve(service).getIdentifier().equalsIgnoreCase("defaults")) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
res = getParentCollection().resolve(service).getDefaultSubject().resolve(service).getOption(contexts, key);
|
||||||
|
if (res.isPresent()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return service.getDefaults().getOption(contexts, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tristate getPermissionValue(@NonNull ContextSet contexts, @NonNull String node) {
|
||||||
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_PERMISSION_VALUE)) {
|
||||||
|
return permissionLookupCache.getUnchecked(PermissionLookup.of(node, contexts));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject subject) {
|
public boolean isChildOf(@NonNull ContextSet contexts, @NonNull SubjectReference subject) {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_IS_CHILD_OF)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_IS_CHILD_OF)) {
|
||||||
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
|
if (getParentCollection().resolve(service).getIdentifier().equalsIgnoreCase("defaults")) {
|
||||||
return subjectData.getParents(contexts).contains(subject);
|
return subjectData.getParents(contexts).contains(subject);
|
||||||
} else {
|
} else {
|
||||||
return subjectData.getParents(contexts).contains(subject) ||
|
return subjectData.getParents(contexts).contains(subject) ||
|
||||||
getContainingCollection().getDefaults().getParents(contexts).contains(subject) ||
|
getParentCollection().resolve(service).getDefaultSubject().resolve(service).getParents(contexts).contains(subject) ||
|
||||||
service.getDefaults().getParents(contexts).contains(subject);
|
service.getDefaults().getParents(contexts).contains(subject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Subject> getParents(@NonNull Set<Context> contexts) {
|
public Set<SubjectReference> getParents(@NonNull ContextSet contexts) {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_PARENTS)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_PARENTS)) {
|
||||||
List<Subject> s = new ArrayList<>();
|
return parentLookupCache.getUnchecked(contexts);
|
||||||
s.addAll(subjectData.getParents(contexts));
|
|
||||||
|
|
||||||
if (!getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")){
|
|
||||||
s.addAll(getContainingCollection().getDefaults().getParents(contexts));
|
|
||||||
s.addAll(service.getDefaults().getParents(contexts));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ImmutableList.copyOf(s);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<String> getOption(Set<Context> set, String key) {
|
public Optional<String> getOption(ContextSet contexts, String key) {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_OPTION)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_OPTION)) {
|
||||||
Optional<String> res = Optional.ofNullable(subjectData.getOptions(getActiveContexts()).get(key));
|
return optionLookupCache.getUnchecked(OptionLookup.of(key, contexts));
|
||||||
if (res.isPresent()) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Subject parent : getParents(getActiveContexts())) {
|
|
||||||
Optional<String> tempRes = parent.getOption(getActiveContexts(), key);
|
|
||||||
if (tempRes.isPresent()) {
|
|
||||||
return tempRes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
res = getContainingCollection().getDefaults().getOption(set, key);
|
|
||||||
if (res.isPresent()) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return service.getDefaults().getOption(set, key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Context> getActiveContexts() {
|
public ContextSet getActiveContextSet() {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_ACTIVE_CONTEXTS)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_ACTIVE_CONTEXTS)) {
|
||||||
return ImmutableSet.copyOf(LuckPermsService.convertContexts(service.getPlugin().getContextManager().getApplicableContext(this)));
|
return service.getPlugin().getContextManager().getApplicableContext(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user