mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-27 11:37:35 +01:00
Further improvements to the Sponge service design
This commit is contained in:
parent
1b98667365
commit
f6c440c172
@ -25,19 +25,10 @@
|
||||
|
||||
package me.lucko.luckperms.common.inheritance;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.LookupSetting;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.graph.Graph;
|
||||
import me.lucko.luckperms.common.graph.GraphTraversers;
|
||||
import me.lucko.luckperms.common.graph.TraversalAlgorithm;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* A {@link Graph} which represents an "inheritance tree".
|
||||
@ -56,57 +47,4 @@ public interface InheritanceGraph extends Graph<PermissionHolder> {
|
||||
return GraphTraversers.traverseUsing(algorithm, this, startNode);
|
||||
}
|
||||
|
||||
final class NonContextual implements InheritanceGraph {
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
NonContextual(LuckPermsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends PermissionHolder> successors(PermissionHolder holder) {
|
||||
Set<Group> successors = new TreeSet<>(holder.getInheritanceComparator());
|
||||
List<Node> nodes = holder.getOwnGroupNodes();
|
||||
for (Node n : nodes) {
|
||||
Group g = this.plugin.getGroupManager().getIfLoaded(n.getGroupName());
|
||||
if (g != null) {
|
||||
successors.add(g);
|
||||
}
|
||||
}
|
||||
return successors;
|
||||
}
|
||||
}
|
||||
|
||||
final class Contextual implements InheritanceGraph {
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
/**
|
||||
* The contexts to resolve inheritance in.
|
||||
*/
|
||||
private final Contexts context;
|
||||
|
||||
Contextual(LuckPermsPlugin plugin, Contexts context) {
|
||||
this.plugin = plugin;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends PermissionHolder> successors(PermissionHolder holder) {
|
||||
Set<Group> successors = new TreeSet<>(holder.getInheritanceComparator());
|
||||
List<Node> nodes = holder.getOwnGroupNodes(this.context.getContexts());
|
||||
for (Node n : nodes) {
|
||||
// effectively: if not (we're applying global groups or it's specific anyways)
|
||||
if (!((this.context.hasSetting(LookupSetting.APPLY_PARENTS_SET_WITHOUT_SERVER) || n.isServerSpecific()) && (this.context.hasSetting(LookupSetting.APPLY_PARENTS_SET_WITHOUT_WORLD) || n.isWorldSpecific()))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Group g = this.plugin.getGroupManager().getIfLoaded(n.getGroupName());
|
||||
if (g != null) {
|
||||
successors.add(g);
|
||||
}
|
||||
}
|
||||
return successors;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,8 +29,15 @@ import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.LookupSetting;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -51,10 +58,10 @@ public class InheritanceHandler {
|
||||
|
||||
public InheritanceHandler(LuckPermsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.nonContextualGraph = new InheritanceGraph.NonContextual(plugin);
|
||||
this.nonContextualGraph = new NonContextualGraph(plugin);
|
||||
this.contextualGraphs = Caffeine.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||
.build(key -> new InheritanceGraph.Contextual(this.plugin, key));
|
||||
.build(key -> new ContextualGraph(this.plugin, key));
|
||||
}
|
||||
|
||||
public InheritanceGraph getGraph() {
|
||||
@ -65,4 +72,57 @@ public class InheritanceHandler {
|
||||
return this.contextualGraphs.get(contexts);
|
||||
}
|
||||
|
||||
private static final class NonContextualGraph implements InheritanceGraph {
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
NonContextualGraph(LuckPermsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends PermissionHolder> successors(PermissionHolder holder) {
|
||||
Set<Group> successors = new TreeSet<>(holder.getInheritanceComparator());
|
||||
List<Node> nodes = holder.getOwnGroupNodes();
|
||||
for (Node n : nodes) {
|
||||
Group g = this.plugin.getGroupManager().getIfLoaded(n.getGroupName());
|
||||
if (g != null) {
|
||||
successors.add(g);
|
||||
}
|
||||
}
|
||||
return successors;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ContextualGraph implements InheritanceGraph {
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
/**
|
||||
* The contexts to resolve inheritance in.
|
||||
*/
|
||||
private final Contexts context;
|
||||
|
||||
ContextualGraph(LuckPermsPlugin plugin, Contexts context) {
|
||||
this.plugin = plugin;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends PermissionHolder> successors(PermissionHolder holder) {
|
||||
Set<Group> successors = new TreeSet<>(holder.getInheritanceComparator());
|
||||
List<Node> nodes = holder.getOwnGroupNodes(this.context.getContexts());
|
||||
for (Node n : nodes) {
|
||||
// effectively: if not (we're applying global groups or it's specific anyways)
|
||||
if (!((this.context.hasSetting(LookupSetting.APPLY_PARENTS_SET_WITHOUT_SERVER) || n.isServerSpecific()) && (this.context.hasSetting(LookupSetting.APPLY_PARENTS_SET_WITHOUT_WORLD) || n.isWorldSpecific()))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Group g = this.plugin.getGroupManager().getIfLoaded(n.getGroupName());
|
||||
if (g != null) {
|
||||
successors.add(g);
|
||||
}
|
||||
}
|
||||
return successors;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ import javax.annotation.Nonnull;
|
||||
public class LuckPermsMessagingService implements InternalMessagingService, IncomingMessageConsumer {
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final Set<UUID> receivedMessages;
|
||||
private final BufferedRequest<Void> updateBuffer;
|
||||
private final PushUpdateBuffer updateBuffer;
|
||||
|
||||
private final MessengerProvider messengerProvider;
|
||||
private final Messenger messenger;
|
||||
|
@ -53,7 +53,7 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
||||
*/
|
||||
private final GroupCachedData cachedData;
|
||||
|
||||
private final BufferedRequest<Void> refreshBuffer;
|
||||
private final GroupRefreshBuffer refreshBuffer;
|
||||
|
||||
public Group(String name, LuckPermsPlugin plugin) {
|
||||
super(name, plugin);
|
||||
|
@ -62,7 +62,7 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
||||
*/
|
||||
private final UserCachedData cachedData;
|
||||
|
||||
private final BufferedRequest<Void> refreshBuffer;
|
||||
private final UserRefreshBuffer refreshBuffer;
|
||||
|
||||
public User(UUID uuid, String name, LuckPermsPlugin plugin) {
|
||||
super(uuid.toString(), plugin);
|
||||
|
@ -44,14 +44,14 @@ import java.util.Objects;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class LPDescriptionBuilder implements PermissionDescription.Builder {
|
||||
public final class DescriptionBuilder implements PermissionDescription.Builder {
|
||||
@Nonnull private final LPPermissionService service;
|
||||
@Nonnull private final PluginContainer container;
|
||||
@Nonnull private final Map<String, Tristate> roles = new HashMap<>();
|
||||
@Nullable private String id = null;
|
||||
@Nullable private Text description = null;
|
||||
|
||||
public LPDescriptionBuilder(@Nonnull LPPermissionService service, @Nonnull PluginContainer container) {
|
||||
public DescriptionBuilder(@Nonnull LPPermissionService service, @Nonnull PluginContainer container) {
|
||||
this.service = Objects.requireNonNull(service, "service");
|
||||
this.container = Objects.requireNonNull(container, "container");
|
||||
}
|
||||
@ -107,8 +107,8 @@ public final class LPDescriptionBuilder implements PermissionDescription.Builder
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof LPDescriptionBuilder)) return false;
|
||||
final LPDescriptionBuilder other = (LPDescriptionBuilder) o;
|
||||
if (!(o instanceof DescriptionBuilder)) return false;
|
||||
final DescriptionBuilder other = (DescriptionBuilder) o;
|
||||
|
||||
return this.container.equals(other.container) &&
|
||||
this.roles.equals(other.roles) &&
|
@ -65,7 +65,7 @@ public final class PermissionServiceProxy implements PermissionService {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Subject getDefaults() {
|
||||
return this.handle.getDefaults().sponge();
|
||||
return this.handle.getRootDefaults().sponge();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -91,7 +91,7 @@ public final class PermissionServiceProxy implements PermissionService {
|
||||
throw new IllegalArgumentException("Couldn't find a plugin container for " + o.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
return Optional.of(new LPDescriptionBuilder(this.handle, container.get()));
|
||||
return Optional.of(new DescriptionBuilder(this.handle, container.get()));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -30,7 +30,6 @@ import me.lucko.luckperms.sponge.service.CompatibilityUtil;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
|
||||
import org.spongepowered.api.service.context.Context;
|
||||
import org.spongepowered.api.service.permission.Subject;
|
||||
@ -79,7 +78,7 @@ public final class SubjectCollectionProxy implements SubjectCollection {
|
||||
// this behaviour should be replaced when CompletableFutures are added to Sponge
|
||||
return (List) this.handle.getAllIdentifiers()
|
||||
.thenApply(ids -> ids.stream()
|
||||
.map(s -> new SubjectProxy(this.service, SubjectReferenceFactory.obtain(this.service, getIdentifier(), s)))
|
||||
.map(s -> new SubjectProxy(this.service, this.service.getReferenceFactory().obtain(getIdentifier(), s)))
|
||||
.collect(ImmutableCollectors.toList())
|
||||
).join();
|
||||
}
|
||||
|
@ -30,8 +30,7 @@ import me.lucko.luckperms.sponge.service.CompatibilityUtil;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
|
||||
import org.spongepowered.api.service.context.Context;
|
||||
import org.spongepowered.api.service.permission.Subject;
|
||||
@ -126,7 +125,7 @@ public final class SubjectDataProxy implements SubjectData {
|
||||
public boolean addParent(@Nonnull Set<Context> contexts, @Nonnull Subject parent) {
|
||||
handle().thenCompose(handle -> handle.addParent(
|
||||
CompatibilityUtil.convertContexts(contexts),
|
||||
SubjectReferenceFactory.obtain(this.service, parent)
|
||||
this.service.getReferenceFactory().obtain(parent)
|
||||
));
|
||||
return true;
|
||||
}
|
||||
@ -135,7 +134,7 @@ public final class SubjectDataProxy implements SubjectData {
|
||||
public boolean removeParent(@Nonnull Set<Context> contexts, @Nonnull Subject parent) {
|
||||
handle().thenCompose(handle -> handle.removeParent(
|
||||
CompatibilityUtil.convertContexts(contexts),
|
||||
SubjectReferenceFactory.obtain(this.service, parent)
|
||||
this.service.getReferenceFactory().obtain(parent)
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
@ -30,9 +30,8 @@ import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||
import me.lucko.luckperms.sponge.service.CompatibilityUtil;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.model.ProxiedSubject;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
|
||||
import org.spongepowered.api.command.CommandSource;
|
||||
import org.spongepowered.api.service.context.Context;
|
||||
@ -110,7 +109,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject {
|
||||
public boolean isChildOf(@Nonnull Subject parent) {
|
||||
return handle().thenApply(handle -> handle.isChildOf(
|
||||
ImmutableContextSet.empty(),
|
||||
SubjectReferenceFactory.obtain(this.service, parent)
|
||||
this.service.getReferenceFactory().obtain(parent)
|
||||
)).join();
|
||||
}
|
||||
|
||||
@ -118,7 +117,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject {
|
||||
public boolean isChildOf(@Nonnull Set<Context> contexts, @Nonnull Subject parent) {
|
||||
return handle().thenApply(handle -> handle.isChildOf(
|
||||
CompatibilityUtil.convertContexts(contexts),
|
||||
SubjectReferenceFactory.obtain(this.service, parent)
|
||||
this.service.getReferenceFactory().obtain(parent)
|
||||
)).join();
|
||||
}
|
||||
|
||||
|
@ -44,14 +44,14 @@ import java.util.Objects;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class LPDescriptionBuilder implements PermissionDescription.Builder {
|
||||
public final class DescriptionBuilder implements PermissionDescription.Builder {
|
||||
@Nonnull private final LPPermissionService service;
|
||||
@Nonnull private final PluginContainer container;
|
||||
@Nonnull private final Map<String, Tristate> roles = new HashMap<>();
|
||||
@Nullable private String id = null;
|
||||
@Nullable private Text description = null;
|
||||
|
||||
public LPDescriptionBuilder(LPPermissionService service, PluginContainer container) {
|
||||
public DescriptionBuilder(LPPermissionService service, PluginContainer container) {
|
||||
this.service = Objects.requireNonNull(service, "service");
|
||||
this.container = Objects.requireNonNull(container, "container");
|
||||
}
|
||||
@ -107,8 +107,8 @@ public final class LPDescriptionBuilder implements PermissionDescription.Builder
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof LPDescriptionBuilder)) return false;
|
||||
final LPDescriptionBuilder other = (LPDescriptionBuilder) o;
|
||||
if (!(o instanceof DescriptionBuilder)) return false;
|
||||
final DescriptionBuilder other = (DescriptionBuilder) o;
|
||||
|
||||
return this.container.equals(other.container) &&
|
||||
this.roles.equals(other.roles) &&
|
@ -31,7 +31,6 @@ import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionDescription;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.plugin.PluginContainer;
|
||||
@ -74,7 +73,7 @@ public final class PermissionServiceProxy implements PermissionService {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Subject getDefaults() {
|
||||
return this.handle.getDefaults().sponge();
|
||||
return this.handle.getRootDefaults().sponge();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -129,7 +128,7 @@ public final class PermissionServiceProxy implements PermissionService {
|
||||
}
|
||||
|
||||
// obtain a reference
|
||||
return SubjectReferenceFactory.obtain(this.handle, collectionIdentifier, subjectIdentifier);
|
||||
return this.handle.getReferenceFactory().obtain(collectionIdentifier, subjectIdentifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -139,7 +138,7 @@ public final class PermissionServiceProxy implements PermissionService {
|
||||
throw new IllegalArgumentException("Couldn't find a plugin container for " + o.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
return new LPDescriptionBuilder(this.handle, container.get());
|
||||
return new DescriptionBuilder(this.handle, container.get());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -29,7 +29,6 @@ import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||
import me.lucko.luckperms.sponge.service.CompatibilityUtil;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
|
||||
import org.spongepowered.api.service.context.Context;
|
||||
import org.spongepowered.api.service.permission.Subject;
|
||||
@ -110,7 +109,7 @@ public final class SubjectCollectionProxy implements SubjectCollection {
|
||||
throw new IllegalArgumentException("Subject identifier '" + subjectIdentifier + "' does not pass the validity predicate");
|
||||
}
|
||||
|
||||
return SubjectReferenceFactory.obtain(this.handle.getService(), getIdentifier(), subjectIdentifier);
|
||||
return this.handle.getService().getReferenceFactory().obtain(getIdentifier(), subjectIdentifier);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -30,8 +30,7 @@ import me.lucko.luckperms.sponge.service.CompatibilityUtil;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
|
||||
import org.spongepowered.api.service.context.Context;
|
||||
import org.spongepowered.api.service.permission.SubjectData;
|
||||
@ -120,13 +119,13 @@ public final class SubjectDataProxy implements SubjectData {
|
||||
@Nonnull
|
||||
@Override
|
||||
public CompletableFuture<Boolean> addParent(@Nonnull Set<Context> contexts, @Nonnull org.spongepowered.api.service.permission.SubjectReference ref) {
|
||||
return handle().thenCompose(handle -> handle.addParent(CompatibilityUtil.convertContexts(contexts), SubjectReferenceFactory.obtain(this.service, ref)));
|
||||
return handle().thenCompose(handle -> handle.addParent(CompatibilityUtil.convertContexts(contexts), this.service.getReferenceFactory().obtain(ref)));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public CompletableFuture<Boolean> removeParent(@Nonnull Set<Context> contexts, @Nonnull org.spongepowered.api.service.permission.SubjectReference ref) {
|
||||
return handle().thenCompose(handle -> handle.removeParent(CompatibilityUtil.convertContexts(contexts), SubjectReferenceFactory.obtain(this.service, ref)));
|
||||
return handle().thenCompose(handle -> handle.removeParent(CompatibilityUtil.convertContexts(contexts), this.service.getReferenceFactory().obtain(ref)));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -29,9 +29,8 @@ import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.sponge.service.CompatibilityUtil;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.model.ProxiedSubject;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
|
||||
import org.spongepowered.api.command.CommandSource;
|
||||
import org.spongepowered.api.service.context.Context;
|
||||
@ -113,12 +112,12 @@ public final class SubjectProxy implements Subject, ProxiedSubject {
|
||||
|
||||
@Override
|
||||
public boolean isChildOf(@Nonnull SubjectReference parent) {
|
||||
return handle().thenApply(handle -> handle.isChildOf(ImmutableContextSet.empty(), SubjectReferenceFactory.obtain(this.service, parent))).join();
|
||||
return handle().thenApply(handle -> handle.isChildOf(ImmutableContextSet.empty(), this.service.getReferenceFactory().obtain(parent))).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChildOf(@Nonnull Set<Context> contexts, @Nonnull SubjectReference parent) {
|
||||
return handle().thenApply(handle -> handle.isChildOf(CompatibilityUtil.convertContexts(contexts), SubjectReferenceFactory.obtain(this.service, parent))).join();
|
||||
return handle().thenApply(handle -> handle.isChildOf(CompatibilityUtil.convertContexts(contexts), this.service.getReferenceFactory().obtain(parent))).join();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
package me.lucko.luckperms.sponge.service.model;
|
||||
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
|
||||
import org.spongepowered.api.plugin.PluginContainer;
|
||||
import org.spongepowered.api.service.permission.PermissionDescription;
|
||||
import org.spongepowered.api.text.Text;
|
||||
|
@ -60,7 +60,7 @@ public interface LPPermissionService {
|
||||
|
||||
LPSubjectCollection getDefaultSubjects();
|
||||
|
||||
LPSubject getDefaults();
|
||||
LPSubject getRootDefaults();
|
||||
|
||||
Predicate<String> getIdentifierValidityPredicate();
|
||||
|
||||
|
@ -29,8 +29,6 @@ import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
|
||||
import org.spongepowered.api.command.CommandSource;
|
||||
import org.spongepowered.api.service.permission.Subject;
|
||||
@ -49,12 +47,10 @@ public interface LPSubject {
|
||||
String getIdentifier();
|
||||
|
||||
default LPSubjectReference toReference() {
|
||||
return SubjectReferenceFactory.obtain(getService(), this);
|
||||
return getService().getReferenceFactory().obtain(this);
|
||||
}
|
||||
|
||||
default LPSubject getDefaults() {
|
||||
return getService().getDefaultSubjects().loadSubject(getIdentifier()).join();
|
||||
}
|
||||
LPSubject getDefaults();
|
||||
|
||||
default Optional<String> getFriendlyIdentifier() {
|
||||
return Optional.empty();
|
||||
|
@ -30,7 +30,6 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
|
||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||
|
||||
|
@ -31,7 +31,6 @@ import com.google.common.collect.ImmutableMap;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.common.model.NodeMapType;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
|
||||
import org.spongepowered.api.service.permission.SubjectData;
|
||||
|
||||
|
@ -23,9 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.sponge.service.reference;
|
||||
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
package me.lucko.luckperms.sponge.service.model;
|
||||
|
||||
import org.spongepowered.api.service.permission.SubjectReference;
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
package me.lucko.luckperms.sponge.service.model;
|
||||
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
|
||||
import org.spongepowered.api.service.permission.Subject;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -25,9 +25,19 @@
|
||||
|
||||
package me.lucko.luckperms.sponge.service.model;
|
||||
|
||||
/**
|
||||
* Defines in what order data should be resolved.
|
||||
*/
|
||||
public enum ResolutionOrder {
|
||||
|
||||
/**
|
||||
* Marks that transient data should be considered before enduring data
|
||||
*/
|
||||
TRANSIENT_FIRST,
|
||||
|
||||
/**
|
||||
* Marks that transient data should be considered after enduring data
|
||||
*/
|
||||
TRANSIENT_LAST
|
||||
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ package me.lucko.luckperms.sponge.service.reference;
|
||||
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
|
||||
import org.spongepowered.api.service.permission.Subject;
|
||||
|
||||
@ -43,7 +44,7 @@ import javax.annotation.Nonnull;
|
||||
* Use of this class (or interface) should have no negative impact on
|
||||
* performance, as {@link #resolve()} calls are cached.
|
||||
*/
|
||||
final class LuckPermsSubjectReference implements LPSubjectReference {
|
||||
final class CachedSubjectReference implements LPSubjectReference {
|
||||
|
||||
/**
|
||||
* The time a subject instance should be cached in this reference
|
||||
@ -71,7 +72,7 @@ final class LuckPermsSubjectReference implements LPSubjectReference {
|
||||
private long lastLookup = 0L;
|
||||
private WeakReference<LPSubject> cache = null;
|
||||
|
||||
LuckPermsSubjectReference(LPPermissionService service, String collectionIdentifier, String subjectIdentifier) {
|
||||
CachedSubjectReference(LPPermissionService service, String collectionIdentifier, String subjectIdentifier) {
|
||||
this.service = Objects.requireNonNull(service);
|
||||
this.collectionIdentifier = Objects.requireNonNull(collectionIdentifier);
|
||||
this.subjectIdentifier = Objects.requireNonNull(subjectIdentifier);
|
@ -31,6 +31,7 @@ import com.google.common.base.Splitter;
|
||||
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.model.ProxiedSubject;
|
||||
|
||||
import org.spongepowered.api.service.permission.Subject;
|
||||
@ -45,34 +46,6 @@ import java.util.concurrent.TimeUnit;
|
||||
*/
|
||||
public final class SubjectReferenceFactory {
|
||||
|
||||
// static util access
|
||||
|
||||
@Deprecated
|
||||
public static LPSubjectReference deserialize(LPPermissionService service, String serializedReference) {
|
||||
Objects.requireNonNull(service, "service");
|
||||
return service.getReferenceFactory().deserialize(serializedReference);
|
||||
}
|
||||
|
||||
public static LPSubjectReference obtain(LPPermissionService service, LPSubject subject) {
|
||||
Objects.requireNonNull(service, "service");
|
||||
return service.getReferenceFactory().obtain(subject);
|
||||
}
|
||||
|
||||
public static LPSubjectReference obtain(LPPermissionService service, Subject subject) {
|
||||
Objects.requireNonNull(service, "service");
|
||||
return service.getReferenceFactory().obtain(subject);
|
||||
}
|
||||
|
||||
public static LPSubjectReference obtain(LPPermissionService service, SubjectReference reference) {
|
||||
Objects.requireNonNull(service, "service");
|
||||
return service.getReferenceFactory().obtain(reference);
|
||||
}
|
||||
|
||||
public static LPSubjectReference obtain(LPPermissionService service, String collectionIdentifier, String subjectIdentifier) {
|
||||
Objects.requireNonNull(service, "service");
|
||||
return service.getReferenceFactory().obtain(collectionIdentifier, subjectIdentifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* The permission service to obtain real subject instances from
|
||||
*/
|
||||
@ -87,9 +60,9 @@ public final class SubjectReferenceFactory {
|
||||
*
|
||||
* It's perfectly ok if two instances of the same SubjectReference exist. (hence the 1 hour expiry)
|
||||
*/
|
||||
private final LoadingCache<SubjectReferenceAttributes, LuckPermsSubjectReference> referenceCache = Caffeine.newBuilder()
|
||||
private final LoadingCache<SubjectReferenceAttributes, CachedSubjectReference> referenceCache = Caffeine.newBuilder()
|
||||
.expireAfterAccess(1, TimeUnit.HOURS)
|
||||
.build(a -> new LuckPermsSubjectReference(SubjectReferenceFactory.this.service, a.collectionId, a.id));
|
||||
.build(a -> new CachedSubjectReference(SubjectReferenceFactory.this.service, a.collectionId, a.id));
|
||||
|
||||
public SubjectReferenceFactory(LPPermissionService service) {
|
||||
this.service = service;
|
||||
@ -105,7 +78,7 @@ public final class SubjectReferenceFactory {
|
||||
public LPSubjectReference obtain(LPSubject subject) {
|
||||
Objects.requireNonNull(subject, "subject");
|
||||
LPSubjectReference ret = obtain(subject.getParentCollection().getIdentifier(), subject.getIdentifier());
|
||||
((LuckPermsSubjectReference) ret).fillCache(subject);
|
||||
((CachedSubjectReference) ret).fillCache(subject);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,6 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin {
|
||||
} else {
|
||||
this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, LPPermissionService.class, this.service);
|
||||
this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, PermissionService.class, this.service.sponge());
|
||||
this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, LuckPermsService.class, this.service);
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +184,6 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin {
|
||||
getLogger().info("Providing late registration of PermissionService...");
|
||||
this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, LPPermissionService.class, this.service);
|
||||
this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, PermissionService.class, this.service.sponge());
|
||||
this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, LuckPermsService.class, this.service);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -29,7 +29,7 @@ import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.CommandUtils;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -42,11 +42,10 @@ import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||
import me.lucko.luckperms.sponge.model.SpongeGroup;
|
||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||
import me.lucko.luckperms.sponge.service.ProxyFactory;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.proxy.ProxyFactory;
|
||||
|
||||
import org.spongepowered.api.service.permission.PermissionService;
|
||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||
@ -191,7 +190,7 @@ public class SpongeGroupManager extends AbstractGroupManager<SpongeGroup> implem
|
||||
List<HeldPermission<String>> lookup = this.plugin.getStorage().getGroupsWithPermission(permission).join();
|
||||
for (HeldPermission<String> holder : lookup) {
|
||||
if (holder.asNode().getFullContexts().equals(ImmutableContextSet.empty())) {
|
||||
ret.put(SubjectReferenceFactory.obtain(getService(), getIdentifier(), holder.getHolder()), holder.getValue());
|
||||
ret.put(getService().getReferenceFactory().obtain(getIdentifier(), holder.getHolder()), holder.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,7 +206,7 @@ public class SpongeGroupManager extends AbstractGroupManager<SpongeGroup> implem
|
||||
List<HeldPermission<String>> lookup = this.plugin.getStorage().getGroupsWithPermission(permission).join();
|
||||
for (HeldPermission<String> holder : lookup) {
|
||||
if (holder.asNode().getFullContexts().equals(contexts)) {
|
||||
ret.put(SubjectReferenceFactory.obtain(getService(), getIdentifier(), holder.getHolder()), holder.getValue());
|
||||
ret.put(getService().getReferenceFactory().obtain(getIdentifier(), holder.getHolder()), holder.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,7 +234,7 @@ public class SpongeGroupManager extends AbstractGroupManager<SpongeGroup> implem
|
||||
|
||||
@Override
|
||||
public LPSubject getDefaults() {
|
||||
return getService().getDefaultSubjects().loadSubject(getIdentifier()).join();
|
||||
return getService().getDefaultSubjects().getTypeDefaults(getIdentifier());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,11 +43,10 @@ import me.lucko.luckperms.common.utils.Uuids;
|
||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||
import me.lucko.luckperms.sponge.model.SpongeUser;
|
||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||
import me.lucko.luckperms.sponge.service.ProxyFactory;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.proxy.ProxyFactory;
|
||||
|
||||
import org.spongepowered.api.service.permission.PermissionService;
|
||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||
@ -216,7 +215,7 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
|
||||
List<HeldPermission<UUID>> lookup = this.plugin.getStorage().getUsersWithPermission(permission).join();
|
||||
for (HeldPermission<UUID> holder : lookup) {
|
||||
if (holder.asNode().getFullContexts().equals(ImmutableContextSet.empty())) {
|
||||
ret.put(SubjectReferenceFactory.obtain(getService(), getIdentifier(), holder.getHolder().toString()), holder.getValue());
|
||||
ret.put(getService().getReferenceFactory().obtain(getIdentifier(), holder.getHolder().toString()), holder.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,7 +231,7 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
|
||||
List<HeldPermission<UUID>> lookup = this.plugin.getStorage().getUsersWithPermission(permission).join();
|
||||
for (HeldPermission<UUID> holder : lookup) {
|
||||
if (holder.asNode().getFullContexts().equals(contexts)) {
|
||||
ret.put(SubjectReferenceFactory.obtain(getService(), getIdentifier(), holder.getHolder().toString()), holder.getValue());
|
||||
ret.put(getService().getReferenceFactory().obtain(getIdentifier(), holder.getHolder().toString()), holder.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,7 +259,7 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
|
||||
|
||||
@Override
|
||||
public LPSubject getDefaults() {
|
||||
return getService().getDefaultSubjects().loadSubject(getIdentifier()).join();
|
||||
return getService().getDefaultSubjects().getTypeDefaults(getIdentifier());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
|
||||
public abstract class DefaultsProcessor implements PermissionProcessor {
|
||||
private final LPPermissionService service;
|
||||
protected final LPPermissionService service;
|
||||
private final ImmutableContextSet contexts;
|
||||
|
||||
public DefaultsProcessor(LPPermissionService service, ImmutableContextSet contexts) {
|
||||
@ -40,16 +40,16 @@ public abstract class DefaultsProcessor implements PermissionProcessor {
|
||||
this.contexts = contexts;
|
||||
}
|
||||
|
||||
protected abstract LPSubject getTypeDefaults(LPPermissionService service);
|
||||
protected abstract LPSubject getTypeDefaults();
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
Tristate t = getTypeDefaults(this.service).getPermissionValue(this.contexts, permission);
|
||||
Tristate t = getTypeDefaults().getPermissionValue(this.contexts, permission);
|
||||
if (t != Tristate.UNDEFINED) {
|
||||
return t;
|
||||
}
|
||||
|
||||
t = this.service.getDefaults().getPermissionValue(this.contexts, permission);
|
||||
t = this.service.getRootDefaults().getPermissionValue(this.contexts, permission);
|
||||
if (t != Tristate.UNDEFINED) {
|
||||
return t;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class FixedDefaultsProcessor extends DefaultsProcessor {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LPSubject getTypeDefaults(LPPermissionService service) {
|
||||
protected LPSubject getTypeDefaults() {
|
||||
return this.defaultsSubject;
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public class GroupDefaultsProcessor extends DefaultsProcessor implements Permiss
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LPSubject getTypeDefaults(LPPermissionService service) {
|
||||
return service.getGroupSubjects().getDefaults();
|
||||
protected LPSubject getTypeDefaults() {
|
||||
return this.service.getGroupSubjects().getDefaults();
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public class UserDefaultsProcessor extends DefaultsProcessor implements Permissi
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LPSubject getTypeDefaults(LPPermissionService service) {
|
||||
return service.getUserSubjects().getDefaults();
|
||||
protected LPSubject getTypeDefaults() {
|
||||
return this.service.getUserSubjects().getDefaults();
|
||||
}
|
||||
}
|
||||
|
@ -36,13 +36,17 @@ import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||
import me.lucko.luckperms.sponge.contexts.SpongeProxiedContextCalculator;
|
||||
import me.lucko.luckperms.sponge.managers.SpongeGroupManager;
|
||||
import me.lucko.luckperms.sponge.managers.SpongeUserManager;
|
||||
import me.lucko.luckperms.sponge.service.misc.SimplePermissionDescription;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionDescription;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.persisted.DefaultsCollection;
|
||||
import me.lucko.luckperms.sponge.service.persisted.PersistedCollection;
|
||||
import me.lucko.luckperms.sponge.service.persisted.SubjectStorage;
|
||||
import me.lucko.luckperms.sponge.service.proxy.ProxyFactory;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
import me.lucko.luckperms.sponge.service.storage.SubjectStorage;
|
||||
|
||||
import org.spongepowered.api.plugin.PluginContainer;
|
||||
import org.spongepowered.api.service.context.ContextCalculator;
|
||||
@ -63,17 +67,39 @@ import java.util.function.Predicate;
|
||||
*/
|
||||
public class LuckPermsService implements LPPermissionService {
|
||||
|
||||
/**
|
||||
* The plugin
|
||||
*/
|
||||
private final LPSpongePlugin plugin;
|
||||
|
||||
/**
|
||||
* A cached proxy of this instance
|
||||
*/
|
||||
private final PermissionService spongeProxy;
|
||||
|
||||
/**
|
||||
* Reference factory, used to obtain {@link LPSubjectReference}s.
|
||||
*/
|
||||
private final SubjectReferenceFactory referenceFactory;
|
||||
private final SubjectStorage storage;
|
||||
private final SpongeUserManager userSubjects;
|
||||
private final SpongeGroupManager groupSubjects;
|
||||
private final PersistedCollection defaultSubjects;
|
||||
private final Set<LPPermissionDescription> descriptionSet;
|
||||
|
||||
/**
|
||||
* Subject storage, used to save PersistedSubjects to a file
|
||||
*/
|
||||
private final SubjectStorage storage;
|
||||
|
||||
/**
|
||||
* The defaults subject collection
|
||||
*/
|
||||
private final DefaultsCollection defaultSubjects;
|
||||
|
||||
/**
|
||||
* A set of registered permission description instances
|
||||
*/
|
||||
private final Set<LPPermissionDescription> permissionDescriptions;
|
||||
|
||||
/**
|
||||
* The loaded collections in this service
|
||||
*/
|
||||
private final LoadingCache<String, LPSubjectCollection> collections = Caffeine.newBuilder()
|
||||
.build(s -> new PersistedCollection(this, s));
|
||||
|
||||
@ -81,29 +107,33 @@ public class LuckPermsService implements LPPermissionService {
|
||||
this.plugin = plugin;
|
||||
this.referenceFactory = new SubjectReferenceFactory(this);
|
||||
this.spongeProxy = ProxyFactory.toSponge(this);
|
||||
this.permissionDescriptions = ConcurrentHashMap.newKeySet();
|
||||
|
||||
// init subject storage
|
||||
this.storage = new SubjectStorage(this, new File(plugin.getBootstrap().getDataDirectory(), "sponge-data"));
|
||||
|
||||
this.userSubjects = plugin.getUserManager();
|
||||
this.groupSubjects = plugin.getGroupManager();
|
||||
this.defaultSubjects = new PersistedCollection(this, "defaults");
|
||||
// load defaults collection
|
||||
this.defaultSubjects = new DefaultsCollection(this);
|
||||
this.defaultSubjects.loadAll();
|
||||
|
||||
this.collections.put("user", this.userSubjects);
|
||||
this.collections.put("group", this.groupSubjects);
|
||||
// pre-populate collections map with the default types
|
||||
this.collections.put("user", plugin.getUserManager());
|
||||
this.collections.put("group", plugin.getGroupManager());
|
||||
this.collections.put("defaults", this.defaultSubjects);
|
||||
|
||||
for (String collection : this.storage.getSavedCollections()) {
|
||||
if (this.collections.asMap().containsKey(collection.toLowerCase())) {
|
||||
// load known collections
|
||||
for (String identifier : this.storage.getSavedCollections()) {
|
||||
if (this.collections.asMap().containsKey(identifier.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PersistedCollection c = new PersistedCollection(this, collection.toLowerCase());
|
||||
c.loadAll();
|
||||
this.collections.put(c.getIdentifier(), c);
|
||||
}
|
||||
// load data
|
||||
PersistedCollection collection = new PersistedCollection(this, identifier.toLowerCase());
|
||||
collection.loadAll();
|
||||
|
||||
this.descriptionSet = ConcurrentHashMap.newKeySet();
|
||||
// cache in this instance
|
||||
this.collections.put(collection.getIdentifier(), collection);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -132,22 +162,22 @@ public class LuckPermsService implements LPPermissionService {
|
||||
|
||||
@Override
|
||||
public SpongeUserManager getUserSubjects() {
|
||||
return this.userSubjects;
|
||||
return this.plugin.getUserManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpongeGroupManager getGroupSubjects() {
|
||||
return this.groupSubjects;
|
||||
return this.plugin.getGroupManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistedCollection getDefaultSubjects() {
|
||||
public DefaultsCollection getDefaultSubjects() {
|
||||
return this.defaultSubjects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LPSubject getDefaults() {
|
||||
return getDefaultSubjects().loadSubject("default").join();
|
||||
public LPSubject getRootDefaults() {
|
||||
return this.defaultSubjects.getRootSubject();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -168,15 +198,15 @@ public class LuckPermsService implements LPPermissionService {
|
||||
|
||||
@Override
|
||||
public LPPermissionDescription registerPermissionDescription(String id, Text description, PluginContainer owner) {
|
||||
LuckPermsPermissionDescription desc = new LuckPermsPermissionDescription(this, id, description, owner);
|
||||
this.descriptionSet.add(desc);
|
||||
SimplePermissionDescription desc = new SimplePermissionDescription(this, id, description, owner);
|
||||
this.permissionDescriptions.add(desc);
|
||||
return desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<LPPermissionDescription> getDescription(String s) {
|
||||
Objects.requireNonNull(s);
|
||||
for (LPPermissionDescription d : this.descriptionSet) {
|
||||
for (LPPermissionDescription d : this.permissionDescriptions) {
|
||||
if (d.getId().equals(s)) {
|
||||
return Optional.of(d);
|
||||
}
|
||||
@ -187,11 +217,11 @@ public class LuckPermsService implements LPPermissionService {
|
||||
|
||||
@Override
|
||||
public ImmutableSet<LPPermissionDescription> getDescriptions() {
|
||||
Set<LPPermissionDescription> descriptions = new HashSet<>(this.descriptionSet);
|
||||
Set<LPPermissionDescription> descriptions = new HashSet<>(this.permissionDescriptions);
|
||||
|
||||
// collect known values from the permission vault
|
||||
for (String knownPermission : this.plugin.getPermissionVault().getKnownPermissions()) {
|
||||
LPPermissionDescription desc = new LuckPermsPermissionDescription(this, knownPermission, null, null);
|
||||
LPPermissionDescription desc = new SimplePermissionDescription(this, knownPermission, null, null);
|
||||
|
||||
// don't override plugin defined values
|
||||
if (!descriptions.contains(desc)) {
|
||||
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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 me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.sponge.service.internal.GroupSubject;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
|
||||
import org.spongepowered.api.service.permission.PermissionService;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class SubjectComparator implements Comparator<LPSubjectReference> {
|
||||
private static final Comparator<LPSubjectReference> INSTANCE = new SubjectComparator();
|
||||
private static final Comparator<LPSubjectReference> REVERSE = INSTANCE.reversed();
|
||||
|
||||
public static Comparator<LPSubjectReference> normal() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static Comparator<LPSubjectReference> reverse() {
|
||||
return REVERSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(LPSubjectReference o1, LPSubjectReference o2) {
|
||||
if (o1.equals(o2)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean o1isGroup = o1.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP);
|
||||
boolean o2isGroup = o2.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP);
|
||||
|
||||
if (o1isGroup != o2isGroup) {
|
||||
return o1isGroup ? 1 : -1;
|
||||
}
|
||||
|
||||
// Neither are groups
|
||||
if (!o1isGroup) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Group g1 = ((GroupSubject) o1.resolveLp().join()).getParent();
|
||||
Group g2 = ((GroupSubject) o2.resolveLp().join()).getParent();
|
||||
|
||||
return Integer.compare(g1.getWeight().orElse(0), g2.getWeight().orElse(0)) == 1 ? 1 : -1;
|
||||
}
|
||||
}
|
@ -29,29 +29,16 @@ import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.caching.MetaContexts;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.metastacking.MetaStackDefinition;
|
||||
import me.lucko.luckperms.common.caching.AbstractCachedData;
|
||||
import me.lucko.luckperms.common.caching.type.MetaAccumulator;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.calculators.PermissionCalculator;
|
||||
import me.lucko.luckperms.common.calculators.PermissionCalculatorMetadata;
|
||||
import me.lucko.luckperms.common.graph.TraversalAlgorithm;
|
||||
import me.lucko.luckperms.common.metastacking.SimpleMetaStackDefinition;
|
||||
import me.lucko.luckperms.common.metastacking.StandardStackElements;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.processors.MapProcessor;
|
||||
import me.lucko.luckperms.common.processors.PermissionProcessor;
|
||||
import me.lucko.luckperms.common.processors.WildcardProcessor;
|
||||
import me.lucko.luckperms.common.verbose.CheckOrigin;
|
||||
import me.lucko.luckperms.sponge.processors.FixedDefaultsProcessor;
|
||||
import me.lucko.luckperms.sponge.processors.SpongeWildcardProcessor;
|
||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||
import me.lucko.luckperms.sponge.service.inheritance.SubjectInheritanceGraph;
|
||||
import me.lucko.luckperms.sponge.service.inheritance.SubjectInheritanceGraphs;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
@ -60,17 +47,17 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class CalculatedSubject implements LPSubject {
|
||||
private static final MetaStackDefinition DEFAULT_META_STACK = new SimpleMetaStackDefinition(
|
||||
ImmutableList.of(StandardStackElements.HIGHEST_PRIORITY),
|
||||
"", "", ""
|
||||
);
|
||||
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final LPSpongePlugin plugin;
|
||||
private final SubjectCachedData cachedData;
|
||||
|
||||
protected CalculatedSubject(LuckPermsPlugin plugin) {
|
||||
protected CalculatedSubject(LPSpongePlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.cachedData = new SubjectCachedData(plugin);
|
||||
this.cachedData = new SubjectCachedData(this, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LPSubject getDefaults() {
|
||||
return this.plugin.getService().getDefaultSubjects().getTypeDefaults(getParentCollection().getIdentifier());
|
||||
}
|
||||
|
||||
public abstract CalculatedSubjectData getSubjectData();
|
||||
@ -353,58 +340,4 @@ public abstract class CalculatedSubject implements LPSubject {
|
||||
this.cachedData.invalidateCaches();
|
||||
}
|
||||
|
||||
private final class SubjectCachedData extends AbstractCachedData implements CalculatorFactory {
|
||||
private SubjectCachedData(LuckPermsPlugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PermissionCalculatorMetadata getMetadataForContexts(Contexts contexts) {
|
||||
return PermissionCalculatorMetadata.of(null, getParentCollection().getIdentifier() + "/" + getIdentifier(), contexts.getContexts());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CalculatorFactory getCalculatorFactory() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MetaContexts getDefaultMetaContexts(Contexts contexts) {
|
||||
return MetaContexts.of(contexts, DEFAULT_META_STACK, DEFAULT_META_STACK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Boolean> resolvePermissions() {
|
||||
return resolveAllPermissions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Boolean> resolvePermissions(Contexts contexts) {
|
||||
return resolveAllPermissions(contexts.getContexts().makeImmutable());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void resolveMeta(MetaAccumulator accumulator) {
|
||||
resolveAllOptions(accumulator);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void resolveMeta(MetaAccumulator accumulator, MetaContexts contexts) {
|
||||
resolveAllOptions(accumulator, contexts.getContexts().getContexts().makeImmutable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionCalculator build(Contexts contexts, PermissionCalculatorMetadata metadata) {
|
||||
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
|
||||
processors.add(new MapProcessor());
|
||||
processors.add(new SpongeWildcardProcessor());
|
||||
processors.add(new WildcardProcessor());
|
||||
|
||||
if (!getParentCollection().isDefaultsCollection()) {
|
||||
processors.add(new FixedDefaultsProcessor(getService(), contexts.getContexts().makeImmutable(), getDefaults()));
|
||||
}
|
||||
|
||||
return new PermissionCalculator(this.plugin, metadata, processors.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,12 +33,11 @@ import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.common.contexts.ContextSetComparator;
|
||||
import me.lucko.luckperms.common.model.NodeMapType;
|
||||
import me.lucko.luckperms.sponge.service.ProxyFactory;
|
||||
import me.lucko.luckperms.sponge.service.SubjectComparator;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.proxy.ProxyFactory;
|
||||
|
||||
import org.spongepowered.api.service.permission.SubjectData;
|
||||
|
||||
@ -207,7 +206,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
public ImmutableMap<ImmutableContextSet, ImmutableList<LPSubjectReference>> getAllParents() {
|
||||
ImmutableMap.Builder<ImmutableContextSet, ImmutableList<LPSubjectReference>> map = ImmutableMap.builder();
|
||||
for (Map.Entry<ImmutableContextSet, Set<LPSubjectReference>> e : this.parents.entrySet()) {
|
||||
map.put(e.getKey(), ImmutableList.sortedCopyOf(SubjectComparator.reverse(), e.getValue()));
|
||||
map.put(e.getKey(), ImmutableList.copyOf(e.getValue()));
|
||||
}
|
||||
return map.build();
|
||||
}
|
||||
|
@ -30,78 +30,77 @@ import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.common.model.NodeMapType;
|
||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Extension of CalculatedSubjectData which allows subclasses to respond to updates
|
||||
*/
|
||||
public abstract class MonitoredSubjectData extends CalculatedSubjectData {
|
||||
private final Function<Boolean, Boolean> saveFunction = b -> {
|
||||
onUpdate(b);
|
||||
return b;
|
||||
};
|
||||
|
||||
public MonitoredSubjectData(LPSubject subject, NodeMapType type, LuckPermsService service) {
|
||||
super(subject, type, service);
|
||||
}
|
||||
|
||||
private boolean callUpdate(boolean success) {
|
||||
onUpdate(success);
|
||||
return success;
|
||||
}
|
||||
|
||||
protected abstract void onUpdate(boolean success);
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> setPermission(ImmutableContextSet contexts, String permission, Tristate value) {
|
||||
return super.setPermission(contexts, permission, value).thenApply(this.saveFunction);
|
||||
return super.setPermission(contexts, permission, value).thenApply(this::callUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> clearPermissions() {
|
||||
return super.clearPermissions().thenApply(this.saveFunction);
|
||||
return super.clearPermissions().thenApply(this::callUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> clearPermissions(ImmutableContextSet contexts) {
|
||||
return super.clearPermissions(contexts).thenApply(this.saveFunction);
|
||||
return super.clearPermissions(contexts).thenApply(this::callUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> addParent(ImmutableContextSet contexts, LPSubjectReference parent) {
|
||||
return super.addParent(contexts, parent).thenApply(this.saveFunction);
|
||||
return super.addParent(contexts, parent).thenApply(this::callUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> removeParent(ImmutableContextSet contexts, LPSubjectReference parent) {
|
||||
return super.removeParent(contexts, parent).thenApply(this.saveFunction);
|
||||
return super.removeParent(contexts, parent).thenApply(this::callUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> clearParents() {
|
||||
return super.clearParents().thenApply(this.saveFunction);
|
||||
return super.clearParents().thenApply(this::callUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> clearParents(ImmutableContextSet contexts) {
|
||||
return super.clearParents(contexts).thenApply(this.saveFunction);
|
||||
return super.clearParents(contexts).thenApply(this::callUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> setOption(ImmutableContextSet contexts, String key, String value) {
|
||||
return super.setOption(contexts, key, value).thenApply(this.saveFunction);
|
||||
return super.setOption(contexts, key, value).thenApply(this::callUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> unsetOption(ImmutableContextSet contexts, String key) {
|
||||
return super.unsetOption(contexts, key).thenApply(this.saveFunction);
|
||||
return super.unsetOption(contexts, key).thenApply(this::callUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> clearOptions() {
|
||||
return super.clearOptions().thenApply(this.saveFunction);
|
||||
return super.clearOptions().thenApply(this::callUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> clearOptions(ImmutableContextSet contexts) {
|
||||
return super.clearOptions(contexts).thenApply(this.saveFunction);
|
||||
return super.clearOptions(contexts).thenApply(this::callUpdate);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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 com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.caching.MetaContexts;
|
||||
import me.lucko.luckperms.api.metastacking.MetaStackDefinition;
|
||||
import me.lucko.luckperms.common.caching.AbstractCachedData;
|
||||
import me.lucko.luckperms.common.caching.type.MetaAccumulator;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.calculators.PermissionCalculator;
|
||||
import me.lucko.luckperms.common.calculators.PermissionCalculatorMetadata;
|
||||
import me.lucko.luckperms.common.metastacking.SimpleMetaStackDefinition;
|
||||
import me.lucko.luckperms.common.metastacking.StandardStackElements;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.processors.MapProcessor;
|
||||
import me.lucko.luckperms.common.processors.PermissionProcessor;
|
||||
import me.lucko.luckperms.common.processors.WildcardProcessor;
|
||||
import me.lucko.luckperms.sponge.processors.FixedDefaultsProcessor;
|
||||
import me.lucko.luckperms.sponge.processors.SpongeWildcardProcessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SubjectCachedData extends AbstractCachedData implements CalculatorFactory {
|
||||
private static final MetaStackDefinition DEFAULT_META_STACK = new SimpleMetaStackDefinition(
|
||||
ImmutableList.of(StandardStackElements.HIGHEST_PRIORITY),
|
||||
"", "", ""
|
||||
);
|
||||
|
||||
private final CalculatedSubject subject;
|
||||
|
||||
SubjectCachedData(CalculatedSubject subject, LuckPermsPlugin plugin) {
|
||||
super(plugin);
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PermissionCalculatorMetadata getMetadataForContexts(Contexts contexts) {
|
||||
return PermissionCalculatorMetadata.of(null, this.subject.getParentCollection().getIdentifier() + "/" + this.subject.getIdentifier(), contexts.getContexts());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CalculatorFactory getCalculatorFactory() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MetaContexts getDefaultMetaContexts(Contexts contexts) {
|
||||
return MetaContexts.of(contexts, DEFAULT_META_STACK, DEFAULT_META_STACK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Boolean> resolvePermissions() {
|
||||
return this.subject.resolveAllPermissions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Boolean> resolvePermissions(Contexts contexts) {
|
||||
return this.subject.resolveAllPermissions(contexts.getContexts().makeImmutable());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void resolveMeta(MetaAccumulator accumulator) {
|
||||
this.subject.resolveAllOptions(accumulator);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void resolveMeta(MetaAccumulator accumulator, MetaContexts contexts) {
|
||||
this.subject.resolveAllOptions(accumulator, contexts.getContexts().getContexts().makeImmutable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionCalculator build(Contexts contexts, PermissionCalculatorMetadata metadata) {
|
||||
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
|
||||
processors.add(new MapProcessor());
|
||||
processors.add(new SpongeWildcardProcessor());
|
||||
processors.add(new WildcardProcessor());
|
||||
|
||||
if (!this.subject.getParentCollection().isDefaultsCollection()) {
|
||||
processors.add(new FixedDefaultsProcessor(this.subject.getService(), contexts.getContexts().makeImmutable(), this.subject.getDefaults()));
|
||||
}
|
||||
|
||||
return new PermissionCalculator(this.plugin, metadata, processors.build());
|
||||
}
|
||||
}
|
@ -27,26 +27,27 @@ package me.lucko.luckperms.sponge.service.internal;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.caching.MetaData;
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.common.graph.TraversalAlgorithm;
|
||||
import me.lucko.luckperms.common.inheritance.InheritanceGraph;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.NodeMapType;
|
||||
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.node.NodeFactory;
|
||||
import me.lucko.luckperms.common.verbose.CheckOrigin;
|
||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||
import me.lucko.luckperms.sponge.model.SpongeGroup;
|
||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||
import me.lucko.luckperms.sponge.service.ProxyFactory;
|
||||
import me.lucko.luckperms.sponge.service.SubjectComparator;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.proxy.ProxyFactory;
|
||||
|
||||
import org.spongepowered.api.service.permission.PermissionService;
|
||||
import org.spongepowered.api.service.permission.Subject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
@ -86,6 +87,11 @@ public abstract class HolderSubject<T extends PermissionHolder> implements LPSub
|
||||
return this.plugin.getService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LPSubject getDefaults() {
|
||||
return this.plugin.getService().getDefaultSubjects().getTypeDefaults(getParentCollection().getIdentifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolderSubjectData getSubjectData() {
|
||||
return this.subjectData;
|
||||
@ -98,38 +104,30 @@ public abstract class HolderSubject<T extends PermissionHolder> implements LPSub
|
||||
|
||||
@Override
|
||||
public Tristate getPermissionValue(ImmutableContextSet contexts, String permission) {
|
||||
return this.parent.getCachedData().getPermissionData(this.plugin.getContextManager().formContexts(contexts)).getPermissionValue(permission, CheckOrigin.PLATFORM_LOOKUP_CHECK);
|
||||
Contexts lookupContexts = this.plugin.getContextManager().formContexts(contexts);
|
||||
return this.parent.getCachedData().getPermissionData(lookupContexts).getPermissionValue(permission, CheckOrigin.PLATFORM_LOOKUP_CHECK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChildOf(ImmutableContextSet contexts, LPSubjectReference parent) {
|
||||
return parent.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP) && getPermissionValue(contexts, NodeFactory.groupNode(parent.getSubjectIdentifier())).asBoolean();
|
||||
return parent.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP) &&
|
||||
getPermissionValue(contexts, NodeFactory.groupNode(parent.getSubjectIdentifier())).asBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<LPSubjectReference> getParents(ImmutableContextSet contexts) {
|
||||
List<LPSubjectReference> subjects = new ArrayList<>();
|
||||
InheritanceGraph graph = this.plugin.getInheritanceHandler().getGraph(this.plugin.getContextManager().formContexts(contexts));
|
||||
Iterable<PermissionHolder> traversal = graph.traverse(TraversalAlgorithm.DEPTH_FIRST_PRE_ORDER, this.parent);
|
||||
|
||||
for (Map.Entry<String, Boolean> entry : this.parent.getCachedData().getPermissionData(this.plugin.getContextManager().formContexts(contexts)).getImmutableBacking().entrySet()) {
|
||||
if (!entry.getValue()) {
|
||||
ImmutableList.Builder<LPSubjectReference> subjects = ImmutableList.builder();
|
||||
for (PermissionHolder parent : traversal) {
|
||||
if (!(parent instanceof Group)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String groupName = NodeFactory.parseGroupNode(entry.getKey());
|
||||
if (groupName == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.plugin.getGroupManager().isLoaded(groupName)) {
|
||||
subjects.add(this.plugin.getService().getGroupSubjects().loadSubject(groupName).join().toReference());
|
||||
}
|
||||
subjects.add(((SpongeGroup) parent).sponge().toReference());
|
||||
}
|
||||
|
||||
subjects.addAll(getParentCollection().getDefaults().getParents(contexts));
|
||||
subjects.addAll(this.plugin.getService().getDefaults().getParents(contexts));
|
||||
|
||||
subjects.sort(SubjectComparator.reverse());
|
||||
return ImmutableList.copyOf(subjects);
|
||||
return subjects.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -157,7 +155,7 @@ public abstract class HolderSubject<T extends PermissionHolder> implements LPSub
|
||||
return v;
|
||||
}
|
||||
|
||||
return this.plugin.getService().getDefaults().getOption(contexts, s);
|
||||
return this.plugin.getService().getRootDefaults().getOption(contexts, s);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -40,10 +40,10 @@ import me.lucko.luckperms.common.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.node.NodeFactory;
|
||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||
import me.lucko.luckperms.sponge.service.ProxyFactory;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.proxy.ProxyFactory;
|
||||
|
||||
import org.spongepowered.api.service.permission.PermissionService;
|
||||
import org.spongepowered.api.service.permission.SubjectData;
|
||||
|
@ -23,13 +23,14 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.sponge.service;
|
||||
package me.lucko.luckperms.sponge.service.misc;
|
||||
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionDescription;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.proxy.ProxyFactory;
|
||||
|
||||
import org.spongepowered.api.plugin.PluginContainer;
|
||||
import org.spongepowered.api.service.permission.PermissionDescription;
|
||||
@ -42,7 +43,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class LuckPermsPermissionDescription implements LPPermissionDescription {
|
||||
public final class SimplePermissionDescription implements LPPermissionDescription {
|
||||
private final LPPermissionService service;
|
||||
|
||||
private final String id;
|
||||
@ -51,7 +52,7 @@ public final class LuckPermsPermissionDescription implements LPPermissionDescrip
|
||||
|
||||
private PermissionDescription spongeProxy = null;
|
||||
|
||||
public LuckPermsPermissionDescription(LPPermissionService service, String id, @Nullable Text description, @Nullable PluginContainer owner) {
|
||||
public SimplePermissionDescription(LPPermissionService service, String id, @Nullable Text description, @Nullable PluginContainer owner) {
|
||||
this.service = service;
|
||||
this.id = Objects.requireNonNull(id, "id");
|
||||
this.description = description;
|
||||
@ -102,8 +103,8 @@ public final class LuckPermsPermissionDescription implements LPPermissionDescrip
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof LuckPermsPermissionDescription)) return false;
|
||||
final LuckPermsPermissionDescription other = (LuckPermsPermissionDescription) o;
|
||||
if (!(o instanceof SimplePermissionDescription)) return false;
|
||||
final SimplePermissionDescription other = (SimplePermissionDescription) o;
|
||||
return this.id.equals(other.id);
|
||||
}
|
||||
|
||||
@ -114,7 +115,7 @@ public final class LuckPermsPermissionDescription implements LPPermissionDescrip
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LuckPermsPermissionDescription(" +
|
||||
return "PermissionDescription(" +
|
||||
"id=" + this.id + ", " +
|
||||
"description=" + this.description + ", " +
|
||||
"owner=" + this.owner + ")";
|
@ -23,16 +23,25 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.sponge.service.model;
|
||||
package me.lucko.luckperms.sponge.service.persisted;
|
||||
|
||||
import me.lucko.luckperms.common.contexts.ContextManager;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
|
||||
import org.spongepowered.api.service.permission.Subject;
|
||||
/**
|
||||
* Subject collection used for storing default subjects
|
||||
*/
|
||||
public class DefaultsCollection extends PersistedCollection {
|
||||
public DefaultsCollection(LuckPermsService service) {
|
||||
super(service, "defaults");
|
||||
}
|
||||
|
||||
public interface LuckPermsSpongePlugin extends LuckPermsPlugin {
|
||||
public LPSubject getRootSubject() {
|
||||
return obtainSubject("default");
|
||||
}
|
||||
|
||||
@Override
|
||||
ContextManager<Subject> getContextManager();
|
||||
public LPSubject getTypeDefaults(String collectionIdentifier) {
|
||||
return obtainSubject(collectionIdentifier);
|
||||
}
|
||||
|
||||
}
|
@ -37,11 +37,10 @@ import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||
import me.lucko.luckperms.sponge.service.ProxyFactory;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.storage.SubjectStorageModel;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.proxy.ProxyFactory;
|
||||
|
||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||
|
||||
@ -57,24 +56,38 @@ import java.util.function.Predicate;
|
||||
*/
|
||||
public class PersistedCollection implements LPSubjectCollection {
|
||||
private final LuckPermsService service;
|
||||
private final String identifier;
|
||||
private final boolean defaultsCollection;
|
||||
|
||||
/**
|
||||
* The collection identifier
|
||||
*/
|
||||
private final String identifier;
|
||||
|
||||
/**
|
||||
* If the collection is the defaults collection
|
||||
*/
|
||||
private final boolean isDefaultsCollection;
|
||||
|
||||
/**
|
||||
* Cached sponge proxy instance
|
||||
*/
|
||||
private final SubjectCollection spongeProxy;
|
||||
|
||||
/**
|
||||
* The contained subjects
|
||||
*/
|
||||
private final LoadingCache<String, PersistedSubject> subjects = Caffeine.newBuilder()
|
||||
.build(s -> new PersistedSubject(s, getService(), this));
|
||||
.build(s -> new PersistedSubject(getService(), this, s));
|
||||
|
||||
public PersistedCollection(LuckPermsService service, String identifier) {
|
||||
this.service = service;
|
||||
this.identifier = identifier;
|
||||
this.defaultsCollection = identifier.equals("defaults");
|
||||
this.isDefaultsCollection = identifier.equals("defaults");
|
||||
this.spongeProxy = ProxyFactory.toSponge(this);
|
||||
}
|
||||
|
||||
public void loadAll() {
|
||||
Map<String, SubjectStorageModel> holders = this.service.getStorage().loadAllFromFile(this.identifier);
|
||||
for (Map.Entry<String, SubjectStorageModel> e : holders.entrySet()) {
|
||||
Map<String, SubjectDataContainer> holders = this.service.getStorage().loadAllFromFile(this.identifier);
|
||||
for (Map.Entry<String, SubjectDataContainer> e : holders.entrySet()) {
|
||||
PersistedSubject subject = this.subjects.get(e.getKey().toLowerCase());
|
||||
if (subject != null) {
|
||||
subject.loadData(e.getValue());
|
||||
@ -104,17 +117,23 @@ public class PersistedCollection implements LPSubjectCollection {
|
||||
|
||||
@Override
|
||||
public boolean isDefaultsCollection() {
|
||||
return this.defaultsCollection;
|
||||
return this.isDefaultsCollection;
|
||||
}
|
||||
|
||||
public LPSubject obtainSubject(String identifier) {
|
||||
return this.subjects.get(identifier.toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated // not necessary to wrap with a completablefuture
|
||||
public CompletableFuture<LPSubject> loadSubject(String identifier) {
|
||||
return CompletableFuture.completedFuture(this.subjects.get(identifier.toLowerCase()));
|
||||
return CompletableFuture.completedFuture(obtainSubject(identifier));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated // not necessary to wrap with an optional
|
||||
public Optional<LPSubject> getSubject(String identifier) {
|
||||
return Optional.of(Objects.requireNonNull(this.subjects.get(identifier.toLowerCase())));
|
||||
return Optional.of(Objects.requireNonNull(obtainSubject(identifier)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -181,7 +200,7 @@ public class PersistedCollection implements LPSubjectCollection {
|
||||
|
||||
@Override
|
||||
public LPSubject getDefaults() {
|
||||
return this.service.getDefaultSubjects().loadSubject(getIdentifier()).join();
|
||||
return this.service.getDefaultSubjects().getTypeDefaults(getIdentifier());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,14 +27,14 @@ package me.lucko.luckperms.sponge.service.persisted;
|
||||
|
||||
import me.lucko.luckperms.common.buffers.BufferedRequest;
|
||||
import me.lucko.luckperms.common.model.NodeMapType;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||
import me.lucko.luckperms.sponge.service.ProxyFactory;
|
||||
import me.lucko.luckperms.sponge.service.calculated.CalculatedSubject;
|
||||
import me.lucko.luckperms.sponge.service.calculated.CalculatedSubjectData;
|
||||
import me.lucko.luckperms.sponge.service.calculated.MonitoredSubjectData;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
|
||||
import me.lucko.luckperms.sponge.service.storage.SubjectStorageModel;
|
||||
import me.lucko.luckperms.sponge.service.proxy.ProxyFactory;
|
||||
|
||||
import org.spongepowered.api.command.CommandSource;
|
||||
import org.spongepowered.api.service.permission.Subject;
|
||||
@ -46,31 +46,33 @@ import java.util.Optional;
|
||||
* A simple persistable Subject implementation
|
||||
*/
|
||||
public class PersistedSubject extends CalculatedSubject implements LPSubject {
|
||||
private final LuckPermsService service;
|
||||
|
||||
/**
|
||||
* The subjects identifier
|
||||
*/
|
||||
private final String identifier;
|
||||
|
||||
private final LuckPermsService service;
|
||||
/**
|
||||
* The parent collection
|
||||
*/
|
||||
private final PersistedCollection parentCollection;
|
||||
|
||||
// subject data instances
|
||||
private final PersistedSubjectData subjectData;
|
||||
private final CalculatedSubjectData transientSubjectData;
|
||||
|
||||
private final BufferedRequest<Void> saveBuffer = new BufferedRequest<Void>(1000L, 500L, r -> PersistedSubject.this.service.getPlugin().getBootstrap().getScheduler().doAsync(r)) {
|
||||
@Override
|
||||
protected Void perform() {
|
||||
try {
|
||||
PersistedSubject.this.service.getStorage().saveToFile(PersistedSubject.this);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* The save buffer instance for saving changes to disk
|
||||
*/
|
||||
private final SaveBuffer saveBuffer;
|
||||
|
||||
public PersistedSubject(String identifier, LuckPermsService service, PersistedCollection parentCollection) {
|
||||
public PersistedSubject(LuckPermsService service, PersistedCollection parentCollection, String identifier) {
|
||||
super(service.getPlugin());
|
||||
this.identifier = identifier;
|
||||
this.service = service;
|
||||
this.parentCollection = parentCollection;
|
||||
this.identifier = identifier;
|
||||
|
||||
this.subjectData = new PersistedSubjectData(this, NodeMapType.ENDURING, service) {
|
||||
@Override
|
||||
protected void onUpdate(boolean success) {
|
||||
@ -88,18 +90,34 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.saveBuffer = new SaveBuffer(service.getPlugin());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the subject data update event for the given {@link LPSubjectData} instance.
|
||||
*
|
||||
* @param subjectData the subject data
|
||||
*/
|
||||
private void fireUpdateEvent(LPSubjectData subjectData) {
|
||||
this.service.getPlugin().getUpdateEventHandler().fireUpdateEvent(subjectData);
|
||||
}
|
||||
|
||||
public void loadData(SubjectStorageModel dataHolder) {
|
||||
/**
|
||||
* Loads data into this {@link PersistedSubject} from the given
|
||||
* {@link SubjectDataContainer} container
|
||||
*
|
||||
* @param container the container to load from
|
||||
*/
|
||||
public void loadData(SubjectDataContainer container) {
|
||||
this.subjectData.setSave(false);
|
||||
dataHolder.applyToData(this.subjectData);
|
||||
container.applyToData(this.subjectData);
|
||||
this.subjectData.setSave(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that this subjects data is saved to disk
|
||||
*/
|
||||
public void save() {
|
||||
this.saveBuffer.request();
|
||||
}
|
||||
@ -138,4 +156,20 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject {
|
||||
public Optional<CommandSource> getCommandSource() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private final class SaveBuffer extends BufferedRequest<Void> {
|
||||
public SaveBuffer(LuckPermsPlugin plugin) {
|
||||
super(1000L, 500L, plugin.getBootstrap().getScheduler().async());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void perform() {
|
||||
try {
|
||||
PersistedSubject.this.service.getStorage().saveToFile(PersistedSubject.this);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.sponge.service.storage;
|
||||
package me.lucko.luckperms.sponge.service.persisted;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@ -38,25 +38,44 @@ import me.lucko.luckperms.common.contexts.ContextSetJsonSerializer;
|
||||
import me.lucko.luckperms.common.utils.CollationKeyCache;
|
||||
import me.lucko.luckperms.sponge.service.calculated.CalculatedSubjectData;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Used for converting a SubjectData instance to and from JSON
|
||||
* Immutable container for a subjects persisted data
|
||||
*/
|
||||
public class SubjectStorageModel {
|
||||
private final LPPermissionService service;
|
||||
public class SubjectDataContainer {
|
||||
|
||||
/**
|
||||
* Creates a {@link SubjectDataContainer} container for the given {@link LPSubjectData}.
|
||||
*
|
||||
* @param subjectData the subject data to copy from
|
||||
* @return a new container
|
||||
*/
|
||||
public static SubjectDataContainer copyOf(LPSubjectData subjectData) {
|
||||
return new SubjectDataContainer(subjectData.getAllPermissions(), subjectData.getAllOptions(), subjectData.getAllParents());
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a {@link SubjectDataContainer} container from a json object
|
||||
*
|
||||
* @param service the permission service
|
||||
* @param root the root json object
|
||||
* @return a container representing the json data
|
||||
*/
|
||||
public static SubjectDataContainer derserialize(LPPermissionService service, JsonObject root) {
|
||||
return new SubjectDataContainer(service, root);
|
||||
}
|
||||
|
||||
private final Map<ImmutableContextSet, Map<String, Boolean>> permissions;
|
||||
private final Map<ImmutableContextSet, Map<String, String>> options;
|
||||
private final Map<ImmutableContextSet, List<LPSubjectReference>> parents;
|
||||
|
||||
public SubjectStorageModel(LPPermissionService service, Map<ImmutableContextSet, ? extends Map<String, Boolean>> permissions, Map<ImmutableContextSet, ? extends Map<String, String>> options, Map<ImmutableContextSet, ? extends List<LPSubjectReference>> parents) {
|
||||
this.service = service;
|
||||
|
||||
private SubjectDataContainer(Map<ImmutableContextSet, ? extends Map<String, Boolean>> permissions, Map<ImmutableContextSet, ? extends Map<String, String>> options, Map<ImmutableContextSet, ? extends List<LPSubjectReference>> parents) {
|
||||
ImmutableMap.Builder<ImmutableContextSet, Map<String, Boolean>> permissionsBuilder = ImmutableMap.builder();
|
||||
for (Map.Entry<ImmutableContextSet, ? extends Map<String, Boolean>> e : permissions.entrySet()) {
|
||||
permissionsBuilder.put(e.getKey(), ImmutableMap.copyOf(e.getValue()));
|
||||
@ -75,18 +94,12 @@ public class SubjectStorageModel {
|
||||
}
|
||||
this.parents = parentsBuilder.build();
|
||||
}
|
||||
|
||||
public SubjectStorageModel(CalculatedSubjectData data) {
|
||||
this(data.getParentSubject().getService(), data.getAllPermissions(), data.getAllOptions(), data.getAllParents());
|
||||
}
|
||||
|
||||
public SubjectStorageModel(LPPermissionService service, JsonObject root) {
|
||||
this.service = service;
|
||||
|
||||
private SubjectDataContainer(LPPermissionService service, JsonObject root) {
|
||||
Preconditions.checkArgument(root.get("permissions").isJsonArray());
|
||||
Preconditions.checkArgument(root.get("options").isJsonArray());
|
||||
Preconditions.checkArgument(root.get("parents").isJsonArray());
|
||||
|
||||
|
||||
JsonArray permissions = root.get("permissions").getAsJsonArray();
|
||||
JsonArray options = root.get("options").getAsJsonArray();
|
||||
JsonArray parents = root.get("parents").getAsJsonArray();
|
||||
@ -96,20 +109,20 @@ public class SubjectStorageModel {
|
||||
if (!e.isJsonObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
JsonObject section = e.getAsJsonObject();
|
||||
if (!section.get("context").isJsonObject()) continue;
|
||||
if (!section.get("data").isJsonObject()) continue;
|
||||
|
||||
|
||||
JsonObject context = section.get("context").getAsJsonObject();
|
||||
JsonObject data = section.get("data").getAsJsonObject();
|
||||
|
||||
|
||||
ImmutableContextSet contextSet = ContextSetJsonSerializer.deserializeContextSet(context).makeImmutable();
|
||||
ImmutableMap.Builder<String, Boolean> perms = ImmutableMap.builder();
|
||||
for (Map.Entry<String, JsonElement> perm : data.entrySet()) {
|
||||
perms.put(perm.getKey(), perm.getValue().getAsBoolean());
|
||||
}
|
||||
|
||||
|
||||
permissionsBuilder.put(contextSet, perms.build());
|
||||
}
|
||||
this.permissions = permissionsBuilder.build();
|
||||
@ -156,13 +169,13 @@ public class SubjectStorageModel {
|
||||
if (!p.isJsonObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
JsonObject parent = p.getAsJsonObject();
|
||||
|
||||
|
||||
String collection = parent.get("collection").getAsString();
|
||||
String subject = parent.get("subject").getAsString();
|
||||
|
||||
pars.add(SubjectReferenceFactory.obtain(service, collection, subject));
|
||||
|
||||
pars.add(service.getReferenceFactory().obtain(collection, subject));
|
||||
}
|
||||
|
||||
parentsBuilder.put(contextSet, pars.build());
|
||||
@ -170,13 +183,12 @@ public class SubjectStorageModel {
|
||||
this.parents = parentsBuilder.build();
|
||||
}
|
||||
|
||||
private static <T> List<Map.Entry<ImmutableContextSet, T>> sortContextMap(Map<ImmutableContextSet, T> map) {
|
||||
List<Map.Entry<ImmutableContextSet, T>> entries = new ArrayList<>(map.entrySet());
|
||||
entries.sort((o1, o2) -> ContextSetComparator.reverse().compare(o1.getKey(), o2.getKey()));
|
||||
return entries;
|
||||
}
|
||||
|
||||
public JsonObject toJson() {
|
||||
/**
|
||||
* Converts this container to json
|
||||
*
|
||||
* @return a json serialisation of the data in this container
|
||||
*/
|
||||
public JsonObject serialize() {
|
||||
JsonObject root = new JsonObject();
|
||||
|
||||
JsonArray permissions = new JsonArray();
|
||||
@ -252,14 +264,22 @@ public class SubjectStorageModel {
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the data encapsulated by this container to the given
|
||||
* {@link CalculatedSubjectData}.
|
||||
*
|
||||
* @param subjectData the data to apply to
|
||||
*/
|
||||
public void applyToData(CalculatedSubjectData subjectData) {
|
||||
subjectData.replacePermissions(this.permissions);
|
||||
subjectData.replaceOptions(this.options);
|
||||
subjectData.replaceParents(this.parents);
|
||||
}
|
||||
|
||||
public LPPermissionService getService() {
|
||||
return this.service;
|
||||
private static <T> List<Map.Entry<ImmutableContextSet, T>> sortContextMap(Map<ImmutableContextSet, T> map) {
|
||||
List<Map.Entry<ImmutableContextSet, T>> entries = new ArrayList<>(map.entrySet());
|
||||
entries.sort((o1, o2) -> ContextSetComparator.reverse().compare(o1.getKey(), o2.getKey()));
|
||||
return entries;
|
||||
}
|
||||
|
||||
}
|
@ -23,16 +23,14 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.sponge.service.storage;
|
||||
package me.lucko.luckperms.sponge.service.persisted;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.persisted.PersistedSubject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
@ -50,8 +48,20 @@ import java.util.stream.Collectors;
|
||||
* Handles persisted Subject I/O and (de)serialization
|
||||
*/
|
||||
public class SubjectStorage {
|
||||
|
||||
/**
|
||||
* The permission service
|
||||
*/
|
||||
private final LPPermissionService service;
|
||||
|
||||
/**
|
||||
* Gson instance
|
||||
*/
|
||||
private final Gson gson;
|
||||
|
||||
/**
|
||||
* The root directory used to store files
|
||||
*/
|
||||
private final File container;
|
||||
|
||||
public SubjectStorage(LPPermissionService service, File container) {
|
||||
@ -65,6 +75,11 @@ public class SubjectStorage {
|
||||
this.container.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of all known collections
|
||||
*
|
||||
* @return the identifiers of all known collections
|
||||
*/
|
||||
public Set<String> getSavedCollections() {
|
||||
checkContainer();
|
||||
|
||||
@ -76,22 +91,42 @@ public class SubjectStorage {
|
||||
return ImmutableSet.copyOf(dirs).stream().map(File::getName).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public File resolveFile(String collectionName, String subjectName) {
|
||||
/**
|
||||
* Returns the file where a subjects data should be stored
|
||||
*
|
||||
* @param collectionIdentifier the identifier of the subjects collection
|
||||
* @param subjectIdentifier the identifier of the subject
|
||||
* @return a file
|
||||
*/
|
||||
private File resolveFile(String collectionIdentifier, String subjectIdentifier) {
|
||||
checkContainer();
|
||||
File collection = new File(this.container, collectionName);
|
||||
File collection = new File(this.container, collectionIdentifier);
|
||||
if (!collection.exists()) {
|
||||
collection.mkdirs();
|
||||
}
|
||||
|
||||
return new File(collection, subjectName + ".json");
|
||||
return new File(collection, subjectIdentifier + ".json");
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a subject
|
||||
*
|
||||
* @param subject the subject to save
|
||||
* @throws IOException if the write fails
|
||||
*/
|
||||
public void saveToFile(PersistedSubject subject) throws IOException {
|
||||
File subjectFile = resolveFile(subject.getParentCollection().getIdentifier(), subject.getIdentifier());
|
||||
saveToFile(new SubjectStorageModel(subject.getSubjectData()), subjectFile);
|
||||
saveToFile(SubjectDataContainer.copyOf(subject.getSubjectData()), subjectFile);
|
||||
}
|
||||
|
||||
public void saveToFile(SubjectStorageModel model, File file) throws IOException {
|
||||
/**
|
||||
* Saves subject data to a specific file
|
||||
*
|
||||
* @param container the data
|
||||
* @param file the file
|
||||
* @throws IOException if the write fails
|
||||
*/
|
||||
public void saveToFile(SubjectDataContainer container, File file) throws IOException {
|
||||
file.getParentFile().mkdirs();
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
@ -99,14 +134,20 @@ public class SubjectStorage {
|
||||
file.createNewFile();
|
||||
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8)) {
|
||||
this.gson.toJson(model.toJson(), writer);
|
||||
this.gson.toJson(container.serialize(), writer);
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, SubjectStorageModel> loadAllFromFile(String collectionName) {
|
||||
/**
|
||||
* Loads all known subjects for a given collection
|
||||
*
|
||||
* @param collectionIdentifier the collection identifier
|
||||
* @return a map of found subjects
|
||||
*/
|
||||
public Map<String, SubjectDataContainer> loadAllFromFile(String collectionIdentifier) {
|
||||
checkContainer();
|
||||
File collection = new File(this.container, collectionName);
|
||||
File collection = new File(this.container, collectionIdentifier);
|
||||
if (!collection.exists()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
@ -114,14 +155,14 @@ public class SubjectStorage {
|
||||
String[] fileNames = collection.list((dir, name) -> name.endsWith(".json"));
|
||||
if (fileNames == null) return Collections.emptyMap();
|
||||
|
||||
Map<String, SubjectStorageModel> holders = new HashMap<>();
|
||||
Map<String, SubjectDataContainer> holders = new HashMap<>();
|
||||
for (String name : fileNames) {
|
||||
File subject = new File(collection, name);
|
||||
File subjectFile = new File(collection, name);
|
||||
|
||||
try {
|
||||
Map.Entry<String, SubjectStorageModel> s = loadFromFile(subject);
|
||||
LoadedSubject s = loadFromFile(subjectFile);
|
||||
if (s != null) {
|
||||
holders.put(s.getKey(), s.getValue());
|
||||
holders.put(s.identifier, s.data);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -131,18 +172,33 @@ public class SubjectStorage {
|
||||
return holders;
|
||||
}
|
||||
|
||||
public Map.Entry<String, SubjectStorageModel> loadFromFile(String collectionName, String subjectName) throws IOException {
|
||||
/**
|
||||
* Loads a subject
|
||||
*
|
||||
* @param collectionIdentifier the collection id
|
||||
* @param subjectIdentifier the subject id
|
||||
* @return a loaded subject
|
||||
* @throws IOException if the read fails
|
||||
*/
|
||||
public LoadedSubject loadFromFile(String collectionIdentifier, String subjectIdentifier) throws IOException {
|
||||
checkContainer();
|
||||
File collection = new File(this.container, collectionName);
|
||||
File collection = new File(this.container, collectionIdentifier);
|
||||
if (!collection.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
File subject = new File(collection, subjectName + ".json");
|
||||
return Maps.immutableEntry(subjectName, loadFromFile(subject).getValue());
|
||||
File subject = new File(collection, subjectIdentifier + ".json");
|
||||
return new LoadedSubject(subjectIdentifier, loadFromFile(subject).data);
|
||||
}
|
||||
|
||||
public Map.Entry<String, SubjectStorageModel> loadFromFile(File file) throws IOException {
|
||||
/**
|
||||
* Loads a subject from a particular file
|
||||
*
|
||||
* @param file the file to load from
|
||||
* @return a loaded subject
|
||||
* @throws IOException if the read fails
|
||||
*/
|
||||
public LoadedSubject loadFromFile(File file) throws IOException {
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
@ -151,8 +207,18 @@ public class SubjectStorage {
|
||||
|
||||
try (BufferedReader reader = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) {
|
||||
JsonObject data = this.gson.fromJson(reader, JsonObject.class);
|
||||
SubjectStorageModel model = new SubjectStorageModel(this.service, data);
|
||||
return Maps.immutableEntry(subjectName, model);
|
||||
SubjectDataContainer model = SubjectDataContainer.derserialize(this.service, data);
|
||||
return new LoadedSubject(subjectName, model);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class LoadedSubject {
|
||||
private final String identifier;
|
||||
private final SubjectDataContainer data;
|
||||
|
||||
private LoadedSubject(String identifier, SubjectDataContainer data) {
|
||||
this.identifier = identifier;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.sponge.service;
|
||||
package me.lucko.luckperms.sponge.service.proxy;
|
||||
|
||||
import me.lucko.luckperms.common.model.NodeMapType;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionDescription;
|
Loading…
Reference in New Issue
Block a user