Refactor PermissionHolder & Sponge subjects
This commit is contained in:
@@ -23,17 +23,12 @@
|
||||
package me.lucko.luckperms.api.sponge;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.contexts.Contexts;
|
||||
import me.lucko.luckperms.core.PermissionHolder;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import org.spongepowered.api.command.CommandSource;
|
||||
@@ -46,7 +41,6 @@ import org.spongepowered.api.util.Tristate;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.lucko.luckperms.utils.ArgumentChecker.escapeCharacters;
|
||||
import static me.lucko.luckperms.utils.ArgumentChecker.unescapeCharacters;
|
||||
|
||||
@EqualsAndHashCode(of = {"holder"})
|
||||
@@ -57,25 +51,28 @@ public class LuckPermsSubject implements Subject {
|
||||
|
||||
@Getter
|
||||
private final PermissionHolder holder;
|
||||
private final EnduringData enduringData;
|
||||
private final TransientData transientData;
|
||||
private final LuckPermsSubjectData enduringData;
|
||||
private final LuckPermsSubjectData transientData;
|
||||
protected final LuckPermsService service;
|
||||
|
||||
LuckPermsSubject(PermissionHolder holder, LuckPermsService service) {
|
||||
this.holder = holder;
|
||||
this.enduringData = new EnduringData(this, service, holder);
|
||||
this.transientData = new TransientData(service, holder);
|
||||
this.enduringData = new LuckPermsSubjectData(true, this, service, holder);
|
||||
this.transientData = new LuckPermsSubjectData(true, this, service, holder);
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
private void objectSave(PermissionHolder t) {
|
||||
if (t instanceof User) {
|
||||
((User) t).refreshPermissions();
|
||||
service.getPlugin().getDatastore().saveUser(((User) t), Callback.empty());
|
||||
}
|
||||
if (t instanceof Group) {
|
||||
service.getPlugin().getDatastore().saveGroup(((Group) t), c -> service.getPlugin().runUpdateTask());
|
||||
}
|
||||
void objectSave(PermissionHolder t) {
|
||||
service.getPlugin().doAsync(() -> {
|
||||
if (t instanceof User) {
|
||||
((User) t).refreshPermissions();
|
||||
service.getPlugin().getDatastore().saveUser(((User) t));
|
||||
}
|
||||
if (t instanceof Group) {
|
||||
service.getPlugin().getDatastore().saveGroup(((Group) t));
|
||||
service.getPlugin().runUpdateTask();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,14 +159,14 @@ public class LuckPermsSubject implements Subject {
|
||||
@Override
|
||||
public Optional<String> getOption(Set<Context> set, String s) {
|
||||
if (s.equalsIgnoreCase("prefix")) {
|
||||
String prefix = getChatMeta(true, holder);
|
||||
String prefix = getChatMeta(set, true, holder);
|
||||
if (!prefix.equals("")) {
|
||||
return Optional.of(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
if (s.equalsIgnoreCase("suffix")) {
|
||||
String suffix = getChatMeta(false, holder);
|
||||
String suffix = getChatMeta(set, false, holder);
|
||||
if (!suffix.equals("")) {
|
||||
return Optional.of(suffix);
|
||||
}
|
||||
@@ -198,9 +195,15 @@ public class LuckPermsSubject implements Subject {
|
||||
return SubjectData.GLOBAL_CONTEXT;
|
||||
}
|
||||
|
||||
private String getChatMeta(boolean prefix, PermissionHolder holder) {
|
||||
private String getChatMeta(Set<Context> contexts, boolean prefix, PermissionHolder holder) {
|
||||
if (holder == null) return "";
|
||||
|
||||
Map<String, String> context = contexts.stream().collect(Collectors.toMap(Context::getKey, Context::getValue));
|
||||
String server = context.get("server");
|
||||
String world = context.get("world");
|
||||
context.remove("server");
|
||||
context.remove("world");
|
||||
|
||||
int priority = Integer.MIN_VALUE;
|
||||
String meta = null;
|
||||
|
||||
@@ -213,15 +216,17 @@ public class LuckPermsSubject implements Subject {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnServer(service.getPlugin().getConfiguration().getVaultServer(), service.getPlugin().getConfiguration().isVaultIncludingGlobal(), false)) {
|
||||
if (!n.shouldApplyOnServer(server, service.getPlugin().getConfiguration().isVaultIncludingGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* TODO per world
|
||||
if (!n.shouldApplyOnWorld(world, service.getPlugin().getConfiguration().getVaultIncludeGlobal(), false)) {
|
||||
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyWithContext(context, false)) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
Map.Entry<Integer, String> value = prefix ? n.getPrefix() : n.getSuffix();
|
||||
if (value.getKey() > priority) {
|
||||
@@ -232,650 +237,4 @@ public class LuckPermsSubject implements Subject {
|
||||
|
||||
return meta == null ? "" : unescapeCharacters(meta);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public static class EnduringData implements SubjectData {
|
||||
private final LuckPermsSubject superClass;
|
||||
private final LuckPermsService service;
|
||||
|
||||
@Getter
|
||||
private final PermissionHolder holder;
|
||||
|
||||
@Override
|
||||
public Map<Set<Context>, Map<String, Boolean>> getAllPermissions() {
|
||||
Map<Set<Context>, Map<String, Boolean>> perms = new HashMap<>();
|
||||
|
||||
for (Node n : holder.getNodes()) {
|
||||
Set<Context> contexts = n.getExtraContexts().entrySet().stream()
|
||||
.map(entry -> new Context(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (n.isServerSpecific()) {
|
||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||
}
|
||||
|
||||
if (n.isWorldSpecific()) {
|
||||
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
|
||||
}
|
||||
|
||||
if (!perms.containsKey(contexts)) {
|
||||
perms.put(contexts, new HashMap<>());
|
||||
}
|
||||
|
||||
perms.get(contexts).put(n.getPermission(), n.getValue());
|
||||
}
|
||||
|
||||
return ImmutableMap.copyOf(perms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getPermissions(Set<Context> set) {
|
||||
return ImmutableMap.copyOf(getAllPermissions().getOrDefault(set, Collections.emptyMap()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setPermission(Set<Context> set, String s, Tristate tristate) {
|
||||
if (tristate == Tristate.UNDEFINED) {
|
||||
// Unset
|
||||
Node.Builder builder = new me.lucko.luckperms.core.Node.Builder(s);
|
||||
|
||||
for (Context ct : set) {
|
||||
builder.withExtraContext(ct.getKey(), ct.getValue());
|
||||
}
|
||||
|
||||
try {
|
||||
holder.unsetPermission(builder.build());
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
superClass.objectSave(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
Node.Builder builder = new me.lucko.luckperms.core.Node.Builder(s)
|
||||
.setValue(tristate.asBoolean());
|
||||
|
||||
for (Context ct : set) {
|
||||
builder.withExtraContext(ct.getKey(), ct.getValue());
|
||||
}
|
||||
|
||||
try {
|
||||
holder.setPermission(builder.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
superClass.objectSave(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearPermissions() {
|
||||
holder.getNodes().clear();
|
||||
if (holder instanceof User) {
|
||||
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
superClass.objectSave(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearPermissions(Set<Context> set) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
for (Context c : set) {
|
||||
context.put(c.getKey(), c.getValue());
|
||||
}
|
||||
|
||||
boolean work = false;
|
||||
Iterator<Node> iterator = holder.getNodes().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Node entry = iterator.next();
|
||||
if (entry.shouldApplyWithContext(context)) {
|
||||
iterator.remove();
|
||||
work = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (holder instanceof User) {
|
||||
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
|
||||
superClass.objectSave(holder);
|
||||
return work;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Set<Context>, List<Subject>> getAllParents() {
|
||||
Map<Set<Context>, List<Subject>> parents = new HashMap<>();
|
||||
|
||||
for (Node n : holder.getAllNodes(null, Contexts.allowAll())) {
|
||||
if (!n.isGroupNode()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<Context> contexts = n.getExtraContexts().entrySet().stream()
|
||||
.map(entry -> new Context(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (n.isServerSpecific()) {
|
||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||
}
|
||||
|
||||
if (n.isWorldSpecific()) {
|
||||
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
|
||||
}
|
||||
|
||||
if (!parents.containsKey(contexts)) {
|
||||
parents.put(contexts, new ArrayList<>());
|
||||
}
|
||||
|
||||
parents.get(contexts).add(service.getGroupSubjects().get(n.getGroupName()));
|
||||
}
|
||||
|
||||
return ImmutableMap.copyOf(parents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Subject> getParents(Set<Context> contexts) {
|
||||
return ImmutableList.copyOf(getAllParents().getOrDefault(contexts, Collections.emptyList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addParent(Set<Context> set, Subject subject) {
|
||||
if (subject instanceof LuckPermsSubject) {
|
||||
LuckPermsSubject permsSubject = ((LuckPermsSubject) subject);
|
||||
|
||||
Map<String, String> contexts = set.stream().collect(Collectors.toMap(Context::getKey, Context::getValue));
|
||||
|
||||
try {
|
||||
holder.setPermission(new me.lucko.luckperms.core.Node.Builder("group." + permsSubject.getIdentifier())
|
||||
.withExtraContext(contexts)
|
||||
.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
superClass.objectSave(holder);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeParent(Set<Context> set, Subject subject) {
|
||||
if (subject instanceof LuckPermsSubject) {
|
||||
LuckPermsSubject permsSubject = ((LuckPermsSubject) subject);
|
||||
|
||||
Map<String, String> contexts = set.stream().collect(Collectors.toMap(Context::getKey, Context::getValue));
|
||||
|
||||
try {
|
||||
holder.unsetPermission(new me.lucko.luckperms.core.Node.Builder("group." + permsSubject.getIdentifier())
|
||||
.withExtraContext(contexts)
|
||||
.build());
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
superClass.objectSave(holder);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearParents() {
|
||||
boolean work = false;
|
||||
Iterator<Node> iterator = holder.getNodes().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Node entry = iterator.next();
|
||||
|
||||
if (entry.isGroupNode()) {
|
||||
iterator.remove();
|
||||
work = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (holder instanceof User) {
|
||||
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
|
||||
superClass.objectSave(holder);
|
||||
return work;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearParents(Set<Context> set) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
for (Context c : set) {
|
||||
context.put(c.getKey(), c.getValue());
|
||||
}
|
||||
|
||||
boolean work = false;
|
||||
Iterator<Node> iterator = holder.getNodes().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Node entry = iterator.next();
|
||||
|
||||
if (!entry.isGroupNode()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.shouldApplyWithContext(context)) {
|
||||
iterator.remove();
|
||||
work = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (holder instanceof User) {
|
||||
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
|
||||
superClass.objectSave(holder);
|
||||
return work;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Set<Context>, Map<String, String>> getAllOptions() {
|
||||
Map<Set<Context>, Map<String, String>> options = new HashMap<>();
|
||||
|
||||
for (Node n : holder.getAllNodes(null, Contexts.allowAll())) {
|
||||
if (!n.isMeta()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<Context> contexts = n.getExtraContexts().entrySet().stream()
|
||||
.map(entry -> new Context(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (n.isServerSpecific()) {
|
||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||
}
|
||||
|
||||
if (n.isWorldSpecific()) {
|
||||
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
|
||||
}
|
||||
|
||||
if (!options.containsKey(contexts)) {
|
||||
options.put(contexts, new HashMap<>());
|
||||
}
|
||||
|
||||
options.get(contexts).put(unescapeCharacters(n.getMeta().getKey()), unescapeCharacters(n.getMeta().getValue()));
|
||||
}
|
||||
|
||||
return ImmutableMap.copyOf(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getOptions(Set<Context> set) {
|
||||
return ImmutableMap.copyOf(getAllOptions().getOrDefault(set, Collections.emptyMap()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setOption(Set<Context> set, String key, String value) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
for (Context c : set) {
|
||||
context.put(c.getKey(), c.getValue());
|
||||
}
|
||||
|
||||
key = escapeCharacters(key);
|
||||
value = escapeCharacters(value);
|
||||
|
||||
try {
|
||||
holder.setPermission(new me.lucko.luckperms.core.Node.Builder("meta." + key + "." + value)
|
||||
.withExtraContext(context)
|
||||
.build()
|
||||
);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
superClass.objectSave(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearOptions(Set<Context> set) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
for (Context c : set) {
|
||||
context.put(c.getKey(), c.getValue());
|
||||
}
|
||||
|
||||
boolean work = false;
|
||||
Iterator<Node> iterator = holder.getNodes().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Node entry = iterator.next();
|
||||
|
||||
if (!entry.isMeta()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.shouldApplyWithContext(context)) {
|
||||
iterator.remove();
|
||||
work = true;
|
||||
}
|
||||
}
|
||||
|
||||
superClass.objectSave(holder);
|
||||
return work;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearOptions() {
|
||||
boolean work = false;
|
||||
Iterator<Node> iterator = holder.getNodes().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Node entry = iterator.next();
|
||||
|
||||
if (entry.isMeta()) {
|
||||
iterator.remove();
|
||||
work = true;
|
||||
}
|
||||
}
|
||||
|
||||
superClass.objectSave(holder);
|
||||
return work;
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public static class TransientData implements SubjectData {
|
||||
private final LuckPermsService service;
|
||||
|
||||
@Getter
|
||||
private final PermissionHolder holder;
|
||||
|
||||
@Override
|
||||
public Map<Set<Context>, Map<String, Boolean>> getAllPermissions() {
|
||||
Map<Set<Context>, Map<String, Boolean>> perms = new HashMap<>();
|
||||
|
||||
for (Node n : holder.getTransientNodes()) {
|
||||
Set<Context> contexts = n.getExtraContexts().entrySet().stream()
|
||||
.map(entry -> new Context(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (n.isServerSpecific()) {
|
||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||
}
|
||||
|
||||
if (n.isWorldSpecific()) {
|
||||
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
|
||||
}
|
||||
|
||||
if (!perms.containsKey(contexts)) {
|
||||
perms.put(contexts, new HashMap<>());
|
||||
}
|
||||
|
||||
perms.get(contexts).put(n.getPermission(), n.getValue());
|
||||
}
|
||||
|
||||
return ImmutableMap.copyOf(perms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getPermissions(Set<Context> set) {
|
||||
return ImmutableMap.copyOf(getAllPermissions().getOrDefault(set, Collections.emptyMap()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setPermission(Set<Context> set, String s, Tristate tristate) {
|
||||
if (tristate == Tristate.UNDEFINED) {
|
||||
// Unset
|
||||
|
||||
Node.Builder builder = new me.lucko.luckperms.core.Node.Builder(s);
|
||||
|
||||
for (Context ct : set) {
|
||||
builder.withExtraContext(ct.getKey(), ct.getValue());
|
||||
}
|
||||
|
||||
try {
|
||||
holder.unsetTransientPermission(builder.build());
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
return true;
|
||||
}
|
||||
|
||||
Node.Builder builder = new me.lucko.luckperms.core.Node.Builder(s)
|
||||
.setValue(tristate.asBoolean());
|
||||
|
||||
for (Context ct : set) {
|
||||
builder.withExtraContext(ct.getKey(), ct.getValue());
|
||||
}
|
||||
|
||||
try {
|
||||
holder.setTransientPermission(builder.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearPermissions() {
|
||||
holder.getTransientNodes().clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearPermissions(Set<Context> set) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
for (Context c : set) {
|
||||
context.put(c.getKey(), c.getValue());
|
||||
}
|
||||
|
||||
boolean work = false;
|
||||
Iterator<Node> iterator = holder.getTransientNodes().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Node entry = iterator.next();
|
||||
if (entry.shouldApplyWithContext(context)) {
|
||||
iterator.remove();
|
||||
work = true;
|
||||
}
|
||||
}
|
||||
|
||||
return work;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Set<Context>, List<Subject>> getAllParents() {
|
||||
Map<Set<Context>, List<Subject>> parents = new HashMap<>();
|
||||
|
||||
for (Node n : holder.getTransientNodes()) {
|
||||
if (!n.isGroupNode()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<Context> contexts = n.getExtraContexts().entrySet().stream()
|
||||
.map(entry -> new Context(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (n.isServerSpecific()) {
|
||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||
}
|
||||
|
||||
if (n.isWorldSpecific()) {
|
||||
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
|
||||
}
|
||||
|
||||
if (!parents.containsKey(contexts)) {
|
||||
parents.put(contexts, new ArrayList<>());
|
||||
}
|
||||
|
||||
parents.get(contexts).add(service.getGroupSubjects().get(n.getGroupName()));
|
||||
}
|
||||
|
||||
return ImmutableMap.copyOf(parents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Subject> getParents(Set<Context> contexts) {
|
||||
return ImmutableList.copyOf(getAllParents().getOrDefault(contexts, Collections.emptyList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addParent(Set<Context> set, Subject subject) {
|
||||
if (subject instanceof LuckPermsSubject) {
|
||||
LuckPermsSubject permsSubject = ((LuckPermsSubject) subject);
|
||||
|
||||
Map<String, String> contexts = set.stream().collect(Collectors.toMap(Context::getKey, Context::getValue));
|
||||
|
||||
try {
|
||||
holder.setTransientPermission(new me.lucko.luckperms.core.Node.Builder("group." + permsSubject.getIdentifier())
|
||||
.withExtraContext(contexts)
|
||||
.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeParent(Set<Context> set, Subject subject) {
|
||||
if (subject instanceof LuckPermsSubject) {
|
||||
LuckPermsSubject permsSubject = ((LuckPermsSubject) subject);
|
||||
|
||||
Map<String, String> contexts = set.stream().collect(Collectors.toMap(Context::getKey, Context::getValue));
|
||||
|
||||
try {
|
||||
holder.unsetTransientPermission(new me.lucko.luckperms.core.Node.Builder("group." + permsSubject.getIdentifier())
|
||||
.withExtraContext(contexts)
|
||||
.build());
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearParents() {
|
||||
boolean work = false;
|
||||
Iterator<Node> iterator = holder.getTransientNodes().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Node entry = iterator.next();
|
||||
|
||||
if (entry.isGroupNode()) {
|
||||
iterator.remove();
|
||||
work = true;
|
||||
}
|
||||
}
|
||||
|
||||
return work;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearParents(Set<Context> set) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
for (Context c : set) {
|
||||
context.put(c.getKey(), c.getValue());
|
||||
}
|
||||
|
||||
boolean work = false;
|
||||
Iterator<Node> iterator = holder.getTransientNodes().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Node entry = iterator.next();
|
||||
|
||||
if (!entry.isGroupNode()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.shouldApplyWithContext(context)) {
|
||||
iterator.remove();
|
||||
work = true;
|
||||
}
|
||||
}
|
||||
|
||||
return work;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Set<Context>, Map<String, String>> getAllOptions() {
|
||||
Map<Set<Context>, Map<String, String>> options = new HashMap<>();
|
||||
|
||||
for (Node n : holder.getTransientNodes()) {
|
||||
if (!n.isMeta()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<Context> contexts = n.getExtraContexts().entrySet().stream()
|
||||
.map(entry -> new Context(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (n.isServerSpecific()) {
|
||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||
}
|
||||
|
||||
if (n.isWorldSpecific()) {
|
||||
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
|
||||
}
|
||||
|
||||
if (!options.containsKey(contexts)) {
|
||||
options.put(contexts, new HashMap<>());
|
||||
}
|
||||
|
||||
options.get(contexts).put(unescapeCharacters(n.getMeta().getKey()), unescapeCharacters(n.getMeta().getValue()));
|
||||
}
|
||||
|
||||
return ImmutableMap.copyOf(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getOptions(Set<Context> set) {
|
||||
return ImmutableMap.copyOf(getAllOptions().getOrDefault(set, Collections.emptyMap()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setOption(Set<Context> set, String key, String value) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
for (Context c : set) {
|
||||
context.put(c.getKey(), c.getValue());
|
||||
}
|
||||
|
||||
key = escapeCharacters(key);
|
||||
value = escapeCharacters(value);
|
||||
|
||||
try {
|
||||
holder.setTransientPermission(new me.lucko.luckperms.core.Node.Builder("meta." + key + "." + value)
|
||||
.withExtraContext(context)
|
||||
.build()
|
||||
);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearOptions(Set<Context> set) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
for (Context c : set) {
|
||||
context.put(c.getKey(), c.getValue());
|
||||
}
|
||||
|
||||
boolean work = false;
|
||||
Iterator<Node> iterator = holder.getTransientNodes().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Node entry = iterator.next();
|
||||
|
||||
if (!entry.isMeta()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.shouldApplyWithContext(context)) {
|
||||
iterator.remove();
|
||||
work = true;
|
||||
}
|
||||
}
|
||||
|
||||
return work;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearOptions() {
|
||||
boolean work = false;
|
||||
Iterator<Node> iterator = holder.getTransientNodes().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Node entry = iterator.next();
|
||||
|
||||
if (entry.isMeta()) {
|
||||
iterator.remove();
|
||||
work = true;
|
||||
}
|
||||
}
|
||||
|
||||
return work;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,412 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.sponge;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.core.PermissionHolder;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import org.spongepowered.api.service.context.Context;
|
||||
import org.spongepowered.api.service.permission.Subject;
|
||||
import org.spongepowered.api.service.permission.SubjectData;
|
||||
import org.spongepowered.api.util.Tristate;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.lucko.luckperms.utils.ArgumentChecker.escapeCharacters;
|
||||
import static me.lucko.luckperms.utils.ArgumentChecker.unescapeCharacters;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class LuckPermsSubjectData implements SubjectData {
|
||||
private final boolean enduring;
|
||||
private final LuckPermsSubject superClass;
|
||||
private final LuckPermsService service;
|
||||
|
||||
@Getter
|
||||
private final PermissionHolder holder;
|
||||
|
||||
@Override
|
||||
public Map<Set<Context>, Map<String, Boolean>> getAllPermissions() {
|
||||
Map<Set<Context>, Map<String, Boolean>> perms = new HashMap<>();
|
||||
|
||||
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
||||
Set<Context> contexts = n.getExtraContexts().entrySet().stream()
|
||||
.map(entry -> new Context(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (n.isServerSpecific()) {
|
||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||
}
|
||||
|
||||
if (n.isWorldSpecific()) {
|
||||
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
|
||||
}
|
||||
|
||||
if (!perms.containsKey(contexts)) {
|
||||
perms.put(contexts, new HashMap<>());
|
||||
}
|
||||
|
||||
perms.get(contexts).put(n.getPermission(), n.getValue());
|
||||
}
|
||||
|
||||
ImmutableMap.Builder<Set<Context>, Map<String, Boolean>> map = ImmutableMap.builder();
|
||||
for (Map.Entry<Set<Context>, Map<String, Boolean>> e : perms.entrySet()) {
|
||||
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableMap.copyOf(e.getValue()));
|
||||
}
|
||||
return map.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getPermissions(Set<Context> set) {
|
||||
return getAllPermissions().getOrDefault(set, ImmutableMap.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setPermission(Set<Context> set, String s, Tristate tristate) {
|
||||
if (tristate == Tristate.UNDEFINED) {
|
||||
// Unset
|
||||
Node.Builder builder = new me.lucko.luckperms.core.Node.Builder(s);
|
||||
|
||||
for (Context ct : set) {
|
||||
builder.withExtraContext(ct.getKey(), ct.getValue());
|
||||
}
|
||||
|
||||
try {
|
||||
if (enduring) {
|
||||
holder.unsetPermission(builder.build());
|
||||
} else {
|
||||
holder.unsetTransientPermission(builder.build());
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
superClass.objectSave(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
Node.Builder builder = new me.lucko.luckperms.core.Node.Builder(s)
|
||||
.setValue(tristate.asBoolean());
|
||||
|
||||
for (Context ct : set) {
|
||||
builder.withExtraContext(ct.getKey(), ct.getValue());
|
||||
}
|
||||
|
||||
try {
|
||||
if (enduring) {
|
||||
holder.setPermission(builder.build());
|
||||
} else {
|
||||
holder.setTransientPermission(builder.build());
|
||||
}
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
superClass.objectSave(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearPermissions() {
|
||||
if (enduring) {
|
||||
holder.clearNodes();
|
||||
} else {
|
||||
holder.clearTransientNodes();
|
||||
}
|
||||
superClass.objectSave(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearPermissions(Set<Context> set) {
|
||||
Map<String, String> context = set.stream().collect(Collectors.toMap(Context::getKey, Context::getValue));
|
||||
List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream()
|
||||
.filter(node -> node.shouldApplyWithContext(context))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
toRemove.forEach(n -> {
|
||||
try {
|
||||
if (enduring) {
|
||||
holder.unsetPermission(n);
|
||||
} else {
|
||||
holder.unsetTransientPermission(n);
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
if (holder instanceof User) {
|
||||
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
|
||||
superClass.objectSave(holder);
|
||||
return !toRemove.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Set<Context>, List<Subject>> getAllParents() {
|
||||
Map<Set<Context>, List<Subject>> parents = new HashMap<>();
|
||||
|
||||
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
||||
if (!n.isGroupNode()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<Context> contexts = n.getExtraContexts().entrySet().stream()
|
||||
.map(entry -> new Context(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (n.isServerSpecific()) {
|
||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||
}
|
||||
|
||||
if (n.isWorldSpecific()) {
|
||||
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
|
||||
}
|
||||
|
||||
if (!parents.containsKey(contexts)) {
|
||||
parents.put(contexts, new ArrayList<>());
|
||||
}
|
||||
|
||||
parents.get(contexts).add(service.getGroupSubjects().get(n.getGroupName()));
|
||||
}
|
||||
|
||||
ImmutableMap.Builder<Set<Context>, List<Subject>> map = ImmutableMap.builder();
|
||||
for (Map.Entry<Set<Context>, List<Subject>> e : parents.entrySet()) {
|
||||
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableList.copyOf(e.getValue()));
|
||||
}
|
||||
return map.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Subject> getParents(Set<Context> contexts) {
|
||||
return getAllParents().getOrDefault(contexts, ImmutableList.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addParent(Set<Context> set, Subject subject) {
|
||||
if (subject instanceof LuckPermsSubject) {
|
||||
LuckPermsSubject permsSubject = ((LuckPermsSubject) subject);
|
||||
Map<String, String> contexts = set.stream().collect(Collectors.toMap(Context::getKey, Context::getValue));
|
||||
|
||||
try {
|
||||
if (enduring) {
|
||||
holder.setPermission(new me.lucko.luckperms.core.Node.Builder("group." + permsSubject.getIdentifier())
|
||||
.withExtraContext(contexts)
|
||||
.build());
|
||||
} else {
|
||||
holder.setTransientPermission(new me.lucko.luckperms.core.Node.Builder("group." + permsSubject.getIdentifier())
|
||||
.withExtraContext(contexts)
|
||||
.build());
|
||||
}
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
superClass.objectSave(holder);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeParent(Set<Context> set, Subject subject) {
|
||||
if (subject instanceof LuckPermsSubject) {
|
||||
LuckPermsSubject permsSubject = ((LuckPermsSubject) subject);
|
||||
Map<String, String> contexts = set.stream().collect(Collectors.toMap(Context::getKey, Context::getValue));
|
||||
|
||||
try {
|
||||
if (enduring) {
|
||||
holder.unsetPermission(new me.lucko.luckperms.core.Node.Builder("group." + permsSubject.getIdentifier())
|
||||
.withExtraContext(contexts)
|
||||
.build());
|
||||
} else {
|
||||
holder.unsetTransientPermission(new me.lucko.luckperms.core.Node.Builder("group." + permsSubject.getIdentifier())
|
||||
.withExtraContext(contexts)
|
||||
.build());
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
superClass.objectSave(holder);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearParents() {
|
||||
List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
toRemove.forEach(n -> {
|
||||
try {
|
||||
if (enduring) {
|
||||
holder.unsetPermission(n);
|
||||
} else {
|
||||
holder.unsetTransientPermission(n);
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
if (holder instanceof User) {
|
||||
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
|
||||
superClass.objectSave(holder);
|
||||
return !toRemove.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearParents(Set<Context> set) {
|
||||
Map<String, String> context = set.stream().collect(Collectors.toMap(Context::getKey, Context::getValue));
|
||||
List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.filter(node -> node.shouldApplyWithContext(context))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
toRemove.forEach(n -> {
|
||||
try {
|
||||
if (enduring) {
|
||||
holder.unsetPermission(n);
|
||||
} else {
|
||||
holder.unsetTransientPermission(n);
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
if (holder instanceof User) {
|
||||
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||
}
|
||||
|
||||
superClass.objectSave(holder);
|
||||
return !toRemove.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Set<Context>, Map<String, String>> getAllOptions() {
|
||||
Map<Set<Context>, Map<String, String>> options = new HashMap<>();
|
||||
|
||||
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
|
||||
if (!n.isMeta() && !n.isPrefix() && !n.isSuffix()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<Context> contexts = n.getExtraContexts().entrySet().stream()
|
||||
.map(entry -> new Context(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (n.isServerSpecific()) {
|
||||
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
|
||||
}
|
||||
|
||||
if (n.isWorldSpecific()) {
|
||||
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
|
||||
}
|
||||
|
||||
if (!options.containsKey(contexts)) {
|
||||
options.put(contexts, new HashMap<>());
|
||||
}
|
||||
|
||||
options.get(contexts).put(unescapeCharacters(n.getMeta().getKey()), unescapeCharacters(n.getMeta().getValue()));
|
||||
}
|
||||
|
||||
ImmutableMap.Builder<Set<Context>, Map<String, String>> map = ImmutableMap.builder();
|
||||
for (Map.Entry<Set<Context>, Map<String, String>> e : options.entrySet()) {
|
||||
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableMap.copyOf(e.getValue()));
|
||||
}
|
||||
return map.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getOptions(Set<Context> set) {
|
||||
return getAllOptions().getOrDefault(set, Collections.emptyMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setOption(Set<Context> set, String key, String value) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
for (Context c : set) {
|
||||
context.put(c.getKey(), c.getValue());
|
||||
}
|
||||
|
||||
key = escapeCharacters(key);
|
||||
value = escapeCharacters(value);
|
||||
|
||||
try {
|
||||
if (enduring) {
|
||||
holder.setPermission(new me.lucko.luckperms.core.Node.Builder("meta." + key + "." + value)
|
||||
.withExtraContext(context)
|
||||
.build()
|
||||
);
|
||||
} else {
|
||||
holder.setTransientPermission(new me.lucko.luckperms.core.Node.Builder("meta." + key + "." + value)
|
||||
.withExtraContext(context)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
superClass.objectSave(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearOptions(Set<Context> set) {
|
||||
Map<String, String> context = set.stream().collect(Collectors.toMap(Context::getKey, Context::getValue));
|
||||
List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream()
|
||||
.filter(n -> n.isMeta() || n.isPrefix() || n.isSuffix())
|
||||
.filter(node -> node.shouldApplyWithContext(context))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
toRemove.forEach(n -> {
|
||||
try {
|
||||
if (enduring) {
|
||||
holder.unsetPermission(n);
|
||||
} else {
|
||||
holder.unsetTransientPermission(n);
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
superClass.objectSave(holder);
|
||||
return !toRemove.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearOptions() {
|
||||
List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream()
|
||||
.filter(n -> n.isMeta() || n.isPrefix() || n.isSuffix())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
toRemove.forEach(n -> {
|
||||
try {
|
||||
if (enduring) {
|
||||
holder.unsetPermission(n);
|
||||
} else {
|
||||
holder.unsetTransientPermission(n);
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
superClass.objectSave(holder);
|
||||
return !toRemove.isEmpty();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user