More progress towards 1.6: add transient permissions
This commit is contained in:
parent
2ea9b36c77
commit
2a305b1c55
@ -44,11 +44,23 @@ public interface Node extends Map.Entry<String, Boolean> {
|
|||||||
@Override
|
@Override
|
||||||
Boolean getValue();
|
Boolean getValue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of this node as a Tristate
|
||||||
|
*/
|
||||||
|
Tristate getTristate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the node is negated
|
* @return true if the node is negated
|
||||||
*/
|
*/
|
||||||
boolean isNegated();
|
boolean isNegated();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this node is set to override explicitly.
|
||||||
|
* This value does not persist across saves, and is therefore only useful for transient nodes
|
||||||
|
* @return true if this node is set to override explicitly
|
||||||
|
*/
|
||||||
|
boolean isOverride();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the server this node applies on, if the node is server specific
|
* Gets the server this node applies on, if the node is server specific
|
||||||
* @return an {@link Optional} containing the server, if one is defined
|
* @return an {@link Optional} containing the server, if one is defined
|
||||||
@ -189,6 +201,13 @@ public interface Node extends Map.Entry<String, Boolean> {
|
|||||||
*/
|
*/
|
||||||
int getWildcardLevel();
|
int getWildcardLevel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to {@link #equals(Object)}, except doesn't take note of the value
|
||||||
|
* @param node the other node
|
||||||
|
* @return true if the two nodes are almost equal
|
||||||
|
*/
|
||||||
|
boolean equalsIgnoringValue(Node node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to {@link #equals(Object)}, except doesn't take note of the expiry time or value
|
* Similar to {@link #equals(Object)}, except doesn't take note of the expiry time or value
|
||||||
* @param node the other node
|
* @param node the other node
|
||||||
@ -199,6 +218,13 @@ public interface Node extends Map.Entry<String, Boolean> {
|
|||||||
interface Builder {
|
interface Builder {
|
||||||
Builder setNegated(boolean negated);
|
Builder setNegated(boolean negated);
|
||||||
Builder setValue(boolean value);
|
Builder setValue(boolean value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warning: this value does not persist, and disappears when the holder is re-loaded.
|
||||||
|
* It is therefore only useful for transient nodes.
|
||||||
|
*/
|
||||||
|
Builder setOverride(boolean override);
|
||||||
|
|
||||||
Builder setExpiry(long expireAt);
|
Builder setExpiry(long expireAt);
|
||||||
Builder setWorld(String world);
|
Builder setWorld(String world);
|
||||||
Builder setServer(String server) throws IllegalArgumentException;
|
Builder setServer(String server) throws IllegalArgumentException;
|
||||||
|
@ -28,6 +28,7 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper interface for internal PermissionHolder (object/group) instances
|
* Wrapper interface for internal PermissionHolder (object/group) instances
|
||||||
@ -43,10 +44,25 @@ public interface PermissionHolder {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an immutable Set of the objects permission nodes
|
* Gets an immutable Set of the objects permission nodes
|
||||||
* @return an immutable set of permissions
|
* @return an immutable set of permissions in priority order
|
||||||
* @since 1.6
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
Set<Node> getPermissionNodes();
|
SortedSet<Node> getPermissions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to {@link #getPermissions()}, except excluding transient permissions
|
||||||
|
* @return a set of nodes
|
||||||
|
* @since 1.6
|
||||||
|
*/
|
||||||
|
Set<Node> getEnduringPermissions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to {@link #getPermissions()}, except excluding non-transient permissions
|
||||||
|
* @return a set of nodes
|
||||||
|
* @since 1.6
|
||||||
|
*/
|
||||||
|
Set<Node> getTransientPermissions();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an immutable set of the nodes that this object has and inherits
|
* Gets an immutable set of the nodes that this object has and inherits
|
||||||
@ -58,7 +74,7 @@ public interface PermissionHolder {
|
|||||||
/**
|
/**
|
||||||
* Gets an immutable Map of the objects permission nodes
|
* Gets an immutable Map of the objects permission nodes
|
||||||
* @return an immutable map of permissions
|
* @return an immutable map of permissions
|
||||||
* @deprecated in favour of {@link #getPermissionNodes()}
|
* @deprecated in favour of {@link #getPermissions()}
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
Map<String, Boolean> getNodes();
|
Map<String, Boolean> getNodes();
|
||||||
@ -66,11 +82,20 @@ public interface PermissionHolder {
|
|||||||
/**
|
/**
|
||||||
* Checks to see if the object has a certain permission
|
* Checks to see if the object has a certain permission
|
||||||
* @param node the node to check for
|
* @param node the node to check for
|
||||||
* @return true if the object has the permission
|
* @return a Tristate for the holders permission status for the node
|
||||||
* @throws NullPointerException if the node is null
|
* @throws NullPointerException if the node is null
|
||||||
* @since 1.6
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
boolean hasPermission(Node node);
|
Tristate hasPermission(Node node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if the object has a certain permission
|
||||||
|
* @param node the node to check for
|
||||||
|
* @return a Tristate for the holders permission status for the node
|
||||||
|
* @throws NullPointerException if the node is null
|
||||||
|
* @since 1.6
|
||||||
|
*/
|
||||||
|
Tristate hasTransientPermission(Node node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks to see if the object has a certain permission
|
* Checks to see if the object has a certain permission
|
||||||
@ -79,9 +104,7 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object has the permission
|
* @return true if the object has the permission
|
||||||
* @throws NullPointerException if the node is null
|
* @throws NullPointerException if the node is null
|
||||||
* @throws IllegalArgumentException if the node is invalid
|
* @throws IllegalArgumentException if the node is invalid
|
||||||
* @deprecated in favour of {@link #hasPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean hasPermission(String node, boolean b);
|
boolean hasPermission(String node, boolean b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,9 +115,7 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object has the permission
|
* @return true if the object has the permission
|
||||||
* @throws NullPointerException if the node or server is null
|
* @throws NullPointerException if the node or server is null
|
||||||
* @throws IllegalArgumentException if the node or server is invalid
|
* @throws IllegalArgumentException if the node or server is invalid
|
||||||
* @deprecated in favour of {@link #hasPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean hasPermission(String node, boolean b, String server);
|
boolean hasPermission(String node, boolean b, String server);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,9 +127,7 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object has the permission
|
* @return true if the object has the permission
|
||||||
* @throws NullPointerException if the node, server or world is null
|
* @throws NullPointerException if the node, server or world is null
|
||||||
* @throws IllegalArgumentException if the node, server or world is invalid
|
* @throws IllegalArgumentException if the node, server or world is invalid
|
||||||
* @deprecated in favour of {@link #hasPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean hasPermission(String node, boolean b, String server, String world);
|
boolean hasPermission(String node, boolean b, String server, String world);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,9 +138,7 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object has the permission
|
* @return true if the object has the permission
|
||||||
* @throws NullPointerException if the node is null
|
* @throws NullPointerException if the node is null
|
||||||
* @throws IllegalArgumentException if the node is invalid
|
* @throws IllegalArgumentException if the node is invalid
|
||||||
* @deprecated in favour of {@link #hasPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean hasPermission(String node, boolean b, boolean temporary);
|
boolean hasPermission(String node, boolean b, boolean temporary);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,9 +150,7 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object has the permission
|
* @return true if the object has the permission
|
||||||
* @throws NullPointerException if the node or server is null
|
* @throws NullPointerException if the node or server is null
|
||||||
* @throws IllegalArgumentException if the node or server is invalid
|
* @throws IllegalArgumentException if the node or server is invalid
|
||||||
* @deprecated in favour of {@link #hasPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean hasPermission(String node, boolean b, String server, boolean temporary);
|
boolean hasPermission(String node, boolean b, String server, boolean temporary);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,19 +163,17 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object has the permission
|
* @return true if the object has the permission
|
||||||
* @throws NullPointerException if the node, server or world is null
|
* @throws NullPointerException if the node, server or world is null
|
||||||
* @throws IllegalArgumentException if the node, server or world is invalid
|
* @throws IllegalArgumentException if the node, server or world is invalid
|
||||||
* @deprecated in favour of {@link #hasPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean hasPermission(String node, boolean b, String server, String world, boolean temporary);
|
boolean hasPermission(String node, boolean b, String server, String world, boolean temporary);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cheks to see if the object inherits a certain permission
|
* Cheks to see if the object inherits a certain permission
|
||||||
* @param node the node to check for
|
* @param node the node to check for
|
||||||
* @return true if the object inherits the permission
|
* @return a Tristate for the holders inheritance status for the node
|
||||||
* @throws NullPointerException if the node is null
|
* @throws NullPointerException if the node is null
|
||||||
* @since 1.6
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
boolean inheritsPermission(Node node);
|
Tristate inheritsPermission(Node node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks to see if the object inherits a certain permission
|
* Checks to see if the object inherits a certain permission
|
||||||
@ -169,9 +182,7 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object inherits the permission
|
* @return true if the object inherits the permission
|
||||||
* @throws NullPointerException if the node is null
|
* @throws NullPointerException if the node is null
|
||||||
* @throws IllegalArgumentException if the node is invalid
|
* @throws IllegalArgumentException if the node is invalid
|
||||||
* @deprecated in favour of {@link #inheritsPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean inheritsPermission(String node, boolean b);
|
boolean inheritsPermission(String node, boolean b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,9 +193,7 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object inherits the permission
|
* @return true if the object inherits the permission
|
||||||
* @throws NullPointerException if the node or server is null
|
* @throws NullPointerException if the node or server is null
|
||||||
* @throws IllegalArgumentException if the node or server is invalid
|
* @throws IllegalArgumentException if the node or server is invalid
|
||||||
* @deprecated in favour of {@link #inheritsPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean inheritsPermission(String node, boolean b, String server);
|
boolean inheritsPermission(String node, boolean b, String server);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -196,9 +205,7 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object inherits the permission
|
* @return true if the object inherits the permission
|
||||||
* @throws NullPointerException if the node, server or world is null
|
* @throws NullPointerException if the node, server or world is null
|
||||||
* @throws IllegalArgumentException if the node server or world is invalid
|
* @throws IllegalArgumentException if the node server or world is invalid
|
||||||
* @deprecated in favour of {@link #inheritsPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean inheritsPermission(String node, boolean b, String server, String world);
|
boolean inheritsPermission(String node, boolean b, String server, String world);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -209,9 +216,7 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object inherits the permission
|
* @return true if the object inherits the permission
|
||||||
* @throws NullPointerException if the node is null
|
* @throws NullPointerException if the node is null
|
||||||
* @throws IllegalArgumentException if the node is invalid
|
* @throws IllegalArgumentException if the node is invalid
|
||||||
* @deprecated in favour of {@link #inheritsPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean inheritsPermission(String node, boolean b, boolean temporary);
|
boolean inheritsPermission(String node, boolean b, boolean temporary);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,9 +228,7 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object inherits the permission
|
* @return true if the object inherits the permission
|
||||||
* @throws NullPointerException if the node or server is null
|
* @throws NullPointerException if the node or server is null
|
||||||
* @throws IllegalArgumentException if the node or server is invalid
|
* @throws IllegalArgumentException if the node or server is invalid
|
||||||
* @deprecated in favour of {@link #inheritsPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean inheritsPermission(String node, boolean b, String server, boolean temporary);
|
boolean inheritsPermission(String node, boolean b, String server, boolean temporary);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -238,9 +241,7 @@ public interface PermissionHolder {
|
|||||||
* @return true if the object inherits the permission
|
* @return true if the object inherits the permission
|
||||||
* @throws NullPointerException if the node, server or world is null
|
* @throws NullPointerException if the node, server or world is null
|
||||||
* @throws IllegalArgumentException if the node, server or world if invalid
|
* @throws IllegalArgumentException if the node, server or world if invalid
|
||||||
* @deprecated in favour of {@link #inheritsPermission(Node)}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
boolean inheritsPermission(String node, boolean b, String server, String world, boolean temporary);
|
boolean inheritsPermission(String node, boolean b, String server, String world, boolean temporary);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -252,6 +253,25 @@ public interface PermissionHolder {
|
|||||||
*/
|
*/
|
||||||
void setPermission(Node node) throws ObjectAlreadyHasException;
|
void setPermission(Node node) throws ObjectAlreadyHasException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a transient permission for the object
|
||||||
|
*
|
||||||
|
* <p> A transient node is a permission that does not persist.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}
|
||||||
|
*
|
||||||
|
* @param node The node to be set
|
||||||
|
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||||
|
* @throws NullPointerException if the node is null
|
||||||
|
* @since 1.6
|
||||||
|
*/
|
||||||
|
void setTransientPermission(Node node) throws ObjectAlreadyHasException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a permission for the object
|
* Sets a permission for the object
|
||||||
* @param node The node to be set
|
* @param node The node to be set
|
||||||
@ -342,6 +362,15 @@ public interface PermissionHolder {
|
|||||||
*/
|
*/
|
||||||
void unsetPermission(Node node) throws ObjectLacksException;
|
void unsetPermission(Node node) throws ObjectLacksException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsets a transient permission for the object
|
||||||
|
* @param node The node to be unset
|
||||||
|
* @throws ObjectLacksException if the node wasn't already set
|
||||||
|
* @throws NullPointerException if the node is null
|
||||||
|
* @since 1.6
|
||||||
|
*/
|
||||||
|
void unsetTransientPermission(Node node) throws ObjectLacksException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsets a permission for the object
|
* Unsets a permission for the object
|
||||||
* @param node The node to be unset
|
* @param node The node to be unset
|
||||||
|
47
api/src/main/java/me/lucko/luckperms/api/Tristate.java
Normal file
47
api/src/main/java/me/lucko/luckperms/api/Tristate.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a permission value
|
||||||
|
*/
|
||||||
|
public enum Tristate {
|
||||||
|
|
||||||
|
TRUE(true),
|
||||||
|
FALSE(false),
|
||||||
|
UNDEFINED(false);
|
||||||
|
|
||||||
|
private final boolean booleanValue;
|
||||||
|
|
||||||
|
Tristate(boolean booleanValue) {
|
||||||
|
this.booleanValue = booleanValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean asBoolean() {
|
||||||
|
return booleanValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tristate fromBoolean(boolean b) {
|
||||||
|
return b ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
}
|
@ -103,7 +103,7 @@ 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.getPermissions("global", world, null, true, Collections.emptyList(), false).entrySet()) {
|
for (Map.Entry<String, Boolean> e : holder.exportNodes("global", world, null, true, false, Collections.emptyList()).entrySet()) {
|
||||||
if (!e.getValue()) continue;
|
if (!e.getValue()) continue;
|
||||||
|
|
||||||
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
||||||
@ -132,7 +132,7 @@ 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.getPermissions("global", world, null, true, Collections.emptyList(), false).entrySet()) {
|
for (Map.Entry<String, Boolean> e : holder.exportNodes("global", world, null, true, false, Collections.emptyList()).entrySet()) {
|
||||||
if (!e.getValue()) continue;
|
if (!e.getValue()) continue;
|
||||||
|
|
||||||
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
||||||
@ -161,7 +161,7 @@ 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.getPermissions("global", world, null, true, Collections.emptyList(), false).entrySet()) {
|
for (Map.Entry<String, Boolean> e : holder.exportNodes("global", world, null, true, false, Collections.emptyList()).entrySet()) {
|
||||||
if (!e.getValue()) continue;
|
if (!e.getValue()) continue;
|
||||||
|
|
||||||
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
||||||
@ -190,7 +190,7 @@ 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.getPermissions("global", world, null, true, Collections.emptyList(), false).entrySet()) {
|
for (Map.Entry<String, Boolean> e : holder.exportNodes("global", world, null, true, false, Collections.emptyList()).entrySet()) {
|
||||||
if (!e.getValue()) continue;
|
if (!e.getValue()) continue;
|
||||||
|
|
||||||
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
String[] parts = Patterns.DOT.split(e.getKey(), 3);
|
||||||
|
@ -26,18 +26,19 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import me.lucko.luckperms.api.Node;
|
import me.lucko.luckperms.api.Node;
|
||||||
import me.lucko.luckperms.api.PermissionHolder;
|
import me.lucko.luckperms.api.PermissionHolder;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static me.lucko.luckperms.api.implementation.internal.Utils.*;
|
import static me.lucko.luckperms.api.implementation.internal.Utils.*;
|
||||||
import static me.lucko.luckperms.core.PermissionHolder.convertToLegacy;
|
import static me.lucko.luckperms.core.PermissionHolder.exportToLegacy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a link between {@link PermissionHolder} and {@link me.lucko.luckperms.core.PermissionHolder}
|
* Provides a link between {@link PermissionHolder} and {@link me.lucko.luckperms.core.PermissionHolder}
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings({"unused", "deprecation"})
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class PermissionHolderLink implements PermissionHolder {
|
public class PermissionHolderLink implements PermissionHolder {
|
||||||
|
|
||||||
@ -50,10 +51,20 @@ public class PermissionHolderLink implements PermissionHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Node> getPermissionNodes() {
|
public SortedSet<Node> getPermissions() {
|
||||||
|
return Collections.unmodifiableSortedSet(master.getPermissions());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Node> getEnduringPermissions() {
|
||||||
return Collections.unmodifiableSet(master.getNodes());
|
return Collections.unmodifiableSet(master.getNodes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Node> getTransientPermissions() {
|
||||||
|
return Collections.unmodifiableSet(master.getTransientNodes());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Node> getAllNodes() {
|
public Set<Node> getAllNodes() {
|
||||||
return Collections.unmodifiableSet(master.getAllNodes(null));
|
return Collections.unmodifiableSet(master.getAllNodes(null));
|
||||||
@ -61,12 +72,17 @@ public class PermissionHolderLink implements PermissionHolder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Boolean> getNodes() {
|
public Map<String, Boolean> getNodes() {
|
||||||
return convertToLegacy(master.getNodes());
|
return exportToLegacy(master.getNodes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPermission(@NonNull Node node) {
|
public Tristate hasPermission(@NonNull Node node) {
|
||||||
return master.hasPermission(node);
|
return master.hasPermission(node, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tristate hasTransientPermission(@NonNull Node node) {
|
||||||
|
return master.hasPermission(node, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -100,7 +116,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean inheritsPermission(@NonNull Node node) {
|
public Tristate inheritsPermission(@NonNull Node node) {
|
||||||
return master.inheritsPermission(node);
|
return master.inheritsPermission(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +155,11 @@ public class PermissionHolderLink implements PermissionHolder {
|
|||||||
master.setPermission(node);
|
master.setPermission(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTransientPermission(@NonNull Node node) throws ObjectAlreadyHasException {
|
||||||
|
master.setTransientPermission(node);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPermission(@NonNull String node, @NonNull boolean value) throws ObjectAlreadyHasException {
|
public void setPermission(@NonNull String node, @NonNull boolean value) throws ObjectAlreadyHasException {
|
||||||
master.setPermission(checkNode(node), value);
|
master.setPermission(checkNode(node), value);
|
||||||
@ -174,6 +195,11 @@ public class PermissionHolderLink implements PermissionHolder {
|
|||||||
master.unsetPermission(node);
|
master.unsetPermission(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unsetTransientPermission(@NonNull Node node) throws ObjectLacksException {
|
||||||
|
master.unsetTransientPermission(node);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unsetPermission(@NonNull String node, @NonNull boolean temporary) throws ObjectLacksException {
|
public void unsetPermission(@NonNull String node, @NonNull boolean temporary) throws ObjectLacksException {
|
||||||
master.unsetPermission(checkNode(node), temporary);
|
master.unsetPermission(checkNode(node), temporary);
|
||||||
@ -226,7 +252,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Boolean> getPermissions(String server, String world, Map<String, String> extraContext, boolean includeGlobal, List<String> possibleNodes, boolean applyGroups) {
|
public Map<String, Boolean> getPermissions(String server, String world, Map<String, String> extraContext, boolean includeGlobal, List<String> possibleNodes, boolean applyGroups) {
|
||||||
return master.getPermissions(server, world, extraContext, includeGlobal, possibleNodes, applyGroups);
|
return master.exportNodes(server, world, extraContext, includeGlobal, applyGroups, possibleNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -247,7 +273,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Boolean> getPermanentNodes() {
|
public Map<String, Boolean> getPermanentNodes() {
|
||||||
return convertToLegacy(master.getPermanentNodes());
|
return exportToLegacy(master.getPermanentNodes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -30,7 +30,7 @@ import me.lucko.luckperms.groups.Group;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static me.lucko.luckperms.core.PermissionHolder.convertToLegacy;
|
import static me.lucko.luckperms.core.PermissionHolder.exportToLegacy;
|
||||||
|
|
||||||
public class GroupListNodes extends SubCommand<Group> {
|
public class GroupListNodes extends SubCommand<Group> {
|
||||||
public GroupListNodes() {
|
public GroupListNodes() {
|
||||||
@ -40,7 +40,7 @@ public class GroupListNodes extends SubCommand<Group> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||||
Message.LISTNODES.send(sender, group.getName(), Util.permNodesToString(convertToLegacy(group.getPermanentNodes())));
|
Message.LISTNODES.send(sender, group.getName(), Util.permNodesToString(exportToLegacy(group.getPermanentNodes())));
|
||||||
Message.LISTNODES_TEMP.send(sender, group.getName(), Util.tempNodesToString(group.getTemporaryNodesLegacy()));
|
Message.LISTNODES_TEMP.send(sender, group.getName(), Util.tempNodesToString(group.getTemporaryNodesLegacy()));
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ import me.lucko.luckperms.LuckPermsPlugin;
|
|||||||
import me.lucko.luckperms.commands.*;
|
import me.lucko.luckperms.commands.*;
|
||||||
import me.lucko.luckperms.constants.Message;
|
import me.lucko.luckperms.constants.Message;
|
||||||
import me.lucko.luckperms.constants.Permission;
|
import me.lucko.luckperms.constants.Permission;
|
||||||
import me.lucko.luckperms.core.PermissionHolder;
|
|
||||||
import me.lucko.luckperms.users.User;
|
import me.lucko.luckperms.users.User;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -41,7 +40,7 @@ public class UserListNodes extends SubCommand<User> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||||
Message.LISTNODES.send(sender, user.getName(), Util.permNodesToString(convertToLegacy(user.getPermanentNodes())));
|
Message.LISTNODES.send(sender, user.getName(), Util.permNodesToString(exportToLegacy(user.getPermanentNodes())));
|
||||||
Message.LISTNODES_TEMP.send(sender, user.getName(), Util.tempNodesToString(user.getTemporaryNodesLegacy()));
|
Message.LISTNODES_TEMP.send(sender, user.getName(), Util.tempNodesToString(user.getTemporaryNodesLegacy()));
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import lombok.Getter;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import me.lucko.luckperms.LuckPermsPlugin;
|
import me.lucko.luckperms.LuckPermsPlugin;
|
||||||
import me.lucko.luckperms.api.Node;
|
import me.lucko.luckperms.api.Node;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.api.event.events.GroupRemoveEvent;
|
import me.lucko.luckperms.api.event.events.GroupRemoveEvent;
|
||||||
import me.lucko.luckperms.api.event.events.PermissionNodeExpireEvent;
|
import me.lucko.luckperms.api.event.events.PermissionNodeExpireEvent;
|
||||||
import me.lucko.luckperms.api.event.events.PermissionNodeSetEvent;
|
import me.lucko.luckperms.api.event.events.PermissionNodeSetEvent;
|
||||||
@ -38,6 +39,7 @@ import me.lucko.luckperms.groups.Group;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentSkipListSet;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,14 +68,195 @@ public abstract class PermissionHolder {
|
|||||||
@Getter
|
@Getter
|
||||||
private Set<Node> nodes = ConcurrentHashMap.newKeySet();
|
private Set<Node> nodes = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user/group's transient permissions
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private Set<Node> transientNodes = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a Set of nodes in priority order
|
||||||
|
* @return the holders transient and permanent nodes
|
||||||
|
*/
|
||||||
|
public SortedSet<Node> getPermissions() {
|
||||||
|
// Returns no duplicate nodes. as in, nodes with the same value.
|
||||||
|
|
||||||
|
TreeSet<Node> permissions = new TreeSet<>(PRIORITY_COMPARATOR);
|
||||||
|
permissions.addAll(nodes);
|
||||||
|
permissions.addAll(transientNodes);
|
||||||
|
|
||||||
|
Iterator<Node> iterator = permissions.descendingIterator(); // TODO check this
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Node entry = iterator.next();
|
||||||
|
|
||||||
|
permissions.stream()
|
||||||
|
.filter(entry::equalsIgnoringValue) // The node appears again at a higher priority
|
||||||
|
.forEachOrdered(other -> iterator.remove()); // Remove it.
|
||||||
|
}
|
||||||
|
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes temporary permissions that have expired
|
||||||
|
* @return true if permissions had expired and were removed
|
||||||
|
*/
|
||||||
|
public boolean auditTemporaryPermissions() {
|
||||||
|
boolean work = false;
|
||||||
|
|
||||||
|
Iterator<Node> iterator = nodes.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Node element = iterator.next();
|
||||||
|
if (element.hasExpired()) {
|
||||||
|
iterator.remove();
|
||||||
|
|
||||||
|
work = true;
|
||||||
|
plugin.getApiProvider().fireEventAsync(new PermissionNodeExpireEvent(new PermissionHolderLink(this), element));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Node> iterator2 = transientNodes.iterator();
|
||||||
|
while (iterator2.hasNext()) {
|
||||||
|
Node element = iterator2.next();
|
||||||
|
if (element.hasExpired()) {
|
||||||
|
iterator2.remove();
|
||||||
|
|
||||||
|
work = true;
|
||||||
|
plugin.getApiProvider().fireEventAsync(new PermissionNodeExpireEvent(new PermissionHolderLink(this), element));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return work;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all of the nodes that this holder has and inherits
|
||||||
|
* @param excludedGroups a list of groups to exclude
|
||||||
|
* @return a set of nodes
|
||||||
|
*/
|
||||||
|
public SortedSet<Node> getAllNodes(List<String> excludedGroups) {
|
||||||
|
SortedSet<Node> all = new ConcurrentSkipListSet<>(PRIORITY_COMPARATOR);
|
||||||
|
all.addAll(getPermissions());
|
||||||
|
|
||||||
|
if (excludedGroups == null) {
|
||||||
|
excludedGroups = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
excludedGroups.add(getObjectName().toLowerCase());
|
||||||
|
|
||||||
|
Set<String> parents = getPermissions().stream()
|
||||||
|
.filter(Node::isGroupNode)
|
||||||
|
.map(Node::getGroupName)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
for (String parent : parents) {
|
||||||
|
Group group = plugin.getGroupManager().get(parent);
|
||||||
|
if (group == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (excludedGroups.contains(group.getObjectName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
inherited:
|
||||||
|
for (Node inherited : group.getAllNodes(excludedGroups)) {
|
||||||
|
for (Node existing : all) {
|
||||||
|
if (existing.almostEquals(inherited)) {
|
||||||
|
continue inherited;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
all.add(inherited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all of the nodes that this holder has (and inherits), given the context
|
||||||
|
* @param server the server
|
||||||
|
* @param world the world
|
||||||
|
* @param extraContext any extra context to filter by
|
||||||
|
* @param includeGlobal whether to include global nodes
|
||||||
|
* @param applyGroups if inherited group permissions should be included
|
||||||
|
* @return a map of permissions
|
||||||
|
*/
|
||||||
|
public Set<Node> getAllNodesFiltered(String server, String world, Map<String, String> extraContext, boolean includeGlobal, boolean applyGroups) {
|
||||||
|
Set<Node> perms = ConcurrentHashMap.newKeySet();
|
||||||
|
SortedSet<Node> allNodes;
|
||||||
|
|
||||||
|
if (applyGroups) {
|
||||||
|
allNodes = sort(getAllNodes(null), true);
|
||||||
|
} else {
|
||||||
|
allNodes = sort(getPermissions(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Node node : allNodes) {
|
||||||
|
if (!node.shouldApplyOnServer(server, includeGlobal, plugin.getConfiguration().getApplyRegex())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!node.shouldApplyOnWorld(world, includeGlobal, plugin.getConfiguration().getApplyRegex())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!node.shouldApplyWithContext(extraContext)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
perms.add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return perms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the output of {@link #getAllNodesFiltered(String, String, Map, boolean, boolean)}, and expands wildcards/regex/shorthand perms
|
||||||
|
* @param server the server
|
||||||
|
* @param world the world
|
||||||
|
* @param extraContext any extra context to filter by
|
||||||
|
* @param includeGlobal whether to include global nodes
|
||||||
|
* @param applyGroups if inherited group permissions should be included
|
||||||
|
* @param possibleNodes a list of possible nodes for wildcards and regex permissions
|
||||||
|
* @return a map of permissions
|
||||||
|
*/
|
||||||
|
public Map<String, Boolean> exportNodes(String server, String world, Map<String, String> extraContext, boolean includeGlobal, boolean applyGroups, List<String> possibleNodes) {
|
||||||
|
Map<String, Boolean> perms = new HashMap<>();
|
||||||
|
|
||||||
|
for (Node node : getAllNodesFiltered(server, world, extraContext, includeGlobal, applyGroups)) {
|
||||||
|
perms.put(node.getPermission(), node.getValue());
|
||||||
|
|
||||||
|
if (plugin.getConfiguration().getApplyShorthand()) {
|
||||||
|
node.resolveShorthand().stream()
|
||||||
|
.filter(s -> !perms.containsKey(s))
|
||||||
|
.forEach(s -> perms.put(s, node.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.getConfiguration().getApplyWildcards()) {
|
||||||
|
node.resolveWildcard(possibleNodes).stream()
|
||||||
|
.filter(s -> !perms.containsKey(s))
|
||||||
|
.forEach(s -> perms.put(s, node.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.unmodifiableMap(perms);
|
||||||
|
}
|
||||||
|
|
||||||
public void setNodes(Set<Node> nodes) {
|
public void setNodes(Set<Node> nodes) {
|
||||||
this.nodes.clear();
|
this.nodes.clear();
|
||||||
this.nodes.addAll(nodes);
|
this.nodes.addAll(nodes);
|
||||||
auditTemporaryPermissions();
|
auditTemporaryPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
public void setTransiestNodes(Set<Node> nodes) {
|
||||||
public static Map<String, Boolean> convertToLegacy(Set<Node> nodes) {
|
this.transientNodes.clear();
|
||||||
|
this.transientNodes.addAll(nodes);
|
||||||
|
auditTemporaryPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Boolean> exportToLegacy(Set<Node> nodes) {
|
||||||
Map<String, Boolean> m = new HashMap<>();
|
Map<String, Boolean> m = new HashMap<>();
|
||||||
for (Node node : nodes) {
|
for (Node node : nodes) {
|
||||||
m.put(node.toSerializedNode(), node.getValue());
|
m.put(node.toSerializedNode(), node.getValue());
|
||||||
@ -81,6 +264,7 @@ public abstract class PermissionHolder {
|
|||||||
return Collections.unmodifiableMap(m);
|
return Collections.unmodifiableMap(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convenience method
|
||||||
private static Node.Builder buildNode(String permission) {
|
private static Node.Builder buildNode(String permission) {
|
||||||
return new me.lucko.luckperms.utils.Node.Builder(permission);
|
return new me.lucko.luckperms.utils.Node.Builder(permission);
|
||||||
}
|
}
|
||||||
@ -96,84 +280,94 @@ public abstract class PermissionHolder {
|
|||||||
auditTemporaryPermissions();
|
auditTemporaryPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasPermission(Set<Node> toQuery, Node node) {
|
private static Tristate hasPermission(Set<Node> toQuery, Node node) {
|
||||||
for (Node n : toQuery) {
|
for (Node n : toQuery) {
|
||||||
if (n.almostEquals(node)) {
|
if (n.equalsIgnoringValue(node)) {
|
||||||
return true;
|
n.getTristate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return Tristate.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the holder has a permission node
|
* Check if the holder has a permission node
|
||||||
* @param node the node to check
|
* @param node the node to check
|
||||||
* @return true if the holder has the node
|
* @param t whether to check transient nodes
|
||||||
|
* @return a tristate
|
||||||
*/
|
*/
|
||||||
public boolean hasPermission(Node node) {
|
public Tristate hasPermission(Node node, boolean t) {
|
||||||
return hasPermission(this.nodes, node);
|
return hasPermission(t ? transientNodes : nodes, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tristate hasPermission(Node node) {
|
||||||
|
return hasPermission(node, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPermission(String node, boolean b) {
|
public boolean hasPermission(String node, boolean b) {
|
||||||
return hasPermission(buildNode(node).setValue(b).build());
|
return hasPermission(buildNode(node).setValue(b).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPermission(String node, boolean b, String server) {
|
public boolean hasPermission(String node, boolean b, String server) {
|
||||||
return hasPermission(buildNode(node).setValue(b).setServer(server).build());
|
return hasPermission(buildNode(node).setValue(b).setServer(server).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPermission(String node, boolean b, String server, String world) {
|
public boolean hasPermission(String node, boolean b, String server, String world) {
|
||||||
return hasPermission(buildNode(node).setValue(b).setServer(server).setWorld(world).build());
|
return hasPermission(buildNode(node).setValue(b).setServer(server).setWorld(world).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPermission(String node, boolean b, boolean temporary) {
|
public boolean hasPermission(String node, boolean b, boolean temporary) {
|
||||||
return hasPermission(buildNode(node).setValue(b).setExpiry(temporary ? 10L : 0L).build());
|
return hasPermission(buildNode(node).setValue(b).setExpiry(temporary ? 10L : 0L).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPermission(String node, boolean b, String server, boolean temporary) {
|
public boolean hasPermission(String node, boolean b, String server, boolean temporary) {
|
||||||
return hasPermission(buildNode(node).setValue(b).setServer(server).setExpiry(temporary ? 10L : 0L).build());
|
return hasPermission(buildNode(node).setValue(b).setServer(server).setExpiry(temporary ? 10L : 0L).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPermission(String node, boolean b, String server, String world, boolean temporary) {
|
public boolean hasPermission(String node, boolean b, String server, String world, boolean temporary) {
|
||||||
return hasPermission(buildNode(node).setValue(b).setServer(server).setWorld(world).setExpiry(temporary ? 10L : 0L).build());
|
return hasPermission(buildNode(node).setValue(b).setServer(server).setWorld(world).setExpiry(temporary ? 10L : 0L).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the holder inherits a node
|
* Check if the holder inherits a node
|
||||||
* @param node the node to check
|
* @param node the node to check
|
||||||
* @return true if the holder inherits the node
|
* @return a tristate
|
||||||
*/
|
*/
|
||||||
public boolean inheritsPermission(Node node) {
|
public Tristate inheritsPermission(Node node) {
|
||||||
return hasPermission(getAllNodes(null), node);
|
return hasPermission(getAllNodes(null), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean inheritsPermission(String node, boolean b) {
|
public boolean inheritsPermission(String node, boolean b) {
|
||||||
return inheritsPermission(buildNode(node).setValue(b).build());
|
return inheritsPermission(buildNode(node).setValue(b).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean inheritsPermission(String node, boolean b, String server) {
|
public boolean inheritsPermission(String node, boolean b, String server) {
|
||||||
return inheritsPermission(buildNode(node).setValue(b).setServer(server).build());
|
return inheritsPermission(buildNode(node).setValue(b).setServer(server).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean inheritsPermission(String node, boolean b, String server, String world) {
|
public boolean inheritsPermission(String node, boolean b, String server, String world) {
|
||||||
return inheritsPermission(buildNode(node).setValue(b).setServer(server).setWorld(world).build());
|
return inheritsPermission(buildNode(node).setValue(b).setServer(server).setWorld(world).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean inheritsPermission(String node, boolean b, boolean temporary) {
|
public boolean inheritsPermission(String node, boolean b, boolean temporary) {
|
||||||
return inheritsPermission(buildNode(node).setValue(b).setExpiry(temporary ? 10L : 0L).build());
|
return inheritsPermission(buildNode(node).setValue(b).setExpiry(temporary ? 10L : 0L).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean inheritsPermission(String node, boolean b, String server, boolean temporary) {
|
public boolean inheritsPermission(String node, boolean b, String server, boolean temporary) {
|
||||||
return inheritsPermission(buildNode(node).setValue(b).setServer(server).setExpiry(temporary ? 10L : 0L).build());
|
return inheritsPermission(buildNode(node).setValue(b).setServer(server).setExpiry(temporary ? 10L : 0L).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean inheritsPermission(String node, boolean b, String server, String world, boolean temporary) {
|
public boolean inheritsPermission(String node, boolean b, String server, String world, boolean temporary) {
|
||||||
return inheritsPermission(buildNode(node).setValue(b).setServer(server).setWorld(world).setExpiry(temporary ? 10L : 0L).build());
|
return inheritsPermission(buildNode(node).setValue(b).setServer(server).setWorld(world).setExpiry(temporary ? 10L : 0L).build()).asBoolean() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a permission node
|
||||||
|
* @param node the node to set
|
||||||
|
* @throws ObjectAlreadyHasException if the holder has this permission already
|
||||||
|
*/
|
||||||
public void setPermission(Node node) throws ObjectAlreadyHasException {
|
public void setPermission(Node node) throws ObjectAlreadyHasException {
|
||||||
if (hasPermission(node)) {
|
if (hasPermission(node, false) == Tristate.TRUE) {
|
||||||
throw new ObjectAlreadyHasException();
|
throw new ObjectAlreadyHasException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,6 +375,20 @@ public abstract class PermissionHolder {
|
|||||||
plugin.getApiProvider().fireEventAsync(new PermissionNodeSetEvent(new PermissionHolderLink(this), node));
|
plugin.getApiProvider().fireEventAsync(new PermissionNodeSetEvent(new PermissionHolderLink(this), node));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a transient permission node
|
||||||
|
* @param node the node to set
|
||||||
|
* @throws ObjectAlreadyHasException if the holder has this permission already
|
||||||
|
*/
|
||||||
|
public void setTransientPermission(Node node) throws ObjectAlreadyHasException {
|
||||||
|
if (hasPermission(node, true) == Tristate.TRUE) {
|
||||||
|
throw new ObjectAlreadyHasException();
|
||||||
|
}
|
||||||
|
|
||||||
|
transientNodes.add(node);
|
||||||
|
plugin.getApiProvider().fireEventAsync(new PermissionNodeSetEvent(new PermissionHolderLink(this), node));
|
||||||
|
}
|
||||||
|
|
||||||
public void setPermission(String node, boolean value) throws ObjectAlreadyHasException {
|
public void setPermission(String node, boolean value) throws ObjectAlreadyHasException {
|
||||||
setPermission(buildNode(node).setValue(value).build());
|
setPermission(buildNode(node).setValue(value).build());
|
||||||
}
|
}
|
||||||
@ -211,7 +419,7 @@ public abstract class PermissionHolder {
|
|||||||
* @throws ObjectLacksException if the holder doesn't have this node already
|
* @throws ObjectLacksException if the holder doesn't have this node already
|
||||||
*/
|
*/
|
||||||
public void unsetPermission(Node node) throws ObjectLacksException {
|
public void unsetPermission(Node node) throws ObjectLacksException {
|
||||||
if (!hasPermission(node)) {
|
if (hasPermission(node, false) == Tristate.FALSE) {
|
||||||
throw new ObjectLacksException();
|
throw new ObjectLacksException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,6 +433,26 @@ public abstract class PermissionHolder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsets a transient permission node
|
||||||
|
* @param node the node to unset
|
||||||
|
* @throws ObjectLacksException if the holder doesn't have this node already
|
||||||
|
*/
|
||||||
|
public void unsetTransientPermission(Node node) throws ObjectLacksException {
|
||||||
|
if (hasPermission(node, true) == Tristate.FALSE) {
|
||||||
|
throw new ObjectLacksException();
|
||||||
|
}
|
||||||
|
|
||||||
|
transientNodes.remove(node);
|
||||||
|
|
||||||
|
if (node.isGroupNode()) {
|
||||||
|
plugin.getApiProvider().fireEventAsync(new GroupRemoveEvent(new PermissionHolderLink(this),
|
||||||
|
node.getGroupName(), node.getServer().orElse(null), node.getWorld().orElse(null), node.isTemporary()));
|
||||||
|
} else {
|
||||||
|
plugin.getApiProvider().fireEventAsync(new PermissionNodeUnsetEvent(new PermissionHolderLink(this), node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void unsetPermission(String node, boolean temporary) throws ObjectLacksException {
|
public void unsetPermission(String node, boolean temporary) throws ObjectLacksException {
|
||||||
unsetPermission(buildNode(node).setExpiry(temporary ? 10L : 0L).build());
|
unsetPermission(buildNode(node).setExpiry(temporary ? 10L : 0L).build());
|
||||||
}
|
}
|
||||||
@ -253,7 +481,7 @@ public abstract class PermissionHolder {
|
|||||||
* @return The temporary nodes held by the holder
|
* @return The temporary nodes held by the holder
|
||||||
*/
|
*/
|
||||||
public Set<Node> getTemporaryNodes() {
|
public Set<Node> getTemporaryNodes() {
|
||||||
return nodes.stream().filter(Node::isTemporary).collect(Collectors.toSet());
|
return getPermissions().stream().filter(Node::isTemporary).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ -271,84 +499,18 @@ public abstract class PermissionHolder {
|
|||||||
* @return The permanent nodes held by the holder
|
* @return The permanent nodes held by the holder
|
||||||
*/
|
*/
|
||||||
public Set<Node> getPermanentNodes() {
|
public Set<Node> getPermanentNodes() {
|
||||||
return nodes.stream().filter(Node::isPermanent).collect(Collectors.toSet());
|
return getPermissions().stream().filter(Node::isPermanent).collect(Collectors.toSet());
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes temporary permissions that have expired
|
|
||||||
* @return true if permissions had expired and were removed
|
|
||||||
*/
|
|
||||||
public boolean auditTemporaryPermissions() {
|
|
||||||
boolean work = false;
|
|
||||||
Iterator<Node> iterator = nodes.iterator();
|
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
Node element = iterator.next();
|
|
||||||
if (element.hasExpired()) {
|
|
||||||
iterator.remove();
|
|
||||||
|
|
||||||
work = true;
|
|
||||||
plugin.getApiProvider().fireEventAsync(new PermissionNodeExpireEvent(new PermissionHolderLink(this), element));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return work;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all of the nodes that this holder has and inherits
|
|
||||||
* @param excludedGroups a list of groups to exclude
|
|
||||||
* @return a set of nodes
|
|
||||||
*/
|
|
||||||
public Set<Node> getAllNodes(List<String> excludedGroups) {
|
|
||||||
Set<Node> all = ConcurrentHashMap.newKeySet();
|
|
||||||
all.addAll(nodes);
|
|
||||||
|
|
||||||
if (excludedGroups == null) {
|
|
||||||
excludedGroups = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
excludedGroups.add(getObjectName().toLowerCase());
|
|
||||||
|
|
||||||
Set<String> parents = nodes.stream()
|
|
||||||
.filter(Node::isGroupNode)
|
|
||||||
.map(Node::getGroupName)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
for (String parent : parents) {
|
|
||||||
Group group = plugin.getGroupManager().get(parent);
|
|
||||||
if (group == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (excludedGroups.contains(group.getObjectName())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
inherited:
|
|
||||||
for (Node inherited : group.getAllNodes(excludedGroups)) {
|
|
||||||
for (Node existing : all) {
|
|
||||||
if (existing.almostEquals(inherited)) {
|
|
||||||
continue inherited;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
all.add(inherited);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return all;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't use these methods, only here for compat reasons
|
* Don't use these methods, only here for compat reasons
|
||||||
*/
|
*/
|
||||||
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups, List<String> possibleNodes) {
|
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups, List<String> possibleNodes) {
|
||||||
return getPermissions(server, world, null, plugin.getConfiguration().getIncludeGlobalPerms(), possibleNodes, true);
|
return exportNodes(server, world, null, plugin.getConfiguration().getIncludeGlobalPerms(), true, possibleNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups) {
|
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups) {
|
||||||
return getPermissions(server, world, null, plugin.getConfiguration().getIncludeGlobalPerms(), null, true);
|
return exportNodes(server, world, null, plugin.getConfiguration().getIncludeGlobalPerms(), true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups, List<String> possibleNodes) {
|
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups, List<String> possibleNodes) {
|
||||||
@ -359,57 +521,6 @@ public abstract class PermissionHolder {
|
|||||||
return getLocalPermissions(server, null, excludedGroups, null);
|
return getLocalPermissions(server, null, excludedGroups, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the holders nodes into a Map of permissions to be applied on the platform
|
|
||||||
* @param server the server
|
|
||||||
* @param world the world
|
|
||||||
* @param extraContext any extra context to filter by
|
|
||||||
* @param includeGlobal whether to include global nodes
|
|
||||||
* @param possibleNodes a list of possible permissions for resolving wildcards
|
|
||||||
* @param applyGroups if inherited group permissions should be included
|
|
||||||
* @return a map of permissions
|
|
||||||
*/
|
|
||||||
public Map<String, Boolean> getPermissions(String server, String world, Map<String, String> extraContext, boolean includeGlobal, List<String> possibleNodes, boolean applyGroups) {
|
|
||||||
Map<String, Boolean> perms = new HashMap<>();
|
|
||||||
SortedSet<Node> allNodes;
|
|
||||||
|
|
||||||
if (applyGroups) {
|
|
||||||
allNodes = sort(getAllNodes(null), true);
|
|
||||||
} else {
|
|
||||||
allNodes = sort(nodes, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Node node : allNodes) {
|
|
||||||
if (!node.shouldApplyOnServer(server, includeGlobal, plugin.getConfiguration().getApplyRegex())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!node.shouldApplyOnWorld(world, includeGlobal, plugin.getConfiguration().getApplyRegex())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!node.shouldApplyWithContext(extraContext)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
perms.put(node.getPermission(), node.getValue());
|
|
||||||
|
|
||||||
if (plugin.getConfiguration().getApplyShorthand()) {
|
|
||||||
node.resolveShorthand().stream()
|
|
||||||
.filter(s -> !perms.containsKey(s))
|
|
||||||
.forEach(s -> perms.put(s, node.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.getConfiguration().getApplyWildcards()) {
|
|
||||||
node.resolveWildcard(possibleNodes).stream()
|
|
||||||
.filter(s -> !perms.containsKey(s))
|
|
||||||
.forEach(s -> perms.put(s, node.getValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return perms;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SortedSet<Node> sort(Set<Node> toSort, boolean reversed) {
|
public static SortedSet<Node> sort(Set<Node> toSort, boolean reversed) {
|
||||||
TreeSet<Node> set = new TreeSet<>(reversed ? PRIORITY_COMPARATOR.reversed() : PRIORITY_COMPARATOR);
|
TreeSet<Node> set = new TreeSet<>(reversed ? PRIORITY_COMPARATOR.reversed() : PRIORITY_COMPARATOR);
|
||||||
set.addAll(toSort);
|
set.addAll(toSort);
|
||||||
@ -421,41 +532,35 @@ public abstract class PermissionHolder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(Node o1, Node o2) {
|
public int compare(Node o1, Node o2) {
|
||||||
if (takesPriority(o1, o2)) {
|
if (o1.isOverride() != o2.isOverride()) {
|
||||||
return 1;
|
return o1.isOverride() ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (takesPriority(o2, o1)) {
|
if (o1.isServerSpecific() != o2.isServerSpecific()) {
|
||||||
return -1;
|
return o1.isServerSpecific() ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o1.isWorldSpecific() != o2.isWorldSpecific()) {
|
||||||
|
return o1.isWorldSpecific() ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o1.isTemporary() != o2.isTemporary()) {
|
||||||
|
return o1.isTemporary() ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o1.isWildcard() != o2.isWildcard()) {
|
||||||
|
return o1.isWildcard() ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o1.isTemporary()) {
|
||||||
|
return o1.getSecondsTilExpiry() < o2.getSecondsTilExpiry() ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o1.isWildcard()) {
|
||||||
|
return o1.getWildcardLevel() > o2.getWildcardLevel() ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean takesPriority(Node target, Node over) {
|
|
||||||
if (target.isTemporary() && !over.isTemporary()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.isWorldSpecific() && !over.isWorldSpecific()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.isServerSpecific() && !over.isServerSpecific()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target.isWildcard() && over.isWildcard()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.isWildcard() && over.isWildcard()) {
|
|
||||||
if (target.getWildcardLevel() > over.getWildcardLevel()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
|||||||
*/
|
*/
|
||||||
private List<String> getGroups(String server, String world, boolean includeGlobal) {
|
private List<String> getGroups(String server, String world, boolean includeGlobal) {
|
||||||
// Call super #getPermissions method, and just sort through those
|
// Call super #getPermissions method, and just sort through those
|
||||||
Map<String, Boolean> perms = getPermissions(server, world, null, includeGlobal, null, true);
|
Map<String, Boolean> perms = exportNodes(server, world, null, includeGlobal, true, null);
|
||||||
return perms.keySet().stream()
|
return perms.keySet().stream()
|
||||||
.filter(s -> Patterns.GROUP_MATCH.matcher(s).matches())
|
.filter(s -> Patterns.GROUP_MATCH.matcher(s).matches())
|
||||||
.map(s -> Patterns.DOT.split(s, 2)[1])
|
.map(s -> Patterns.DOT.split(s, 2)[1])
|
||||||
|
@ -28,7 +28,6 @@ import lombok.Cleanup;
|
|||||||
import me.lucko.luckperms.LuckPermsPlugin;
|
import me.lucko.luckperms.LuckPermsPlugin;
|
||||||
import me.lucko.luckperms.api.LogEntry;
|
import me.lucko.luckperms.api.LogEntry;
|
||||||
import me.lucko.luckperms.constants.Constants;
|
import me.lucko.luckperms.constants.Constants;
|
||||||
import me.lucko.luckperms.core.PermissionHolder;
|
|
||||||
import me.lucko.luckperms.data.Log;
|
import me.lucko.luckperms.data.Log;
|
||||||
import me.lucko.luckperms.groups.Group;
|
import me.lucko.luckperms.groups.Group;
|
||||||
import me.lucko.luckperms.storage.Datastore;
|
import me.lucko.luckperms.storage.Datastore;
|
||||||
@ -188,7 +187,7 @@ public class FlatfileDatastore extends Datastore {
|
|||||||
writer.name("primaryGroup").value(user.getPrimaryGroup());
|
writer.name("primaryGroup").value(user.getPrimaryGroup());
|
||||||
writer.name("perms");
|
writer.name("perms");
|
||||||
writer.beginObject();
|
writer.beginObject();
|
||||||
for (Map.Entry<String, Boolean> e : convertToLegacy(user.getNodes()).entrySet()) {
|
for (Map.Entry<String, Boolean> e : exportToLegacy(user.getNodes()).entrySet()) {
|
||||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||||
}
|
}
|
||||||
writer.endObject();
|
writer.endObject();
|
||||||
@ -229,7 +228,7 @@ public class FlatfileDatastore extends Datastore {
|
|||||||
writer.name("primaryGroup").value(user.getPrimaryGroup());
|
writer.name("primaryGroup").value(user.getPrimaryGroup());
|
||||||
writer.name("perms");
|
writer.name("perms");
|
||||||
writer.beginObject();
|
writer.beginObject();
|
||||||
for (Map.Entry<String, Boolean> e : convertToLegacy(user.getNodes()).entrySet()) {
|
for (Map.Entry<String, Boolean> e : exportToLegacy(user.getNodes()).entrySet()) {
|
||||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||||
}
|
}
|
||||||
writer.endObject();
|
writer.endObject();
|
||||||
@ -295,7 +294,7 @@ public class FlatfileDatastore extends Datastore {
|
|||||||
writer.name("primaryGroup").value(user.getPrimaryGroup());
|
writer.name("primaryGroup").value(user.getPrimaryGroup());
|
||||||
writer.name("perms");
|
writer.name("perms");
|
||||||
writer.beginObject();
|
writer.beginObject();
|
||||||
for (Map.Entry<String, Boolean> e : convertToLegacy(user.getNodes()).entrySet()) {
|
for (Map.Entry<String, Boolean> e : exportToLegacy(user.getNodes()).entrySet()) {
|
||||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||||
}
|
}
|
||||||
writer.endObject();
|
writer.endObject();
|
||||||
@ -323,7 +322,7 @@ public class FlatfileDatastore extends Datastore {
|
|||||||
writer.name("name").value(group.getName());
|
writer.name("name").value(group.getName());
|
||||||
writer.name("perms");
|
writer.name("perms");
|
||||||
writer.beginObject();
|
writer.beginObject();
|
||||||
for (Map.Entry<String, Boolean> e : convertToLegacy(group.getNodes()).entrySet()) {
|
for (Map.Entry<String, Boolean> e : exportToLegacy(group.getNodes()).entrySet()) {
|
||||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||||
}
|
}
|
||||||
writer.endObject();
|
writer.endObject();
|
||||||
@ -415,7 +414,7 @@ public class FlatfileDatastore extends Datastore {
|
|||||||
writer.name("name").value(group.getName());
|
writer.name("name").value(group.getName());
|
||||||
writer.name("perms");
|
writer.name("perms");
|
||||||
writer.beginObject();
|
writer.beginObject();
|
||||||
for (Map.Entry<String, Boolean> e : convertToLegacy(group.getNodes()).entrySet()) {
|
for (Map.Entry<String, Boolean> e : exportToLegacy(group.getNodes()).entrySet()) {
|
||||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||||
}
|
}
|
||||||
writer.endObject();
|
writer.endObject();
|
||||||
|
@ -31,7 +31,6 @@ import com.mongodb.client.MongoDatabase;
|
|||||||
import com.mongodb.client.model.InsertOneOptions;
|
import com.mongodb.client.model.InsertOneOptions;
|
||||||
import me.lucko.luckperms.LuckPermsPlugin;
|
import me.lucko.luckperms.LuckPermsPlugin;
|
||||||
import me.lucko.luckperms.api.LogEntry;
|
import me.lucko.luckperms.api.LogEntry;
|
||||||
import me.lucko.luckperms.core.PermissionHolder;
|
|
||||||
import me.lucko.luckperms.data.Log;
|
import me.lucko.luckperms.data.Log;
|
||||||
import me.lucko.luckperms.groups.Group;
|
import me.lucko.luckperms.groups.Group;
|
||||||
import me.lucko.luckperms.groups.GroupManager;
|
import me.lucko.luckperms.groups.GroupManager;
|
||||||
@ -46,7 +45,7 @@ import java.util.*;
|
|||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static me.lucko.luckperms.core.PermissionHolder.convertToLegacy;
|
import static me.lucko.luckperms.core.PermissionHolder.exportToLegacy;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class MongoDBDatastore extends Datastore {
|
public class MongoDBDatastore extends Datastore {
|
||||||
@ -430,7 +429,7 @@ public class MongoDBDatastore extends Datastore {
|
|||||||
.append("primaryGroup", user.getPrimaryGroup());
|
.append("primaryGroup", user.getPrimaryGroup());
|
||||||
|
|
||||||
Document perms = new Document();
|
Document perms = new Document();
|
||||||
for (Map.Entry<String, Boolean> e : convert(convertToLegacy(user.getNodes())).entrySet()) {
|
for (Map.Entry<String, Boolean> e : convert(exportToLegacy(user.getNodes())).entrySet()) {
|
||||||
perms.append(e.getKey(), e.getValue());
|
perms.append(e.getKey(), e.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,7 +441,7 @@ public class MongoDBDatastore extends Datastore {
|
|||||||
Document main = new Document("_id", group.getName());
|
Document main = new Document("_id", group.getName());
|
||||||
|
|
||||||
Document perms = new Document();
|
Document perms = new Document();
|
||||||
for (Map.Entry<String, Boolean> e : convert(convertToLegacy(group.getNodes())).entrySet()) {
|
for (Map.Entry<String, Boolean> e : convert(exportToLegacy(group.getNodes())).entrySet()) {
|
||||||
perms.append(e.getKey(), e.getValue());
|
perms.append(e.getKey(), e.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ public abstract class User extends PermissionHolder implements Identifiable<UUID
|
|||||||
*/
|
*/
|
||||||
private List<String> getGroups(String server, String world, boolean includeGlobal) {
|
private List<String> getGroups(String server, String world, boolean includeGlobal) {
|
||||||
// Call super #getPermissions method, and just sort through those
|
// Call super #getPermissions method, and just sort through those
|
||||||
Map<String, Boolean> perms = getPermissions(server, world, null, includeGlobal, null, true);
|
Map<String, Boolean> perms = exportNodes(server, world, null, includeGlobal, true, null);
|
||||||
return perms.keySet().stream()
|
return perms.keySet().stream()
|
||||||
.filter(s -> Patterns.GROUP_MATCH.matcher(s).matches())
|
.filter(s -> Patterns.GROUP_MATCH.matcher(s).matches())
|
||||||
.map(s -> Patterns.DOT.split(s, 2)[1])
|
.map(s -> Patterns.DOT.split(s, 2)[1])
|
||||||
|
@ -24,6 +24,7 @@ package me.lucko.luckperms.utils;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.constants.Patterns;
|
import me.lucko.luckperms.constants.Patterns;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -85,6 +86,9 @@ public class Node implements me.lucko.luckperms.api.Node {
|
|||||||
@Getter
|
@Getter
|
||||||
private Boolean value;
|
private Boolean value;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private boolean override;
|
||||||
|
|
||||||
private String server = null;
|
private String server = null;
|
||||||
private String world = null;
|
private String world = null;
|
||||||
|
|
||||||
@ -101,7 +105,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
|||||||
* @param world the world this node applies on
|
* @param world the world this node applies on
|
||||||
* @param extraContexts any additional contexts applying to this node
|
* @param extraContexts any additional contexts applying to this node
|
||||||
*/
|
*/
|
||||||
public Node(String permission, boolean value, long expireAt, String server, String world, Map<String, String> extraContexts) {
|
public Node(String permission, boolean value, boolean override, long expireAt, String server, String world, Map<String, String> extraContexts) {
|
||||||
if (permission == null || permission.equals("")) {
|
if (permission == null || permission.equals("")) {
|
||||||
throw new IllegalArgumentException("Empty permission");
|
throw new IllegalArgumentException("Empty permission");
|
||||||
}
|
}
|
||||||
@ -120,6 +124,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
|||||||
|
|
||||||
this.permission = permission;
|
this.permission = permission;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
this.override = override;
|
||||||
this.expireAt = expireAt;
|
this.expireAt = expireAt;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.world = world;
|
this.world = world;
|
||||||
@ -129,6 +134,11 @@ public class Node implements me.lucko.luckperms.api.Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tristate getTristate() {
|
||||||
|
return Tristate.fromBoolean(value);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isNegated() {
|
public boolean isNegated() {
|
||||||
return !value;
|
return !value;
|
||||||
}
|
}
|
||||||
@ -395,6 +405,53 @@ 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 equalsIgnoringValue(me.lucko.luckperms.api.Node other) {
|
||||||
|
if (!other.getPermission().equalsIgnoreCase(this.getPermission())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.isTemporary() != this.isTemporary()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isTemporary()) {
|
||||||
|
if (other.getExpiryUnixTime() != this.getExpiryUnixTime()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.getServer().isPresent() != this.getServer().isPresent()) {
|
||||||
|
if (other.getServer().isPresent()) {
|
||||||
|
if (!other.getServer().get().equalsIgnoreCase(this.getServer().get())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.getWorld().isPresent() != this.getWorld().isPresent()) {
|
||||||
|
if (other.getWorld().isPresent()) {
|
||||||
|
if (!other.getWorld().get().equalsIgnoreCase(this.getWorld().get())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!other.getExtraContexts().equals(this.getExtraContexts())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.isTemporary() != this.isTemporary()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean almostEquals(me.lucko.luckperms.api.Node other) {
|
public boolean almostEquals(me.lucko.luckperms.api.Node other) {
|
||||||
if (!other.getPermission().equalsIgnoreCase(this.getPermission())) {
|
if (!other.getPermission().equalsIgnoreCase(this.getPermission())) {
|
||||||
@ -446,6 +503,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
|||||||
public static class Builder implements me.lucko.luckperms.api.Node.Builder {
|
public static class Builder implements me.lucko.luckperms.api.Node.Builder {
|
||||||
private final String permission;
|
private final String permission;
|
||||||
private Boolean value = true;
|
private Boolean value = true;
|
||||||
|
private boolean override = false;
|
||||||
private String server = null;
|
private String server = null;
|
||||||
private String world = null;
|
private String world = null;
|
||||||
private long expireAt = 0L;
|
private long expireAt = 0L;
|
||||||
@ -488,6 +546,12 @@ public class Node implements me.lucko.luckperms.api.Node {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public me.lucko.luckperms.api.Node.Builder setOverride(boolean override) {
|
||||||
|
this.override = override;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public me.lucko.luckperms.api.Node.Builder setExpiry(long expireAt) {
|
public me.lucko.luckperms.api.Node.Builder setExpiry(long expireAt) {
|
||||||
this.expireAt = expireAt;
|
this.expireAt = expireAt;
|
||||||
@ -523,7 +587,7 @@ public class Node implements me.lucko.luckperms.api.Node {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public me.lucko.luckperms.api.Node build() {
|
public me.lucko.luckperms.api.Node build() {
|
||||||
return new Node(permission, value, expireAt, server, world, extraContexts);
|
return new Node(permission, value, override, expireAt, server, world, extraContexts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,10 @@ import org.spongepowered.api.command.CommandException;
|
|||||||
import org.spongepowered.api.command.CommandResult;
|
import org.spongepowered.api.command.CommandResult;
|
||||||
import org.spongepowered.api.command.CommandSource;
|
import org.spongepowered.api.command.CommandSource;
|
||||||
import org.spongepowered.api.text.Text;
|
import org.spongepowered.api.text.Text;
|
||||||
|
import org.spongepowered.api.world.Location;
|
||||||
|
import org.spongepowered.api.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -49,6 +52,15 @@ class SpongeCommand extends CommandManager implements CommandCallable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public List<String> getSuggestions(CommandSource source, String s, @Nullable Location<World> location) throws CommandException {
|
||||||
|
List<String> args = new ArrayList<>(Arrays.asList(Patterns.SPACE.split(s)));
|
||||||
|
if (s.endsWith(" ")) {
|
||||||
|
args.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return onTabComplete(SpongeSenderFactory.get().wrap(source), args);
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getSuggestions(CommandSource source, String s) throws CommandException {
|
public List<String> getSuggestions(CommandSource source, String s) throws CommandException {
|
||||||
List<String> args = new ArrayList<>(Arrays.asList(Patterns.SPACE.split(s)));
|
List<String> args = new ArrayList<>(Arrays.asList(Patterns.SPACE.split(s)));
|
||||||
if (s.endsWith(" ")) {
|
if (s.endsWith(" ")) {
|
||||||
@ -64,12 +76,12 @@ class SpongeCommand extends CommandManager implements CommandCallable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<? extends Text> getShortDescription(CommandSource source) {
|
public Optional<Text> getShortDescription(CommandSource source) {
|
||||||
return Optional.of(Text.of("LuckPerms main command."));
|
return Optional.of(Text.of("LuckPerms main command."));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<? extends Text> getHelp(CommandSource source) {
|
public Optional<Text> getHelp(CommandSource source) {
|
||||||
return Optional.of(Text.of("Type /perms for help."));
|
return Optional.of(Text.of("Type /perms for help."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,10 +25,7 @@ package me.lucko.luckperms;
|
|||||||
import me.lucko.luckperms.constants.Message;
|
import me.lucko.luckperms.constants.Message;
|
||||||
import me.lucko.luckperms.users.User;
|
import me.lucko.luckperms.users.User;
|
||||||
import me.lucko.luckperms.utils.AbstractListener;
|
import me.lucko.luckperms.utils.AbstractListener;
|
||||||
import org.spongepowered.api.entity.Entity;
|
|
||||||
import org.spongepowered.api.entity.living.player.Player;
|
|
||||||
import org.spongepowered.api.event.Listener;
|
import org.spongepowered.api.event.Listener;
|
||||||
import org.spongepowered.api.event.entity.DisplaceEntityEvent;
|
|
||||||
import org.spongepowered.api.event.network.ClientConnectionEvent;
|
import org.spongepowered.api.event.network.ClientConnectionEvent;
|
||||||
import org.spongepowered.api.profile.GameProfile;
|
import org.spongepowered.api.profile.GameProfile;
|
||||||
import org.spongepowered.api.text.serializer.TextSerializers;
|
import org.spongepowered.api.text.serializer.TextSerializers;
|
||||||
@ -75,8 +72,10 @@ public class SpongeListener extends AbstractListener {
|
|||||||
refreshPlayer(e.getTargetEntity().getUniqueId());
|
refreshPlayer(e.getTargetEntity().getUniqueId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Use reflection/any other method to refresh on world change
|
||||||
|
/*
|
||||||
@Listener
|
@Listener
|
||||||
public void onPlayerTeleport(DisplaceEntityEvent.Teleport e) {
|
public void onPlayerTeleport(DisplaceEntityEvent e) {
|
||||||
final Entity entity = e.getTargetEntity();
|
final Entity entity = e.getTargetEntity();
|
||||||
if (!(entity instanceof Player)){
|
if (!(entity instanceof Player)){
|
||||||
return;
|
return;
|
||||||
@ -84,6 +83,7 @@ public class SpongeListener extends AbstractListener {
|
|||||||
|
|
||||||
refreshPlayer(entity.getUniqueId());
|
refreshPlayer(entity.getUniqueId());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
@Listener
|
@Listener
|
||||||
public void onClientLeave(ClientConnectionEvent.Disconnect e) {
|
public void onClientLeave(ClientConnectionEvent.Disconnect e) {
|
||||||
|
@ -83,4 +83,9 @@ public class GroupCollection implements SubjectCollection {
|
|||||||
.map(sub -> new AbstractMap.SimpleEntry<Subject, Boolean>(sub, sub.getPermissionValue(contexts, node).asBoolean()))
|
.map(sub -> new AbstractMap.SimpleEntry<Subject, Boolean>(sub, sub.getPermissionValue(contexts, node).asBoolean()))
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subject getDefaults() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,4 +101,9 @@ public class UserCollection implements SubjectCollection {
|
|||||||
.map(sub -> new AbstractMap.SimpleEntry<Subject, Boolean>(sub, sub.getPermissionValue(contexts, node).asBoolean()))
|
.map(sub -> new AbstractMap.SimpleEntry<Subject, Boolean>(sub, sub.getPermissionValue(contexts, node).asBoolean()))
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subject getDefaults() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user