More progress towards 1.6: implement PermissionService
This commit is contained in:
parent
2a305b1c55
commit
a3ebf86f6b
@ -180,6 +180,7 @@ public interface LuckPermsApi {
|
|||||||
* @param permission the main permission node to build
|
* @param permission the main permission node to build
|
||||||
* @return a {@link Node.Builder} instance
|
* @return a {@link Node.Builder} instance
|
||||||
* @throws IllegalArgumentException if the permission is invalid
|
* @throws IllegalArgumentException if the permission is invalid
|
||||||
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
Node.Builder buildNode(String permission) throws IllegalArgumentException;
|
Node.Builder buildNode(String permission) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ import java.util.Optional;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an immutable node object
|
* Represents an immutable node object
|
||||||
|
* <p> Use {@link LuckPermsApi#buildNode(String)} to get an instance.
|
||||||
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
public interface Node extends Map.Entry<String, Boolean> {
|
public interface Node extends Map.Entry<String, Boolean> {
|
||||||
|
|
||||||
@ -201,6 +203,42 @@ public interface Node extends Map.Entry<String, Boolean> {
|
|||||||
*/
|
*/
|
||||||
int getWildcardLevel();
|
int getWildcardLevel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this node is a meta node
|
||||||
|
*/
|
||||||
|
boolean isMeta();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the meta value from this node
|
||||||
|
* @return the meta value
|
||||||
|
* @throws IllegalStateException if this node is not a meta node
|
||||||
|
*/
|
||||||
|
Map.Entry<String, String> getMeta();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this node is a prefix node
|
||||||
|
*/
|
||||||
|
boolean isPrefix();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the prefix value from this node
|
||||||
|
* @return the prefix value
|
||||||
|
* @throws IllegalStateException if this node is a not a prefix node
|
||||||
|
*/
|
||||||
|
Map.Entry<Integer, String> getPrefix();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this node is a suffix node
|
||||||
|
*/
|
||||||
|
boolean isSuffix();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the suffix value from this node
|
||||||
|
* @return the suffix value
|
||||||
|
* @throws IllegalStateException if this node is a not a suffix node
|
||||||
|
*/
|
||||||
|
Map.Entry<Integer, String> getSuffix();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to {@link #equals(Object)}, except doesn't take note of the value
|
* Similar to {@link #equals(Object)}, except doesn't take note of the value
|
||||||
* @param node the other node
|
* @param node the other node
|
||||||
@ -229,6 +267,8 @@ public interface Node extends Map.Entry<String, Boolean> {
|
|||||||
Builder setWorld(String world);
|
Builder setWorld(String world);
|
||||||
Builder setServer(String server) throws IllegalArgumentException;
|
Builder setServer(String server) throws IllegalArgumentException;
|
||||||
Builder withExtraContext(String key, String value);
|
Builder withExtraContext(String key, String value);
|
||||||
|
Builder withExtraContext(Map<String, String> map);
|
||||||
|
Builder withExtraContext(Map.Entry<String, String> entry);
|
||||||
Node build();
|
Node build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ import java.util.Set;
|
|||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper interface for internal PermissionHolder (object/group) instances
|
* Wrapper interface for internal PermissionHolder (user/group) instances
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public interface PermissionHolder {
|
public interface PermissionHolder {
|
||||||
@ -260,11 +260,10 @@ public interface PermissionHolder {
|
|||||||
* Whenever a user logs out of the server, or the server restarts, this permission will disappear.
|
* Whenever a user logs out of the server, or the server restarts, this permission will disappear.
|
||||||
* It is never saved to the datastore, and therefore will not apply on other servers.
|
* It is never saved to the datastore, and therefore will not apply on other servers.
|
||||||
*
|
*
|
||||||
* This is useful if you want to temporarily set a permission for a user while they're online, but don't
|
* <p> This is useful if you want to temporarily set a permission for a user while they're online, but don't
|
||||||
* want it to persist, and have to worry about removing it when they log out.
|
* want it to persist, and have to worry about removing it when they log out.
|
||||||
*
|
*
|
||||||
* For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}
|
* <p> For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}
|
||||||
*
|
|
||||||
* @param node The node to be set
|
* @param node The node to be set
|
||||||
* @throws ObjectAlreadyHasException if the object already has the permission
|
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||||
* @throws NullPointerException if the node is null
|
* @throws NullPointerException if the node is null
|
||||||
|
@ -26,7 +26,7 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback used to wait for the completion of asynchronous operations.
|
* A callback used to wait for the completion of asynchronous operations.
|
||||||
* All callbacks are ran on the main Bukkit server thread.
|
* All callbacks are ran on the main server thread.
|
||||||
* @param <T> the return type
|
* @param <T> the return type
|
||||||
*/
|
*/
|
||||||
public interface Callback<T> {
|
public interface Callback<T> {
|
||||||
|
@ -51,6 +51,7 @@ import java.util.regex.Pattern;
|
|||||||
* - suffix
|
* - suffix
|
||||||
* - meta_<node>
|
* - meta_<node>
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||||
private static final String IDENTIFIER = "luckperms";
|
private static final String IDENTIFIER = "luckperms";
|
||||||
private static final String PLUGIN_NAME = "LuckPerms";
|
private static final String PLUGIN_NAME = "LuckPerms";
|
||||||
|
@ -25,16 +25,14 @@ package me.lucko.luckperms.api.vault;
|
|||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import me.lucko.luckperms.LPBukkitPlugin;
|
import me.lucko.luckperms.LPBukkitPlugin;
|
||||||
import me.lucko.luckperms.constants.Patterns;
|
import me.lucko.luckperms.api.Node;
|
||||||
import me.lucko.luckperms.core.PermissionHolder;
|
import me.lucko.luckperms.core.PermissionHolder;
|
||||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||||
import me.lucko.luckperms.groups.Group;
|
import me.lucko.luckperms.groups.Group;
|
||||||
import me.lucko.luckperms.users.User;
|
import me.lucko.luckperms.users.User;
|
||||||
import net.milkbowl.vault.chat.Chat;
|
import net.milkbowl.vault.chat.Chat;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import static me.lucko.luckperms.utils.ArgumentChecker.escapeCharacters;
|
import static me.lucko.luckperms.utils.ArgumentChecker.escapeCharacters;
|
||||||
import static me.lucko.luckperms.utils.ArgumentChecker.unescapeCharacters;
|
import static me.lucko.luckperms.utils.ArgumentChecker.unescapeCharacters;
|
||||||
@ -58,8 +56,6 @@ import static me.lucko.luckperms.utils.ArgumentChecker.unescapeCharacters;
|
|||||||
* Registered on normal priority so other plugins can override.
|
* Registered on normal priority so other plugins can override.
|
||||||
*/
|
*/
|
||||||
class VaultChatHook extends Chat {
|
class VaultChatHook extends Chat {
|
||||||
private static final Pattern PREFIX_PATTERN = Pattern.compile("(?i)prefix\\.\\d+\\..*");
|
|
||||||
private static final Pattern SUFFIX_PATTERN = Pattern.compile("(?i)suffix\\.\\d+\\..*");
|
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private LPBukkitPlugin plugin;
|
private LPBukkitPlugin plugin;
|
||||||
@ -103,24 +99,24 @@ class VaultChatHook extends Chat {
|
|||||||
if (node.equals("")) return defaultValue;
|
if (node.equals("")) return defaultValue;
|
||||||
node = escapeCharacters(node);
|
node = escapeCharacters(node);
|
||||||
|
|
||||||
for (Map.Entry<String, Boolean> e : holder.exportNodes("global", world, null, true, false, Collections.emptyList()).entrySet()) {
|
for (Node n : holder.getPermissions()) {
|
||||||
if (!e.getValue()) continue;
|
if (!n.isMeta()) {
|
||||||
|
|
||||||
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
|
||||||
if (parts.length < 3) continue;
|
|
||||||
|
|
||||||
if (!parts[0].equalsIgnoreCase("meta")) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parts[1].equalsIgnoreCase(node)) {
|
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
Map.Entry<String, String> meta = n.getMeta();
|
||||||
return Integer.parseInt(unescapeCharacters(parts[2]));
|
if (meta.getKey().equalsIgnoreCase(node)) {
|
||||||
} catch (Throwable t) {
|
|
||||||
return defaultValue;
|
try {
|
||||||
|
return Integer.parseInt(unescapeCharacters(meta.getValue()));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,24 +128,24 @@ class VaultChatHook extends Chat {
|
|||||||
if (node.equals("")) return defaultValue;
|
if (node.equals("")) return defaultValue;
|
||||||
node = escapeCharacters(node);
|
node = escapeCharacters(node);
|
||||||
|
|
||||||
for (Map.Entry<String, Boolean> e : holder.exportNodes("global", world, null, true, false, Collections.emptyList()).entrySet()) {
|
for (Node n : holder.getPermissions()) {
|
||||||
if (!e.getValue()) continue;
|
if (!n.isMeta()) {
|
||||||
|
|
||||||
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
|
||||||
if (parts.length < 3) continue;
|
|
||||||
|
|
||||||
if (!parts[0].equalsIgnoreCase("meta")) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parts[1].equalsIgnoreCase(node)) {
|
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
Map.Entry<String, String> meta = n.getMeta();
|
||||||
return Double.parseDouble(unescapeCharacters(parts[2]));
|
if (meta.getKey().equalsIgnoreCase(node)) {
|
||||||
} catch (Throwable t) {
|
|
||||||
return defaultValue;
|
try {
|
||||||
|
return Double.parseDouble(unescapeCharacters(meta.getValue()));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,24 +157,24 @@ class VaultChatHook extends Chat {
|
|||||||
if (node.equals("")) return defaultValue;
|
if (node.equals("")) return defaultValue;
|
||||||
node = escapeCharacters(node);
|
node = escapeCharacters(node);
|
||||||
|
|
||||||
for (Map.Entry<String, Boolean> e : holder.exportNodes("global", world, null, true, false, Collections.emptyList()).entrySet()) {
|
for (Node n : holder.getPermissions()) {
|
||||||
if (!e.getValue()) continue;
|
if (!n.isMeta()) {
|
||||||
|
|
||||||
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
|
||||||
if (parts.length < 3) continue;
|
|
||||||
|
|
||||||
if (!parts[0].equalsIgnoreCase("meta")) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parts[1].equalsIgnoreCase(node)) {
|
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
Map.Entry<String, String> meta = n.getMeta();
|
||||||
return Boolean.parseBoolean(unescapeCharacters(parts[2]));
|
if (meta.getKey().equalsIgnoreCase(node)) {
|
||||||
} catch (Throwable t) {
|
|
||||||
return defaultValue;
|
try {
|
||||||
|
return Boolean.parseBoolean(unescapeCharacters(meta.getValue()));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,41 +186,68 @@ class VaultChatHook extends Chat {
|
|||||||
if (node.equals("")) return defaultValue;
|
if (node.equals("")) return defaultValue;
|
||||||
node = escapeCharacters(node);
|
node = escapeCharacters(node);
|
||||||
|
|
||||||
for (Map.Entry<String, Boolean> e : holder.exportNodes("global", world, null, true, false, Collections.emptyList()).entrySet()) {
|
for (Node n : holder.getPermissions()) {
|
||||||
if (!e.getValue()) continue;
|
if (!n.getValue()) {
|
||||||
|
|
||||||
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
|
||||||
if (parts.length < 3) continue;
|
|
||||||
|
|
||||||
if (!parts[0].equalsIgnoreCase("meta")) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parts[1].equalsIgnoreCase(node)) {
|
if (!n.isMeta()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return unescapeCharacters(parts[2]);
|
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<String, String> meta = n.getMeta();
|
||||||
|
if (meta.getKey().equalsIgnoreCase(node)) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
return unescapeCharacters(meta.getValue());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getChatMeta(Pattern pattern, PermissionHolder holder, String world) {
|
private static String getChatMeta(boolean prefix, PermissionHolder holder, String world) {
|
||||||
if (holder == null) return "";
|
if (holder == null) return "";
|
||||||
|
|
||||||
int priority = 0;
|
int priority = -1000;
|
||||||
String meta = null;
|
String meta = null;
|
||||||
for (Map.Entry<String, Boolean> e : holder.getLocalPermissions("global", world, null).entrySet()) {
|
|
||||||
if (!e.getValue()) continue;
|
|
||||||
|
|
||||||
if (pattern.matcher(e.getKey()).matches()) {
|
for (Node n : holder.getAllNodes(null)) {
|
||||||
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
if (!n.getValue()) {
|
||||||
int p = Integer.parseInt(parts[1]);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (meta == null || p > priority) {
|
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||||
meta = parts[2];
|
continue;
|
||||||
priority = p;
|
}
|
||||||
|
|
||||||
|
if (prefix) {
|
||||||
|
if (!n.isPrefix()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<Integer, String> prefixValue = n.getPrefix();
|
||||||
|
if (prefixValue.getKey() > priority) {
|
||||||
|
meta = prefixValue.getValue();
|
||||||
|
priority = prefixValue.getKey();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!n.isSuffix()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<Integer, String> suffixValue = n.getSuffix();
|
||||||
|
if (suffixValue.getKey() > priority) {
|
||||||
|
meta = suffixValue.getValue();
|
||||||
|
priority = suffixValue.getKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,7 +257,7 @@ class VaultChatHook extends Chat {
|
|||||||
|
|
||||||
public String getPlayerPrefix(String world, @NonNull String player) {
|
public String getPlayerPrefix(String world, @NonNull String player) {
|
||||||
final User user = plugin.getUserManager().get(player);
|
final User user = plugin.getUserManager().get(player);
|
||||||
return getChatMeta(PREFIX_PATTERN, user, world);
|
return getChatMeta(true, user, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlayerPrefix(String world, @NonNull String player, @NonNull String prefix) {
|
public void setPlayerPrefix(String world, @NonNull String player, @NonNull String prefix) {
|
||||||
@ -252,7 +275,7 @@ class VaultChatHook extends Chat {
|
|||||||
|
|
||||||
public String getPlayerSuffix(String world, @NonNull String player) {
|
public String getPlayerSuffix(String world, @NonNull String player) {
|
||||||
final User user = plugin.getUserManager().get(player);
|
final User user = plugin.getUserManager().get(player);
|
||||||
return getChatMeta(SUFFIX_PATTERN, user, world);
|
return getChatMeta(false, user, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlayerSuffix(String world, @NonNull String player, @NonNull String suffix) {
|
public void setPlayerSuffix(String world, @NonNull String player, @NonNull String suffix) {
|
||||||
@ -270,7 +293,7 @@ class VaultChatHook extends Chat {
|
|||||||
|
|
||||||
public String getGroupPrefix(String world, @NonNull String group) {
|
public String getGroupPrefix(String world, @NonNull String group) {
|
||||||
final Group g = plugin.getGroupManager().get(group);
|
final Group g = plugin.getGroupManager().get(group);
|
||||||
return getChatMeta(PREFIX_PATTERN, g, world);
|
return getChatMeta(false, g, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGroupPrefix(String world, @NonNull String group, @NonNull String prefix) {
|
public void setGroupPrefix(String world, @NonNull String group, @NonNull String prefix) {
|
||||||
@ -288,7 +311,7 @@ class VaultChatHook extends Chat {
|
|||||||
|
|
||||||
public String getGroupSuffix(String world, @NonNull String group) {
|
public String getGroupSuffix(String world, @NonNull String group) {
|
||||||
final Group g = plugin.getGroupManager().get(group);
|
final Group g = plugin.getGroupManager().get(group);
|
||||||
return getChatMeta(SUFFIX_PATTERN, g, world);
|
return getChatMeta(false, g, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGroupSuffix(String world, @NonNull String group, @NonNull String suffix) {
|
public void setGroupSuffix(String world, @NonNull String group, @NonNull String suffix) {
|
||||||
|
@ -38,6 +38,9 @@ import java.util.stream.Collectors;
|
|||||||
@ToString
|
@ToString
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
public class Node implements me.lucko.luckperms.api.Node {
|
public class Node implements me.lucko.luckperms.api.Node {
|
||||||
|
private static final Pattern PREFIX_PATTERN = Pattern.compile("(?i)prefix\\.\\d+\\..*");
|
||||||
|
private static final Pattern SUFFIX_PATTERN = Pattern.compile("(?i)suffix\\.\\d+\\..*");
|
||||||
|
|
||||||
public static me.lucko.luckperms.api.Node fromSerialisedNode(String s, Boolean b) {
|
public static me.lucko.luckperms.api.Node fromSerialisedNode(String s, Boolean b) {
|
||||||
return builderFromSerialisedNode(s, b).build();
|
return builderFromSerialisedNode(s, b).build();
|
||||||
}
|
}
|
||||||
@ -234,6 +237,18 @@ public class Node implements me.lucko.luckperms.api.Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Map.Entry<String, String> c : context.entrySet()) {
|
for (Map.Entry<String, String> c : context.entrySet()) {
|
||||||
|
if (c.getKey().equals("server")) {
|
||||||
|
if (shouldApplyOnServer(c.getValue(), false, false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.getKey().equals("world")) {
|
||||||
|
if (shouldApplyOnWorld(c.getValue(), false, false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!getExtraContexts().containsKey(c.getKey())) {
|
if (!getExtraContexts().containsKey(c.getKey())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -405,6 +420,55 @@ public class Node implements me.lucko.luckperms.api.Node {
|
|||||||
return (int) getPermission().chars().filter(num -> num == Character.getNumericValue('.')).count();
|
return (int) getPermission().chars().filter(num -> num == Character.getNumericValue('.')).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMeta() {
|
||||||
|
return getPermission().matches("meta\\..*\\..*");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map.Entry<String, String> getMeta() {
|
||||||
|
if (!isMeta()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] metaPart = getPermission().substring("meta.".length()).split("\\.", 2);
|
||||||
|
return new AbstractMap.SimpleEntry<>(metaPart[0], metaPart[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPrefix() {
|
||||||
|
return PREFIX_PATTERN.matcher(getPermission()).matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map.Entry<Integer, String> getPrefix() {
|
||||||
|
if (!isPrefix()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] prefixPart = Patterns.DOT.split(getPermission().substring("prefix.".length()), 2);
|
||||||
|
Integer i = Integer.parseInt(prefixPart[0]);
|
||||||
|
|
||||||
|
return new AbstractMap.SimpleEntry<>(i, prefixPart[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSuffix() {
|
||||||
|
return SUFFIX_PATTERN.matcher(getPermission()).matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map.Entry<Integer, String> getSuffix() {
|
||||||
|
if (!isPrefix()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] suffixPart = Patterns.DOT.split(getPermission().substring("suffix.".length()), 2);
|
||||||
|
Integer i = Integer.parseInt(suffixPart[0]);
|
||||||
|
|
||||||
|
return new AbstractMap.SimpleEntry<>(i, suffixPart[1]);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equalsIgnoringValue(me.lucko.luckperms.api.Node other) {
|
public boolean equalsIgnoringValue(me.lucko.luckperms.api.Node other) {
|
||||||
if (!other.getPermission().equalsIgnoreCase(this.getPermission())) {
|
if (!other.getPermission().equalsIgnoreCase(this.getPermission())) {
|
||||||
@ -581,7 +645,30 @@ public class Node implements me.lucko.luckperms.api.Node {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public me.lucko.luckperms.api.Node.Builder withExtraContext(@NonNull String key, @NonNull String value) {
|
public me.lucko.luckperms.api.Node.Builder withExtraContext(@NonNull String key, @NonNull String value) {
|
||||||
this.extraContexts.put(key, value);
|
switch (key) {
|
||||||
|
case "server":
|
||||||
|
setServer(value);
|
||||||
|
break;
|
||||||
|
case "world":
|
||||||
|
setWorld(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.extraContexts.put(key, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public me.lucko.luckperms.api.Node.Builder withExtraContext(Map<String, String> map) {
|
||||||
|
map.entrySet().forEach(this::withExtraContext);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public me.lucko.luckperms.api.Node.Builder withExtraContext(Map.Entry<String, String> entry) {
|
||||||
|
withExtraContext(entry.getKey(), entry.getValue());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,14 +20,14 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.service;
|
package me.lucko.luckperms.api.sponge;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import me.lucko.luckperms.LPSpongePlugin;
|
import me.lucko.luckperms.LPSpongePlugin;
|
||||||
import me.lucko.luckperms.service.collections.GroupCollection;
|
import me.lucko.luckperms.api.sponge.collections.GroupCollection;
|
||||||
import me.lucko.luckperms.service.collections.UserCollection;
|
import me.lucko.luckperms.api.sponge.collections.UserCollection;
|
||||||
import me.lucko.luckperms.service.simple.SimpleCollection;
|
import me.lucko.luckperms.api.sponge.simple.SimpleCollection;
|
||||||
import org.spongepowered.api.plugin.PluginContainer;
|
import org.spongepowered.api.plugin.PluginContainer;
|
||||||
import org.spongepowered.api.service.context.ContextCalculator;
|
import org.spongepowered.api.service.context.ContextCalculator;
|
||||||
import org.spongepowered.api.service.permission.*;
|
import org.spongepowered.api.service.permission.*;
|
||||||
@ -41,6 +41,7 @@ import java.util.stream.Collectors;
|
|||||||
public class LuckPermsService implements PermissionService {
|
public class LuckPermsService implements PermissionService {
|
||||||
public static final String SERVER_CONTEXT = "server";
|
public static final String SERVER_CONTEXT = "server";
|
||||||
|
|
||||||
|
@Getter
|
||||||
private final LPSpongePlugin plugin;
|
private final LPSpongePlugin plugin;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@ -103,7 +104,7 @@ public class LuckPermsService implements PermissionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<PermissionDescription> getDescription(String s) {
|
public Optional<PermissionDescription> getDescription(@NonNull String s) {
|
||||||
for (PermissionDescription d : descriptionSet) {
|
for (PermissionDescription d : descriptionSet) {
|
||||||
if (d.getId().equals(s)) {
|
if (d.getId().equals(s)) {
|
||||||
return Optional.of(d);
|
return Optional.of(d);
|
||||||
@ -119,7 +120,7 @@ public class LuckPermsService implements PermissionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerContextCalculator(ContextCalculator<Subject> contextCalculator) {
|
public void registerContextCalculator(@NonNull ContextCalculator<Subject> contextCalculator) {
|
||||||
contextCalculators.add(contextCalculator);
|
contextCalculators.add(contextCalculator);
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,837 @@
|
|||||||
|
/*
|
||||||
|
* 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 lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import me.lucko.luckperms.api.Node;
|
||||||
|
import me.lucko.luckperms.api.data.Callback;
|
||||||
|
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.Sponge;
|
||||||
|
import org.spongepowered.api.command.CommandSource;
|
||||||
|
import org.spongepowered.api.entity.living.player.Player;
|
||||||
|
import org.spongepowered.api.service.context.Context;
|
||||||
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectData;
|
||||||
|
import org.spongepowered.api.util.Tristate;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static me.lucko.luckperms.utils.ArgumentChecker.escapeCharacters;
|
||||||
|
import static me.lucko.luckperms.utils.ArgumentChecker.unescapeCharacters;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class LuckPermsSubject implements Subject {
|
||||||
|
private final EnduringData enduringData;
|
||||||
|
private final TransientData transientData;
|
||||||
|
private final LuckPermsService service;
|
||||||
|
|
||||||
|
public LuckPermsSubject(PermissionHolder holder, LuckPermsService service) {
|
||||||
|
this.enduringData = new EnduringData(this, service, holder);
|
||||||
|
this.transientData = new TransientData(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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return enduringData.getHolder().getObjectName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<CommandSource> getCommandSource() {
|
||||||
|
if (enduringData.getHolder() instanceof User) {
|
||||||
|
final UUID uuid = ((User) enduringData.getHolder()).getUuid();
|
||||||
|
|
||||||
|
Optional<Player> p = Sponge.getServer().getPlayer(uuid);
|
||||||
|
if (p.isPresent()) {
|
||||||
|
return Optional.of(p.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubjectCollection getContainingCollection() {
|
||||||
|
if (enduringData.getHolder() instanceof Group) {
|
||||||
|
return service.getGroupSubjects();
|
||||||
|
} else {
|
||||||
|
return service.getUserSubjects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubjectData getSubjectData() {
|
||||||
|
return enduringData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubjectData getTransientSubjectData() {
|
||||||
|
return transientData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
||||||
|
return getPermissionValue(contexts, node).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(String permission) {
|
||||||
|
return getPermissionValue(getActiveContexts(), permission).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) {
|
||||||
|
Map<String, String> context = new HashMap<>();
|
||||||
|
for (Context c : contexts) {
|
||||||
|
context.put(c.getKey(), c.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
me.lucko.luckperms.api.Tristate t = enduringData.getHolder().hasPermission(new me.lucko.luckperms.utils.Node.Builder(node).withExtraContext(context).build());
|
||||||
|
if (t == me.lucko.luckperms.api.Tristate.UNDEFINED) {
|
||||||
|
return Tristate.UNDEFINED;
|
||||||
|
}
|
||||||
|
if (t == me.lucko.luckperms.api.Tristate.TRUE) {
|
||||||
|
return Tristate.TRUE;
|
||||||
|
}
|
||||||
|
if (t == me.lucko.luckperms.api.Tristate.FALSE) {
|
||||||
|
return Tristate.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChildOf(@NonNull Subject parent) {
|
||||||
|
return isChildOf(getActiveContexts(), parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject parent) {
|
||||||
|
return parent instanceof PermissionHolder && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Subject> getParents() {
|
||||||
|
return getParents(getActiveContexts());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Subject> getParents(@NonNull Set<Context> contexts) {
|
||||||
|
List<Subject> parents = new ArrayList<>();
|
||||||
|
parents.addAll(enduringData.getParents(contexts));
|
||||||
|
parents.addAll(transientData.getParents(contexts));
|
||||||
|
return ImmutableList.copyOf(parents);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getOption(Set<Context> set, String s) {
|
||||||
|
Map<String, String> enduringOptions = enduringData.getOptions(set);
|
||||||
|
if (enduringOptions.containsKey(s)) {
|
||||||
|
return Optional.of(enduringOptions.get(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> transientOptions = enduringData.getOptions(set);
|
||||||
|
if (transientOptions.containsKey(s)) {
|
||||||
|
return Optional.of(transientOptions.get(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getOption(String key) {
|
||||||
|
return getOption(getActiveContexts(), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Context> getActiveContexts() {
|
||||||
|
return SubjectData.GLOBAL_CONTEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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.utils.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.utils.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() {
|
||||||
|
// TODO re-give default nodes?
|
||||||
|
|
||||||
|
holder.getNodes().clear();
|
||||||
|
superClass.objectSave(holder);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean clearPermissions(Set<Context> set) {
|
||||||
|
// TODO re-give default nodes?
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
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()
|
||||||
|
.map(context -> new AbstractMap.SimpleEntry<>(context.getKey(), context.getValue()))
|
||||||
|
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
|
||||||
|
|
||||||
|
try {
|
||||||
|
holder.setPermission(new me.lucko.luckperms.utils.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()
|
||||||
|
.map(context -> new AbstractMap.SimpleEntry<>(context.getKey(), context.getValue()))
|
||||||
|
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
|
||||||
|
|
||||||
|
try {
|
||||||
|
holder.unsetPermission(new me.lucko.luckperms.utils.Node.Builder("group." + permsSubject.getIdentifier())
|
||||||
|
.withExtraContext(contexts)
|
||||||
|
.build());
|
||||||
|
} catch (ObjectLacksException ignored) {}
|
||||||
|
superClass.objectSave(holder);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean clearParents() {
|
||||||
|
// TODO re-give default nodes?
|
||||||
|
|
||||||
|
boolean work = false;
|
||||||
|
Iterator<Node> iterator = holder.getNodes().iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Node entry = iterator.next();
|
||||||
|
|
||||||
|
if (entry.isGroupNode()) {
|
||||||
|
iterator.remove();
|
||||||
|
work = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
superClass.objectSave(holder);
|
||||||
|
return work;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean clearParents(Set<Context> set) {
|
||||||
|
// TODO re-give default nodes?
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
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.utils.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.utils.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.utils.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()
|
||||||
|
.map(context -> new AbstractMap.SimpleEntry<>(context.getKey(), context.getValue()))
|
||||||
|
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
|
||||||
|
|
||||||
|
try {
|
||||||
|
holder.setTransientPermission(new me.lucko.luckperms.utils.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()
|
||||||
|
.map(context -> new AbstractMap.SimpleEntry<>(context.getKey(), context.getValue()))
|
||||||
|
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
|
||||||
|
|
||||||
|
try {
|
||||||
|
holder.unsetTransientPermission(new me.lucko.luckperms.utils.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.utils.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,14 +20,14 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.service.collections;
|
package me.lucko.luckperms.api.sponge.collections;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import me.lucko.luckperms.groups.GroupManager;
|
import me.lucko.luckperms.groups.GroupManager;
|
||||||
import me.lucko.luckperms.service.LuckPermsService;
|
import me.lucko.luckperms.api.sponge.LuckPermsService;
|
||||||
import me.lucko.luckperms.service.simple.SimpleSubject;
|
import me.lucko.luckperms.api.sponge.simple.SimpleSubject;
|
||||||
import me.lucko.luckperms.service.wrapping.LuckPermsSubject;
|
import me.lucko.luckperms.api.sponge.LuckPermsSubject;
|
||||||
import org.spongepowered.api.service.context.Context;
|
import org.spongepowered.api.service.context.Context;
|
||||||
import org.spongepowered.api.service.permission.PermissionService;
|
import org.spongepowered.api.service.permission.PermissionService;
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
@ -86,6 +86,6 @@ public class GroupCollection implements SubjectCollection {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getDefaults() {
|
public Subject getDefaults() {
|
||||||
return null;
|
return new SimpleSubject("default", service, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,13 +20,13 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.service.collections;
|
package me.lucko.luckperms.api.sponge.collections;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import me.lucko.luckperms.service.LuckPermsService;
|
import me.lucko.luckperms.api.sponge.LuckPermsService;
|
||||||
import me.lucko.luckperms.service.simple.SimpleSubject;
|
import me.lucko.luckperms.api.sponge.simple.SimpleSubject;
|
||||||
import me.lucko.luckperms.service.wrapping.LuckPermsSubject;
|
import me.lucko.luckperms.api.sponge.LuckPermsSubject;
|
||||||
import me.lucko.luckperms.users.User;
|
import me.lucko.luckperms.users.User;
|
||||||
import me.lucko.luckperms.users.UserManager;
|
import me.lucko.luckperms.users.UserManager;
|
||||||
import org.spongepowered.api.service.context.Context;
|
import org.spongepowered.api.service.context.Context;
|
||||||
@ -66,7 +66,8 @@ public class UserCollection implements SubjectCollection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wtf am I meant to do here? What if no user is loaded? Load it? Create it?
|
// What am I meant to do here? What if no user is loaded? Load it? Create it?
|
||||||
|
// If I do load/create it, this method should always be called async??.... errr.
|
||||||
return new SimpleSubject(id, service, this);
|
return new SimpleSubject(id, service, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +105,6 @@ public class UserCollection implements SubjectCollection {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getDefaults() {
|
public Subject getDefaults() {
|
||||||
return null;
|
return new SimpleSubject("default", service, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,7 +20,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.service.simple;
|
package me.lucko.luckperms.api.sponge.simple;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
@ -85,6 +85,6 @@ public class SimpleCollection implements SubjectCollection {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getDefaults() {
|
public Subject getDefaults() {
|
||||||
return null; // TODO
|
return new SimpleSubject("default", service, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,7 +20,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.service.simple;
|
package me.lucko.luckperms.api.sponge.simple;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
@ -29,8 +29,9 @@ import org.spongepowered.api.service.context.Context;
|
|||||||
import org.spongepowered.api.service.permission.*;
|
import org.spongepowered.api.service.permission.*;
|
||||||
import org.spongepowered.api.util.Tristate;
|
import org.spongepowered.api.util.Tristate;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Super simple Subject implementation.
|
* Super simple Subject implementation.
|
||||||
@ -43,9 +44,6 @@ public class SimpleSubject implements Subject {
|
|||||||
private final SubjectCollection containingCollection;
|
private final SubjectCollection containingCollection;
|
||||||
private final SubjectData subjectData;
|
private final SubjectData subjectData;
|
||||||
|
|
||||||
private final Map<Set<Context>, Map<String, Tristate>> perms = new ConcurrentHashMap<>();
|
|
||||||
private final Map<Set<Context>, Set<Subject>> parents = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public SimpleSubject(String identifier, PermissionService service, SubjectCollection containingCollection) {
|
public SimpleSubject(String identifier, PermissionService service, SubjectCollection containingCollection) {
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
this.service = service;
|
this.service = service;
|
||||||
@ -65,33 +63,21 @@ public class SimpleSubject implements Subject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
public boolean hasPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
||||||
return getPermissionValue(contexts, node).asBoolean();
|
return subjectData.getPermissions(contexts).getOrDefault(node, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPermission(@NonNull String permission) {
|
public boolean hasPermission(@NonNull String permission) {
|
||||||
return getPermissionValue(getActiveContexts(), permission).asBoolean();
|
return hasPermission(getActiveContexts(), permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) {
|
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) {
|
||||||
if (!perms.containsKey(contexts)) {
|
if (!subjectData.getPermissions(contexts).containsKey(node)) {
|
||||||
return Tristate.UNDEFINED;
|
return Tristate.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Tristate> context = perms.get(contexts);
|
return Tristate.fromBoolean(subjectData.getPermissions(contexts).get(node));
|
||||||
if (context.containsKey(node)) {
|
|
||||||
return context.get(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Subject parent : getParents(contexts)) {
|
|
||||||
Tristate ts = parent.getPermissionValue(contexts, node);
|
|
||||||
if (ts != Tristate.UNDEFINED) {
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Tristate.UNDEFINED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -101,7 +87,7 @@ public class SimpleSubject implements Subject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject subject) {
|
public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject subject) {
|
||||||
return parents.containsKey(contexts) && parents.get(contexts).contains(subject);
|
return subjectData.getParents(contexts).contains(subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -111,21 +97,17 @@ public class SimpleSubject implements Subject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Subject> getParents(@NonNull Set<Context> contexts) {
|
public List<Subject> getParents(@NonNull Set<Context> contexts) {
|
||||||
if (!parents.containsKey(contexts)) {
|
return subjectData.getParents(contexts);
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ArrayList<>(parents.get(contexts));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<String> getOption(Set<Context> set, String s) {
|
public Optional<String> getOption(Set<Context> set, String s) {
|
||||||
return null; // TODO
|
return Optional.ofNullable(subjectData.getOptions(set).get(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<String> getOption(String key) {
|
public Optional<String> getOption(String key) {
|
||||||
return null; // TODO
|
return Optional.ofNullable(subjectData.getOptions(getActiveContexts()).get(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -1,464 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package me.lucko.luckperms.service.wrapping;
|
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import me.lucko.luckperms.constants.Patterns;
|
|
||||||
import me.lucko.luckperms.core.PermissionHolder;
|
|
||||||
import me.lucko.luckperms.groups.Group;
|
|
||||||
import me.lucko.luckperms.service.LuckPermsService;
|
|
||||||
import me.lucko.luckperms.users.User;
|
|
||||||
import org.spongepowered.api.Sponge;
|
|
||||||
import org.spongepowered.api.command.CommandSource;
|
|
||||||
import org.spongepowered.api.entity.living.player.Player;
|
|
||||||
import org.spongepowered.api.service.context.Context;
|
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
|
||||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
|
||||||
import org.spongepowered.api.service.permission.SubjectData;
|
|
||||||
import org.spongepowered.api.util.Tristate;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO
|
|
||||||
* this class is aids rn
|
|
||||||
*/
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class LuckPermsSubject implements Subject {
|
|
||||||
private final EnduringData enduringData;
|
|
||||||
private final LuckPermsService service;
|
|
||||||
|
|
||||||
public LuckPermsSubject(PermissionHolder holder, LuckPermsService service) {
|
|
||||||
this.enduringData = new EnduringData(service, holder);
|
|
||||||
this.service = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIdentifier() {
|
|
||||||
return enduringData.getHolder().getObjectName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<CommandSource> getCommandSource() {
|
|
||||||
if (enduringData.getHolder() instanceof User) {
|
|
||||||
final UUID uuid = ((User) enduringData.getHolder()).getUuid();
|
|
||||||
|
|
||||||
Optional<Player> p = Sponge.getServer().getPlayer(uuid);
|
|
||||||
if (p.isPresent()) {
|
|
||||||
return Optional.of(p.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SubjectCollection getContainingCollection() {
|
|
||||||
if (enduringData.getHolder() instanceof Group) {
|
|
||||||
return service.getGroupSubjects();
|
|
||||||
} else {
|
|
||||||
return service.getUserSubjects();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SubjectData getSubjectData() {
|
|
||||||
return null; // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SubjectData getTransientSubjectData() {
|
|
||||||
return null; // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
|
||||||
return getPermissionValue(contexts, node).asBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasPermission(String permission) {
|
|
||||||
return getPermissionValue(getActiveContexts(), permission).asBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) {
|
|
||||||
return null;
|
|
||||||
/*
|
|
||||||
final Map<String, Boolean> nodes = applyContexts(contexts);
|
|
||||||
|
|
||||||
if (nodes.containsKey(node)) {
|
|
||||||
return Tristate.fromBoolean(nodes.get(node));
|
|
||||||
} else {
|
|
||||||
return Tristate.UNDEFINED;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isChildOf(@NonNull Subject parent) {
|
|
||||||
return isChildOf(getActiveContexts(), parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject parent) {
|
|
||||||
return parent instanceof PermissionHolder && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Subject> getParents() {
|
|
||||||
return getParents(getActiveContexts());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Subject> getParents(@NonNull Set<Context> contexts) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<String> getOption(Set<Context> set, String s) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<String> getOption(String key) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Context> getActiveContexts() {
|
|
||||||
return SubjectData.GLOBAL_CONTEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
|
||||||
public static class EnduringData implements SubjectData {
|
|
||||||
private final LuckPermsService service;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final PermissionHolder holder;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Set<Context>, Map<String, Boolean>> getAllPermissions() {
|
|
||||||
return null;
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
/*
|
|
||||||
Map<String, Boolean> nodes = holder.convertTemporaryPerms();
|
|
||||||
Map<Set<Context>, Map<String, Boolean>> permissions = new HashMap<>();
|
|
||||||
|
|
||||||
for (Map.Entry<String, Boolean> e : nodes.entrySet()) {
|
|
||||||
String node = e.getKey();
|
|
||||||
if (node.contains("/")) {
|
|
||||||
// server and/or world specific
|
|
||||||
String[] parts = Patterns.SERVER_DELIMITER.split(node, 2);
|
|
||||||
// 0 = server+world 1 = node
|
|
||||||
|
|
||||||
node = parts[1];
|
|
||||||
String server = null;
|
|
||||||
String world = null;
|
|
||||||
|
|
||||||
if (parts[0].contains("-")) {
|
|
||||||
String[] serverParts = Patterns.WORLD_DELIMITER.split(parts[0], 2);
|
|
||||||
world = serverParts[0];
|
|
||||||
server = serverParts[1];
|
|
||||||
|
|
||||||
} else {
|
|
||||||
server = parts[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (world == null) {
|
|
||||||
if (Patterns.NODE_CONTEXTS.matcher(node).matches()) {
|
|
||||||
// Has special context
|
|
||||||
Set<Context> c = Sets.newHashSet(new Context(LuckPermsService.SERVER_CONTEXT, server));
|
|
||||||
|
|
||||||
String[] contextParts = e.getKey().substring(1).split("\\)", 2);
|
|
||||||
// 0 = context, 1 = node
|
|
||||||
|
|
||||||
node = contextParts[1];
|
|
||||||
|
|
||||||
// Parse the context values from this node
|
|
||||||
for (String s : contextParts[0].split("\\,")) {
|
|
||||||
if (!s.contains("=")) {
|
|
||||||
// Not valid
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// contextKey=value
|
|
||||||
String[] con = s.split("\\=", 2);
|
|
||||||
c.add(new Context(con[0], con[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!permissions.containsKey(c)) {
|
|
||||||
permissions.put(c, new HashMap<>());
|
|
||||||
}
|
|
||||||
permissions.get(c).put(node, e.getValue());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// No special context
|
|
||||||
Set<Context> c = Sets.newHashSet(new Context(LuckPermsService.SERVER_CONTEXT, server));
|
|
||||||
if (!permissions.containsKey(c)) {
|
|
||||||
permissions.put(c, new HashMap<>());
|
|
||||||
}
|
|
||||||
permissions.get(c).put(node, e.getValue());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (Patterns.NODE_CONTEXTS.matcher(node).matches()) {
|
|
||||||
// Has special context
|
|
||||||
Set<Context> c = Sets.newHashSet(new Context(Context.WORLD_KEY, world), new Context(LuckPermsService.SERVER_CONTEXT, server));
|
|
||||||
|
|
||||||
String[] contextParts = e.getKey().substring(1).split("\\)", 2);
|
|
||||||
// 0 = context, 1 = node
|
|
||||||
|
|
||||||
node = contextParts[1];
|
|
||||||
|
|
||||||
// Parse the context values from this node
|
|
||||||
for (String s : contextParts[0].split("\\,")) {
|
|
||||||
if (!s.contains("=")) {
|
|
||||||
// Not valid
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// contextKey=value
|
|
||||||
String[] con = s.split("\\=", 2);
|
|
||||||
c.add(new Context(con[0], con[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!permissions.containsKey(c)) {
|
|
||||||
permissions.put(c, new HashMap<>());
|
|
||||||
}
|
|
||||||
permissions.get(c).put(node, e.getValue());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// No special context
|
|
||||||
Set<Context> c = Sets.newHashSet(new Context(Context.WORLD_KEY, world), new Context(LuckPermsService.SERVER_CONTEXT, server));
|
|
||||||
if (!permissions.containsKey(c)) {
|
|
||||||
permissions.put(c, new HashMap<>());
|
|
||||||
}
|
|
||||||
permissions.get(c).put(node, e.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Plain node
|
|
||||||
if (Patterns.NODE_CONTEXTS.matcher(e.getKey()).matches()) {
|
|
||||||
// Has special context
|
|
||||||
Set<Context> c = Sets.newHashSet();
|
|
||||||
|
|
||||||
String[] contextParts = e.getKey().substring(1).split("\\)", 2);
|
|
||||||
// 0 = context, 1 = node
|
|
||||||
|
|
||||||
node = contextParts[1];
|
|
||||||
|
|
||||||
// Parse the context values from this node
|
|
||||||
for (String s : contextParts[0].split("\\,")) {
|
|
||||||
if (!s.contains("=")) {
|
|
||||||
// Not valid
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// contextKey=value
|
|
||||||
String[] con = s.split("\\=", 2);
|
|
||||||
c.add(new Context(con[0], con[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!permissions.containsKey(c)) {
|
|
||||||
permissions.put(c, new HashMap<>());
|
|
||||||
}
|
|
||||||
permissions.get(c).put(node, e.getValue());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (!permissions.containsKey(new HashSet<Context>())) {
|
|
||||||
permissions.put(new HashSet<>(), new HashMap<>());
|
|
||||||
}
|
|
||||||
permissions.get(new HashSet<Context>()).put(node, e.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return permissions;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Boolean> getPermissions(Set<Context> set) {
|
|
||||||
return getAllPermissions().getOrDefault(set, Collections.emptyMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setPermission(Set<Context> set, String s, Tristate tristate) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean clearPermissions() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean clearPermissions(Set<Context> set) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Set<Context>, List<Subject>> getAllParents() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Subject> getParents(Set<Context> contexts) {
|
|
||||||
final Set<String> parents = new HashSet<>();
|
|
||||||
final Map<String, Boolean> nodes = applyContexts(contexts);
|
|
||||||
|
|
||||||
for (Map.Entry<String, Boolean> e : nodes.entrySet()) {
|
|
||||||
if (!e.getValue()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Patterns.GROUP_MATCH.matcher(e.getKey()).matches()) {
|
|
||||||
final String groupName = e.getKey().substring("group.".length());
|
|
||||||
parents.add(groupName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parents.stream().map(s -> service.getGroupSubjects().get(s)).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean addParent(Set<Context> set, Subject subject) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeParent(Set<Context> set, Subject subject) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean clearParents() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean clearParents(Set<Context> set) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Set<Context>, Map<String, String>> getAllOptions() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getOptions(Set<Context> set) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setOption(Set<Context> set, String s, String s1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean clearOptions(Set<Context> set) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean clearOptions() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, Boolean> applyContexts(@NonNull Set<Context> set) {
|
|
||||||
final Map<String, Boolean> map = new HashMap<>();
|
|
||||||
|
|
||||||
String world = null;
|
|
||||||
String server = null;
|
|
||||||
|
|
||||||
Map<String, String> contexts = new HashMap<>();
|
|
||||||
|
|
||||||
for (Context context : set) {
|
|
||||||
if (context.getType().equals(Context.WORLD_KEY)) {
|
|
||||||
world = context.getName();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context.getType().equals(LuckPermsService.SERVER_CONTEXT)) {
|
|
||||||
server = context.getName();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
contexts.put(context.getType(), context.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Boolean> local = holder.getLocalPermissions(server, world, null, service.getPossiblePermissions());
|
|
||||||
perms:
|
|
||||||
for (Map.Entry<String, Boolean> e : local.entrySet()) {
|
|
||||||
if (!contexts.isEmpty()) {
|
|
||||||
if (!Patterns.NODE_CONTEXTS.matcher(e.getKey()).matches()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] parts = e.getKey().substring(1).split("\\)", 2);
|
|
||||||
// 0 = context, 1 = node
|
|
||||||
|
|
||||||
// Parse the context values from this node
|
|
||||||
Map<String, String> contextValues = new HashMap<>();
|
|
||||||
for (String s : parts[0].split("\\,")) {
|
|
||||||
if (!s.contains("=")) {
|
|
||||||
// Not valid
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// contextKey=value
|
|
||||||
String[] con = s.split("\\=", 2);
|
|
||||||
contextValues.put(con[0], con[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that all of the requested contexts are met
|
|
||||||
for (Map.Entry<String, String> req : contexts.entrySet()) {
|
|
||||||
if (!contextValues.containsKey(e.getKey())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!contextValues.get(req.getKey()).equalsIgnoreCase(req.getValue())) {
|
|
||||||
// Not valid within the current contexts
|
|
||||||
continue perms;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Passed all da tests.
|
|
||||||
map.put(parts[1], e.getValue());
|
|
||||||
} else {
|
|
||||||
map.put(e.getKey(), e.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user