Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aea44fc8bc | ||
|
|
c0da9d49d9 | ||
|
|
ce42573f43 | ||
|
|
148fe4c729 | ||
|
|
32fd484b58 | ||
|
|
7d24e748b7 | ||
|
|
f1a1612f5d | ||
|
|
6501e5cf8d | ||
|
|
cd4a684613 | ||
|
|
d06fda6d9d | ||
|
|
139010e75b | ||
|
|
7638b07e34 | ||
|
|
f7bf4416c9 | ||
|
|
2b96b656a9 | ||
|
|
0fe251b6ec | ||
|
|
a1afc70bcb | ||
|
|
ced3e6959c | ||
|
|
1c229d54d9 | ||
|
|
dd50193c18 | ||
|
|
ab0f9bbdbd | ||
|
|
055d181c67 | ||
|
|
7042c45deb | ||
|
|
960c2291b6 | ||
|
|
773bfe1407 | ||
|
|
a23f995717 | ||
|
|
bd509b3c75 | ||
|
|
a0f8ba9afb | ||
|
|
a71e040c6d | ||
|
|
454abec468 | ||
|
|
96035d5257 | ||
|
|
9f2b59f2a2 | ||
|
|
a54046907d | ||
|
|
2ce5679373 | ||
|
|
2dad9f84fc | ||
|
|
a81a361a93 | ||
|
|
4660e68abf | ||
|
|
f8a77cf809 | ||
|
|
0abe9598f6 | ||
|
|
20de713716 | ||
|
|
9dbef6acc2 | ||
|
|
4c93bf7cf0 | ||
|
|
a8fea0fc49 | ||
|
|
2d5975d6e3 | ||
|
|
6874cfd5b1 | ||
|
|
d34013396a | ||
|
|
a35b0915ab | ||
|
|
b35f3b4375 | ||
|
|
f4f9612789 | ||
|
|
bfc79c6051 | ||
|
|
d3e60487bb | ||
|
|
f36f411a8d | ||
|
|
35f4aea69f | ||
|
|
8795383e7c | ||
|
|
fc4750706b | ||
|
|
0ae59bd3e6 | ||
|
|
61fd14c816 | ||
|
|
c7d3d87b09 | ||
|
|
5e68f7b58c | ||
|
|
8a692200d5 | ||
|
|
829eacb0fb | ||
|
|
9aeca91f22 | ||
|
|
1bdb512826 | ||
|
|
060fa6e5f7 | ||
|
|
171a54c0fc | ||
|
|
17406b448d | ||
|
|
b4b661a3ad | ||
|
|
4857969ca4 | ||
|
|
d9d01e09aa | ||
|
|
dadca97d8a | ||
|
|
8afba8b53d | ||
|
|
85dac1184c | ||
|
|
4167460d28 | ||
|
|
1d8a60749d | ||
|
|
31a597ca81 | ||
|
|
e5e77ffec5 | ||
|
|
41c3df41b4 | ||
|
|
053066f1a7 | ||
|
|
21135dac07 | ||
|
|
22ccce3208 | ||
|
|
70aa3964ee | ||
|
|
167489823a | ||
|
|
d1426f1b37 | ||
|
|
7dcdc59c8e | ||
|
|
1e13ee87af | ||
|
|
5101c1a759 | ||
|
|
74bb079625 | ||
|
|
2da7979d94 | ||
|
|
4ecb2c7c27 | ||
|
|
251f51b01c | ||
|
|
2fba9b83af | ||
|
|
1c97cb3cec | ||
|
|
25511f898c | ||
|
|
d820f153a9 | ||
|
|
77b06acad4 | ||
|
|
6760a96527 | ||
|
|
257f426ab9 | ||
|
|
3771a50f30 | ||
|
|
85ee211172 | ||
|
|
1b7a66b41a | ||
|
|
8f9a1aa931 | ||
|
|
8b60fd0e55 | ||
|
|
cd7b3b4f6e | ||
|
|
83b0f62d59 | ||
|
|
dd3a78ada8 |
No files matched your search
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.16-SNAPSHOT</version>
|
||||
<version>2.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -27,13 +27,16 @@ import me.lucko.luckperms.api.LuckPermsApi;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Static access to LuckPerms
|
||||
* Singleton for the {@link LuckPermsApi}.
|
||||
*
|
||||
* <p> Ideally, the ServiceManager for the platform should be used to obtain and cache an instance, however, this can be
|
||||
* used if you need static access.
|
||||
*/
|
||||
public final class LuckPerms {
|
||||
private static LuckPermsApi api = null;
|
||||
|
||||
/**
|
||||
* Gets an instance of {@link LuckPermsApi}
|
||||
* Gets an instance of {@link LuckPermsApi}, throwing {@link IllegalStateException} if the API is not loaded.
|
||||
*
|
||||
* @return an api instance
|
||||
* @throws IllegalStateException if the api is not loaded
|
||||
@@ -46,8 +49,10 @@ public final class LuckPerms {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of {@link LuckPermsApi} safely. Unlike {@link LuckPerms#getApi}, this method will not throw an
|
||||
* {@link IllegalStateException} if the api is not loaded, rather return an empty {@link Optional}.
|
||||
* Gets an instance of {@link LuckPermsApi} safely.
|
||||
*
|
||||
* <p> Unlike {@link LuckPerms#getApi}, this method will not throw an {@link IllegalStateException} if the API is
|
||||
* not loaded, rather return an empty {@link Optional}.
|
||||
*
|
||||
* @return an optional api instance
|
||||
*/
|
||||
|
||||
@@ -27,8 +27,9 @@ import me.lucko.luckperms.api.context.ContextSet;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents the context and options for a permission lookup.
|
||||
* All values are immutable.
|
||||
* Context and options for a permission lookup.
|
||||
*
|
||||
* <p> All values are immutable.
|
||||
*
|
||||
* @since 2.11
|
||||
*/
|
||||
@@ -67,28 +68,34 @@ public class Contexts {
|
||||
* The keys for servers and worlds are defined as static values.
|
||||
*/
|
||||
private final ContextSet context;
|
||||
|
||||
/**
|
||||
* The mode to parse defaults on Bukkit
|
||||
*
|
||||
* @since 2.12
|
||||
*/
|
||||
private final boolean op;
|
||||
|
||||
/**
|
||||
* If global or non server specific nodes should be applied
|
||||
*/
|
||||
private final boolean includeGlobal;
|
||||
|
||||
/**
|
||||
* If global or non world specific nodes should be applied
|
||||
*/
|
||||
private final boolean includeGlobalWorld;
|
||||
|
||||
/**
|
||||
* If parent groups should be applied
|
||||
*/
|
||||
private final boolean applyGroups;
|
||||
|
||||
/**
|
||||
* If global or non server specific group memberships should be applied
|
||||
*/
|
||||
private final boolean applyGlobalGroups;
|
||||
|
||||
/**
|
||||
* If global or non world specific group memberships should be applied
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Interface for the internal Datastore instance
|
||||
* Deprecated Storage interface. Use {@link Storage} instead.
|
||||
*
|
||||
* @deprecated as of version 2.14 in favour of {@link Storage}.
|
||||
*/
|
||||
|
||||
@@ -26,14 +26,16 @@ import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/**
|
||||
* Interface for internal Group instances
|
||||
* A group which holds permission data.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Group extends PermissionHolder {
|
||||
|
||||
/**
|
||||
* Get the name of the group
|
||||
*
|
||||
* @return the name of the group
|
||||
*/
|
||||
String getName();
|
||||
@@ -220,11 +222,6 @@ public interface Group extends PermissionHolder {
|
||||
*/
|
||||
void unsetInheritGroup(Group group, String server, String world, boolean temporary) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Clear all of the groups permission nodes
|
||||
*/
|
||||
void clearNodes();
|
||||
|
||||
/**
|
||||
* Get a {@link List} of all of the groups the group inherits, on all servers
|
||||
*
|
||||
@@ -236,6 +233,17 @@ public interface Group extends PermissionHolder {
|
||||
* Get a {@link List} of the groups the group inherits on a specific server
|
||||
*
|
||||
* @param server the server to check
|
||||
* @return a {@link List} of group names
|
||||
* @throws NullPointerException if the server is null
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
*/
|
||||
List<String> getLocalGroups(String server);
|
||||
|
||||
|
||||
/**
|
||||
* Get a {@link List} of the groups the group inherits on a specific server and world
|
||||
*
|
||||
* @param server the server to check
|
||||
* @param world the world to check
|
||||
* @return a {@link List} of group names
|
||||
* @throws NullPointerException if the server or world is null
|
||||
@@ -244,12 +252,11 @@ public interface Group extends PermissionHolder {
|
||||
List<String> getLocalGroups(String server, String world);
|
||||
|
||||
/**
|
||||
* Get a {@link List} of the groups the group inherits on a specific server
|
||||
* Gets the weight of this group, is present.
|
||||
*
|
||||
* @param server the server to check
|
||||
* @return a {@link List} of group names
|
||||
* @throws NullPointerException if the server is null
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
* @return the group weight
|
||||
* @since 2.17
|
||||
*/
|
||||
List<String> getLocalGroups(String server);
|
||||
OptionalInt getWeight();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalLong;
|
||||
|
||||
/**
|
||||
* A relationship between a Holder and a permission
|
||||
*
|
||||
* @param <T> the identifier type of the holder
|
||||
* @since 2.17
|
||||
*/
|
||||
public interface HeldPermission<T> {
|
||||
|
||||
/**
|
||||
* Gets the holder of the permission
|
||||
*
|
||||
* @return the holder
|
||||
*/
|
||||
T getHolder();
|
||||
|
||||
/**
|
||||
* Gets the permission being held
|
||||
*
|
||||
* @return the permission
|
||||
*/
|
||||
String getPermission();
|
||||
|
||||
/**
|
||||
* Gets the value of the permission
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
boolean getValue();
|
||||
|
||||
/**
|
||||
* Gets the server where the permission is held
|
||||
*
|
||||
* @return the server
|
||||
*/
|
||||
Optional<String> getServer();
|
||||
|
||||
/**
|
||||
* Gets the world where the permission is held
|
||||
*
|
||||
* @return the world
|
||||
*/
|
||||
Optional<String> getWorld();
|
||||
|
||||
/**
|
||||
* Gets the time in unix time when the permission will expire
|
||||
*
|
||||
* @return the expiry time
|
||||
*/
|
||||
OptionalLong getExpiry();
|
||||
|
||||
/**
|
||||
* Gets the context for the permission.
|
||||
*
|
||||
* @return the context
|
||||
*/
|
||||
Multimap<String, String> getContext();
|
||||
|
||||
/**
|
||||
* Converts this permission into a Node
|
||||
*
|
||||
* @return a Node copy of this permission
|
||||
*/
|
||||
Node asNode();
|
||||
|
||||
}
|
||||
@@ -28,22 +28,24 @@ import me.lucko.luckperms.api.data.MySQLConfiguration;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A wrapper interface for the internal LuckPerms configuration, providing read only access.
|
||||
* Read-only access to the LuckPerms configuration settings
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface LPConfiguration {
|
||||
|
||||
/**
|
||||
* Returns the name of this server
|
||||
* @return the name of this server
|
||||
*/
|
||||
String getServer();
|
||||
|
||||
/**
|
||||
* Returns how often a sync task will run in minutes
|
||||
* @return how often a sync task will run in minutes
|
||||
*/
|
||||
int getSyncTime();
|
||||
|
||||
/**
|
||||
* Returns the default group, in a node representation
|
||||
* @return the default group, in a node representation
|
||||
* @deprecated as of 2.6, the default group is always "default"
|
||||
*/
|
||||
@@ -51,6 +53,7 @@ public interface LPConfiguration {
|
||||
String getDefaultGroupNode();
|
||||
|
||||
/**
|
||||
* Returns the name of the default group
|
||||
* @return the name of the default group
|
||||
* @deprecated as of 2.6, the default group is always "default"
|
||||
*/
|
||||
@@ -58,55 +61,65 @@ public interface LPConfiguration {
|
||||
String getDefaultGroupName();
|
||||
|
||||
/**
|
||||
* Returns if the users on this server will have their global permissions applied
|
||||
* @return if the users on this server will have their global permissions applied
|
||||
*/
|
||||
boolean getIncludeGlobalPerms();
|
||||
|
||||
/**
|
||||
* Returns if the users on this server will have their global world permissions applied
|
||||
* @return if the users on this server will have their global world permissions applied
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getIncludeGlobalWorldPerms();
|
||||
|
||||
/**
|
||||
* Returns true if the platform is applying global groups
|
||||
* @return true if the platform is applying global groups
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getApplyGlobalGroups();
|
||||
|
||||
/**
|
||||
* Returns true if the platform is applying global world groups
|
||||
* @return true if the platform is applying global world groups
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getApplyGlobalWorldGroups();
|
||||
|
||||
/**
|
||||
* @return the online mode setting in the config
|
||||
* Returns the online mode setting
|
||||
* @return the online mode setting
|
||||
*/
|
||||
boolean getOnlineMode();
|
||||
|
||||
/**
|
||||
* Returns if LuckPerms is applying wildcard permissions
|
||||
* @return if LuckPerms is applying wildcard permissions
|
||||
*/
|
||||
boolean getApplyWildcards();
|
||||
|
||||
/**
|
||||
* Returns if LuckPerms is resolving and applying regex permissions
|
||||
* @return if LuckPerms is resolving and applying regex permissions
|
||||
*/
|
||||
boolean getApplyRegex();
|
||||
|
||||
/**
|
||||
* Returns if LuckPerms is expanding shorthand permissions
|
||||
* @return if LuckPerms is expanding shorthand permissions
|
||||
*/
|
||||
boolean getApplyShorthand();
|
||||
|
||||
/**
|
||||
* Returns if LuckPerms will send notifications to users when permissions are modified
|
||||
* @return if LuckPerms will send notifications to users when permissions are modified
|
||||
* @since 2.7
|
||||
*/
|
||||
boolean getLogNotify();
|
||||
|
||||
/**
|
||||
* Returns true if permission checks are being recorded / debugged
|
||||
* @return true if permission checks are being recorded / debugged
|
||||
* @since 2.9
|
||||
* @deprecated as this value is now always false. Functionality was replaced by the verbose command.
|
||||
@@ -115,36 +128,42 @@ public interface LPConfiguration {
|
||||
boolean getDebugPermissionChecks();
|
||||
|
||||
/**
|
||||
* Returns true if the vanilla op system is enabled
|
||||
* @return true if the vanilla op system is enabled
|
||||
* @since 2.8
|
||||
*/
|
||||
boolean getEnableOps();
|
||||
|
||||
/**
|
||||
* Returns true if opped players are allowed to use LuckPerms commands
|
||||
* @return true if opped players are allowed to use LuckPerms commands
|
||||
* @since 2.8
|
||||
*/
|
||||
boolean getCommandsAllowOp();
|
||||
|
||||
/**
|
||||
* Returns true if auto op is enabled
|
||||
* @return true if auto op is enabled
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getAutoOp();
|
||||
|
||||
/**
|
||||
* Returns the name of the server used within Vault operations
|
||||
* @return the name of the server used within Vault operations
|
||||
* @since 2.7
|
||||
*/
|
||||
String getVaultServer();
|
||||
|
||||
/**
|
||||
* Returns true if global permissions should be considered when retrieving meta or player groups
|
||||
* @return true if global permissions should be considered when retrieving meta or player groups
|
||||
* @since 2.7
|
||||
*/
|
||||
boolean getVaultIncludeGlobal();
|
||||
|
||||
/**
|
||||
* Returns the database values set in the configuration
|
||||
* @return the database values set in the configuration
|
||||
* @deprecated use {@link #getDatastoreConfig()}
|
||||
*/
|
||||
@@ -153,22 +172,26 @@ public interface LPConfiguration {
|
||||
MySQLConfiguration getDatabaseValues();
|
||||
|
||||
/**
|
||||
* Returns the values set for data storage in the configuration
|
||||
* @return the values set for data storage in the configuration
|
||||
*/
|
||||
DatastoreConfiguration getDatastoreConfig();
|
||||
|
||||
/**
|
||||
* Returns the storage method string from the configuration
|
||||
* @return the storage method string from the configuration
|
||||
*/
|
||||
String getStorageMethod();
|
||||
|
||||
/**
|
||||
* Returns true if split storage is enabled
|
||||
* @return true if split storage is enabled
|
||||
* @since 2.7
|
||||
*/
|
||||
boolean getSplitStorage();
|
||||
|
||||
/**
|
||||
* Returns a map of split storage options
|
||||
* @return a map of split storage options, where the key is the storage section, and the value is the storage
|
||||
* method. For example: key = user, value = json
|
||||
* @since 2.7
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* Represents a Node and where it was inherited from.
|
||||
* A node with a traceable origin
|
||||
*
|
||||
* @since 2.11
|
||||
*/
|
||||
public interface LocalizedNode extends Node {
|
||||
|
||||
/**
|
||||
* Gets the node
|
||||
* Gets the delegate node
|
||||
*
|
||||
* @return the node this instance is representing
|
||||
*/
|
||||
|
||||
@@ -27,10 +27,11 @@ import java.util.SortedSet;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents the internal LuckPerms log. All content internally is immutable. You can add to the log using the {@link
|
||||
* Datastore}, and then request an updated copy.
|
||||
* Represents the internal LuckPerms log.
|
||||
*
|
||||
* <p> The returned instance provides a copy of the data at the time of retrieval. Any changes made to log entries will
|
||||
* only apply to this instance of the log. You can add to the log using the {@link Storage}, and then request an updated copy.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Log {
|
||||
|
||||
/**
|
||||
@@ -48,6 +49,8 @@ public interface Log {
|
||||
*
|
||||
* @param pageNo the page number
|
||||
* @return the page content
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getRecentMaxPages()}}
|
||||
*/
|
||||
SortedMap<Integer, LogEntry> getRecent(int pageNo);
|
||||
|
||||
@@ -69,6 +72,8 @@ public interface Log {
|
||||
* @param pageNo the page number
|
||||
* @param actor the uuid of the actor to filter by
|
||||
* @return the page content
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getRecentMaxPages(UUID)}}
|
||||
*/
|
||||
SortedMap<Integer, LogEntry> getRecent(int pageNo, UUID actor);
|
||||
|
||||
@@ -91,6 +96,8 @@ public interface Log {
|
||||
* @param pageNo the page number
|
||||
* @param uuid the uuid of the acted user to filter by
|
||||
* @return the page content
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getUserHistoryMaxPages(UUID)}}
|
||||
*/
|
||||
SortedMap<Integer, LogEntry> getUserHistory(int pageNo, UUID uuid);
|
||||
|
||||
@@ -113,6 +120,8 @@ public interface Log {
|
||||
* @param pageNo the page number
|
||||
* @param name the name of the acted group to filter by
|
||||
* @return the page content
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getGroupHistoryMaxPages(String)}}
|
||||
*/
|
||||
SortedMap<Integer, LogEntry> getGroupHistory(int pageNo, String name);
|
||||
|
||||
@@ -141,9 +150,12 @@ public interface Log {
|
||||
/**
|
||||
* @param name the name to filter by
|
||||
* @return the max page number allowed in the {@link #getTrackHistory(int, String)} method
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getTrackHistoryMaxPages(String)}}
|
||||
*/
|
||||
int getTrackHistoryMaxPages(String name);
|
||||
|
||||
|
||||
/**
|
||||
* @param query the query to filter by
|
||||
* @return all content in this log where the content matches query
|
||||
@@ -156,6 +168,8 @@ public interface Log {
|
||||
* @param pageNo the page number
|
||||
* @param query the query to filter by
|
||||
* @return the page content
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getSearchMaxPages(String)}}
|
||||
*/
|
||||
SortedMap<Integer, LogEntry> getSearch(int pageNo, String query);
|
||||
|
||||
|
||||
@@ -25,9 +25,10 @@ package me.lucko.luckperms.api;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents a single entry in a log
|
||||
* A single entry in the log
|
||||
*
|
||||
* <p> Implements {@link Comparable} ordering based upon the timestamp of the entry.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class LogEntry implements Comparable<LogEntry> {
|
||||
private static final String FORMAT = "&8(&e%s&8) [&a%s&8] (&b%s&8) &7--> &f%s";
|
||||
|
||||
@@ -154,9 +155,15 @@ public class LogEntry implements Comparable<LogEntry> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LogEntry(timestamp=" + this.getTimestamp() + ", actor=" + this.getActor() + ", actorName=" +
|
||||
this.getActorName() + ", type=" + this.getType() + ", acted=" + this.getActed() + ", actedName=" +
|
||||
this.getActedName() + ", action=" + this.getAction() + ")";
|
||||
return "LogEntry(" +
|
||||
"timestamp=" + this.getTimestamp() + ", " +
|
||||
"actor=" + this.getActor() + ", " +
|
||||
"actorName=" + this.getActorName() + ", " +
|
||||
"type=" + this.getType() + ", " +
|
||||
"acted=" + this.getActed() + ", " +
|
||||
"actedName=" + this.getActedName() + ", " +
|
||||
"action=" + this.getAction() +
|
||||
")";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,41 +172,25 @@ public class LogEntry implements Comparable<LogEntry> {
|
||||
if (!(o instanceof LogEntry)) return false;
|
||||
final LogEntry other = (LogEntry) o;
|
||||
if (this.getTimestamp() != other.getTimestamp()) return false;
|
||||
final Object this$actor = this.getActor();
|
||||
final Object other$actor = other.getActor();
|
||||
if (this$actor == null ? other$actor != null : !this$actor.equals(other$actor)) return false;
|
||||
final Object this$actorName = this.getActorName();
|
||||
final Object other$actorName = other.getActorName();
|
||||
if (this$actorName == null ? other$actorName != null : !this$actorName.equals(other$actorName)) return false;
|
||||
if (this.getActor() == null ? other.getActor() != null : !this.getActor().equals(other.getActor())) return false;
|
||||
if (this.getActorName() == null ? other.getActorName() != null : !this.getActorName().equals(other.getActorName())) return false;
|
||||
if (this.getType() != other.getType()) return false;
|
||||
final Object this$acted = this.getActed();
|
||||
final Object other$acted = other.getActed();
|
||||
if (this$acted == null ? other$acted != null : !this$acted.equals(other$acted)) return false;
|
||||
final Object this$actedName = this.getActedName();
|
||||
final Object other$actedName = other.getActedName();
|
||||
if (this$actedName == null ? other$actedName != null : !this$actedName.equals(other$actedName)) return false;
|
||||
final Object this$action = this.getAction();
|
||||
final Object other$action = other.getAction();
|
||||
return this$action == null ? other$action == null : this$action.equals(other$action);
|
||||
if (this.getActed() == null ? other.getActed() != null : !this.getActed().equals(other.getActed())) return false;
|
||||
if (this.getActedName() == null ? other.getActedName() != null : !this.getActedName().equals(other.getActedName())) return false;
|
||||
return this.getAction() == null ? other.getAction() == null : this.getAction().equals(other.getAction());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 59;
|
||||
int result = 1;
|
||||
final long $timestamp = this.getTimestamp();
|
||||
result = result * PRIME + (int) ($timestamp >>> 32 ^ $timestamp);
|
||||
final Object $actor = this.getActor();
|
||||
result = result * PRIME + ($actor == null ? 43 : $actor.hashCode());
|
||||
final Object $actorName = this.getActorName();
|
||||
result = result * PRIME + ($actorName == null ? 43 : $actorName.hashCode());
|
||||
result = result * PRIME + (int) (this.getTimestamp() >>> 32 ^ this.getTimestamp());
|
||||
result = result * PRIME + (this.getActor() == null ? 43 : this.getActor().hashCode());
|
||||
result = result * PRIME + (this.getActorName() == null ? 43 : this.getActorName().hashCode());
|
||||
result = result * PRIME + this.getType();
|
||||
final Object $acted = this.getActed();
|
||||
result = result * PRIME + ($acted == null ? 43 : $acted.hashCode());
|
||||
final Object $actedName = this.getActedName();
|
||||
result = result * PRIME + ($actedName == null ? 43 : $actedName.hashCode());
|
||||
final Object $action = this.getAction();
|
||||
result = result * PRIME + ($action == null ? 43 : $action.hashCode());
|
||||
result = result * PRIME + (this.getActed() == null ? 43 : this.getActed().hashCode());
|
||||
result = result * PRIME + (this.getActedName() == null ? 43 : this.getActedName().hashCode());
|
||||
result = result * PRIME + (this.getAction() == null ? 43 : this.getAction().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -214,6 +205,7 @@ public class LogEntry implements Comparable<LogEntry> {
|
||||
protected LogEntryBuilder getThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static abstract class AbstractLogEntryBuilder<T extends LogEntry, B extends AbstractLogEntryBuilder<T, B>> {
|
||||
@@ -311,9 +303,15 @@ public class LogEntry implements Comparable<LogEntry> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LogEntry.LogEntryBuilder(timestamp=" + getTimestamp() + ", actor=" + getActor() + ", actorName=" +
|
||||
getActorName() + ", type=" + getType() + ", acted=" + getActed() + ", actedName=" + getActedName() +
|
||||
", action=" + getAction() + ")";
|
||||
return "LogEntry.LogEntryBuilder(" +
|
||||
"timestamp=" + this.getTimestamp() + ", " +
|
||||
"actor=" + this.getActor() + ", " +
|
||||
"actorName=" + this.getActorName() + ", " +
|
||||
"type=" + this.getType() + ", " +
|
||||
"acted=" + this.getActed() + ", " +
|
||||
"actedName=" + this.getActedName() + ", " +
|
||||
"action=" + this.getAction() +
|
||||
")";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* A wrapper interface for platform logger instances.
|
||||
* A wrapper interface for platform logger instances
|
||||
*
|
||||
* <p> Bukkit/Bungee both use java.util.logging, and Sponge uses org.slf4j. This class wraps those classes so the
|
||||
* commons module can access a logger.
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.IContextCalculator;
|
||||
import me.lucko.luckperms.api.event.LPListener;
|
||||
|
||||
@@ -31,9 +32,8 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* The root API interface in LuckPerms
|
||||
* The root API interface for LuckPerms
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
@@ -250,6 +250,13 @@ public interface LuckPermsApi {
|
||||
*/
|
||||
boolean isTrackLoaded(String name);
|
||||
|
||||
/**
|
||||
* Gets the node factory instance for the platform
|
||||
*
|
||||
* @return the node factory
|
||||
*/
|
||||
NodeFactory getNodeFactory();
|
||||
|
||||
/**
|
||||
* Returns a permission builder instance
|
||||
*
|
||||
@@ -279,11 +286,21 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a calculated context instance for the user using the rules of the platform.
|
||||
* These values are calculated using the options in the configuration, and the provided calculators.
|
||||
*
|
||||
* <p> These values are calculated using the options in the configuration, and the provided calculators.
|
||||
*
|
||||
* @param user the user to get contexts for
|
||||
* @return an optional containing contexts. Will return empty if the user is not online.
|
||||
*/
|
||||
Optional<Contexts> getContextForUser(User user);
|
||||
|
||||
/**
|
||||
* Gets set of contexts applicable to a player using the platforms {@link IContextCalculator}s.
|
||||
*
|
||||
* @param player the player to calculate for. Must be the player instance for the platform.
|
||||
* @return a set of contexts.
|
||||
* @since 2.17
|
||||
*/
|
||||
ContextSet getContextForPlayer(Object player);
|
||||
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* Exposes any networking provider being used on the platform. e.g. Redis
|
||||
* A means to push changes to other servers using the platforms networking
|
||||
*
|
||||
* @since 2.14
|
||||
*/
|
||||
@@ -31,7 +31,9 @@ public interface MessagingService {
|
||||
|
||||
/**
|
||||
* Uses the messaging service to inform other servers about changes.
|
||||
* This will push the update asynchronously, and this method will return almost immediately.
|
||||
*
|
||||
* <p> This will push the update asynchronously, and this method will return immediately. Calling this method is
|
||||
* equivalent to running "/lp networksync", except will not sync this server.
|
||||
*/
|
||||
void pushUpdate();
|
||||
|
||||
|
||||
@@ -31,12 +31,12 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents an immutable node object
|
||||
* An immutable permission node
|
||||
*
|
||||
* <p> Use {@link LuckPermsApi#buildNode(String)} to get an instance.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Builds {@link Node} instances
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
public interface NodeFactory {
|
||||
|
||||
/**
|
||||
* Creates a node from a serialised node string
|
||||
*
|
||||
* @param serialisedPermission the serialised permission string
|
||||
* @param value the value of the node
|
||||
* @return a node instance
|
||||
* @throws NullPointerException if the permission is null
|
||||
*/
|
||||
Node fromSerialisedNode(String serialisedPermission, boolean value);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new node builder from a given base permission string
|
||||
*
|
||||
* @param permission the permission
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the permission is null
|
||||
*/
|
||||
Node.Builder newBuilder(String permission);
|
||||
|
||||
/**
|
||||
* Creates a node builder instance from an existing node
|
||||
*
|
||||
* @param other the other node
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the other node is null
|
||||
*/
|
||||
Node.Builder newBuilderFromExisting(Node other);
|
||||
|
||||
/**
|
||||
* Creates a node builder from a serialised node string
|
||||
* @param serialisedPermission the serialised permission string
|
||||
* @param value the value of the node
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the permission is null
|
||||
*/
|
||||
Node.Builder newBuilderFromSerialisedNode(String serialisedPermission, boolean value);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a node builder from a key value pair
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the key or value is null
|
||||
*/
|
||||
Node.Builder makeMetaNode(String key, String value);
|
||||
|
||||
/**
|
||||
* Creates a node builder from a prefix string and priority
|
||||
*
|
||||
* @param priority the priority
|
||||
* @param prefix the prefix string
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the prefix is null
|
||||
*/
|
||||
Node.Builder makePrefixNode(int priority, String prefix);
|
||||
|
||||
/**
|
||||
* Creates a node builder from a prefix string and priority
|
||||
*
|
||||
* @param priority the priority
|
||||
* @param suffix the suffix string
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the suffix is null
|
||||
*/
|
||||
Node.Builder makeSuffixNode(int priority, String suffix);
|
||||
|
||||
}
|
||||
@@ -31,19 +31,24 @@ import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
/**
|
||||
* Interface for internal PermissionHolder (user/group) instances
|
||||
* An object capable of holding permissions
|
||||
*
|
||||
* <p> Any changes made will be lost unless the instance is saved back to the {@link Storage}.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* @return the identifier for this object. either a uuid string or name However, you should really just use {@link
|
||||
* User#getUuid()}, {@link User#getName()} or {@link Group#getName()}
|
||||
* Gets the objects name
|
||||
*
|
||||
* <p> {@link User#getUuid()}, {@link User#getName()} or {@link Group#getName()} should normally be used instead of
|
||||
* this method.
|
||||
*
|
||||
* @return the identifier for this object. Either a uuid string or name.
|
||||
*/
|
||||
String getObjectName();
|
||||
|
||||
/**
|
||||
* Gets an immutable Set of the objects permission nodes
|
||||
* Gets a sorted set of all held permissions.
|
||||
*
|
||||
* @return an immutable set of permissions in priority order
|
||||
* @since 2.6
|
||||
@@ -51,20 +56,22 @@ public interface PermissionHolder {
|
||||
SortedSet<? extends Node> getPermissions();
|
||||
|
||||
/**
|
||||
* Similar to {@link #getPermissions()}, except excluding transient permissions
|
||||
* Similar to {@link #getPermissions()}, except without transient permissions
|
||||
*
|
||||
* @return a set of nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getEnduringPermissions();
|
||||
Set<? extends Node> getEnduringPermissions();
|
||||
|
||||
/**
|
||||
* Similar to {@link #getPermissions()}, except excluding non-transient permissions
|
||||
* Gets an immutable set of all transiently held permissions.
|
||||
*
|
||||
* <p> Transient permissions only exist for the duration of the session.
|
||||
*
|
||||
* @return a set of nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getTransientPermissions();
|
||||
Set<? extends Node> getTransientPermissions();
|
||||
|
||||
|
||||
/**
|
||||
@@ -91,7 +98,7 @@ public interface PermissionHolder {
|
||||
SortedSet<LocalizedNode> getAllNodes(Contexts contexts);
|
||||
|
||||
/**
|
||||
* Gets a mutable set of the nodes that is objects has and inherits, filtered by context.
|
||||
* Gets a mutable set of the nodes that this object has and inherits, filtered by context.
|
||||
* Unlike {@link #getAllNodes(Contexts)}, this method WILL filter individual nodes, and only return ones that fully
|
||||
* meet the context provided.
|
||||
*
|
||||
@@ -102,6 +109,14 @@ public interface PermissionHolder {
|
||||
*/
|
||||
Set<LocalizedNode> getAllNodesFiltered(Contexts contexts);
|
||||
|
||||
/**
|
||||
* Converts the output of {@link #getAllNodesFiltered(Contexts)}, and expands shorthand permissions.
|
||||
* @param contexts the context for the lookup
|
||||
* @param lowerCase if the keys should be made lowercase whilst being exported
|
||||
* @return a mutable map of permissions
|
||||
*/
|
||||
Map<String, Boolean> exportNodes(Contexts contexts, boolean lowerCase);
|
||||
|
||||
/**
|
||||
* Gets an immutable Map of the objects permission nodes
|
||||
*
|
||||
@@ -111,6 +126,11 @@ public interface PermissionHolder {
|
||||
@Deprecated
|
||||
Map<String, Boolean> getNodes();
|
||||
|
||||
/**
|
||||
* Removes temporary permissions that have expired
|
||||
*/
|
||||
void auditTemporaryPermissions();
|
||||
|
||||
/**
|
||||
* Checks to see if the object has a certain permission
|
||||
*
|
||||
@@ -508,6 +528,109 @@ public interface PermissionHolder {
|
||||
@Deprecated
|
||||
void unsetPermission(String node, String server, String world, boolean temporary) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Clears all nodes held by the object
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearNodes();
|
||||
|
||||
/**
|
||||
* Clears all nodes held by the object on a specific server
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearNodes(String server);
|
||||
|
||||
/**
|
||||
* Clears all nodes held by the object on a specific server and world
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @param world the world to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearNodes(String server, String world);
|
||||
|
||||
/**
|
||||
* Clears all parent groups
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearParents();
|
||||
|
||||
/**
|
||||
* Clears all parents on a specific server
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearParents(String server);
|
||||
|
||||
/**
|
||||
* Clears all parents on a specific server and world
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @param world the world to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearParents(String server, String world);
|
||||
|
||||
/**
|
||||
* Clears all meta held by the object
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearMeta();
|
||||
|
||||
/**
|
||||
* Clears all meta held by the object on a specific server
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearMeta(String server);
|
||||
|
||||
/**
|
||||
* Clears all meta held by the object on a specific server and world
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @param world the world to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearMeta(String server, String world);
|
||||
|
||||
/**
|
||||
* Clears all meta for a given key.
|
||||
*
|
||||
* @param key the meta key
|
||||
* @param server the server to filter by, can be null
|
||||
* @param world the world to filter by, can be null
|
||||
* @param temporary whether the query is for temporary nodes or not.
|
||||
*/
|
||||
void clearMetaKeys(String key, String server, String world, boolean temporary);
|
||||
|
||||
/**
|
||||
* Clears all transient permissions the holder has.
|
||||
*/
|
||||
void clearTransientNodes();
|
||||
|
||||
/**
|
||||
* Processes the nodes and returns the non-temporary ones.
|
||||
*
|
||||
* @return a set of permanent nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getPermanentPermissionNodes();
|
||||
|
||||
/**
|
||||
* Processes the nodes and returns the temporary ones.
|
||||
*
|
||||
* @return a set of temporary nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getTemporaryPermissionNodes();
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server and world
|
||||
*
|
||||
@@ -581,14 +704,6 @@ public interface PermissionHolder {
|
||||
@Deprecated
|
||||
Map<Map.Entry<String, Boolean>, Long> getTemporaryNodes();
|
||||
|
||||
/**
|
||||
* Processes the nodes and returns the temporary ones.
|
||||
*
|
||||
* @return a set of temporary nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getTemporaryPermissionNodes();
|
||||
|
||||
/**
|
||||
* Processes the nodes and returns the non-temporary ones.
|
||||
*
|
||||
@@ -598,17 +713,4 @@ public interface PermissionHolder {
|
||||
@Deprecated
|
||||
Map<String, Boolean> getPermanentNodes();
|
||||
|
||||
/**
|
||||
* Processes the nodes and returns the non-temporary ones.
|
||||
*
|
||||
* @return a set of permanent nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getPermanentPermissionNodes();
|
||||
|
||||
/**
|
||||
* Removes temporary permissions that have expired
|
||||
*/
|
||||
void auditTemporaryPermissions();
|
||||
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* Represents the platform type that LuckPerms is running on
|
||||
* The platforms which LuckPerms can run on
|
||||
*
|
||||
* @since 2.7
|
||||
*/
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -29,7 +30,7 @@ import java.util.concurrent.Executor;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Interface for the internal Storage instance
|
||||
* A means of loading and saving data to/from the Storage provider.
|
||||
*
|
||||
* <p>All methods return {@link CompletableFuture}s, which will be populated with the result once the data has been
|
||||
* loaded asynchronously. Care should be taken when using the methods to ensure that the main server thread is not
|
||||
@@ -124,6 +125,16 @@ public interface Storage {
|
||||
*/
|
||||
CompletableFuture<Set<UUID>> getUniqueUsers();
|
||||
|
||||
/**
|
||||
* Searches for a list of users with a given permission.
|
||||
*
|
||||
* @param permission the permission to search for
|
||||
* @return a list of held permissions, or null if the operation failed
|
||||
* @throws NullPointerException if the permission is null
|
||||
* @since 2.17
|
||||
*/
|
||||
CompletableFuture<List<HeldPermission<UUID>>> getUsersWithPermission(String permission);
|
||||
|
||||
/**
|
||||
* Creates and loads a group into the plugins local storage
|
||||
*
|
||||
@@ -171,6 +182,16 @@ public interface Storage {
|
||||
*/
|
||||
CompletableFuture<Boolean> deleteGroup(Group group);
|
||||
|
||||
/**
|
||||
* Searches for a list of groups with a given permission.
|
||||
*
|
||||
* @param permission the permission to search for
|
||||
* @return a list of held permissions, or null if the operation failed
|
||||
* @throws NullPointerException if the permission is null
|
||||
* @since 2.17
|
||||
*/
|
||||
CompletableFuture<List<HeldPermission<String>>> getGroupsWithPermission(String permission);
|
||||
|
||||
/**
|
||||
* Creates and loads a track into the plugins local storage
|
||||
*
|
||||
@@ -239,4 +260,14 @@ public interface Storage {
|
||||
*/
|
||||
CompletableFuture<UUID> getUUID(String username);
|
||||
|
||||
/**
|
||||
* Gets a username from a UUID
|
||||
*
|
||||
* @param uuid the corresponding uuid
|
||||
* @return a name string, could be null
|
||||
* @throws NullPointerException if either parameters are null
|
||||
* @since 2.17
|
||||
*/
|
||||
CompletableFuture<String> getName(UUID uuid);
|
||||
|
||||
}
|
||||
@@ -28,19 +28,20 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface for internal Track instances
|
||||
* An ordered collection of groups for easy promotions and demotions
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Track {
|
||||
|
||||
/**
|
||||
* Gets the name of this track
|
||||
* @return the name of this track
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Gets an ordered list of the groups on this track
|
||||
* Index 0 is the first/lowest group in (or start of) the track
|
||||
*
|
||||
* <p> Index 0 is the first/lowest group in (or start of) the track
|
||||
*
|
||||
* @return an ordered {@link List} of the groups on this track
|
||||
*/
|
||||
@@ -136,7 +137,7 @@ public interface Track {
|
||||
boolean containsGroup(String group);
|
||||
|
||||
/**
|
||||
* Clear all of the groups within this track
|
||||
* Clear all of the groups from this track
|
||||
*/
|
||||
void clearGroups();
|
||||
|
||||
|
||||
@@ -23,14 +23,34 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* Represents a permission value
|
||||
* Represents a permission setting.
|
||||
*
|
||||
* <p> Consider a value of {@link #FALSE} to be a "negated" setting, and a value of {@link #UNDEFINED} to be a
|
||||
* non-existent value.
|
||||
*/
|
||||
public enum Tristate {
|
||||
|
||||
/**
|
||||
* A value indicating a holder has a permission set.
|
||||
*/
|
||||
TRUE(true),
|
||||
|
||||
/**
|
||||
* A value indicating a holder has a negated value for a permission.
|
||||
*/
|
||||
FALSE(false),
|
||||
|
||||
/**
|
||||
* A value indicating a holder doesn't have a value for a permission set.
|
||||
*/
|
||||
UNDEFINED(false);
|
||||
|
||||
/**
|
||||
* Converts from {@link Boolean} a boolean
|
||||
*
|
||||
* @param b the boolean
|
||||
* @return {@link #TRUE} or {@link #FALSE}, depending on the value of the boolean.
|
||||
*/
|
||||
public static Tristate fromBoolean(boolean b) {
|
||||
return b ? TRUE : FALSE;
|
||||
}
|
||||
@@ -41,6 +61,12 @@ public enum Tristate {
|
||||
this.booleanValue = booleanValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the Tristate as a boolean.
|
||||
* <p> A value of {@link #UNDEFINED} converts to false.
|
||||
*
|
||||
* @return a boolean representation of the Tristate.
|
||||
*/
|
||||
public boolean asBoolean() {
|
||||
return booleanValue;
|
||||
}
|
||||
|
||||
@@ -31,17 +31,20 @@ import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Interface for internal User instances
|
||||
* A player holding permission data
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface User extends PermissionHolder {
|
||||
|
||||
/**
|
||||
* Gets the users unique ID
|
||||
*
|
||||
* @return the users Mojang assigned unique id
|
||||
*/
|
||||
UUID getUuid();
|
||||
|
||||
/**
|
||||
* Gets the users username
|
||||
*
|
||||
* @return the Users Username
|
||||
*/
|
||||
String getName();
|
||||
@@ -64,7 +67,10 @@ public interface User extends PermissionHolder {
|
||||
void setPrimaryGroup(String group) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Refresh and re-assign the users permissions
|
||||
* Refresh and re-assign the users permissions.
|
||||
*
|
||||
* <p> This request is not buffered, and the refresh call will be ran directly. This should ideally be called on
|
||||
* an asynchronous thread.
|
||||
*/
|
||||
void refreshPermissions();
|
||||
|
||||
@@ -76,6 +82,13 @@ public interface User extends PermissionHolder {
|
||||
*/
|
||||
Optional<UserData> getUserDataCache();
|
||||
|
||||
/**
|
||||
* Sets up the users data cache, if the don't have one setup already.
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
void setupDataCache();
|
||||
|
||||
/**
|
||||
* Check to see if the user is a member of a group
|
||||
*
|
||||
@@ -255,11 +268,6 @@ public interface User extends PermissionHolder {
|
||||
*/
|
||||
void removeGroup(Group group, String server, String world, boolean temporary) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Clear all of the users permission nodes
|
||||
*/
|
||||
void clearNodes();
|
||||
|
||||
/**
|
||||
* Get a {@link List} of all of the groups the user is a member of, on all servers
|
||||
*
|
||||
|
||||
@@ -28,16 +28,15 @@ import java.util.UUID;
|
||||
* A UUID cache for online users, between external Mojang UUIDs, and internal LuckPerms UUIDs.
|
||||
*
|
||||
* <p> This UuidCache is a means of allowing users to have the same internal UUID across a network of offline mode
|
||||
* servers or mixed offline mode and online mode servers. Platforms running in offline mode generate a random UUID for a
|
||||
* servers or mixed offline mode and online mode servers. Platforms running in offline mode generate a UUID for a
|
||||
* user when they first join the server, but this UUID will then not be consistent across the network. LuckPerms will
|
||||
* instead check the datastore cache, to get a UUID for a user that is consistent across an entire network.
|
||||
*
|
||||
* <p> If you want to get a user object from the Storage using the api on a server in offline mode, you will need to use
|
||||
* this cache, OR use Storage#getUUID, for users that are not online.
|
||||
*
|
||||
* <p> WARNING: THIS IS ONLY EFFECTIVE FOR ONLINE PLAYERS. USE THE DATASTORE METHODS FOR OFFLINE PLAYERS.
|
||||
* <p> THIS IS ONLY EFFECTIVE FOR ONLINE PLAYERS. USE THE DATASTORE METHODS FOR OFFLINE PLAYERS.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface UuidCache {
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,7 +44,8 @@ public interface PermissionData {
|
||||
|
||||
/**
|
||||
* Invalidates the underlying permission calculator cache.
|
||||
* Can be called to allow for an update in defaults.
|
||||
*
|
||||
* <p> Can be called to allow for an update in defaults.
|
||||
*/
|
||||
void invalidateCache();
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ public interface UserData {
|
||||
|
||||
/**
|
||||
* Gets PermissionData from the cache, given a specified context.
|
||||
* If the data is not cached, it is calculated. Therefore, this call could be costly.
|
||||
*
|
||||
* <p> If the data is not cached, it is calculated. Therefore, this call could be costly.
|
||||
*
|
||||
* @param contexts the contexts to get the permission data in
|
||||
* @return a permission data instance
|
||||
@@ -48,7 +49,8 @@ public interface UserData {
|
||||
|
||||
/**
|
||||
* Gets MetaData from the cache, given a specified context.
|
||||
* If the data is not cached, it is calculated. Therefore, this call could be costly.
|
||||
*
|
||||
* <p> If the data is not cached, it is calculated. Therefore, this call could be costly.
|
||||
*
|
||||
* @param contexts the contexts to get the permission data in
|
||||
* @return a meta data instance
|
||||
@@ -75,8 +77,10 @@ public interface UserData {
|
||||
MetaData calculateMeta(Contexts contexts);
|
||||
|
||||
/**
|
||||
* Calculates permission data and stores it in the cache. If there is already data cached for the given contexts,
|
||||
* and if the resultant output is different, the cached value is updated.
|
||||
* Calculates permission data and stores it in the cache.
|
||||
*
|
||||
* <p> If there is already data cached for the given contexts, and if the resultant output is different,
|
||||
* the cached value is updated.
|
||||
*
|
||||
* @param contexts the contexts to recalculate in.
|
||||
* @throws NullPointerException if contexts is null
|
||||
@@ -84,8 +88,10 @@ public interface UserData {
|
||||
void recalculatePermissions(Contexts contexts);
|
||||
|
||||
/**
|
||||
* Calculates meta data and stores it in the cache. If there is already data cached for the given contexts,
|
||||
* and if the resultant output is different, the cached value is updated.
|
||||
* Calculates meta data and stores it in the cache.
|
||||
*
|
||||
* <p> If there is already data cached for the given contexts, and if the resultant output is different,
|
||||
* the cached value is updated.
|
||||
*
|
||||
* @param contexts the contexts to recalculate in.
|
||||
* @throws NullPointerException if contexts is null
|
||||
@@ -111,8 +117,9 @@ public interface UserData {
|
||||
void preCalculate(Set<Contexts> contexts);
|
||||
|
||||
/**
|
||||
* Ensures that PermissionData and MetaData is cached for a context. If the cache does not contain any data for the
|
||||
* context, it will be calculated and saved.
|
||||
* Ensures that PermissionData and MetaData is cached for a context.
|
||||
*
|
||||
* <p> If the cache does not contain any data for the context, it will be calculated and saved.
|
||||
*
|
||||
* @param contexts the contexts to pre-calculate for
|
||||
* @throws NullPointerException if contexts is null
|
||||
|
||||
@@ -65,7 +65,7 @@ public interface ContextSet {
|
||||
* @return a new ImmutableContextSet representing the pairs in the iterable
|
||||
* @throws NullPointerException if the iterable is null
|
||||
*/
|
||||
static ImmutableContextSet fromEntries(Iterable<Map.Entry<String, String>> iterable) {
|
||||
static ImmutableContextSet fromEntries(Iterable<? extends Map.Entry<String, String>> iterable) {
|
||||
return ImmutableContextSet.fromEntries(iterable);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
package me.lucko.luckperms.api.context;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -40,37 +39,9 @@ public interface IContextCalculator<T> {
|
||||
* @param subject the subject to add contexts to
|
||||
* @param accumulator a map of contexts to add to
|
||||
* @return the map
|
||||
* @deprecated in favour of {@link #giveApplicableContext(Object, MutableContextSet)}. Older implementations of this
|
||||
* interface will still work, as the replacement method is given as a default, and falls back to using this method.
|
||||
*/
|
||||
@Deprecated
|
||||
default Map<String, String> giveApplicableContext(T subject, Map<String, String> accumulator) {
|
||||
MutableContextSet acc = new MutableContextSet();
|
||||
giveApplicableContext(subject, acc);
|
||||
|
||||
accumulator.putAll(acc.toMap());
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the subject all of the applicable contexts they meet
|
||||
*
|
||||
* <p><b>You MUST implement this method. The default is only provided for backwards compatibility with
|
||||
* {@link #giveApplicableContext(Object, Map)}.</b>
|
||||
*
|
||||
* @param subject the subject to add contexts to
|
||||
* @param accumulator a map of contexts to add to
|
||||
* @return the map
|
||||
* @since 2.13
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
default MutableContextSet giveApplicableContext(T subject, MutableContextSet accumulator) {
|
||||
Map<String, String> acc = new HashMap<>();
|
||||
giveApplicableContext(subject, acc);
|
||||
|
||||
accumulator.addAll(acc.entrySet());
|
||||
return accumulator;
|
||||
}
|
||||
MutableContextSet giveApplicableContext(T subject, MutableContextSet accumulator);
|
||||
|
||||
/**
|
||||
* Checks to see if a context is applicable to a subject
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.google.common.collect.Multimap;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* An immutable implementation of {@link ContextSet}.
|
||||
@@ -71,13 +70,12 @@ public final class ImmutableContextSet implements ContextSet {
|
||||
throw new NullPointerException("map");
|
||||
}
|
||||
|
||||
return new ImmutableContextSet(ImmutableMultimap.copyOf(
|
||||
map.entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
e -> e.getKey().toLowerCase(),
|
||||
Map.Entry::getValue
|
||||
)).entrySet()
|
||||
));
|
||||
ImmutableMultimap.Builder<String, String> b = ImmutableMultimap.builder();
|
||||
for (Map.Entry<String, String> e : map.entrySet()) {
|
||||
b.put(e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
return new ImmutableContextSet(b.build());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,7 +85,7 @@ public final class ImmutableContextSet implements ContextSet {
|
||||
* @return a new ImmutableContextSet representing the pairs in the iterable
|
||||
* @throws NullPointerException if the iterable is null
|
||||
*/
|
||||
public static ImmutableContextSet fromEntries(Iterable<Map.Entry<String, String>> iterable) {
|
||||
public static ImmutableContextSet fromEntries(Iterable<? extends Map.Entry<String, String>> iterable) {
|
||||
if (iterable == null) {
|
||||
throw new NullPointerException("iterable");
|
||||
}
|
||||
@@ -160,7 +158,12 @@ public final class ImmutableContextSet implements ContextSet {
|
||||
|
||||
@Override
|
||||
public Map<String, String> toMap() {
|
||||
return ImmutableMap.copyOf(map.entries());
|
||||
ImmutableMap.Builder<String, String> m = ImmutableMap.builder();
|
||||
for (Map.Entry<String, String> e : map.entries()) {
|
||||
m.put(e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
return m.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -84,7 +84,7 @@ public final class MutableContextSet implements ContextSet {
|
||||
* @return a new MutableContextSet representing the pairs in the iterable
|
||||
* @throws NullPointerException if the iterable is null
|
||||
*/
|
||||
public static MutableContextSet fromEntries(Iterable<Map.Entry<String, String>> iterable) {
|
||||
public static MutableContextSet fromEntries(Iterable<? extends Map.Entry<String, String>> iterable) {
|
||||
if (iterable == null) {
|
||||
throw new NullPointerException("iterable");
|
||||
}
|
||||
@@ -168,7 +168,12 @@ public final class MutableContextSet implements ContextSet {
|
||||
|
||||
@Override
|
||||
public Map<String, String> toMap() {
|
||||
return ImmutableMap.copyOf(map.entries());
|
||||
ImmutableMap.Builder<String, String> m = ImmutableMap.builder();
|
||||
for (Map.Entry<String, String> e : map.entries()) {
|
||||
m.put(e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
return m.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -277,7 +282,7 @@ public final class MutableContextSet implements ContextSet {
|
||||
* @param iterable an iterable of key value context pairs
|
||||
* @throws NullPointerException if iterable is null
|
||||
*/
|
||||
public void addAll(Iterable<Map.Entry<String, String>> iterable) {
|
||||
public void addAll(Iterable<? extends Map.Entry<String, String>> iterable) {
|
||||
if (iterable == null) {
|
||||
throw new NullPointerException("contexts");
|
||||
}
|
||||
|
||||
+4
-32
@@ -5,14 +5,14 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.16-SNAPSHOT</version>
|
||||
<version>2.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>luckperms-bukkit-legacy</artifactId>
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<finalName>LuckPerms-bukkit-legacy-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<finalName>LuckPerms-Bukkit-Legacy-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
@@ -47,26 +47,6 @@
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.slf4j</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.slf4j</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.zaxxer.hikari</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.hikari</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.mongodb</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.mongodb</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bson</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.bson</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.h2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.h2</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.google.common</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.guava</shadedPattern>
|
||||
@@ -76,16 +56,8 @@
|
||||
<shadedPattern>me.lucko.luckperms.lib.gson</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.jedis</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.jedis</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.util</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.util</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.apache.commons.pool2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.pool2</shadedPattern>
|
||||
<pattern>io.github.mkremins.fanciful</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.fanciful</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.16-SNAPSHOT</version>
|
||||
<version>2.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
+13
-39
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.16-SNAPSHOT</version>
|
||||
<version>2.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<finalName>LuckPerms-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<finalName>LuckPerms-Bukkit-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
@@ -44,43 +44,10 @@
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>false</minimizeJar>
|
||||
<artifactSet>
|
||||
<excludes>
|
||||
<exclude>org.xerial:*</exclude>
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.slf4j</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.slf4j</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.zaxxer.hikari</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.hikari</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.mongodb</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.mongodb</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bson</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.bson</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.h2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.h2</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.jedis</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.jedis</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.util</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.util</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.apache.commons.pool2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.pool2</shadedPattern>
|
||||
<pattern>io.github.mkremins.fanciful</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.fanciful</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
@@ -108,8 +75,8 @@
|
||||
<dependencies>
|
||||
<!-- BukkitAPI -->
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
@@ -134,6 +101,13 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- HikariCP - needed as source -->
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>2.5.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
|
||||
@@ -50,8 +50,7 @@ class BukkitCommand extends CommandManager implements CommandExecutor, TabExecut
|
||||
onCommand(
|
||||
plugin.getSenderFactory().wrap(sender),
|
||||
label,
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))),
|
||||
null
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
plugin.getWorldCalculator().getWorldCache().remove(internal);
|
||||
|
||||
// Remove the custom permissible
|
||||
Injector.unInject(player);
|
||||
Injector.unInject(player, true);
|
||||
|
||||
// Handle auto op
|
||||
if (plugin.getConfiguration().isAutoOp()) {
|
||||
@@ -140,7 +140,7 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
.replace("spigot:", "")
|
||||
.replace("minecraft:", "");
|
||||
|
||||
if (s.startsWith("op") || s.startsWith("deop")) {
|
||||
if (s.equals("op") || s.startsWith("op ") || s.equals("deop") || s.startsWith("deop ")) {
|
||||
e.setCancelled(true);
|
||||
e.getPlayer().sendMessage(Message.OP_DISABLED.toString());
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import me.lucko.luckperms.bukkit.compat.MessageHandler;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.sender.SenderFactory;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
@@ -29,11 +30,16 @@ import me.lucko.luckperms.common.constants.Constants;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import io.github.mkremins.fanciful.FancyMessage;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitSenderFactory extends SenderFactory<CommandSender> {
|
||||
private final MessageHandler messageHandler;
|
||||
|
||||
public BukkitSenderFactory(LuckPermsPlugin plugin) {
|
||||
super(plugin);
|
||||
messageHandler = new MessageHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,7 +47,7 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> {
|
||||
if (sender instanceof Player) {
|
||||
return sender.getName();
|
||||
}
|
||||
return Constants.getConsoleName();
|
||||
return Constants.CONSOLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,7 +55,7 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> {
|
||||
if (sender instanceof Player) {
|
||||
return ((Player) sender).getUniqueId();
|
||||
}
|
||||
return Constants.getConsoleUUID();
|
||||
return Constants.CONSOLE_UUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,6 +63,11 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> {
|
||||
sender.sendMessage(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendMessage(CommandSender sender, FancyMessage message) {
|
||||
messageHandler.sendJsonMessage(sender, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasPermission(CommandSender sender, String node) {
|
||||
return sender.hasPermission(node);
|
||||
|
||||
@@ -26,7 +26,6 @@ import lombok.Getter;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import me.lucko.luckperms.ApiHandler;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
@@ -34,13 +33,16 @@ import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.bukkit.calculators.AutoOPListener;
|
||||
import me.lucko.luckperms.bukkit.inject.Injector;
|
||||
import me.lucko.luckperms.bukkit.model.ChildPermissionProvider;
|
||||
import me.lucko.luckperms.bukkit.model.DefaultsProvider;
|
||||
import me.lucko.luckperms.bukkit.model.LPPermissible;
|
||||
import me.lucko.luckperms.bukkit.vault.VaultHook;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.api.ApiHandler;
|
||||
import me.lucko.luckperms.common.api.ApiProvider;
|
||||
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.config.LPConfiguration;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
@@ -49,6 +51,7 @@ import me.lucko.luckperms.common.contexts.ServerCalculator;
|
||||
import me.lucko.luckperms.common.core.UuidCache;
|
||||
import me.lucko.luckperms.common.core.model.User;
|
||||
import me.lucko.luckperms.common.data.Importer;
|
||||
import me.lucko.luckperms.common.dependencies.DependencyManager;
|
||||
import me.lucko.luckperms.common.managers.GroupManager;
|
||||
import me.lucko.luckperms.common.managers.TrackManager;
|
||||
import me.lucko.luckperms.common.managers.UserManager;
|
||||
@@ -58,6 +61,8 @@ import me.lucko.luckperms.common.managers.impl.GenericUserManager;
|
||||
import me.lucko.luckperms.common.messaging.RedisMessaging;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
import me.lucko.luckperms.common.storage.StorageFactory;
|
||||
import me.lucko.luckperms.common.storage.StorageType;
|
||||
import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
|
||||
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.common.tasks.UpdateTask;
|
||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||
@@ -69,12 +74,14 @@ import me.lucko.luckperms.common.utils.PermissionCache;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -89,7 +96,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
|
||||
private Set<UUID> ignoringLogs;
|
||||
private Executor syncExecutor;
|
||||
private Executor asyncExecutor;
|
||||
private VaultHook vaultHook = null;
|
||||
@@ -100,13 +107,14 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
private Storage storage;
|
||||
private RedisMessaging redisMessaging = null;
|
||||
private UuidCache uuidCache;
|
||||
private BukkitListener listener;
|
||||
private ApiProvider apiProvider;
|
||||
private Logger log;
|
||||
private Importer importer;
|
||||
private ConsecutiveExecutor consecutiveExecutor;
|
||||
private DefaultsProvider defaultsProvider;
|
||||
private ChildPermissionProvider childPermissionProvider;
|
||||
private LocaleManager localeManager;
|
||||
private CachedStateManager cachedStateManager;
|
||||
private ContextManager<Player> contextManager;
|
||||
private WorldCalculator worldCalculator;
|
||||
private CalculatorFactory calculatorFactory;
|
||||
@@ -124,13 +132,17 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
Executor bukkitAsyncExecutor = r -> getServer().getScheduler().runTaskAsynchronously(this, r);
|
||||
|
||||
log = LogFactory.wrap(getLogger());
|
||||
debugHandler = new DebugHandler(bukkitAsyncExecutor);
|
||||
ignoringLogs = ConcurrentHashMap.newKeySet();
|
||||
debugHandler = new DebugHandler(bukkitAsyncExecutor, getVersion());
|
||||
senderFactory = new BukkitSenderFactory(this);
|
||||
permissionCache = new PermissionCache(bukkitAsyncExecutor);
|
||||
|
||||
getLog().info("Loading configuration...");
|
||||
configuration = new BukkitConfig(this);
|
||||
|
||||
Set<StorageType> storageTypes = StorageFactory.getRequiredTypes(this, StorageType.H2);
|
||||
DependencyManager.loadDependencies(this, storageTypes);
|
||||
|
||||
// setup the Bukkit defaults hook
|
||||
defaultsProvider = new DefaultsProvider();
|
||||
childPermissionProvider = new ChildPermissionProvider();
|
||||
@@ -162,10 +174,11 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
|
||||
// register events
|
||||
PluginManager pm = getServer().getPluginManager();
|
||||
pm.registerEvents(new BukkitListener(this), this);
|
||||
listener = new BukkitListener(this);
|
||||
pm.registerEvents(listener, this);
|
||||
|
||||
// initialise datastore
|
||||
storage = StorageFactory.getInstance(this, "h2");
|
||||
storage = StorageFactory.getInstance(this, StorageType.H2);
|
||||
|
||||
// initialise redis
|
||||
if (getConfiguration().isRedisEnabled()) {
|
||||
@@ -207,7 +220,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
PluginCommand main = getServer().getPluginCommand("luckperms");
|
||||
main.setExecutor(commandManager);
|
||||
main.setTabCompleter(commandManager);
|
||||
main.setAliases(Arrays.asList("perms", "lp", "permissions", "p", "perm"));
|
||||
main.setAliases(Arrays.asList("perms", "lp", "permissions", "perm"));
|
||||
|
||||
// load internal managers
|
||||
getLog().info("Loading internal permission managers...");
|
||||
@@ -216,8 +229,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
groupManager = new GenericGroupManager(this);
|
||||
trackManager = new GenericTrackManager();
|
||||
importer = new Importer(commandManager);
|
||||
consecutiveExecutor = new ConsecutiveExecutor(commandManager);
|
||||
calculatorFactory = new BukkitCalculatorFactory(this);
|
||||
cachedStateManager = new CachedStateManager(this);
|
||||
|
||||
contextManager = new ContextManager<>();
|
||||
worldCalculator = new WorldCalculator(this);
|
||||
@@ -244,7 +257,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
int mins = getConfiguration().getSyncTime();
|
||||
if (mins > 0) {
|
||||
long ticks = mins * 60 * 20;
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, () -> updateTaskBuffer.request(), 20L, ticks);
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, () -> updateTaskBuffer.request(), 40L, ticks);
|
||||
}
|
||||
|
||||
// run an update instantly.
|
||||
@@ -252,7 +265,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
|
||||
// register tasks
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, new ExpireTemporaryTask(this), 60L, 60L);
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, consecutiveExecutor, 20L, 20L);
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, new CacheHousekeepingTask(this), 2400L, 2400L);
|
||||
|
||||
// register permissions
|
||||
registerPermissions(getConfiguration().isCommandsAllowOp() ? PermissionDefault.OP : PermissionDefault.FALSE);
|
||||
@@ -265,6 +278,24 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
asyncExecutor = bukkitAsyncExecutor;
|
||||
});
|
||||
|
||||
// Load any online users (in the case of a reload)
|
||||
for (Player player : getServer().getOnlinePlayers()) {
|
||||
doAsync(() -> {
|
||||
listener.onAsyncLogin(player.getUniqueId(), player.getName());
|
||||
User user = getUserManager().get(getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (user != null) {
|
||||
doSync(() -> {
|
||||
try {
|
||||
LPPermissible lpPermissible = new LPPermissible(player, user, this);
|
||||
Injector.inject(player, lpPermissible);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
started = true;
|
||||
getLog().info("Successfully loaded.");
|
||||
}
|
||||
@@ -272,6 +303,24 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
@Override
|
||||
public void onDisable() {
|
||||
started = false;
|
||||
|
||||
defaultsProvider.close();
|
||||
permissionCache.setShutdown(true);
|
||||
debugHandler.setShutdown(true);
|
||||
|
||||
for (Player player : getServer().getOnlinePlayers()) {
|
||||
Injector.unInject(player, false);
|
||||
if (getConfiguration().isAutoOp()) {
|
||||
player.setOp(false);
|
||||
}
|
||||
|
||||
final User user = getUserManager().get(getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (user != null) {
|
||||
user.unregisterData();
|
||||
getUserManager().unload(user);
|
||||
}
|
||||
}
|
||||
|
||||
getLog().info("Closing datastore...");
|
||||
storage.shutdown();
|
||||
|
||||
@@ -287,6 +336,38 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
if (vaultHook != null) {
|
||||
vaultHook.unhook(this);
|
||||
}
|
||||
|
||||
// Bukkit will do this again when #onDisable completes, but we do it early to prevent NPEs elsewhere.
|
||||
getServer().getScheduler().cancelTasks(this);
|
||||
HandlerList.unregisterAll(this);
|
||||
|
||||
// Null everything
|
||||
ignoringLogs = null;
|
||||
syncExecutor = null;
|
||||
asyncExecutor = null;
|
||||
vaultHook = null;
|
||||
configuration = null;
|
||||
userManager = null;
|
||||
groupManager = null;
|
||||
trackManager = null;
|
||||
storage = null;
|
||||
redisMessaging = null;
|
||||
uuidCache = null;
|
||||
listener = null;
|
||||
apiProvider = null;
|
||||
log = null;
|
||||
importer = null;
|
||||
defaultsProvider = null;
|
||||
childPermissionProvider = null;
|
||||
localeManager = null;
|
||||
cachedStateManager = null;
|
||||
contextManager = null;
|
||||
worldCalculator = null;
|
||||
calculatorFactory = null;
|
||||
updateTaskBuffer = null;
|
||||
debugHandler = null;
|
||||
senderFactory = null;
|
||||
permissionCache = null;
|
||||
}
|
||||
|
||||
public void tryVaultHook(boolean force) {
|
||||
@@ -310,6 +391,14 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserRefresh(User user) {
|
||||
LPPermissible lpp = Injector.getPermissible(uuidCache.getExternalUUID(user.getUuid()));
|
||||
if (lpp != null) {
|
||||
lpp.updateSubscriptions();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAsync(Runnable r) {
|
||||
asyncExecutor.execute(r);
|
||||
@@ -335,11 +424,26 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
return PlatformType.BUKKIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerName() {
|
||||
return getServer().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerVersion() {
|
||||
return getServer().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getMainDir() {
|
||||
return getDataFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getResourceStream(String path) {
|
||||
return getResource(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer(User user) {
|
||||
return getServer().getPlayer(uuidCache.getExternalUUID(user.getUuid()));
|
||||
|
||||
@@ -35,14 +35,16 @@ public class AutoOPListener implements ContextListener<Player> {
|
||||
|
||||
@Override
|
||||
public void onContextChange(Player subject, Map.Entry<String, String> before, Map.Entry<String, String> current) throws Exception {
|
||||
LPPermissible permissible = Injector.getPermissible(subject.getUniqueId());
|
||||
if (permissible == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
LPPermissible permissible = Injector.getPermissible(subject.getUniqueId());
|
||||
if (permissible == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Boolean> backing = permissible.getUser().getUserData().getPermissionData(permissible.calculateContexts()).getImmutableBacking();
|
||||
boolean op = Optional.ofNullable(backing.get("luckperms.autoop")).orElse(false);
|
||||
subject.setOp(op);
|
||||
Map<String, Boolean> backing = permissible.getUser().getUserData().getPermissionData(permissible.calculateContexts()).getImmutableBacking();
|
||||
boolean op = Optional.ofNullable(backing.get("luckperms.autoop")).orElse(false);
|
||||
subject.setOp(op);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.bukkit.compat;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class BukkitJsonMessageHandler {
|
||||
private static boolean setup = false;
|
||||
private static boolean triedAndFailed = false;
|
||||
|
||||
private static Method GET_HANDLE_METHOD;
|
||||
private static Field PLAYER_CONNECTION_FIELD;
|
||||
private static Method SEND_PACKET_METHOD;
|
||||
private static Constructor<?> PACKET_CHAT_CONSTRUCTOR;
|
||||
private static Method SERIALIZE_METHOD;
|
||||
|
||||
private static void setup(Object player) throws Exception {
|
||||
Class<?> craftPlayerClass = player.getClass();
|
||||
GET_HANDLE_METHOD = craftPlayerClass.getDeclaredMethod("getHandle");
|
||||
|
||||
Object handleObject = GET_HANDLE_METHOD.invoke(player);
|
||||
Class<?> handleClass = handleObject.getClass();
|
||||
|
||||
PLAYER_CONNECTION_FIELD = handleClass.getDeclaredField("playerConnection");
|
||||
|
||||
Object playerConnectionObject = PLAYER_CONNECTION_FIELD.get(handleObject);
|
||||
|
||||
Method[] playerConnectionMethods = playerConnectionObject.getClass().getDeclaredMethods();
|
||||
for (Method m : playerConnectionMethods) {
|
||||
if (m.getName().equals("sendPacket")) {
|
||||
SEND_PACKET_METHOD = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> packetChatClass = Class.forName(getVersionedClassName("PacketPlayOutChat"));
|
||||
Constructor[] packetConstructors = packetChatClass.getDeclaredConstructors();
|
||||
for (Constructor c : packetConstructors) {
|
||||
Class<?>[] parameters = c.getParameterTypes();
|
||||
if (parameters.length == 1 && parameters[0].getName().endsWith("IChatBaseComponent")) {
|
||||
PACKET_CHAT_CONSTRUCTOR = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> baseComponentClass = Class.forName(getVersionedClassName("IChatBaseComponent"));
|
||||
Class<?> chatSerializerClass = baseComponentClass.getClasses()[0];
|
||||
|
||||
SERIALIZE_METHOD = chatSerializerClass.getDeclaredMethod("a", String.class);
|
||||
}
|
||||
|
||||
private static String getVersionedClassName(String className) {
|
||||
Class server = Bukkit.getServer().getClass();
|
||||
if (!server.getSimpleName().equals("CraftServer")) {
|
||||
throw new RuntimeException("Couldn't reflect into server " + server);
|
||||
}
|
||||
|
||||
String version;
|
||||
if (server.getName().equals("org.bukkit.craftbukkit.CraftServer")) {
|
||||
// Non versioned class
|
||||
version = ".";
|
||||
} else {
|
||||
version = server.getName().substring("org.bukkit.craftbukkit".length());
|
||||
version = version.substring(0, version.length() - "CraftServer".length());
|
||||
}
|
||||
|
||||
return "net.minecraft.server" + version + className;
|
||||
}
|
||||
|
||||
private static synchronized boolean trySetup(Object player) {
|
||||
if (setup) return true;
|
||||
if (triedAndFailed) return false;
|
||||
|
||||
try {
|
||||
setup(player);
|
||||
setup = true;
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
triedAndFailed = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean sendJsonMessage(Player player, String json) {
|
||||
if (!trySetup(player)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
Object connection = PLAYER_CONNECTION_FIELD.get(GET_HANDLE_METHOD.invoke(player));
|
||||
SEND_PACKET_METHOD.invoke(connection, PACKET_CHAT_CONSTRUCTOR.newInstance(SERIALIZE_METHOD.invoke(null, json)));
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.compat;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import io.github.mkremins.fanciful.FancyMessage;
|
||||
|
||||
public class MessageHandler {
|
||||
private final BukkitJsonMessageHandler bukkitHandler;
|
||||
private final SpigotJsonMessageHandler spigotHandler;
|
||||
|
||||
public MessageHandler() {
|
||||
bukkitHandler = new BukkitJsonMessageHandler();
|
||||
spigotHandler = isSpigot() ? new SpigotJsonMessageHandler() : null;
|
||||
}
|
||||
|
||||
public void sendJsonMessage(CommandSender sender, FancyMessage message) {
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
String json = message.toJSONString();
|
||||
|
||||
// Try Bukkit.
|
||||
if (bukkitHandler.sendJsonMessage(player, json)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try Spigot.
|
||||
if (spigotHandler != null && spigotHandler.sendJsonMessage(player, json)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to Bukkit
|
||||
sender.sendMessage(message.toOldMessageFormat());
|
||||
}
|
||||
|
||||
private static boolean isSpigot() {
|
||||
try {
|
||||
Class.forName("net.md_5.bungee.chat.ComponentSerializer");
|
||||
return true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.compat;
|
||||
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class SpigotJsonMessageHandler {
|
||||
|
||||
public boolean sendJsonMessage(Player player, String json) {
|
||||
try {
|
||||
player.spigot().sendMessage(ComponentSerializer.parse(json));
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,9 +28,11 @@ import me.lucko.luckperms.bukkit.model.LPPermissible;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -41,21 +43,44 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
@UtilityClass
|
||||
public class Injector {
|
||||
private static final Map<UUID, LPPermissible> INJECTED_PERMISSIBLES = new ConcurrentHashMap<>();
|
||||
|
||||
private static Field HUMAN_ENTITY_FIELD;
|
||||
private static Field PERMISSIBLEBASE_ATTACHMENTS;
|
||||
|
||||
static {
|
||||
try {
|
||||
HUMAN_ENTITY_FIELD = Class.forName(getVersionedClassName("entity.CraftHumanEntity")).getDeclaredField("perm");
|
||||
HUMAN_ENTITY_FIELD.setAccessible(true);
|
||||
|
||||
PERMISSIBLEBASE_ATTACHMENTS = PermissibleBase.class.getDeclaredField("attachments");
|
||||
PERMISSIBLEBASE_ATTACHMENTS.setAccessible(true);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean inject(Player player, LPPermissible permissible) {
|
||||
public static boolean inject(Player player, LPPermissible lpPermissible) {
|
||||
try {
|
||||
HUMAN_ENTITY_FIELD.set(player, permissible);
|
||||
INJECTED_PERMISSIBLES.put(player.getUniqueId(), permissible);
|
||||
PermissibleBase existing = (PermissibleBase) HUMAN_ENTITY_FIELD.get(player);
|
||||
if (existing instanceof LPPermissible) {
|
||||
// uh oh
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
// Move attachments over from the old permissible.
|
||||
List<PermissionAttachment> attachments = (List<PermissionAttachment>) PERMISSIBLEBASE_ATTACHMENTS.get(existing);
|
||||
lpPermissible.addAttachments(attachments);
|
||||
attachments.clear();
|
||||
existing.clearPermissions();
|
||||
|
||||
lpPermissible.recalculatePermissions();
|
||||
lpPermissible.setOldPermissible(existing);
|
||||
|
||||
lpPermissible.updateSubscriptionsAsync();
|
||||
|
||||
HUMAN_ENTITY_FIELD.set(player, lpPermissible);
|
||||
INJECTED_PERMISSIBLES.put(player.getUniqueId(), lpPermissible);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -63,14 +88,31 @@ public class Injector {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean unInject(Player player) {
|
||||
public static boolean unInject(Player player, boolean dummy) {
|
||||
try {
|
||||
Permissible permissible = (Permissible) HUMAN_ENTITY_FIELD.get(player);
|
||||
PermissibleBase permissible = (PermissibleBase) HUMAN_ENTITY_FIELD.get(player);
|
||||
if (permissible instanceof LPPermissible) {
|
||||
/* The player is most likely leaving. Bukkit will attempt to call #clearPermissions, so we cannot set to null.
|
||||
However, there's no need to re-inject a real PermissibleBase, so we just inject a dummy instead.
|
||||
This saves tick time, pointlessly recalculating defaults when the instance will never be used. */
|
||||
HUMAN_ENTITY_FIELD.set(player, new DummyPermissibleBase());
|
||||
|
||||
permissible.clearPermissions();
|
||||
((LPPermissible) permissible).unsubscribeFromAllAsync();
|
||||
|
||||
if (dummy) {
|
||||
HUMAN_ENTITY_FIELD.set(player, new DummyPermissibleBase());
|
||||
} else {
|
||||
LPPermissible lpp = ((LPPermissible) permissible);
|
||||
List<PermissionAttachment> attachments = lpp.getAttachments();
|
||||
|
||||
PermissibleBase newPb = lpp.getOldPermissible();
|
||||
if (newPb == null) {
|
||||
newPb = new PermissibleBase(player);
|
||||
}
|
||||
|
||||
List<PermissionAttachment> newAttachments = (List<PermissionAttachment>) PERMISSIBLEBASE_ATTACHMENTS.get(newPb);
|
||||
newAttachments.addAll(attachments);
|
||||
attachments.clear();
|
||||
|
||||
HUMAN_ENTITY_FIELD.set(player, newPb);
|
||||
}
|
||||
}
|
||||
INJECTED_PERMISSIBLES.remove(player.getUniqueId());
|
||||
return true;
|
||||
|
||||
@@ -99,7 +99,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(p.name(), p.isTrue(), "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + p.name() + " " + p.isTrue() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -113,7 +113,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(child.getKey(), child.getValue(), "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + child.getKey() + " " + child.getValue() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -129,7 +129,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission("group." + parent.getName(), true, "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("setinherit " + parent.getName() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -146,7 +146,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(meta.getKey().toLowerCase() + "." + c.getPriority() + "." + chatMeta, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + meta.getKey().toLowerCase() + "." + c.getPriority() + "." + chatMeta + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -160,7 +160,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission("meta." + meta.getKey() + "." + meta.getValue(), true, "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set meta." + meta.getKey() + "." + meta.getValue() + " true global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -215,7 +215,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
me.lucko.luckperms.common.core.model.Group lpGroup = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
|
||||
@@ -81,7 +81,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(g.getName().toLowerCase());
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -101,7 +101,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission(node, value);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set " + node + " " + value)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -115,7 +115,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission("group." + s.toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("setinherit " + s.toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -204,7 +204,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(e.getKey());
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -222,12 +222,12 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
if (n.getKey().getValue().startsWith("group.")) {
|
||||
String groupName = n.getKey().getValue().substring(6);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("setinherit " + groupName + " global " + n.getKey().getKey())
|
||||
.build().submit(plugin);
|
||||
} else {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set " + n.getKey().getValue() + " " + n.getValue() + " global " + n.getKey().getKey())
|
||||
.build().submit(plugin);
|
||||
}
|
||||
@@ -256,12 +256,12 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
if (n.getKey().getValue().startsWith("group.")) {
|
||||
String group = n.getKey().getValue().substring(6);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + group + " global " + n.getKey().getKey())
|
||||
.build().submit(plugin);
|
||||
} else {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set " + n.getKey().getValue() + " " + n.getValue() + " global " + n.getKey().getKey())
|
||||
.build().submit(plugin);
|
||||
}
|
||||
|
||||
+19
-19
@@ -39,17 +39,17 @@ import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ru.tehkode.permissions.NativeInterface;
|
||||
import ru.tehkode.permissions.PermissionGroup;
|
||||
import ru.tehkode.permissions.PermissionManager;
|
||||
import ru.tehkode.permissions.PermissionUser;
|
||||
import ru.tehkode.permissions.bukkit.PermissionsEx;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
public MigrationPermissionsEx() {
|
||||
super("permissionsex", "Migration from PermissionsEx", Permission.MIGRATION, Predicates.alwaysFalse(),
|
||||
@@ -105,7 +105,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
Group lpGroup = plugin.getGroupManager().getIfLoaded(name);
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -123,7 +123,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission(node, value);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("set " + node + " " + value)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -148,7 +148,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission(node, value, "global", world);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("set " + node + " " + value + " global " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -164,7 +164,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission("group." + g.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("setinherit " + g.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -180,7 +180,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission("group." + g.getName().toLowerCase(), true, "global", world);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("setinherit " + g.getName().toLowerCase() + " global " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -200,7 +200,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission("prefix." + groupWeight + "." + prefix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("set prefix." + groupWeight + "." + prefix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -215,7 +215,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission("suffix." + groupWeight + "." + suffix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("set suffix." + groupWeight + "." + suffix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -253,7 +253,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
userCount++;
|
||||
plugin.getStorage().loadUser(u, "null").join();
|
||||
plugin.getStorage().loadUser(u, user.getName()).join();
|
||||
User lpUser = plugin.getUserManager().get(u);
|
||||
|
||||
try {
|
||||
@@ -267,7 +267,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission(node, value);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("set " + node + " " + value)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -292,7 +292,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission(node, value, "global", world);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("set " + node + " " + value + " global " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -308,7 +308,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission("group." + s.toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("addgroup " + s.toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -324,7 +324,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission("group." + s.toLowerCase(), true, "global", world);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("addgroup " + s.toLowerCase() + " global " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -344,7 +344,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission("prefix." + maxGroupWeight + "." + prefix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("set prefix." + maxGroupWeight + "." + prefix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -359,7 +359,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission("suffix." + maxGroupWeight + "." + suffix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("set suffix." + maxGroupWeight + "." + suffix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
|
||||
+14
-14
@@ -271,7 +271,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
final me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(g.getName().toLowerCase());
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -286,7 +286,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission("group." + parent.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("setinherit " + parent.getName().toLowerCase()) // All versions
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -353,7 +353,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -365,7 +365,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -386,7 +386,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -398,7 +398,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -413,7 +413,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -425,7 +425,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -549,7 +549,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value, server, world);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + node + " " + value + " " + server + " " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -561,7 +561,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value, server, world, expireAt);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("settemp " + node + " " + value + " " + expireAt + " " + server + " " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -576,7 +576,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + node + " " + value + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -588,7 +588,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value, server, expireAt);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("settemp " + node + " " + value + " " + expireAt + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -602,7 +602,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + node + " " + value)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -614,7 +614,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value, expireAt);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("settemp " + node + " " + value + " " + expireAt)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
|
||||
+24
-11
@@ -42,6 +42,7 @@ import org.tyrannyofheaven.bukkit.zPermissions.dao.PermissionService;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.EntityMetadata;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.Entry;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.Inheritance;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.Membership;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.PermissionEntity;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@@ -49,6 +50,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MigrationZPermissions extends SubCommand<Object> {
|
||||
|
||||
public MigrationZPermissions() {
|
||||
super("zpermissions", "Migration from zPermissions", Permission.MIGRATION, Predicates.alwaysFalse(), null);
|
||||
}
|
||||
@@ -85,7 +87,7 @@ public class MigrationZPermissions extends SubCommand<Object> {
|
||||
Group group = plugin.getGroupManager().getIfLoaded(g.toLowerCase());
|
||||
|
||||
PermissionEntity entity = internalService.getEntity(g, null, true);
|
||||
migrateEntity(group, entity);
|
||||
migrateEntity(group, entity, null);
|
||||
|
||||
plugin.getStorage().saveGroup(group);
|
||||
}
|
||||
@@ -106,10 +108,14 @@ public class MigrationZPermissions extends SubCommand<Object> {
|
||||
User user = plugin.getUserManager().get(u);
|
||||
|
||||
PermissionEntity entity = internalService.getEntity(null, u, false);
|
||||
migrateEntity(user, entity);
|
||||
migrateEntity(user, entity, internalService.getGroups(u));
|
||||
|
||||
user.setPrimaryGroup(service.getPlayerPrimaryGroup(u));
|
||||
|
||||
if (!entity.isGroup()) {
|
||||
user.setName(entity.getDisplayName());
|
||||
}
|
||||
|
||||
plugin.getUserManager().cleanup(user);
|
||||
plugin.getStorage().saveUser(user);
|
||||
}
|
||||
@@ -118,7 +124,7 @@ public class MigrationZPermissions extends SubCommand<Object> {
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private void migrateEntity(PermissionHolder group, PermissionEntity entity) {
|
||||
private void migrateEntity(PermissionHolder group, PermissionEntity entity, List<Membership> memberships) {
|
||||
for (Entry e : entity.getPermissions()) {
|
||||
if (e.getWorld() != null) {
|
||||
try {
|
||||
@@ -133,15 +139,22 @@ public class MigrationZPermissions extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
for (Inheritance inheritance : entity.getInheritancesAsChild()) {
|
||||
if (!inheritance.getChild().getId().equals(entity.getId())) {
|
||||
new Throwable("Illegal inheritance").printStackTrace();
|
||||
continue;
|
||||
if (entity.isGroup()) {
|
||||
for (Inheritance inheritance : entity.getInheritancesAsChild()) {
|
||||
try {
|
||||
if (!inheritance.getParent().getName().equals(group.getObjectName())) {
|
||||
group.setPermission("group." + inheritance.getParent().getName(), true);
|
||||
}
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
group.setPermission("group." + inheritance.getParent(), true);
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
} else {
|
||||
// entity.getMemberships() doesn't work (always returns 0 records)
|
||||
for (Membership membership : memberships) {
|
||||
try {
|
||||
group.setPermission("group." + membership.getGroup().getDisplayName(), true);
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ public class DefaultsProvider {
|
||||
@Getter
|
||||
private Map<String, Boolean> opDefaults = ImmutableMap.of();
|
||||
private final DummyPermissible opDummy = new DummyPermissible(this::refreshOp);
|
||||
|
||||
@Getter
|
||||
private Map<String, Boolean> nonOpDefaults = ImmutableMap.of();
|
||||
private final DummyPermissible nonOpDummy = new DummyPermissible(this::refreshNonOp);
|
||||
@@ -111,6 +112,11 @@ public class DefaultsProvider {
|
||||
nonOpDefaults = ImmutableMap.copyOf(builder);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
unregisterDefaults(opDefaults, opDummy);
|
||||
unregisterDefaults(nonOpDefaults, nonOpDummy);
|
||||
}
|
||||
|
||||
public Tristate hasDefault(String permission, boolean isOp) {
|
||||
Map<String, Boolean> map = isOp ? opDefaults : nonOpDefaults;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ package me.lucko.luckperms.bukkit.model;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
@@ -39,12 +40,13 @@ import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.permissions.PermissionRemovedExecutor;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -59,22 +61,62 @@ public class LPPermissible extends PermissibleBase {
|
||||
@Getter
|
||||
private final Player parent;
|
||||
|
||||
@Getter
|
||||
private final LPBukkitPlugin plugin;
|
||||
|
||||
@Getter
|
||||
private final SubscriptionManager subscriptions;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private PermissibleBase oldPermissible = null;
|
||||
|
||||
// Attachment stuff.
|
||||
@Getter
|
||||
private final Map<String, PermissionAttachmentInfo> attachmentPermissions = new HashMap<>();
|
||||
private final List<PermissionAttachment> attachments = new LinkedList<>();
|
||||
private final Map<String, PermissionAttachmentInfo> attachmentPermissions = new ConcurrentHashMap<>();
|
||||
@Getter
|
||||
private final List<PermissionAttachment> attachments = Collections.synchronizedList(new LinkedList<>());
|
||||
|
||||
public LPPermissible(@NonNull Player parent, User user, LPBukkitPlugin plugin) {
|
||||
super(parent);
|
||||
this.user = user;
|
||||
this.parent = parent;
|
||||
this.plugin = plugin;
|
||||
this.subscriptions = new SubscriptionManager(this);
|
||||
|
||||
recalculatePermissions();
|
||||
}
|
||||
|
||||
public void updateSubscriptionsAsync() {
|
||||
plugin.doAsync(this::updateSubscriptions);
|
||||
}
|
||||
|
||||
public void updateSubscriptions() {
|
||||
Set<String> ent = new HashSet<>(user.getUserData().getPermissionData(calculateContexts()).getImmutableBacking().keySet());
|
||||
|
||||
if (parent.isOp()) {
|
||||
ent.addAll(plugin.getDefaultsProvider().getOpDefaults().keySet());
|
||||
} else {
|
||||
ent.addAll(plugin.getDefaultsProvider().getNonOpDefaults().keySet());
|
||||
}
|
||||
|
||||
subscriptions.subscribe(ent);
|
||||
}
|
||||
|
||||
public void unsubscribeFromAllAsync() {
|
||||
plugin.doAsync(this::unsubscribeFromAll);
|
||||
}
|
||||
|
||||
public void unsubscribeFromAll() {
|
||||
subscriptions.subscribe(Collections.emptySet());
|
||||
}
|
||||
|
||||
public void addAttachments(List<PermissionAttachment> attachments) {
|
||||
for (PermissionAttachment attachment : attachments) {
|
||||
this.attachments.add(attachment);
|
||||
}
|
||||
}
|
||||
|
||||
public Contexts calculateContexts() {
|
||||
return new Contexts(
|
||||
plugin.getContextManager().getApplicableContext(parent),
|
||||
@@ -195,7 +237,7 @@ public class LPPermissible extends PermissibleBase {
|
||||
}
|
||||
|
||||
PermissionAttachment result = addAttachment(plugin);
|
||||
if (Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> result.remove(), ticks) == -1) {
|
||||
if (Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, result::remove, ticks) == -1) {
|
||||
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add PermissionAttachment to " + parent + " for plugin " + plugin.getDescription().getFullName() + ": Scheduler returned -1");
|
||||
result.remove();
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.bukkit.model;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SubscriptionManager {
|
||||
|
||||
private final LPPermissible permissible;
|
||||
private Set<String> currentSubscriptions = ImmutableSet.of();
|
||||
|
||||
public synchronized void subscribe(Set<String> perms) {
|
||||
Set<String> newPerms = ImmutableSet.copyOf(perms);
|
||||
|
||||
Map.Entry<Set<String>, Set<String>> changes = compareSets(newPerms, currentSubscriptions);
|
||||
|
||||
Set<String> toAdd = changes.getKey();
|
||||
Set<String> toRemove = changes.getValue();
|
||||
|
||||
permissible.getPlugin().doSync(() -> {
|
||||
for (String s : toAdd) {
|
||||
permissible.getPlugin().getServer().getPluginManager().subscribeToPermission(s, permissible.getParent());
|
||||
}
|
||||
for (String s : toRemove) {
|
||||
permissible.getPlugin().getServer().getPluginManager().unsubscribeFromPermission(s, permissible.getParent());
|
||||
}
|
||||
});
|
||||
|
||||
this.currentSubscriptions = newPerms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two sets
|
||||
* @param local the local set
|
||||
* @param remote the remote set
|
||||
* @return the entries to add to remote, and the entries to remove from remote
|
||||
*/
|
||||
private static Map.Entry<Set<String>, Set<String>> compareSets(Set<String> local, Set<String> remote) {
|
||||
// entries in local but not remote need to be added
|
||||
// entries in remote but not local need to be removed
|
||||
|
||||
Set<String> toAdd = new HashSet<>(local);
|
||||
toAdd.removeAll(remote);
|
||||
|
||||
Set<String> toRemove = new HashSet<>(remote);
|
||||
toRemove.removeAll(local);
|
||||
|
||||
return Maps.immutableEntry(toAdd, toRemove);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -60,7 +60,7 @@ import static me.lucko.luckperms.api.MetaUtils.unescapeCharacters;
|
||||
* Normal inheritance rules DO NOT apply.
|
||||
* Permission Nodes = meta.node.value
|
||||
*
|
||||
* Node that special characters used within LuckPerms are escaped:
|
||||
* Note that special characters used within LuckPerms are escaped:
|
||||
* See {@link me.lucko.luckperms.api.MetaUtils#unescapeCharacters(String)}
|
||||
*/
|
||||
public class VaultChatHook extends Chat {
|
||||
@@ -86,7 +86,7 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
perms.log("Setting meta: '" + node + "' for " + holder.getObjectName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
perms.getScheduler().scheduleTask(() -> {
|
||||
perms.getScheduler().execute(() -> {
|
||||
List<Node> toRemove = holder.getNodes().stream()
|
||||
.filter(n -> n.isMeta() && n.getMeta().getKey().equals(node))
|
||||
.collect(Collectors.toList());
|
||||
@@ -122,7 +122,7 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
perms.log("Setting " + (prefix ? "prefix" : "suffix") + " for " + holder.getObjectName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
perms.getScheduler().scheduleTask(() -> {
|
||||
perms.getScheduler().execute(() -> {
|
||||
Node.Builder node = new NodeBuilder((prefix ? "prefix" : "suffix") + ".1000." + escapeCharacters(value));
|
||||
node.setValue(true);
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
@@ -153,7 +153,7 @@ public class VaultChatHook extends Chat {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return unescapeCharacters(user.getUserData().getMetaData(perms.createContext(perms.getServer(), world)).getMeta().getOrDefault(node, defaultValue));
|
||||
return unescapeCharacters(user.getUserData().getMetaData(perms.createContextForWorld(world)).getMeta().getOrDefault(node, defaultValue));
|
||||
}
|
||||
|
||||
private String getUserChatMeta(boolean prefix, User user, String world) {
|
||||
@@ -166,7 +166,7 @@ public class VaultChatHook extends Chat {
|
||||
return "";
|
||||
}
|
||||
|
||||
MetaData data = user.getUserData().getMetaData(perms.createContext(perms.getServer(), world));
|
||||
MetaData data = user.getUserData().getMetaData(perms.createContextForWorld(world));
|
||||
String v = prefix ? data.getPrefix() : data.getSuffix();
|
||||
return v == null ? "" : unescapeCharacters(v);
|
||||
}
|
||||
@@ -270,7 +270,7 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public String getGroupPrefix(String world, @NonNull String group) {
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
return getGroupChatMeta(false, g, world);
|
||||
return getGroupChatMeta(true, g, world);
|
||||
}
|
||||
|
||||
public void setGroupPrefix(String world, @NonNull String group, @NonNull String prefix) {
|
||||
|
||||
@@ -32,6 +32,9 @@ import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.ServicesManager;
|
||||
|
||||
/**
|
||||
* Handles hooking with the Vault API
|
||||
*/
|
||||
@Getter
|
||||
public class VaultHook {
|
||||
private VaultChatHook chatHook = null;
|
||||
@@ -40,17 +43,8 @@ public class VaultHook {
|
||||
public void hook(LPBukkitPlugin plugin) {
|
||||
try {
|
||||
if (permissionHook == null) {
|
||||
permissionHook = new VaultPermissionHook();
|
||||
permissionHook = new VaultPermissionHook(plugin);
|
||||
}
|
||||
permissionHook.setPlugin(plugin);
|
||||
permissionHook.setServer(plugin.getConfiguration().getVaultServer());
|
||||
permissionHook.setIncludeGlobal(plugin.getConfiguration().isVaultIncludingGlobal());
|
||||
permissionHook.setIgnoreWorld(plugin.getConfiguration().isVaultIgnoreWorld());
|
||||
permissionHook.setPgo(plugin.getConfiguration().isVaultPrimaryGroupOverrides());
|
||||
permissionHook.setPgoCheckInherited(plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckInherited());
|
||||
permissionHook.setPgoCheckExists(plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckExists());
|
||||
permissionHook.setPgoCheckMemberOf(plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckMemberOf());
|
||||
permissionHook.setup();
|
||||
|
||||
if (chatHook == null) {
|
||||
chatHook = new VaultChatHook(permissionHook);
|
||||
@@ -69,9 +63,12 @@ public class VaultHook {
|
||||
final ServicesManager sm = plugin.getServer().getServicesManager();
|
||||
if (permissionHook != null) {
|
||||
sm.unregister(Permission.class, permissionHook);
|
||||
permissionHook.getScheduler().cancelTask();
|
||||
permissionHook = null;
|
||||
}
|
||||
if (chatHook != null) {
|
||||
sm.unregister(Chat.class, chatHook);
|
||||
chatHook = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,8 @@
|
||||
|
||||
package me.lucko.luckperms.bukkit.vault;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
@@ -44,31 +42,44 @@ import net.milkbowl.vault.permission.Permission;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* The LuckPerms Vault Permission implementation
|
||||
* Most lookups are cached.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class VaultPermissionHook extends Permission {
|
||||
private LPBukkitPlugin plugin;
|
||||
|
||||
@Setter(value = AccessLevel.NONE)
|
||||
private VaultScheduler scheduler;
|
||||
|
||||
private final String name = "LuckPerms";
|
||||
|
||||
private String server = "global";
|
||||
private boolean includeGlobal = true;
|
||||
private boolean ignoreWorld = false;
|
||||
|
||||
// Primary Group override settings
|
||||
private boolean pgo = false;
|
||||
private boolean pgoCheckInherited = false;
|
||||
private boolean pgoCheckExists = true;
|
||||
private boolean pgoCheckMemberOf = true;
|
||||
|
||||
public void setup() {
|
||||
scheduler = new VaultScheduler(plugin);
|
||||
private Function<String, String> WORLD_CORRECTION_FUNCTION = s -> ignoreWorld ? null : s;
|
||||
|
||||
public VaultPermissionHook(LPBukkitPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.scheduler = new VaultScheduler(plugin);
|
||||
|
||||
super.plugin = plugin;
|
||||
|
||||
// Config options
|
||||
this.server = plugin.getConfiguration().getVaultServer();
|
||||
this.includeGlobal = plugin.getConfiguration().isVaultIncludingGlobal();
|
||||
this.ignoreWorld = plugin.getConfiguration().isVaultIgnoreWorld();
|
||||
this.pgo = plugin.getConfiguration().isVaultPrimaryGroupOverrides();
|
||||
this.pgoCheckInherited = plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckInherited();
|
||||
this.pgoCheckExists = plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckExists();
|
||||
this.pgoCheckMemberOf = plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckMemberOf();
|
||||
}
|
||||
|
||||
public void log(String s) {
|
||||
@@ -77,14 +88,9 @@ public class VaultPermissionHook extends Permission {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "LuckPerms";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return plugin.getStorage().isAcceptingLogins();
|
||||
return plugin.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,17 +105,18 @@ public class VaultPermissionHook extends Permission {
|
||||
* @param holder the holder to add the permission to
|
||||
* @param permission the permission to add
|
||||
*/
|
||||
private void add(String world, PermissionHolder holder, String permission) {
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
holder.setPermission(permission, true, server, world);
|
||||
} else {
|
||||
holder.setPermission(permission, true, server);
|
||||
}
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
}
|
||||
private CompletableFuture<Void> add(String world, PermissionHolder holder, String permission) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
if (world != null && !world.equals("") && !world.equalsIgnoreCase("global")) {
|
||||
holder.setPermission(permission, true, server, world);
|
||||
} else {
|
||||
holder.setPermission(permission, true, server);
|
||||
}
|
||||
|
||||
save(holder);
|
||||
save(holder);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
}, scheduler);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,36 +126,37 @@ public class VaultPermissionHook extends Permission {
|
||||
* @param holder the holder to remove the permission from
|
||||
* @param permission the permission to remove
|
||||
*/
|
||||
private void remove(String world, PermissionHolder holder, String permission) {
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
holder.unsetPermission(permission, server, world);
|
||||
} else {
|
||||
holder.unsetPermission(permission, server);
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {
|
||||
}
|
||||
private CompletableFuture<Void> remove(String world, PermissionHolder holder, String permission) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
if (world != null && !world.equals("") && !world.equalsIgnoreCase("global")) {
|
||||
holder.unsetPermission(permission, server, world);
|
||||
} else {
|
||||
holder.unsetPermission(permission, server);
|
||||
}
|
||||
|
||||
save(holder);
|
||||
save(holder);
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
}, scheduler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for saving a user or group
|
||||
* Utility method to asynchronously save a user or group
|
||||
*
|
||||
* @param holder the holder instance
|
||||
*/
|
||||
void save(PermissionHolder holder) {
|
||||
public void save(PermissionHolder holder) {
|
||||
if (holder instanceof User) {
|
||||
plugin.getStorage().saveUser(((User) holder))
|
||||
.thenRunAsync(() -> ((User) holder).getRefreshBuffer().request(), plugin.getAsyncExecutor());
|
||||
User u = (User) holder;
|
||||
plugin.getStorage().saveUser(u).thenRunAsync(() -> u.getRefreshBuffer().request(), plugin.getAsyncExecutor());
|
||||
}
|
||||
if (holder instanceof Group) {
|
||||
plugin.getStorage().saveGroup(((Group) holder))
|
||||
.thenRunAsync(() -> plugin.getUpdateTaskBuffer().request(), plugin.getAsyncExecutor());
|
||||
Group g = (Group) holder;
|
||||
plugin.getStorage().saveGroup(g).thenRunAsync(() -> plugin.getUpdateTaskBuffer().request(), plugin.getAsyncExecutor());
|
||||
}
|
||||
}
|
||||
|
||||
Contexts createContext(String server, String world) {
|
||||
public Contexts createContextForWorld(String world) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
if (world != null && !world.equals("")) {
|
||||
context.put("world", world);
|
||||
@@ -159,7 +167,7 @@ public class VaultPermissionHook extends Permission {
|
||||
|
||||
@Override
|
||||
public boolean playerHas(String world, @NonNull String player, @NonNull String permission) {
|
||||
world = ignoreWorld ? null : world; // Correct world value
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Checking if player " + player + " has permission: " + permission + " on world " + world + ", server " + server);
|
||||
|
||||
User user = plugin.getUserManager().getByUsername(player);
|
||||
@@ -170,92 +178,91 @@ public class VaultPermissionHook extends Permission {
|
||||
}
|
||||
|
||||
// Effectively fallback to the standard Bukkit #hasPermission check.
|
||||
return user.getUserData().getPermissionData(createContext(server, world)).getPermissionValue(permission).asBoolean();
|
||||
return user.getUserData().getPermissionData(createContextForWorld(world)).getPermissionValue(permission).asBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerAdd(String world, @NonNull String player, @NonNull String permission) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Adding permission to player " + player + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Adding permission to player " + player + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> add(finalWorld, user, permission));
|
||||
add(world, user, permission);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerRemove(String world, @NonNull String player, @NonNull String permission) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Removing permission from player " + player + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Removing permission from player " + player + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> remove(finalWorld, user, permission));
|
||||
remove(world, user, permission);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean groupHas(String world, @NonNull String groupName, @NonNull String permission) {
|
||||
world = ignoreWorld ? null : world; // Correct world value
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Checking if group " + groupName + " has permission: " + permission + " on world " + world + ", server " + server);
|
||||
|
||||
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
// This is a nasty call. Groups aren't cached. :(
|
||||
Map<String, Boolean> permissions = group.exportNodes(createContext(server, world), true);
|
||||
|
||||
return permissions.containsKey(permission) && permissions.get(permission);
|
||||
Map<String, Boolean> permissions = group.exportNodes(createContextForWorld(world), true);
|
||||
return permissions.containsKey(permission.toLowerCase()) && permissions.get(permission.toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean groupAdd(String world, @NonNull String groupName, @NonNull String permission) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Adding permission to group " + groupName + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Adding permission to group " + groupName + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
|
||||
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> add(finalWorld, group, permission));
|
||||
add(world, group, permission);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean groupRemove(String world, @NonNull String groupName, @NonNull String permission) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Removing permission from group " + groupName + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Removing permission from group " + groupName + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
|
||||
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> remove(finalWorld, group, permission));
|
||||
remove(world, group, permission);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerInGroup(String world, @NonNull String player, @NonNull String group) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Checking if player " + player + " is in group: " + group + " on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Checking if player " + player + " is in group: " + group + " on world " + world + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
|
||||
String w = world; // screw effectively final
|
||||
return user.getNodes().stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.filter(n -> n.shouldApplyOnServer(server, isIncludeGlobal(), false))
|
||||
.filter(n -> n.shouldApplyOnWorld(finalWorld, true, false))
|
||||
.filter(n -> n.shouldApplyOnWorld(w, true, false))
|
||||
.map(Node::getGroupName)
|
||||
.filter(s -> s.equalsIgnoreCase(group))
|
||||
.findAny().isPresent();
|
||||
.anyMatch(s -> s.equalsIgnoreCase(group));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerAddGroup(String world, @NonNull String player, @NonNull String groupName) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Adding player " + player + " to group: '" + groupName + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Adding player " + player + " to group: '" + groupName + "' on world " + world + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
@@ -263,24 +270,25 @@ public class VaultPermissionHook extends Permission {
|
||||
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> {
|
||||
String w = world;
|
||||
scheduler.execute(() -> {
|
||||
try {
|
||||
if (finalWorld != null && !finalWorld.equals("")) {
|
||||
user.setInheritGroup(group, server, finalWorld);
|
||||
if (w != null && !w.equals("") && !w.equalsIgnoreCase("global")) {
|
||||
user.setInheritGroup(group, server, w);
|
||||
} else {
|
||||
user.setInheritGroup(group, server);
|
||||
}
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
}
|
||||
save(user);
|
||||
|
||||
save(user);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerRemoveGroup(String world, @NonNull String player, @NonNull String groupName) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Removing player " + player + " from group: '" + groupName + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Removing player " + player + " from group: '" + groupName + "' on world " + world + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
@@ -288,39 +296,41 @@ public class VaultPermissionHook extends Permission {
|
||||
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> {
|
||||
String w = world;
|
||||
scheduler.execute(() -> {
|
||||
try {
|
||||
if (finalWorld != null && !finalWorld.equals("")) {
|
||||
user.unsetInheritGroup(group, server, finalWorld);
|
||||
if (w != null && !w.equals("") && !w.equalsIgnoreCase("global")) {
|
||||
user.unsetInheritGroup(group, server, w);
|
||||
} else {
|
||||
user.unsetInheritGroup(group, server);
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {
|
||||
}
|
||||
save(user);
|
||||
|
||||
save(user);
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getPlayerGroups(String world, @NonNull String player) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Getting groups of player: " + player + ", on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Getting groups of player: " + player + ", on world " + world + ", server " + server);
|
||||
|
||||
User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return new String[0];
|
||||
|
||||
String w = world; // screw effectively final
|
||||
return user.getNodes().stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.filter(n -> n.shouldApplyOnServer(server, isIncludeGlobal(), false))
|
||||
.filter(n -> n.shouldApplyOnWorld(finalWorld, true, false))
|
||||
.filter(n -> n.shouldApplyOnWorld(w, true, false))
|
||||
.map(Node::getGroupName)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryGroup(String world, @NonNull String player) {
|
||||
world = ignoreWorld ? null : world; // Correct world value
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Getting primary group of player: " + player);
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
|
||||
@@ -329,11 +339,12 @@ public class VaultPermissionHook extends Permission {
|
||||
}
|
||||
|
||||
if (!pgo) {
|
||||
return user.getPrimaryGroup();
|
||||
String g = user.getPrimaryGroup();
|
||||
return plugin.getConfiguration().getGroupNameRewrites().getOrDefault(g, g);
|
||||
}
|
||||
|
||||
if (pgoCheckInherited) {
|
||||
PermissionData data = user.getUserData().getPermissionData(createContext(server, world));
|
||||
PermissionData data = user.getUserData().getPermissionData(createContextForWorld(world));
|
||||
for (Map.Entry<String, Boolean> e : data.getImmutableBacking().entrySet()) {
|
||||
if (!e.getValue()) {
|
||||
continue;
|
||||
@@ -394,7 +405,8 @@ public class VaultPermissionHook extends Permission {
|
||||
}
|
||||
|
||||
// Fallback
|
||||
return user.getPrimaryGroup();
|
||||
String g = user.getPrimaryGroup();
|
||||
return plugin.getConfiguration().getGroupNameRewrites().getOrDefault(g, g);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,17 +24,26 @@ package me.lucko.luckperms.bukkit.vault;
|
||||
|
||||
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
|
||||
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public class VaultScheduler implements Runnable {
|
||||
/**
|
||||
* Sequential executor for Vault modifications
|
||||
*/
|
||||
public class VaultScheduler implements Runnable, Executor {
|
||||
|
||||
private BukkitTask task = null;
|
||||
private final List<Runnable> tasks = new ArrayList<>();
|
||||
|
||||
public VaultScheduler(LPBukkitPlugin plugin) {
|
||||
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this, 1L, 1L);
|
||||
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this, 1L, 1L);
|
||||
}
|
||||
|
||||
public void scheduleTask(Runnable r) {
|
||||
@Override
|
||||
public void execute(Runnable r) {
|
||||
synchronized (tasks) {
|
||||
tasks.add(r);
|
||||
}
|
||||
@@ -42,12 +51,24 @@ public class VaultScheduler implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<Runnable> toRun = new ArrayList<>();
|
||||
List<Runnable> toRun;
|
||||
synchronized (tasks) {
|
||||
if (tasks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
toRun = new ArrayList<>();
|
||||
toRun.addAll(tasks);
|
||||
tasks.clear();
|
||||
}
|
||||
|
||||
toRun.forEach(Runnable::run);
|
||||
}
|
||||
|
||||
public void cancelTask() {
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
task = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,8 +148,8 @@ group-name-rewrite:
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL or MongoDB
|
||||
# Currently supported: mysql, postgresql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL, PostgreSQL or MongoDB
|
||||
storage-method: h2
|
||||
|
||||
# This block enables support for split datastores.
|
||||
@@ -163,12 +163,20 @@ split-storage:
|
||||
log: h2
|
||||
|
||||
data:
|
||||
address: localhost:3306
|
||||
# Uses standard DB engine port by default
|
||||
# MySQL: 3306, PostgreSQL: 5432, MongoDB: 27017
|
||||
# Specify as "host:port" if differs
|
||||
address: localhost
|
||||
|
||||
database: minecraft
|
||||
username: root
|
||||
password: ''
|
||||
pool-size: 10 # The size of the MySQL connection pool.
|
||||
|
||||
# The prefix for all LuckPerms tables. Change this is you want to use different tables for different servers.
|
||||
# This should *not* be set to "lp_" if you have previously ran LuckPerms v2.16.81 or earlier with this database.
|
||||
table_prefix: 'luckperms_'
|
||||
|
||||
# Set to -1 to disable. If this is the only instance accessing the datastore, you can disable syncing.
|
||||
# e.g. if you're using sqlite or flatfile, this can be set to -1 to save resources.
|
||||
sync-minutes: 3
|
||||
@@ -181,9 +189,11 @@ data:
|
||||
#
|
||||
# If you decide to enable this feature, you should set "sync-minutes" to -1, as there is no need for LuckPerms
|
||||
# to poll the database for changes.
|
||||
#
|
||||
# Port 6379 is used by default; set address to "host:port" if differs
|
||||
redis:
|
||||
enabled: false
|
||||
address: localhost:6379
|
||||
address: localhost
|
||||
password: ''
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ loadbefore: [Vault]
|
||||
commands:
|
||||
luckperms:
|
||||
description: Manage permissions
|
||||
aliases: [perms, permissions, lp, p, perm]
|
||||
aliases: [perms, permissions, lp, perm]
|
||||
|
||||
|
||||
# Permissions are registered programmatically instead of here.
|
||||
|
||||
+11
-36
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.16-SNAPSHOT</version>
|
||||
<version>2.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<finalName>LuckPermsBungee-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<finalName>LuckPerms-Bungee-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
@@ -46,40 +46,8 @@
|
||||
<minimizeJar>false</minimizeJar>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.slf4j</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.slf4j</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.zaxxer.hikari</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.hikari</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.mongodb</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.mongodb</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bson</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.bson</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.h2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.h2</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.sqlite</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.sqlite</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.jedis</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.jedis</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.util</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.util</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.apache.commons.pool2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.pool2</shadedPattern>
|
||||
<pattern>io.github.mkremins.fanciful</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.fanciful</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
@@ -126,6 +94,13 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- slf4j library -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.9</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
|
||||
@@ -50,8 +50,7 @@ class BungeeCommand extends Command implements TabExecutor {
|
||||
manager.onCommand(
|
||||
plugin.getSenderFactory().wrap(sender),
|
||||
"bperms",
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))),
|
||||
null
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -108,8 +108,8 @@ public class BungeeListener extends AbstractListener implements Listener {
|
||||
plugin.getStorage().force().saveUUIDData(c.getName(), c.getUniqueId()).join();
|
||||
}
|
||||
} else {
|
||||
UUID uuid = plugin.getStorage().getUUID(c.getName()).join();
|
||||
if (uuid == null) {
|
||||
String name = plugin.getStorage().getName(c.getUniqueId()).join();
|
||||
if (name == null) {
|
||||
plugin.getApiProvider().fireEventAsync(new UserFirstLoginEvent(c.getUniqueId(), c.getName()));
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@ import me.lucko.luckperms.common.constants.Constants;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
|
||||
import io.github.mkremins.fanciful.FancyMessage;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -42,7 +45,7 @@ public class BungeeSenderFactory extends SenderFactory<CommandSender> {
|
||||
if (sender instanceof ProxiedPlayer) {
|
||||
return sender.getName();
|
||||
}
|
||||
return Constants.getConsoleName();
|
||||
return Constants.CONSOLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,7 +53,7 @@ public class BungeeSenderFactory extends SenderFactory<CommandSender> {
|
||||
if (sender instanceof ProxiedPlayer) {
|
||||
return ((ProxiedPlayer) sender).getUniqueId();
|
||||
}
|
||||
return Constants.getConsoleUUID();
|
||||
return Constants.CONSOLE_UUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,6 +61,15 @@ public class BungeeSenderFactory extends SenderFactory<CommandSender> {
|
||||
sender.sendMessage(new TextComponent(s));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendMessage(CommandSender sender, FancyMessage message) {
|
||||
try {
|
||||
sender.sendMessage(ComponentSerializer.parse(message.toJSONString()));
|
||||
} catch (Exception e) {
|
||||
sendMessage(sender, message.toOldMessageFormat());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasPermission(CommandSender sender, String node) {
|
||||
return sender.hasPermission(node);
|
||||
|
||||
@@ -24,17 +24,17 @@ package me.lucko.luckperms.bungee;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import me.lucko.luckperms.ApiHandler;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.api.ApiHandler;
|
||||
import me.lucko.luckperms.common.api.ApiProvider;
|
||||
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.CommandManager;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.config.LPConfiguration;
|
||||
import me.lucko.luckperms.common.contexts.ContextManager;
|
||||
@@ -42,6 +42,7 @@ import me.lucko.luckperms.common.contexts.ServerCalculator;
|
||||
import me.lucko.luckperms.common.core.UuidCache;
|
||||
import me.lucko.luckperms.common.core.model.User;
|
||||
import me.lucko.luckperms.common.data.Importer;
|
||||
import me.lucko.luckperms.common.dependencies.DependencyManager;
|
||||
import me.lucko.luckperms.common.managers.GroupManager;
|
||||
import me.lucko.luckperms.common.managers.TrackManager;
|
||||
import me.lucko.luckperms.common.managers.UserManager;
|
||||
@@ -51,6 +52,8 @@ import me.lucko.luckperms.common.managers.impl.GenericUserManager;
|
||||
import me.lucko.luckperms.common.messaging.RedisMessaging;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
import me.lucko.luckperms.common.storage.StorageFactory;
|
||||
import me.lucko.luckperms.common.storage.StorageType;
|
||||
import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
|
||||
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.common.tasks.UpdateTask;
|
||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||
@@ -64,6 +67,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -87,8 +91,8 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
private ApiProvider apiProvider;
|
||||
private Logger log;
|
||||
private Importer importer;
|
||||
private ConsecutiveExecutor consecutiveExecutor;
|
||||
private LocaleManager localeManager;
|
||||
private CachedStateManager cachedStateManager;
|
||||
private ContextManager<ProxiedPlayer> contextManager;
|
||||
private CalculatorFactory calculatorFactory;
|
||||
private BufferedRequest<Void> updateTaskBuffer;
|
||||
@@ -100,18 +104,21 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
public void onEnable() {
|
||||
executor = r -> getProxy().getScheduler().runAsync(this, r);
|
||||
log = LogFactory.wrap(getLogger());
|
||||
debugHandler = new DebugHandler(executor);
|
||||
debugHandler = new DebugHandler(executor, getVersion());
|
||||
senderFactory = new BungeeSenderFactory(this);
|
||||
permissionCache = new PermissionCache(executor);
|
||||
|
||||
getLog().info("Loading configuration...");
|
||||
configuration = new BungeeConfig(this);
|
||||
|
||||
Set<StorageType> storageTypes = StorageFactory.getRequiredTypes(this, StorageType.H2);
|
||||
DependencyManager.loadDependencies(this, storageTypes);
|
||||
|
||||
// register events
|
||||
getProxy().getPluginManager().registerListener(this, new BungeeListener(this));
|
||||
|
||||
// initialise datastore
|
||||
storage = StorageFactory.getInstance(this, "h2");
|
||||
storage = StorageFactory.getInstance(this, StorageType.H2);
|
||||
|
||||
// initialise redis
|
||||
if (getConfiguration().isRedisEnabled()) {
|
||||
@@ -162,8 +169,8 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
groupManager = new GenericGroupManager(this);
|
||||
trackManager = new GenericTrackManager();
|
||||
importer = new Importer(commandManager);
|
||||
consecutiveExecutor = new ConsecutiveExecutor(commandManager);
|
||||
calculatorFactory = new BungeeCalculatorFactory(this);
|
||||
cachedStateManager = new CachedStateManager(this);
|
||||
|
||||
contextManager = new ContextManager<>();
|
||||
BackendServerCalculator serverCalculator = new BackendServerCalculator();
|
||||
@@ -187,7 +194,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
|
||||
// register tasks
|
||||
getProxy().getScheduler().schedule(this, new ExpireTemporaryTask(this), 3L, 3L, TimeUnit.SECONDS);
|
||||
getProxy().getScheduler().schedule(this, consecutiveExecutor, 1L, 1L, TimeUnit.SECONDS);
|
||||
getProxy().getScheduler().schedule(this, new CacheHousekeepingTask(this), 2L, 2L, TimeUnit.MINUTES);
|
||||
|
||||
getLog().info("Successfully loaded.");
|
||||
}
|
||||
@@ -216,11 +223,26 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
return PlatformType.BUNGEE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerName() {
|
||||
return getProxy().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerVersion() {
|
||||
return getProxy().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getMainDir() {
|
||||
return getDataFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getResourceStream(String path) {
|
||||
return getResourceAsStream(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxiedPlayer getPlayer(User user) {
|
||||
return getProxy().getPlayer(uuidCache.getExternalUUID(user.getUuid()));
|
||||
|
||||
+13
-13
@@ -73,7 +73,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(g.getName().toLowerCase());
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -86,7 +86,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission(perm, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set " + perm + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -102,7 +102,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission(perm, true, e.getKey());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set " + perm + " true " + e.getKey())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -118,7 +118,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission(perm, true, e.getKey(), we.getKey());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set " + perm + " true " + e.getKey() + " " + we.getKey())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -135,7 +135,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission("group." + inherit, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("setinherit " + group)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -154,7 +154,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission("prefix.50." + prefix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set prefix.50." + prefix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -169,7 +169,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission("suffix.50." + suffix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set suffix.50." + suffix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -201,7 +201,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission(perm, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set " + perm + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -217,7 +217,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission(perm, true, e.getKey());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set " + perm + " true " + e.getKey())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -233,7 +233,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission(perm, true, e.getKey(), we.getKey());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set " + perm + " true " + e.getKey() + " " + we.getKey())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -250,7 +250,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + group, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + group)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -269,7 +269,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("prefix.100." + prefix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set prefix.100." + prefix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -284,7 +284,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("suffix.100." + suffix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set suffix.100." + suffix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
|
||||
@@ -90,8 +90,8 @@ group-weight:
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL or MongoDB
|
||||
# Currently supported: mysql, postgresql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL, PostgreSQL or MongoDB
|
||||
storage-method: h2
|
||||
|
||||
# This block enables support for split datastores.
|
||||
@@ -105,12 +105,20 @@ split-storage:
|
||||
log: h2
|
||||
|
||||
data:
|
||||
address: localhost:3306
|
||||
# Uses standard DB engine port by default
|
||||
# MySQL: 3306, PostgreSQL: 5432, MongoDB: 27017
|
||||
# Specify as "host:port" if differs
|
||||
address: localhost
|
||||
|
||||
database: minecraft
|
||||
username: root
|
||||
password: ''
|
||||
pool-size: 10 # The size of the MySQL connection pool.
|
||||
|
||||
# The prefix for all LuckPerms tables. Change this is you want to use different tables for different servers.
|
||||
# This should *not* be set to "lp_" if you have previously ran LuckPerms v2.16.81 or earlier with this database.
|
||||
table_prefix: 'luckperms_'
|
||||
|
||||
# Set to -1 to disable. If this is the only instance accessing the datastore, you can disable syncing.
|
||||
# e.g. if you're using sqlite or flatfile, this can be set to -1 to save resources.
|
||||
sync-minutes: 3
|
||||
@@ -123,9 +131,11 @@ data:
|
||||
#
|
||||
# If you decide to enable this feature, you should set "sync-minutes" to -1, as there is no need for LuckPerms
|
||||
# to poll the database for changes.
|
||||
#
|
||||
# Port 6379 is used by default; set address to "host:port" if differs
|
||||
redis:
|
||||
enabled: false
|
||||
address: localhost:6379
|
||||
address: localhost
|
||||
password: ''
|
||||
|
||||
|
||||
|
||||
+28
-7
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.16-SNAPSHOT</version>
|
||||
<version>2.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -30,49 +30,70 @@
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<artifactId>luckperms-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- fanciful -->
|
||||
<dependency>
|
||||
<groupId>io.github.mkremins</groupId>
|
||||
<artifactId>fanciful</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- MySQL -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.40</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- HikariCP -->
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>2.5.1</version>
|
||||
<scope>compile</scope>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Jedis -->
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>2.8.1</version>
|
||||
<scope>compile</scope>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- SQLite -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.8.11.2</version>
|
||||
<scope>compile</scope>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- H2 -->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.192</version>
|
||||
<scope>compile</scope>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- PostgreSQL -->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>9.4.1212</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<scope>compile</scope>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- slf4j library -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.9</version>
|
||||
<scope>compile</scope>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- SnakeYAML -->
|
||||
<dependency>
|
||||
|
||||
@@ -26,9 +26,9 @@ import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.common.api.ApiProvider;
|
||||
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.BaseCommand;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.config.LPConfiguration;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
@@ -47,6 +47,7 @@ import me.lucko.luckperms.common.utils.LocaleManager;
|
||||
import me.lucko.luckperms.common.utils.PermissionCache;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -131,13 +132,6 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
Importer getImporter();
|
||||
|
||||
/**
|
||||
* Gets the consecutive command executor instance
|
||||
*
|
||||
* @return the consecutive executor
|
||||
*/
|
||||
ConsecutiveExecutor getConsecutiveExecutor();
|
||||
|
||||
/**
|
||||
* Gets the instance providing locale translations for the plugin
|
||||
*
|
||||
@@ -153,6 +147,13 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
ContextManager getContextManager();
|
||||
|
||||
/**
|
||||
* Gets the cached state manager for the platform.
|
||||
*
|
||||
* @return the cached state manager
|
||||
*/
|
||||
CachedStateManager getCachedStateManager();
|
||||
|
||||
/**
|
||||
* Gets the class responsible for constructing PermissionCalculators on this platform.
|
||||
*
|
||||
@@ -214,6 +215,18 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
PlatformType getType();
|
||||
|
||||
/**
|
||||
* Gets the name or "brand" of the running platform
|
||||
* @return the server brand
|
||||
*/
|
||||
String getServerName();
|
||||
|
||||
/**
|
||||
* Gets the version of the running platform
|
||||
* @return the server version
|
||||
*/
|
||||
String getServerVersion();
|
||||
|
||||
/**
|
||||
* Gets the plugins main directory
|
||||
*
|
||||
@@ -228,6 +241,14 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
File getDataFolder();
|
||||
|
||||
/**
|
||||
* Gets a bundled resource file from the jar
|
||||
*
|
||||
* @param path the path of the file
|
||||
* @return the file as an input stream
|
||||
*/
|
||||
InputStream getResourceStream(String path);
|
||||
|
||||
/**
|
||||
* Returns a colored string indicating the status of a player
|
||||
*
|
||||
@@ -366,4 +387,20 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
BufferedRequest<Void> getUpdateTaskBuffer();
|
||||
|
||||
/**
|
||||
* Called at the end of the sync task.
|
||||
*/
|
||||
default void onPostUpdate() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a users data is refreshed
|
||||
*
|
||||
* @param user the user
|
||||
*/
|
||||
default void onUserRefresh(User user) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.common.api;
|
||||
|
||||
import me.lucko.luckperms.LuckPerms;
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class ApiHandler {
|
||||
private static Method REGISTER;
|
||||
private static Method UNREGISTER;
|
||||
static {
|
||||
try {
|
||||
REGISTER = LuckPerms.class.getDeclaredMethod("registerProvider", LuckPermsApi.class);
|
||||
REGISTER.setAccessible(true);
|
||||
|
||||
UNREGISTER = LuckPerms.class.getDeclaredMethod("unregisterProvider");
|
||||
UNREGISTER.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerProvider(LuckPermsApi luckPermsApi) {
|
||||
try {
|
||||
REGISTER.invoke(null, luckPermsApi);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void unregisterProvider() {
|
||||
try {
|
||||
UNREGISTER.invoke(null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,24 +35,26 @@ import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
import me.lucko.luckperms.api.MessagingService;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.NodeFactory;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.Storage;
|
||||
import me.lucko.luckperms.api.Track;
|
||||
import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.api.UuidCache;
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.IContextCalculator;
|
||||
import me.lucko.luckperms.api.event.LPEvent;
|
||||
import me.lucko.luckperms.api.event.LPListener;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.api.internal.DatastoreLink;
|
||||
import me.lucko.luckperms.common.api.internal.GroupLink;
|
||||
import me.lucko.luckperms.common.api.internal.LPConfigurationLink;
|
||||
import me.lucko.luckperms.common.api.internal.StorageLink;
|
||||
import me.lucko.luckperms.common.api.internal.TrackLink;
|
||||
import me.lucko.luckperms.common.api.internal.UserLink;
|
||||
import me.lucko.luckperms.common.api.internal.Utils;
|
||||
import me.lucko.luckperms.common.api.internal.UuidCacheLink;
|
||||
import me.lucko.luckperms.common.api.delegate.DatastoreDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.GroupDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.LPConfigurationDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.NodeFactoryDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.StorageDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.TrackDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.UserDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.UuidCacheDelegate;
|
||||
import me.lucko.luckperms.common.core.NodeBuilder;
|
||||
import me.lucko.luckperms.common.core.UserIdentifier;
|
||||
|
||||
@@ -61,7 +63,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkNode;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkNode;
|
||||
|
||||
/**
|
||||
* Implements the LuckPerms API using the plugin instance
|
||||
@@ -92,7 +94,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public double getApiVersion() {
|
||||
return 2.16;
|
||||
return 2.17;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,18 +119,18 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public LPConfiguration getConfiguration() {
|
||||
return new LPConfigurationLink(plugin.getConfiguration());
|
||||
return new LPConfigurationDelegate(plugin.getConfiguration());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Storage getStorage() {
|
||||
return new StorageLink(plugin, plugin.getStorage());
|
||||
return new StorageDelegate(plugin, plugin.getStorage());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public Datastore getDatastore() {
|
||||
return new DatastoreLink(plugin, plugin.getStorage());
|
||||
return new DatastoreDelegate(plugin, plugin.getStorage());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,7 +140,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public UuidCache getUuidCache() {
|
||||
return new UuidCacheLink(plugin.getUuidCache());
|
||||
return new UuidCacheDelegate(plugin.getUuidCache());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -149,7 +151,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
@Override
|
||||
public User getUser(@NonNull UUID uuid) {
|
||||
final me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().get(uuid);
|
||||
return user == null ? null : new UserLink(user);
|
||||
return user == null ? null : new UserDelegate(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -160,7 +162,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
@Override
|
||||
public User getUser(@NonNull String name) {
|
||||
final me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().getByUsername(name);
|
||||
return user == null ? null : new UserLink(user);
|
||||
return user == null ? null : new UserDelegate(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -170,7 +172,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Set<User> getUsers() {
|
||||
return plugin.getUserManager().getAll().values().stream().map(UserLink::new).collect(Collectors.toSet());
|
||||
return plugin.getUserManager().getAll().values().stream().map(UserDelegate::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -180,14 +182,14 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public void cleanupUser(@NonNull User user) {
|
||||
Utils.checkUser(user);
|
||||
plugin.getUserManager().cleanup(((UserLink) user).getMaster());
|
||||
ApiUtils.checkUser(user);
|
||||
plugin.getUserManager().cleanup(((UserDelegate) user).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group getGroup(@NonNull String name) {
|
||||
final me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(name);
|
||||
return group == null ? null : new GroupLink(group);
|
||||
return group == null ? null : new GroupDelegate(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -197,7 +199,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Set<Group> getGroups() {
|
||||
return plugin.getGroupManager().getAll().values().stream().map(GroupLink::new).collect(Collectors.toSet());
|
||||
return plugin.getGroupManager().getAll().values().stream().map(GroupDelegate::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -208,7 +210,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
@Override
|
||||
public Track getTrack(@NonNull String name) {
|
||||
final me.lucko.luckperms.common.core.model.Track track = plugin.getTrackManager().getIfLoaded(name);
|
||||
return track == null ? null : new TrackLink(track);
|
||||
return track == null ? null : new TrackDelegate(track);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -218,7 +220,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Set<Track> getTracks() {
|
||||
return plugin.getTrackManager().getAll().values().stream().map(TrackLink::new).collect(Collectors.toSet());
|
||||
return plugin.getTrackManager().getAll().values().stream().map(TrackDelegate::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,6 +228,11 @@ public class ApiProvider implements LuckPermsApi {
|
||||
return plugin.getTrackManager().isLoaded(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeFactory getNodeFactory() {
|
||||
return NodeFactoryDelegate.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node.Builder buildNode(@NonNull String permission) throws IllegalArgumentException {
|
||||
return new NodeBuilder(checkNode(permission));
|
||||
@@ -245,7 +252,13 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Optional<Contexts> getContextForUser(User user) {
|
||||
Utils.checkUser(user);
|
||||
return Optional.ofNullable(plugin.getContextForUser(((UserLink) user).getMaster()));
|
||||
ApiUtils.checkUser(user);
|
||||
return Optional.ofNullable(plugin.getContextForUser(((UserDelegate) user).getMaster()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ContextSet getContextForPlayer(Object player) {
|
||||
return plugin.getContextManager().getApplicableContext(player);
|
||||
}
|
||||
}
|
||||
+8
-5
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
@@ -29,21 +29,24 @@ import com.google.common.base.Preconditions;
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.Track;
|
||||
import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.common.api.delegate.GroupDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.TrackDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.UserDelegate;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
|
||||
@UtilityClass
|
||||
public class Utils {
|
||||
public class ApiUtils {
|
||||
|
||||
public static void checkUser(User user) {
|
||||
Preconditions.checkState(user instanceof UserLink, "User instance cannot be handled by this implementation.");
|
||||
Preconditions.checkState(user instanceof UserDelegate, "User instance cannot be handled by this implementation.");
|
||||
}
|
||||
|
||||
public static void checkGroup(Group group) {
|
||||
Preconditions.checkState(group instanceof GroupLink, "Group instance cannot be handled by this implementation.");
|
||||
Preconditions.checkState(group instanceof GroupDelegate, "Group instance cannot be handled by this implementation.");
|
||||
}
|
||||
|
||||
public static void checkTrack(Track track) {
|
||||
Preconditions.checkState(track instanceof TrackLink, "Track instance cannot be handled by this implementation.");
|
||||
Preconditions.checkState(track instanceof TrackDelegate, "Track instance cannot be handled by this implementation.");
|
||||
}
|
||||
|
||||
public static String checkUsername(String s) {
|
||||
+27
-32
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api.delegate;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
@@ -39,19 +39,14 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkName;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkTrack;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkUser;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkUsername;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkName;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkTrack;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkUser;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkUsername;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Datastore} and {@link Storage}
|
||||
*
|
||||
* Note that this class only provides for the old deprecated interface, see {@link StorageLink} for the new one.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess", "deprecation"})
|
||||
public class DatastoreLink implements Datastore {
|
||||
@SuppressWarnings("deprecation")
|
||||
public class DatastoreDelegate implements Datastore {
|
||||
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final Storage master;
|
||||
@@ -59,7 +54,7 @@ public class DatastoreLink implements Datastore {
|
||||
private final Sync sync;
|
||||
private final Future future;
|
||||
|
||||
public DatastoreLink(@NonNull LuckPermsPlugin plugin, @NonNull Storage master) {
|
||||
public DatastoreDelegate(@NonNull LuckPermsPlugin plugin, @NonNull Storage master) {
|
||||
this.plugin = plugin;
|
||||
this.master = master;
|
||||
this.async = new Async(master);
|
||||
@@ -109,7 +104,7 @@ public class DatastoreLink implements Datastore {
|
||||
|
||||
@Override
|
||||
public void getLog(@NonNull Callback<Log> callback) {
|
||||
master.force().getLog().thenAcceptAsync(log -> callback.onComplete(new LogLink(log)), plugin.getSyncExecutor());
|
||||
master.force().getLog().thenAcceptAsync(log -> callback.onComplete(new LogDelegate(log)), plugin.getSyncExecutor());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,7 +125,7 @@ public class DatastoreLink implements Datastore {
|
||||
@Override
|
||||
public void saveUser(@NonNull User user, Callback<Boolean> callback) {
|
||||
checkUser(user);
|
||||
registerCallback(master.force().saveUser(((UserLink) user).getMaster()), callback);
|
||||
registerCallback(master.force().saveUser(((UserDelegate) user).getMaster()), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -161,7 +156,7 @@ public class DatastoreLink implements Datastore {
|
||||
@Override
|
||||
public void saveGroup(@NonNull Group group, Callback<Boolean> callback) {
|
||||
checkGroup(group);
|
||||
registerCallback(master.force().saveGroup(((GroupLink) group).getMaster()), callback);
|
||||
registerCallback(master.force().saveGroup(((GroupDelegate) group).getMaster()), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -170,7 +165,7 @@ public class DatastoreLink implements Datastore {
|
||||
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
|
||||
throw new IllegalArgumentException("Cannot delete the default group.");
|
||||
}
|
||||
registerCallback(master.force().deleteGroup(((GroupLink) group).getMaster()), callback);
|
||||
registerCallback(master.force().deleteGroup(((GroupDelegate) group).getMaster()), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -191,13 +186,13 @@ public class DatastoreLink implements Datastore {
|
||||
@Override
|
||||
public void saveTrack(@NonNull Track track, Callback<Boolean> callback) {
|
||||
checkTrack(track);
|
||||
registerCallback(master.force().saveTrack(((TrackLink) track).getMaster()), callback);
|
||||
registerCallback(master.force().saveTrack(((TrackDelegate) track).getMaster()), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTrack(@NonNull Track track, Callback<Boolean> callback) {
|
||||
checkTrack(track);
|
||||
registerCallback(master.force().deleteTrack(((TrackLink) track).getMaster()), callback);
|
||||
registerCallback(master.force().deleteTrack(((TrackDelegate) track).getMaster()), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,7 +221,7 @@ public class DatastoreLink implements Datastore {
|
||||
if (log == null) {
|
||||
return null;
|
||||
}
|
||||
return new LogLink(log);
|
||||
return new LogDelegate(log);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -247,7 +242,7 @@ public class DatastoreLink implements Datastore {
|
||||
@Override
|
||||
public boolean saveUser(@NonNull User user) {
|
||||
checkUser(user);
|
||||
return master.force().saveUser(((UserLink) user).getMaster()).join();
|
||||
return master.force().saveUser(((UserDelegate) user).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -278,7 +273,7 @@ public class DatastoreLink implements Datastore {
|
||||
@Override
|
||||
public boolean saveGroup(@NonNull Group group) {
|
||||
checkGroup(group);
|
||||
return master.force().saveGroup(((GroupLink) group).getMaster()).join();
|
||||
return master.force().saveGroup(((GroupDelegate) group).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -287,7 +282,7 @@ public class DatastoreLink implements Datastore {
|
||||
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
|
||||
throw new IllegalArgumentException("Cannot delete the default group.");
|
||||
}
|
||||
return master.force().deleteGroup(((GroupLink) group).getMaster()).join();
|
||||
return master.force().deleteGroup(((GroupDelegate) group).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -308,13 +303,13 @@ public class DatastoreLink implements Datastore {
|
||||
@Override
|
||||
public boolean saveTrack(@NonNull Track track) {
|
||||
checkTrack(track);
|
||||
return master.force().saveTrack(((TrackLink) track).getMaster()).join();
|
||||
return master.force().saveTrack(((TrackDelegate) track).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteTrack(@NonNull Track track) {
|
||||
checkTrack(track);
|
||||
return master.force().deleteTrack(((TrackLink) track).getMaster()).join();
|
||||
return master.force().deleteTrack(((TrackDelegate) track).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -339,7 +334,7 @@ public class DatastoreLink implements Datastore {
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Log> getLog() {
|
||||
return master.force().getLog().thenApply(log -> log == null ? null : new LogLink(log));
|
||||
return master.force().getLog().thenApply(log -> log == null ? null : new LogDelegate(log));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -360,7 +355,7 @@ public class DatastoreLink implements Datastore {
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> saveUser(@NonNull User user) {
|
||||
checkUser(user);
|
||||
return master.force().saveUser(((UserLink) user).getMaster());
|
||||
return master.force().saveUser(((UserDelegate) user).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -391,7 +386,7 @@ public class DatastoreLink implements Datastore {
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> saveGroup(@NonNull Group group) {
|
||||
checkGroup(group);
|
||||
return master.force().saveGroup(((GroupLink) group).getMaster());
|
||||
return master.force().saveGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -400,7 +395,7 @@ public class DatastoreLink implements Datastore {
|
||||
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
|
||||
throw new IllegalArgumentException("Cannot delete the default group.");
|
||||
}
|
||||
return master.force().deleteGroup(((GroupLink) group).getMaster());
|
||||
return master.force().deleteGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -421,13 +416,13 @@ public class DatastoreLink implements Datastore {
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> saveTrack(@NonNull Track track) {
|
||||
checkTrack(track);
|
||||
return master.force().saveTrack(((TrackLink) track).getMaster());
|
||||
return master.force().saveTrack(((TrackDelegate) track).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> deleteTrack(@NonNull Track track) {
|
||||
checkTrack(track);
|
||||
return master.force().deleteTrack(((TrackLink) track).getMaster());
|
||||
return master.force().deleteTrack(((TrackDelegate) track).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
+27
-22
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api.delegate;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -32,17 +32,17 @@ import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkServer;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkTime;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkServer;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkTime;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Group} and {@link me.lucko.luckperms.common.core.model.Group}
|
||||
*/
|
||||
@EqualsAndHashCode(of = {"name"}, callSuper = false)
|
||||
@SuppressWarnings("unused")
|
||||
public class GroupLink extends PermissionHolderLink implements Group {
|
||||
public class GroupDelegate extends PermissionHolderDelegate implements Group {
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final me.lucko.luckperms.common.core.model.Group master;
|
||||
@@ -50,7 +50,7 @@ public class GroupLink extends PermissionHolderLink implements Group {
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
public GroupLink(@NonNull me.lucko.luckperms.common.core.model.Group master) {
|
||||
public GroupDelegate(@NonNull me.lucko.luckperms.common.core.model.Group master) {
|
||||
super(master);
|
||||
this.master = master;
|
||||
this.name = master.getName();
|
||||
@@ -59,91 +59,91 @@ public class GroupLink extends PermissionHolderLink implements Group {
|
||||
@Override
|
||||
public boolean inheritsGroup(@NonNull Group group) {
|
||||
checkGroup(group);
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster());
|
||||
return master.inheritsGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inheritsGroup(@NonNull Group group, @NonNull String server) {
|
||||
checkGroup(group);
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster(), server);
|
||||
return master.inheritsGroup(((GroupDelegate) group).getMaster(), server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inheritsGroup(@NonNull Group group, @NonNull String server, @NonNull String world) {
|
||||
checkGroup(group);
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster(), server, world);
|
||||
return master.inheritsGroup(((GroupDelegate) group).getMaster(), server, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster());
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group, @NonNull String server) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world);
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world, checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world, checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster());
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), temporary);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group, @NonNull String server) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server));
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), temporary);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world, temporary);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world, temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -161,6 +161,11 @@ public class GroupLink extends PermissionHolderLink implements Group {
|
||||
return master.getLocalGroups(checkServer(server), world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt getWeight() {
|
||||
return master.getWeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLocalGroups(@NonNull String server) {
|
||||
return master.getLocalGroups(checkServer(server));
|
||||
+2
-2
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api.delegate;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.util.Map;
|
||||
* Provides a link between {@link LPConfiguration} and {@link me.lucko.luckperms.common.config.LPConfiguration}
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class LPConfigurationLink implements LPConfiguration {
|
||||
public class LPConfigurationDelegate implements LPConfiguration {
|
||||
private final me.lucko.luckperms.common.config.LPConfiguration master;
|
||||
|
||||
@Override
|
||||
+3
-3
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api.delegate;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
@@ -32,13 +32,13 @@ import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.UUID;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkName;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkName;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Log} and {@link me.lucko.luckperms.common.data.Log}
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class LogLink implements Log {
|
||||
public class LogDelegate implements Log {
|
||||
private final me.lucko.luckperms.common.data.Log master;
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.common.api.delegate;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
|
||||
public class NodeFactoryDelegate implements me.lucko.luckperms.api.NodeFactory {
|
||||
public static final NodeFactoryDelegate INSTANCE = new NodeFactoryDelegate();
|
||||
|
||||
@Override
|
||||
public Node fromSerialisedNode(@NonNull String serialisedPermission, boolean value) {
|
||||
return NodeFactory.fromSerialisedNode(serialisedPermission, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node.Builder newBuilder(@NonNull String permission) {
|
||||
return NodeFactory.newBuilder(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node.Builder newBuilderFromExisting(@NonNull Node other) {
|
||||
return NodeFactory.builderFromExisting(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node.Builder newBuilderFromSerialisedNode(@NonNull String serialisedPermission, boolean value) {
|
||||
return NodeFactory.builderFromSerialisedNode(serialisedPermission, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node.Builder makeMetaNode(@NonNull String key, @NonNull String value) {
|
||||
return NodeFactory.makeMetaNode(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node.Builder makePrefixNode(int priority, @NonNull String prefix) {
|
||||
return NodeFactory.makePrefixNode(priority, prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node.Builder makeSuffixNode(int priority, @NonNull String suffix) {
|
||||
return NodeFactory.makeSuffixNode(priority, suffix);
|
||||
}
|
||||
}
|
||||
+78
-13
@@ -20,11 +20,15 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api.delegate;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
@@ -36,16 +40,17 @@ import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkNode;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkServer;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkTime;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkNode;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkServer;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkTime;
|
||||
import static me.lucko.luckperms.common.core.model.PermissionHolder.exportToLegacy;
|
||||
|
||||
/**
|
||||
@@ -53,7 +58,7 @@ import static me.lucko.luckperms.common.core.model.PermissionHolder.exportToLega
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@AllArgsConstructor
|
||||
public class PermissionHolderLink implements PermissionHolder {
|
||||
public class PermissionHolderDelegate implements PermissionHolder {
|
||||
private final me.lucko.luckperms.common.core.model.PermissionHolder master;
|
||||
|
||||
@Override
|
||||
@@ -63,37 +68,42 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
|
||||
@Override
|
||||
public SortedSet<? extends Node> getPermissions() {
|
||||
return master.getPermissions(false);
|
||||
return ImmutableSortedSet.copyOf(master.getPermissions(false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Node> getEnduringPermissions() {
|
||||
return master.getNodes();
|
||||
return ImmutableSet.copyOf(master.getNodes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Node> getTransientPermissions() {
|
||||
return master.getTransientNodes();
|
||||
return ImmutableSet.copyOf(master.getTransientNodes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Node> getAllNodes() {
|
||||
return Collections.unmodifiableSet(master.getAllNodes(null, ExtractedContexts.generate(Contexts.allowAll())));
|
||||
return ImmutableSet.copyOf(master.getAllNodes(null, ExtractedContexts.generate(Contexts.allowAll())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<LocalizedNode> getAllNodes(@NonNull Contexts contexts) {
|
||||
return master.getAllNodes(null, ExtractedContexts.generate(contexts));
|
||||
return new TreeSet<>(master.getAllNodes(null, ExtractedContexts.generate(contexts)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<LocalizedNode> getAllNodesFiltered(@NonNull Contexts contexts) {
|
||||
return master.getAllNodesFiltered(ExtractedContexts.generate(contexts));
|
||||
return new HashSet<>(master.getAllNodesFiltered(ExtractedContexts.generate(contexts)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> exportNodes(Contexts contexts, boolean lowerCase) {
|
||||
return new HashMap<>(master.exportNodes(contexts, lowerCase));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getNodes() {
|
||||
return exportToLegacy(master.getNodes());
|
||||
return ImmutableMap.copyOf(exportToLegacy(master.getNodes()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -251,6 +261,61 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
master.unsetPermission(checkNode(node), checkServer(server), world, temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearNodes() {
|
||||
master.clearNodes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearNodes(String server) {
|
||||
master.clearNodes(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearNodes(String server, String world) {
|
||||
master.clearNodes(server, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearParents() {
|
||||
master.clearParents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearParents(String server) {
|
||||
master.clearParents(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearParents(String server, String world) {
|
||||
master.clearParents(server, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearMeta() {
|
||||
master.clearMeta();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearMeta(String server) {
|
||||
master.clearMeta(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearMeta(String server, String world) {
|
||||
master.clearMeta(server, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearMetaKeys(String key, String server, String world, boolean temporary) {
|
||||
master.clearMetaKeys(key, server, world, temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearTransientNodes() {
|
||||
master.clearTransientNodes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups, List<String> possibleNodes) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
+30
-13
@@ -20,12 +20,13 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api.delegate;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.HeldPermission;
|
||||
import me.lucko.luckperms.api.Log;
|
||||
import me.lucko.luckperms.api.LogEntry;
|
||||
import me.lucko.luckperms.api.Storage;
|
||||
@@ -33,22 +34,23 @@ import me.lucko.luckperms.api.Track;
|
||||
import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkName;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkTrack;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkUser;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkUsername;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkName;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkTrack;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkUser;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkUsername;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Storage} and {@link me.lucko.luckperms.common.storage.Storage}
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class StorageLink implements Storage {
|
||||
public class StorageDelegate implements Storage {
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final me.lucko.luckperms.common.storage.Storage master;
|
||||
|
||||
@@ -79,7 +81,7 @@ public class StorageLink implements Storage {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Log> getLog() {
|
||||
return master.force().getLog().thenApply(log -> log == null ? null : new LogLink(log));
|
||||
return master.force().getLog().thenApply(log -> log == null ? null : new LogDelegate(log));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -90,7 +92,7 @@ public class StorageLink implements Storage {
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveUser(User user) {
|
||||
checkUser(user);
|
||||
return master.force().saveUser(((UserLink) user).getMaster());
|
||||
return master.force().saveUser(((UserDelegate) user).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,6 +105,11 @@ public class StorageLink implements Storage {
|
||||
return master.force().getUniqueUsers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<HeldPermission<UUID>>> getUsersWithPermission(@NonNull String permission) {
|
||||
return master.force().getUsersWithPermission(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> createAndLoadGroup(String name) {
|
||||
return master.force().createAndLoadGroup(checkName(name));
|
||||
@@ -121,7 +128,7 @@ public class StorageLink implements Storage {
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveGroup(Group group) {
|
||||
checkGroup(group);
|
||||
return master.force().saveGroup(((GroupLink) group).getMaster());
|
||||
return master.force().saveGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,7 +137,12 @@ public class StorageLink implements Storage {
|
||||
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
|
||||
throw new IllegalArgumentException("Cannot delete the default group.");
|
||||
}
|
||||
return master.force().deleteGroup(((GroupLink) group).getMaster());
|
||||
return master.force().deleteGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<HeldPermission<String>>> getGroupsWithPermission(@NonNull String permission) {
|
||||
return master.force().getGroupsWithPermission(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -151,13 +163,13 @@ public class StorageLink implements Storage {
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveTrack(Track track) {
|
||||
checkTrack(track);
|
||||
return master.force().saveTrack(((TrackLink) track).getMaster());
|
||||
return master.force().saveTrack(((TrackDelegate) track).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> deleteTrack(Track track) {
|
||||
checkTrack(track);
|
||||
return master.force().deleteTrack(((TrackLink) track).getMaster());
|
||||
return master.force().deleteTrack(((TrackDelegate) track).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,4 +181,9 @@ public class StorageLink implements Storage {
|
||||
public CompletableFuture<UUID> getUUID(String username) {
|
||||
return master.force().getUUID(checkUsername(username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<String> getName(@NonNull UUID uuid) {
|
||||
return master.force().getName(uuid);
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api.delegate;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -34,14 +34,14 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkGroup;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Track} and {@link me.lucko.luckperms.common.core.model.Track}
|
||||
*/
|
||||
@EqualsAndHashCode(of = {"name"})
|
||||
@SuppressWarnings("unused")
|
||||
public class TrackLink implements Track {
|
||||
public class TrackDelegate implements Track {
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final me.lucko.luckperms.common.core.model.Track master;
|
||||
@@ -49,7 +49,7 @@ public class TrackLink implements Track {
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
public TrackLink(@NonNull me.lucko.luckperms.common.core.model.Track master) {
|
||||
public TrackDelegate(@NonNull me.lucko.luckperms.common.core.model.Track master) {
|
||||
this.master = master;
|
||||
this.name = master.getName();
|
||||
}
|
||||
@@ -67,31 +67,31 @@ public class TrackLink implements Track {
|
||||
@Override
|
||||
public String getNext(@NonNull Group current) throws ObjectLacksException {
|
||||
checkGroup(current);
|
||||
return master.getNext(((GroupLink) current).getMaster());
|
||||
return master.getNext(((GroupDelegate) current).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrevious(@NonNull Group current) throws ObjectLacksException {
|
||||
checkGroup(current);
|
||||
return master.getPrevious(((GroupLink) current).getMaster());
|
||||
return master.getPrevious(((GroupDelegate) current).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendGroup(@NonNull Group group) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.appendGroup(((GroupLink) group).getMaster());
|
||||
master.appendGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertGroup(@NonNull Group group, @NonNull int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException {
|
||||
checkGroup(group);
|
||||
master.insertGroup(((GroupLink) group).getMaster(), position);
|
||||
master.insertGroup(((GroupDelegate) group).getMaster(), position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.removeGroup(((GroupLink) group).getMaster());
|
||||
master.removeGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,7 +102,7 @@ public class TrackLink implements Track {
|
||||
@Override
|
||||
public boolean containsGroup(@NonNull Group group) {
|
||||
checkGroup(group);
|
||||
return master.containsGroup(((GroupLink) group).getMaster());
|
||||
return master.containsGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
+26
-21
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api.delegate;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
@@ -36,16 +36,16 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkServer;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkTime;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkServer;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkTime;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link User} and {@link me.lucko.luckperms.common.core.model.User}
|
||||
*/
|
||||
@EqualsAndHashCode(of = {"uuid"}, callSuper = false)
|
||||
@SuppressWarnings("unused")
|
||||
public class UserLink extends PermissionHolderLink implements User {
|
||||
public class UserDelegate extends PermissionHolderDelegate implements User {
|
||||
|
||||
@Getter
|
||||
private final me.lucko.luckperms.common.core.model.User master;
|
||||
@@ -53,7 +53,7 @@ public class UserLink extends PermissionHolderLink implements User {
|
||||
@Getter
|
||||
private final UUID uuid;
|
||||
|
||||
public UserLink(@NonNull me.lucko.luckperms.common.core.model.User master) {
|
||||
public UserDelegate(@NonNull me.lucko.luckperms.common.core.model.User master) {
|
||||
super(master);
|
||||
this.master = master;
|
||||
this.uuid = master.getUuid();
|
||||
@@ -92,94 +92,99 @@ public class UserLink extends PermissionHolderLink implements User {
|
||||
return Optional.ofNullable(master.getUserData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupDataCache() {
|
||||
master.setupData(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGroup(@NonNull Group group) {
|
||||
checkGroup(group);
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster());
|
||||
return master.inheritsGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGroup(@NonNull Group group, @NonNull String server) {
|
||||
checkGroup(group);
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster(), server);
|
||||
return master.inheritsGroup(((GroupDelegate) group).getMaster(), server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGroup(@NonNull Group group, @NonNull String server, @NonNull String world) {
|
||||
checkGroup(group);
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster(), server, world);
|
||||
return master.inheritsGroup(((GroupDelegate) group).getMaster(), server, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster());
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group, @NonNull String server) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world);
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world, checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world, checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster());
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), temporary);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group, @NonNull String server) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server));
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), temporary);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world, temporary);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world, temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
+2
-2
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api.delegate;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
@@ -33,7 +33,7 @@ import java.util.UUID;
|
||||
* Provides a link between {@link UuidCache} and {@link me.lucko.luckperms.common.core.UuidCache}
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class UuidCacheLink implements UuidCache {
|
||||
public class UuidCacheDelegate implements UuidCache {
|
||||
private final me.lucko.luckperms.common.core.UuidCache master;
|
||||
|
||||
@Override
|
||||
@@ -41,6 +41,7 @@ import me.lucko.luckperms.common.core.model.User;
|
||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Holds an easily accessible cache of a user's data in a number of contexts
|
||||
@@ -59,6 +60,7 @@ public class UserCache implements UserData {
|
||||
private final CalculatorFactory calculatorFactory;
|
||||
|
||||
private final LoadingCache<Contexts, PermissionCache> permission = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||
.build(new CacheLoader<Contexts, PermissionCache>() {
|
||||
@Override
|
||||
public PermissionCache load(Contexts contexts) {
|
||||
@@ -73,6 +75,7 @@ public class UserCache implements UserData {
|
||||
});
|
||||
|
||||
private final LoadingCache<Contexts, MetaCache> meta = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||
.build(new CacheLoader<Contexts, MetaCache>() {
|
||||
@Override
|
||||
public MetaCache load(Contexts contexts) {
|
||||
@@ -153,4 +156,9 @@ public class UserCache implements UserData {
|
||||
permission.asMap().values().forEach(PermissionData::invalidateCache);
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
permission.cleanUp();
|
||||
meta.cleanUp();
|
||||
}
|
||||
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.common.caching.handlers;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Manages the cached state of all permission holders
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class CachedStateManager {
|
||||
private static final Consumer<PermissionHolder> INVALIDATE_CONSUMER = PermissionHolder::invalidateInheritanceCaches;
|
||||
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
// Group --> Groups that inherit from that group. (reverse relationship)
|
||||
private final Multimap<HolderReference, HolderReference> map = HashMultimap.create();
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* Gets a set of holder names that inherit permissions (either directly or via other groups)
|
||||
* from the given holder name
|
||||
*
|
||||
* @param holder the holder name to query for
|
||||
* @return a set of inherited groups
|
||||
*/
|
||||
public Set<HolderReference> getInheritances(HolderReference holder) {
|
||||
Set<HolderReference> set = new HashSet<>();
|
||||
set.add(holder);
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
while (true) {
|
||||
Set<HolderReference> clone = new HashSet<>(set);
|
||||
|
||||
boolean work = false;
|
||||
|
||||
for (HolderReference s : clone) {
|
||||
if (set.addAll(map.get(s))) {
|
||||
work = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!work) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
set.remove(holder);
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a holder and the groups they inherit from within this map.
|
||||
*
|
||||
* @param holder the holder to add
|
||||
* @param inheritedGroups a list of groups the holder inherits from
|
||||
*/
|
||||
public void putAll(HolderReference holder, Set<HolderReference> inheritedGroups) {
|
||||
lock.lock();
|
||||
try {
|
||||
map.entries().removeIf(entry -> entry.getValue().equals(holder));
|
||||
|
||||
for (HolderReference child : inheritedGroups) {
|
||||
map.put(child, holder);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears defined inheritances for the given holder name.
|
||||
*
|
||||
* @param holder the holder name to clear
|
||||
*/
|
||||
public void clear(HolderReference holder) {
|
||||
lock.lock();
|
||||
try {
|
||||
map.entries().removeIf(entry -> entry.getValue().equals(holder));
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidateInheritances(HolderReference holder) {
|
||||
Set<HolderReference> toInvalidate = getInheritances(holder);
|
||||
invalidateInheritances(plugin, toInvalidate);
|
||||
}
|
||||
|
||||
public static void invalidateInheritances(LuckPermsPlugin plugin, Set<HolderReference> references) {
|
||||
references.forEach(hr -> hr.apply(plugin, INVALIDATE_CONSUMER));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.common.caching.handlers;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.core.model.Group;
|
||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@AllArgsConstructor(staticName = "of")
|
||||
public class GroupReference implements HolderReference<String> {
|
||||
|
||||
private final String id;
|
||||
|
||||
@Override
|
||||
public HolderType getType() {
|
||||
return HolderType.GROUP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(LuckPermsPlugin plugin, Consumer<PermissionHolder> consumer) {
|
||||
Group group = plugin.getGroupManager().getIfLoaded(id);
|
||||
if (group == null) return;
|
||||
|
||||
consumer.accept(group);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.common.caching.handlers;
|
||||
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.utils.Identifiable;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface HolderReference<T> extends Identifiable<T> {
|
||||
|
||||
HolderType getType();
|
||||
void apply(LuckPermsPlugin plugin, Consumer<PermissionHolder> consumer);
|
||||
|
||||
}
|
||||
+3
-13
@@ -20,18 +20,8 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
|
||||
public class ApiHandler {
|
||||
|
||||
public static void registerProvider(LuckPermsApi luckPermsApi) {
|
||||
LuckPerms.registerProvider(luckPermsApi);
|
||||
}
|
||||
|
||||
public static void unregisterProvider() {
|
||||
LuckPerms.unregisterProvider();
|
||||
}
|
||||
package me.lucko.luckperms.common.caching.handlers;
|
||||
|
||||
public enum HolderType {
|
||||
USER, GROUP
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.common.caching.handlers;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.core.UserIdentifier;
|
||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.core.model.User;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@AllArgsConstructor(staticName = "of")
|
||||
public class UserReference implements HolderReference<UserIdentifier> {
|
||||
private final UserIdentifier id;
|
||||
|
||||
@Override
|
||||
public HolderType getType() {
|
||||
return HolderType.USER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(LuckPermsPlugin plugin, Consumer<PermissionHolder> consumer) {
|
||||
User user = plugin.getUserManager().getIfLoaded(id);
|
||||
if (user == null) return;
|
||||
|
||||
consumer.accept(user);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.common.caching.holder;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@AllArgsConstructor(staticName = "of")
|
||||
public class ExportNodesHolder {
|
||||
|
||||
private final Contexts contexts;
|
||||
private final Boolean lowerCase;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.caching.holder;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@AllArgsConstructor(staticName = "of")
|
||||
public class GetAllNodesRequest {
|
||||
|
||||
private final ImmutableList<String> excludedGroups;
|
||||
private final ExtractedContexts contexts;
|
||||
|
||||
}
|
||||
+4
-1
@@ -57,7 +57,10 @@ public class RegexProcessor implements PermissionProcessor {
|
||||
continue;
|
||||
}
|
||||
|
||||
regexPermissions.put(e.getKey().substring(2), e.getValue());
|
||||
String pattern = e.getKey().substring(2);
|
||||
Patterns.compile(pattern); // Cache the lookup for later.
|
||||
|
||||
regexPermissions.put(pattern, e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ import me.lucko.luckperms.common.commands.misc.ExportCommand;
|
||||
import me.lucko.luckperms.common.commands.misc.ImportCommand;
|
||||
import me.lucko.luckperms.common.commands.misc.InfoCommand;
|
||||
import me.lucko.luckperms.common.commands.misc.NetworkSyncCommand;
|
||||
import me.lucko.luckperms.common.commands.misc.QueueCommand;
|
||||
import me.lucko.luckperms.common.commands.misc.SearchCommand;
|
||||
import me.lucko.luckperms.common.commands.misc.SyncCommand;
|
||||
import me.lucko.luckperms.common.commands.misc.VerboseCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
@@ -50,15 +50,186 @@ import me.lucko.luckperms.common.commands.usersbulkedit.UsersBulkEditMainCommand
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
|
||||
import io.github.mkremins.fanciful.ChatColor;
|
||||
import io.github.mkremins.fanciful.FancyMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CommandManager {
|
||||
|
||||
@Getter
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
private final ExecutorService executor;
|
||||
|
||||
@Getter
|
||||
private final List<BaseCommand> mainCommands;
|
||||
|
||||
public CommandManager(LuckPermsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
ImmutableList.Builder<BaseCommand> l = ImmutableList.builder();
|
||||
l.add(new UserMainCommand())
|
||||
.add(new GroupMainCommand())
|
||||
.add(new TrackMainCommand())
|
||||
.addAll(plugin.getExtraCommands())
|
||||
.add(new LogMainCommand())
|
||||
.add(new SyncCommand())
|
||||
.add(new InfoCommand())
|
||||
.add(new VerboseCommand())
|
||||
.add(new SearchCommand())
|
||||
.add(new NetworkSyncCommand())
|
||||
.add(new ImportCommand())
|
||||
.add(new ExportCommand())
|
||||
.add(new MigrationMainCommand())
|
||||
.add(new UsersBulkEditMainCommand())
|
||||
.add(new CreateGroup())
|
||||
.add(new DeleteGroup())
|
||||
.add(new ListGroups())
|
||||
.add(new CreateTrack())
|
||||
.add(new DeleteTrack())
|
||||
.add(new ListTracks());
|
||||
|
||||
mainCommands = l.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic on command method to be called from the command executor object of the platform
|
||||
* Unlike {@link #onCommand(Sender, String, List)}, this method is called in a new thread
|
||||
* @param sender who sent the command
|
||||
* @param label the command label used
|
||||
* @param args the arguments provided
|
||||
*/
|
||||
public Future<CommandResult> onCommand(Sender sender, String label, List<String> args) {
|
||||
return executor.submit(() -> execute(sender, label, args));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private CommandResult execute(Sender sender, String label, List<String> args) {
|
||||
// Handle no arguments
|
||||
if (args.size() == 0) {
|
||||
sendCommandUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
// Look for the main command.
|
||||
Optional<BaseCommand> o = mainCommands.stream()
|
||||
.filter(m -> m.getName().equalsIgnoreCase(args.get(0)))
|
||||
.limit(1)
|
||||
.findAny();
|
||||
|
||||
// Main command not found
|
||||
if (!o.isPresent()) {
|
||||
sendCommandUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
// Check the Sender has permission to use the main command.
|
||||
final Command main = o.get();
|
||||
if (!main.isAuthorized(sender)) {
|
||||
sendCommandUsage(sender, label);
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
List<String> arguments = new ArrayList<>(args);
|
||||
handleRewrites(arguments);
|
||||
arguments.remove(0); // remove the main command arg.
|
||||
|
||||
// Check the correct number of args were given for the main command
|
||||
if (main.getArgumentCheck().test(arguments.size())) {
|
||||
main.sendUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
// Try to execute the command.
|
||||
CommandResult result;
|
||||
try {
|
||||
result = main.execute(plugin, sender, null, arguments, label);
|
||||
} catch (CommandException e) {
|
||||
result = handleException(e, sender, label, main);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
result = CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic tab complete method to be called from the command executor object of the platform
|
||||
*
|
||||
* @param sender who is tab completing
|
||||
* @param args the arguments provided so far
|
||||
* @return a list of suggestions
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> onTabComplete(Sender sender, List<String> args) {
|
||||
final List<Command> mains = mainCommands.stream()
|
||||
.filter(m -> m.isAuthorized(sender))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Not yet past the point of entering a main command
|
||||
if (args.size() <= 1) {
|
||||
|
||||
// Nothing yet entered
|
||||
if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) {
|
||||
return mains.stream()
|
||||
.map(m -> m.getName().toLowerCase())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// Started typing a main command
|
||||
return mains.stream()
|
||||
.map(m -> m.getName().toLowerCase())
|
||||
.filter(s -> s.startsWith(args.get(0).toLowerCase()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// Find a main command matching the first arg
|
||||
Optional<Command> o = mains.stream()
|
||||
.filter(m -> m.getName().equalsIgnoreCase(args.get(0)))
|
||||
.limit(1)
|
||||
.findAny();
|
||||
|
||||
if (!o.isPresent()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// Pass the processing onto the main command
|
||||
return o.get().tabComplete(plugin, sender, args.subList(1, args.size()));
|
||||
}
|
||||
|
||||
private void sendCommandUsage(Sender sender, String label) {
|
||||
Util.sendPluginMessage(sender, "&2Running &bLuckPerms v" + plugin.getVersion() + "&2.");
|
||||
mainCommands.stream()
|
||||
.filter(c -> c.isAuthorized(sender))
|
||||
.forEach(c -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
String permission = (String) c.getPermission().map(p -> ((Permission) p).getExample()).orElse("None");
|
||||
FancyMessage msg = new FancyMessage("> ").color(ChatColor.getByChar('3')).then().text(String.format(c.getUsage(), label)).color(ChatColor.getByChar('a'))
|
||||
.formattedTooltip(
|
||||
new FancyMessage("Command: ").color(ChatColor.getByChar('b')).then().text(c.getName()).color(ChatColor.getByChar('2')),
|
||||
new FancyMessage("Description: ").color(ChatColor.getByChar('b')).then().text(c.getDescription()).color(ChatColor.getByChar('2')),
|
||||
new FancyMessage("Usage: ").color(ChatColor.getByChar('b')).then().text(String.format(c.getUsage(), label)).color(ChatColor.getByChar('2')),
|
||||
new FancyMessage("Permission: ").color(ChatColor.getByChar('b')).then().text(permission).color(ChatColor.getByChar('2')),
|
||||
new FancyMessage(" "),
|
||||
new FancyMessage("Click to auto-complete.").color(ChatColor.getByChar('7'))
|
||||
)
|
||||
.suggest(String.format(c.getUsage(), label));
|
||||
sender.sendMessage(msg);
|
||||
});
|
||||
}
|
||||
|
||||
public static CommandResult handleException(CommandException e, Sender sender, String label, Command command) {
|
||||
if (e instanceof ArgumentUtils.ArgumentException) {
|
||||
if (e instanceof ArgumentUtils.DetailedUsageException) {
|
||||
@@ -223,165 +394,4 @@ public class CommandManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
private final LuckPermsPlugin plugin;
|
||||
@Getter
|
||||
private final List<BaseCommand> mainCommands;
|
||||
|
||||
public CommandManager(LuckPermsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
ImmutableList.Builder<BaseCommand> l = ImmutableList.builder();
|
||||
l.add(new UserMainCommand())
|
||||
.add(new GroupMainCommand())
|
||||
.add(new TrackMainCommand())
|
||||
.addAll(plugin.getExtraCommands())
|
||||
.add(new LogMainCommand())
|
||||
.add(new SyncCommand())
|
||||
.add(new NetworkSyncCommand())
|
||||
.add(new InfoCommand())
|
||||
.add(new VerboseCommand())
|
||||
.add(new ImportCommand())
|
||||
.add(new ExportCommand())
|
||||
.add(new QueueCommand())
|
||||
.add(new MigrationMainCommand())
|
||||
.add(new UsersBulkEditMainCommand())
|
||||
.add(new CreateGroup())
|
||||
.add(new DeleteGroup())
|
||||
.add(new ListGroups())
|
||||
.add(new CreateTrack())
|
||||
.add(new DeleteTrack())
|
||||
.add(new ListTracks());
|
||||
|
||||
mainCommands = l.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic on command method to be called from the command executor object of the platform
|
||||
* Unlike {@link #onCommand(Sender, String, List)}, this method is called in a new thread
|
||||
*
|
||||
* @param sender who sent the command
|
||||
* @param label the command label used
|
||||
* @param args the arguments provided
|
||||
* @param result the callback to be called when the command has fully executed
|
||||
*/
|
||||
public void onCommand(Sender sender, String label, List<String> args, Consumer<CommandResult> result) {
|
||||
plugin.doAsync(() -> {
|
||||
CommandResult r = onCommand(sender, label, args);
|
||||
if (result != null) {
|
||||
plugin.doSync(() -> result.accept(r));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic on command method to be called from the command executor object of the platform
|
||||
*
|
||||
* @param sender who sent the command
|
||||
* @param label the command label used
|
||||
* @param args the arguments provided
|
||||
* @return if the command was successful
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public CommandResult onCommand(Sender sender, String label, List<String> args) {
|
||||
// Handle no arguments
|
||||
if (args.size() == 0) {
|
||||
sendCommandUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
// Look for the main command.
|
||||
Optional<BaseCommand> o = mainCommands.stream()
|
||||
.filter(m -> m.getName().equalsIgnoreCase(args.get(0)))
|
||||
.limit(1)
|
||||
.findAny();
|
||||
|
||||
// Main command not found
|
||||
if (!o.isPresent()) {
|
||||
sendCommandUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
// Check the Sender has permission to use the main command.
|
||||
final Command main = o.get();
|
||||
if (!main.isAuthorized(sender)) {
|
||||
sendCommandUsage(sender, label);
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
List<String> arguments = new ArrayList<>(args);
|
||||
handleRewrites(arguments);
|
||||
arguments.remove(0); // remove the main command arg.
|
||||
|
||||
// Check the correct number of args were given for the main command
|
||||
if (main.getArgumentCheck().test(arguments.size())) {
|
||||
main.sendUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
// Try to execute the command.
|
||||
CommandResult result;
|
||||
try {
|
||||
result = main.execute(plugin, sender, null, arguments, label);
|
||||
} catch (CommandException e) {
|
||||
result = handleException(e, sender, label, main);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
result = CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic tab complete method to be called from the command executor object of the platform
|
||||
*
|
||||
* @param sender who is tab completing
|
||||
* @param args the arguments provided so far
|
||||
* @return a list of suggestions
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> onTabComplete(Sender sender, List<String> args) {
|
||||
final List<Command> mains = mainCommands.stream()
|
||||
.filter(m -> m.isAuthorized(sender))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Not yet past the point of entering a main command
|
||||
if (args.size() <= 1) {
|
||||
|
||||
// Nothing yet entered
|
||||
if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) {
|
||||
return mains.stream()
|
||||
.map(m -> m.getName().toLowerCase())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// Started typing a main command
|
||||
return mains.stream()
|
||||
.map(m -> m.getName().toLowerCase())
|
||||
.filter(s -> s.startsWith(args.get(0).toLowerCase()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// Find a main command matching the first arg
|
||||
Optional<Command> o = mains.stream()
|
||||
.filter(m -> m.getName().equalsIgnoreCase(args.get(0)))
|
||||
.limit(1)
|
||||
.findAny();
|
||||
|
||||
if (!o.isPresent()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// Pass the processing onto the main command
|
||||
return o.get().tabComplete(plugin, sender, args.subList(1, args.size()));
|
||||
}
|
||||
|
||||
private void sendCommandUsage(Sender sender, String label) {
|
||||
Util.sendPluginMessage(sender, "&2Running &bLuckPerms v" + plugin.getVersion() + "&2.");
|
||||
mainCommands.stream()
|
||||
.filter(c -> c.isAuthorized(sender))
|
||||
.forEach(c -> Util.sendPluginMessage(sender, "&3> &a" + String.format(c.getUsage(), label)));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -122,7 +122,7 @@ public class SharedMainCommand<T extends PermissionHolder> extends SubCommand<T>
|
||||
|
||||
CommandResult result;
|
||||
try {
|
||||
result = sub.execute(plugin, sender, t, strippedArgs);
|
||||
result = sub.execute(plugin, sender, t, strippedArgs, label);
|
||||
} catch (CommandException e) {
|
||||
result = handleException(e, sender, sub);
|
||||
}
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ public abstract class SharedSubCommand {
|
||||
private final Predicate<? super Integer> isArgumentInvalid;
|
||||
private final ImmutableList<Arg> args;
|
||||
|
||||
public abstract CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException;
|
||||
public abstract CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException;
|
||||
|
||||
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
return Collections.emptyList();
|
||||
|
||||
+2
-2
@@ -55,9 +55,9 @@ public class MetaAddPrefix extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String prefix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String prefix = ArgumentUtils.handleString(1, args);
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
|
||||
+2
-2
@@ -55,9 +55,9 @@ public class MetaAddSuffix extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String suffix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String suffix = ArgumentUtils.handleString(1, args);
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
|
||||
+2
-2
@@ -57,9 +57,9 @@ public class MetaAddTempPrefix extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String prefix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String prefix = ArgumentUtils.handleString(1, args);
|
||||
long duration = ArgumentUtils.handleDuration(2, args);
|
||||
String server = ArgumentUtils.handleServer(3, args);
|
||||
String world = ArgumentUtils.handleWorld(4, args);
|
||||
|
||||
+2
-2
@@ -57,9 +57,9 @@ public class MetaAddTempSuffix extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String suffix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String suffix = ArgumentUtils.handleString(1, args);
|
||||
long duration = ArgumentUtils.handleDuration(2, args);
|
||||
String server = ArgumentUtils.handleServer(3, args);
|
||||
String world = ArgumentUtils.handleWorld(4, args);
|
||||
|
||||
@@ -50,7 +50,7 @@ public class MetaClear extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
int before = holder.getNodes().size();
|
||||
|
||||
String server = ArgumentUtils.handleServer(0, args);
|
||||
|
||||
@@ -54,7 +54,7 @@ public class MetaInfo extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
SortedSet<Map.Entry<Integer, LocalizedNode>> prefixes = new TreeSet<>(Util.META_COMPARATOR.reversed());
|
||||
SortedSet<Map.Entry<Integer, LocalizedNode>> suffixes = new TreeSet<>(Util.META_COMPARATOR.reversed());
|
||||
Set<LocalizedNode> meta = new HashSet<>();
|
||||
|
||||
+4
-4
@@ -46,10 +46,10 @@ import java.util.stream.Collectors;
|
||||
public class MetaRemovePrefix extends SharedSubCommand {
|
||||
public MetaRemovePrefix() {
|
||||
super("removeprefix", "Removes a prefix", Permission.USER_META_REMOVEPREFIX, Permission.GROUP_META_REMOVEPREFIX,
|
||||
Predicates.notInRange(2, 4),
|
||||
Predicates.notInRange(1, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the prefix at"),
|
||||
Arg.create("prefix", true, "the prefix string"),
|
||||
Arg.create("prefix", false, "the prefix string"),
|
||||
Arg.create("server", false, "the server to add the prefix on"),
|
||||
Arg.create("world", false, "the world to add the prefix on")
|
||||
)
|
||||
@@ -57,9 +57,9 @@ public class MetaRemovePrefix extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String prefix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String prefix = ArgumentUtils.handleStringOrElse(1, args, "null");
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
|
||||
+4
-4
@@ -46,10 +46,10 @@ import java.util.stream.Collectors;
|
||||
public class MetaRemoveSuffix extends SharedSubCommand {
|
||||
public MetaRemoveSuffix() {
|
||||
super("removesuffix", "Removes a suffix", Permission.USER_META_REMOVESUFFIX, Permission.GROUP_META_REMOVESUFFIX,
|
||||
Predicates.notInRange(2, 4),
|
||||
Predicates.notInRange(1, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the suffix at"),
|
||||
Arg.create("suffix", true, "the suffix string"),
|
||||
Arg.create("suffix", false, "the suffix string"),
|
||||
Arg.create("server", false, "the server to add the suffix on"),
|
||||
Arg.create("world", false, "the world to add the suffix on")
|
||||
)
|
||||
@@ -57,9 +57,9 @@ public class MetaRemoveSuffix extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String suffix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String suffix = ArgumentUtils.handleStringOrElse(1, args, "null");
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
|
||||
+6
-6
@@ -45,10 +45,11 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class MetaRemoveTempPrefix extends SharedSubCommand {
|
||||
public MetaRemoveTempPrefix() {
|
||||
super("removetempprefix", "Removes a temporary prefix", Permission.USER_META_REMOVETEMP_PREFIX, Permission.GROUP_META_REMOVETEMP_PREFIX, Predicates.notInRange(2, 4),
|
||||
super("removetempprefix", "Removes a temporary prefix", Permission.USER_META_REMOVETEMP_PREFIX, Permission.GROUP_META_REMOVETEMP_PREFIX,
|
||||
Predicates.notInRange(1, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the prefix at"),
|
||||
Arg.create("prefix", true, "the prefix string"),
|
||||
Arg.create("prefix", false, "the prefix string"),
|
||||
Arg.create("server", false, "the server to add the prefix on"),
|
||||
Arg.create("world", false, "the world to add the prefix on")
|
||||
)
|
||||
@@ -56,9 +57,9 @@ public class MetaRemoveTempPrefix extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String prefix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String prefix = ArgumentUtils.handleStringOrElse(1, args, "null");
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
@@ -90,8 +91,7 @@ public class MetaRemoveTempPrefix extends SharedSubCommand {
|
||||
toRemove.forEach(n -> {
|
||||
try {
|
||||
holder.unsetPermission(n);
|
||||
} catch (ObjectLacksException ignored) {
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
Message.BULK_CHANGE_SUCCESS.send(sender, toRemove.size());
|
||||
|
||||
+5
-4
@@ -45,10 +45,11 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class MetaRemoveTempSuffix extends SharedSubCommand {
|
||||
public MetaRemoveTempSuffix() {
|
||||
super("removetempsuffix", "Removes a temporary suffix", Permission.USER_META_REMOVETEMP_SUFFIX, Permission.GROUP_META_REMOVETEMP_SUFFIX, Predicates.notInRange(2, 4),
|
||||
super("removetempsuffix", "Removes a temporary suffix", Permission.USER_META_REMOVETEMP_SUFFIX, Permission.GROUP_META_REMOVETEMP_SUFFIX,
|
||||
Predicates.notInRange(1, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the suffix at"),
|
||||
Arg.create("suffix", true, "the suffix string"),
|
||||
Arg.create("suffix", false, "the suffix string"),
|
||||
Arg.create("server", false, "the server to add the suffix on"),
|
||||
Arg.create("world", false, "the world to add the suffix on")
|
||||
)
|
||||
@@ -56,9 +57,9 @@ public class MetaRemoveTempSuffix extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String suffix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String suffix = ArgumentUtils.handleStringOrElse(1, args, "null");
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public class MetaSet extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
String key = args.get(0);
|
||||
String value = args.get(1);
|
||||
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public class MetaSetTemp extends SharedSubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label) throws CommandException {
|
||||
String key = args.get(0);
|
||||
String value = args.get(1);
|
||||
long duration = ArgumentUtils.handleDuration(2, args);
|
||||
|
||||
Loaded 100 of 227 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user