Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa9324bda8 | ||
|
|
1e72f9d8fe | ||
|
|
50fd954599 | ||
|
|
b1e34b55f8 | ||
|
|
cff1b8a411 | ||
|
|
6ffa6720be | ||
|
|
f52a106165 | ||
|
|
bf247b71e1 | ||
|
|
66818e4c82 | ||
|
|
23d53d39b4 | ||
|
|
30ea5a5b69 | ||
|
|
e7a210dc06 | ||
|
|
497de9824a | ||
|
|
be74b50762 | ||
|
|
f2e06b56e7 | ||
|
|
f6aa20c300 | ||
|
|
5e16134f6f | ||
|
|
6165fcbb21 | ||
|
|
831e882db0 | ||
|
|
feb8bf4bd3 | ||
|
|
ce3ee866ca | ||
|
|
d29dd35689 | ||
|
|
3a0a89853f | ||
|
|
e7ca79d251 | ||
|
|
22426bab33 | ||
|
|
116094ea96 | ||
|
|
9df39a9545 | ||
|
|
b8f44df723 | ||
|
|
74f275eb69 | ||
|
|
1142cbcb2c | ||
|
|
37749e5829 | ||
|
|
f9025c7a51 | ||
|
|
c7bfc38477 | ||
|
|
7ca394d7b9 | ||
|
|
31884ea59d | ||
|
|
e79b7c7023 | ||
|
|
1fdb4e8ade | ||
|
|
53db8c5928 | ||
|
|
07514000a4 | ||
|
|
f28721e55a | ||
|
|
fc230291d3 | ||
|
|
89ff4cfa40 | ||
|
|
d786b6abb2 | ||
|
|
fb0e694155 | ||
|
|
cd6cac1fb6 | ||
|
|
ea07f05097 | ||
|
|
d84767af68 | ||
|
|
aab73a8d81 | ||
|
|
995fc2ccd8 | ||
|
|
60bcd5f643 | ||
|
|
ba04fb320b | ||
|
|
770b7dc282 | ||
|
|
ed85eee36c | ||
|
|
23df8a2df8 | ||
|
|
36cd388607 | ||
|
|
4d48ef1939 | ||
|
|
7970e2a1c6 | ||
|
|
cee96d7daa | ||
|
|
861c1ddd69 | ||
|
|
5dec5a54cb | ||
|
|
5c760aabd4 | ||
|
|
1a2fa5d8c3 | ||
|
|
ef0c53da82 | ||
|
|
3fd62a80e2 | ||
|
|
5c19dd8b15 | ||
|
|
1fc88e147f | ||
|
|
9b4bbe0500 | ||
|
|
b37fdd3619 | ||
|
|
ab00c41452 | ||
|
|
c15727377b | ||
|
|
1e6f32bdc4 | ||
|
|
42e69c98a7 | ||
|
|
a217727bb4 | ||
|
|
ba10b1c06e | ||
|
|
075ba33e8b | ||
|
|
19dbc7d90a | ||
|
|
ade70bb7ba | ||
|
|
4b67913eee | ||
|
|
75858c1555 | ||
|
|
659baaf5fb | ||
|
|
3c83c578eb | ||
|
|
3ddbf1da87 | ||
|
|
35cb5b81dc | ||
|
|
02d9b996a7 | ||
|
|
d4cf6a5ad7 | ||
|
|
9fdb4fa25f | ||
|
|
d5bc1cdf5d | ||
|
|
f5995c0afa | ||
|
|
2cc65160b4 |
No files matched your search
@@ -1,5 +1,6 @@
|
||||

|
||||
# LuckPerms [](https://ci.lucko.me/job/LuckPerms/)
|
||||
A permissions implementation for Bukkit/Spigot, BungeeCord and Sponge.
|
||||
An advanced permissions implementation for Bukkit/Spigot, BungeeCord and Sponge.
|
||||
|
||||
## Links
|
||||
* **Development Builds** - <https://ci.lucko.me/job/LuckPerms>
|
||||
@@ -9,9 +10,17 @@ A permissions implementation for Bukkit/Spigot, BungeeCord and Sponge.
|
||||
## Description
|
||||
LuckPerms is an advanced permissions implementation aiming to be a flexible, performant and reliable alternative to other permission systems, providing all the features you could ever possibly need in a permissions plugin, along with an extensive and well documented API for developers.
|
||||
|
||||
* [Spigot Plugin Page](https://www.spigotmc.org/resources/luckperms-an-advanced-permissions-system.28140/ "Spigot Plugin Page")
|
||||
* [Sponge Plugin Page](https://forums.spongepowered.org/t/luckperms-an-advanced-permissions-system/14274 "Sponge Plugin Page")
|
||||
|
||||
## LuckPerms vs Other Plugins
|
||||

|
||||
_Features checked on 23rd Aug 2016. If you find any inaccuracies, please do let me know. I tried to be as fair as possible, and copy all major features from the respective plugin pages._
|
||||
|
||||
## License
|
||||
See LICENSE.md.
|
||||
|
||||
## Thanks to:
|
||||
[](http://www.ej-technologies.com/products/jprofiler/overview.html)
|
||||
|
||||
Thanks to ej-technologies for granting LuckPerms an open source licence to their [java profiling software](http://www.ej-technologies.com/products/jprofiler/overview.html "Java Profiler").
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.6-SNAPSHOT</version>
|
||||
<version>2.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Wrapper interface for the internal Datastore instance
|
||||
* Interface for the internal Datastore instance
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Datastore {
|
||||
@@ -55,7 +55,7 @@ public interface Datastore {
|
||||
Async async();
|
||||
|
||||
/**
|
||||
* Gets the {@link Future} interface
|
||||
* Gets the {@link Future} interface.
|
||||
*
|
||||
* All operations through this interface are called in a new, separate asynchronous thread, similar to {@link Async}.
|
||||
* The only difference is that instead of providing a callback, a {@link java.util.concurrent.Future} is returned.
|
||||
@@ -112,7 +112,7 @@ public interface Datastore {
|
||||
* @param username the users username. (if you want to specify <code>null</code> here, just input "null" as a string.)
|
||||
* @return if the operation was performed successfully
|
||||
* @throws NullPointerException if uuid or username is null
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
boolean loadUser(UUID uuid, String username);
|
||||
|
||||
@@ -128,14 +128,14 @@ public interface Datastore {
|
||||
/**
|
||||
* Removes users from the datastore who are "default". This is called every time the plugin loads.
|
||||
* @return true if the operation completed successfully
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
boolean cleanupUsers();
|
||||
|
||||
/**
|
||||
* Gets a set all user's UUIDs who are "unique", and aren't just a member of the "default" group.
|
||||
* @return a set of uuids, or null if the operation failed.
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<UUID> getUniqueUsers();
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper interface for internal Group instances
|
||||
* Interface for internal Group instances
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Group extends PermissionHolder {
|
||||
|
||||
@@ -25,6 +25,8 @@ package me.lucko.luckperms.api;
|
||||
import me.lucko.luckperms.api.data.DatastoreConfiguration;
|
||||
import me.lucko.luckperms.api.data.MySQLConfiguration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A wrapper interface for the internal LuckPerms configuration, providing read only access.
|
||||
*/
|
||||
@@ -43,14 +45,14 @@ public interface LPConfiguration {
|
||||
|
||||
/**
|
||||
* @return the default group, in a node representation
|
||||
* @deprecated as of 1.6, the default group is always "default"
|
||||
* @deprecated as of 2.6, the default group is always "default"
|
||||
*/
|
||||
@Deprecated
|
||||
String getDefaultGroupNode();
|
||||
|
||||
/**
|
||||
* @return the name of the default group
|
||||
* @deprecated as of 1.6, the default group is always "default"
|
||||
* @deprecated as of 2.6, the default group is always "default"
|
||||
*/
|
||||
@Deprecated
|
||||
String getDefaultGroupName();
|
||||
@@ -60,6 +62,24 @@ public interface LPConfiguration {
|
||||
*/
|
||||
boolean getIncludeGlobalPerms();
|
||||
|
||||
/**
|
||||
* @return if the users on this server will have their global world permissions applied
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getIncludeGlobalWorldPerms();
|
||||
|
||||
/**
|
||||
* @return true if the platform is applying global groups
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getApplyGlobalGroups();
|
||||
|
||||
/**
|
||||
* @return true if the platform is applying global world groups
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getApplyGlobalWorldGroups();
|
||||
|
||||
/**
|
||||
* @return the online mode setting in the config
|
||||
*/
|
||||
@@ -80,6 +100,48 @@ public interface LPConfiguration {
|
||||
*/
|
||||
boolean getApplyShorthand();
|
||||
|
||||
/**
|
||||
* @return if LuckPerms will send notifications to users when permissions are modified
|
||||
* @since 2.7
|
||||
*/
|
||||
boolean getLogNotify();
|
||||
|
||||
/**
|
||||
* @return true if permission checks are being recorded / debugged
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getDebugPermissionChecks();
|
||||
|
||||
/**
|
||||
* @return true if the vanilla op system is enabled
|
||||
* @since 2.8
|
||||
*/
|
||||
boolean getEnableOps();
|
||||
|
||||
/**
|
||||
* @return true if opped players are allowed to use LuckPerms commands
|
||||
* @since 2.8
|
||||
*/
|
||||
boolean getCommandsAllowOp();
|
||||
|
||||
/**
|
||||
* @return true if auto op is enabled
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getAutoOp();
|
||||
|
||||
/**
|
||||
* @return the name of the server used within Vault operations
|
||||
* @since 2.7
|
||||
*/
|
||||
String getVaultServer();
|
||||
|
||||
/**
|
||||
* @return true if global permissions should be considered when retrieving meta or player groups
|
||||
* @since 2.7
|
||||
*/
|
||||
boolean getVaultIncludeGlobal();
|
||||
|
||||
/**
|
||||
* @return the database values set in the configuration
|
||||
* @deprecated use {@link #getDatastoreConfig()}
|
||||
@@ -98,4 +160,17 @@ public interface LPConfiguration {
|
||||
*/
|
||||
String getStorageMethod();
|
||||
|
||||
/**
|
||||
* @return true if split storage is enabled
|
||||
* @since 2.7
|
||||
*/
|
||||
boolean getSplitStorage();
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
Map<String, String> getSplitStorageOptions();
|
||||
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import java.util.UUID;
|
||||
/**
|
||||
* Represents a single entry in a log
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class LogEntry implements Comparable<LogEntry> {
|
||||
public static LogEntryBuilder builder() {
|
||||
return new LogEntryBuilder();
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* A wrapper class 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.
|
||||
|
||||
@@ -41,7 +41,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* @return the version of the API running on the platform
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
double getApiVersion();
|
||||
|
||||
@@ -50,6 +50,12 @@ public interface LuckPermsApi {
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* @return the platform LuckPerms is running on
|
||||
* @since 2.7
|
||||
*/
|
||||
PlatformType getPlatformType();
|
||||
|
||||
/**
|
||||
* Registers a listener to be sent LuckPerms events
|
||||
* @param listener the listener instance
|
||||
@@ -138,7 +144,7 @@ public interface LuckPermsApi {
|
||||
* Unload a user from the internal storage, if they're not currently online.
|
||||
* @param user the user to unload
|
||||
* @throws NullPointerException if the user is null
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
void cleanupUser(User user);
|
||||
|
||||
@@ -181,7 +187,7 @@ public interface LuckPermsApi {
|
||||
Track getTrack(String name);
|
||||
|
||||
/**
|
||||
* Gets a wrapped tracj object from the track storage. This method does not return null, unlike {@link #getTrack}
|
||||
* Gets a wrapped track object from the track storage. This method does not return null, unlike {@link #getTrack}
|
||||
* @param name the name of the track to get
|
||||
* @return an optional {@link Track} object
|
||||
* @throws NullPointerException if the name is null
|
||||
@@ -208,7 +214,7 @@ public interface LuckPermsApi {
|
||||
* @return a {@link Node.Builder} instance
|
||||
* @throws IllegalArgumentException if the permission is invalid
|
||||
* @throws NullPointerException if the permission is null
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
Node.Builder buildNode(String permission) throws IllegalArgumentException;
|
||||
|
||||
|
||||
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* 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 me.lucko.luckperms.LuckPerms;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A collection of utilities to help retrieve meta values for {@link PermissionHolder}s
|
||||
* @since 2.7
|
||||
*/
|
||||
public class MetaUtils {
|
||||
|
||||
private MetaUtils(){}
|
||||
|
||||
/**
|
||||
* Escapes special characters used within LuckPerms, so the string can be saved without issues
|
||||
* @param s the string to escape
|
||||
* @return an escaped string
|
||||
* @throws NullPointerException if the string is null
|
||||
*/
|
||||
public static String escapeCharacters(String s) {
|
||||
if (s == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
s = s.replace(".", "{SEP}");
|
||||
s = s.replace("/", "{FSEP}");
|
||||
s = s.replace("$", "{DSEP}");
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unescapes special characters used within LuckPerms, the inverse of {@link #escapeCharacters(String)}
|
||||
* @param s the string to unescape
|
||||
* @return an unescaped string
|
||||
* @throws NullPointerException if the string is null
|
||||
*/
|
||||
public static String unescapeCharacters(String s) {
|
||||
if (s == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
s = s.replace("{SEP}", ".");
|
||||
s = s.replace("{FSEP}", "/");
|
||||
s = s.replace("{DSEP}", "$");
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a meta value on a holder
|
||||
* @param holder the holder to apply the meta node to
|
||||
* @param server the server to apply the meta on, can be null
|
||||
* @param world the world to apply the meta on, can be null
|
||||
* @param node the meta node
|
||||
* @param value the meta value
|
||||
* @throws NullPointerException if the holder, node or value is null
|
||||
* @throws IllegalArgumentException if the node or value is empty
|
||||
*/
|
||||
public static void setMeta(PermissionHolder holder, String server, String world, String node, String value) {
|
||||
if (holder == null) {
|
||||
throw new NullPointerException("holder");
|
||||
}
|
||||
|
||||
if (node == null) {
|
||||
throw new NullPointerException("node");
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
if (node.equals("")) {
|
||||
throw new IllegalArgumentException("node is empty");
|
||||
}
|
||||
|
||||
if (value.equals("")) {
|
||||
throw new IllegalArgumentException("value is empty");
|
||||
}
|
||||
|
||||
if (server == null || server.equals("")) {
|
||||
server = "global";
|
||||
}
|
||||
|
||||
node = escapeCharacters(node);
|
||||
value = escapeCharacters(value);
|
||||
|
||||
Set<Node> toRemove = new HashSet<>();
|
||||
for (Node n : holder.getEnduringPermissions()) {
|
||||
if (n.isMeta() && n.getMeta().getKey().equals(node)) {
|
||||
toRemove.add(n);
|
||||
}
|
||||
}
|
||||
|
||||
for (Node n : toRemove) {
|
||||
try {
|
||||
holder.unsetPermission(n);
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
}
|
||||
|
||||
Node.Builder metaNode = LuckPerms.getApi().buildNode("meta." + node + "." + value).setValue(true);
|
||||
if (!server.equalsIgnoreCase("global")) {
|
||||
metaNode.setServer(server);
|
||||
}
|
||||
if (world != null && !world.equals("")) {
|
||||
metaNode.setServer(server).setWorld(world);
|
||||
}
|
||||
|
||||
try {
|
||||
holder.setPermission(metaNode.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a meta value for the holder
|
||||
* @param holder the holder to get the meta from
|
||||
* @param server the server to retrieve the meta on, can be null
|
||||
* @param world the world to retrieve the meta on, can be null
|
||||
* @param node the node to get
|
||||
* @param defaultValue the default value to return if the node is not set
|
||||
* @param includeGlobal if global nodes should be considered when retrieving the meta
|
||||
* @return a meta string, or the default value if the user does not have the meta node
|
||||
* @throws NullPointerException if the holder or node is null
|
||||
* @throws IllegalArgumentException if the node is empty
|
||||
*/
|
||||
public static String getMeta(PermissionHolder holder, String server, String world, String node, String defaultValue, boolean includeGlobal) {
|
||||
if (holder == null) {
|
||||
throw new NullPointerException("holder");
|
||||
}
|
||||
|
||||
if (server == null || server.equals("")) {
|
||||
server = "global";
|
||||
}
|
||||
|
||||
if (node == null) {
|
||||
throw new NullPointerException("node");
|
||||
}
|
||||
|
||||
if (node.equals("")) {
|
||||
throw new IllegalArgumentException("node is empty");
|
||||
}
|
||||
|
||||
node = escapeCharacters(node);
|
||||
|
||||
for (Node n : holder.getPermissions()) {
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.isMeta()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!server.equalsIgnoreCase("global")) {
|
||||
if (!n.shouldApplyOnServer(server, includeGlobal, false)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, includeGlobal, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map.Entry<String, String> meta = n.getMeta();
|
||||
if (meta.getKey().equalsIgnoreCase(node)) {
|
||||
return unescapeCharacters(meta.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static void setChatMeta(boolean prefix, PermissionHolder holder, String value, int priority, String server, String world) {
|
||||
if (holder == null) {
|
||||
throw new NullPointerException("holder");
|
||||
}
|
||||
|
||||
if (value == null || value.equals("")) {
|
||||
throw new IllegalArgumentException("value is null/empty");
|
||||
}
|
||||
|
||||
Node.Builder node = LuckPerms.getApi().buildNode(prefix ? "prefix" : "suffix" + "." + priority + "." + escapeCharacters(value));
|
||||
node.setValue(true);
|
||||
if (!server.equalsIgnoreCase("global")) {
|
||||
node.setServer(server);
|
||||
}
|
||||
if (world != null && !world.equals("")) {
|
||||
node.setServer(server).setWorld(world);
|
||||
}
|
||||
|
||||
try {
|
||||
holder.setPermission(node.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a prefix to a holder on a specific server and world
|
||||
* @param holder the holder to set the prefix for
|
||||
* @param prefix the prefix value
|
||||
* @param priority the priority to set the prefix at
|
||||
* @param server the server to set the prefix on, can be null
|
||||
* @param world the world to set the prefix on, can be null
|
||||
* @throws NullPointerException if the holder is null
|
||||
* @throws IllegalArgumentException if the prefix is null or empty
|
||||
*/
|
||||
public static void setPrefix(PermissionHolder holder, String prefix, int priority, String server, String world) {
|
||||
setChatMeta(true, holder, prefix, priority, server, world);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a suffix to a holder on a specific server and world
|
||||
* @param holder the holder to set the suffix for
|
||||
* @param suffix the suffix value
|
||||
* @param priority the priority to set the suffix at
|
||||
* @param server the server to set the suffix on, can be null
|
||||
* @param world the world to set the suffix on, can be null
|
||||
* @throws NullPointerException if the holder is null
|
||||
* @throws IllegalArgumentException if the suffix is null or empty
|
||||
*/
|
||||
public static void setSuffix(PermissionHolder holder, String suffix, int priority, String server, String world) {
|
||||
setChatMeta(false, holder, suffix, priority, server, world);
|
||||
}
|
||||
|
||||
private static String getChatMeta(boolean prefix, PermissionHolder holder, String server, String world, boolean includeGlobal) {
|
||||
if (holder == null) {
|
||||
throw new NullPointerException("holder");
|
||||
}
|
||||
if (server == null) {
|
||||
server = "global";
|
||||
}
|
||||
|
||||
int priority = Integer.MIN_VALUE;
|
||||
String meta = null;
|
||||
for (Node n : holder.getAllNodes()) {
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!server.equalsIgnoreCase("global")) {
|
||||
if (!n.shouldApplyOnServer(server, includeGlobal, false)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, includeGlobal, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prefix ? !n.isPrefix() : !n.isSuffix()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map.Entry<Integer, String> value = prefix ? n.getPrefix() : n.getSuffix();
|
||||
if (value.getKey() > priority) {
|
||||
meta = value.getValue();
|
||||
priority = value.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
return meta == null ? "" : unescapeCharacters(meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a holders highest priority prefix, if they have one
|
||||
* @param holder the holder
|
||||
* @param server the server to retrieve the prefix on
|
||||
* @param world the world to retrieve the prefix on
|
||||
* @param includeGlobal if global nodes should be considered when retrieving the prefix
|
||||
* @return a prefix string, if the holder has one, or an empty string if not.
|
||||
* @throws NullPointerException if the holder is null
|
||||
*/
|
||||
public static String getPrefix(PermissionHolder holder, String server, String world, boolean includeGlobal) {
|
||||
return getChatMeta(true, holder, server, world, includeGlobal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a holders highest priority suffix, if they have one
|
||||
* @param holder the holder
|
||||
* @param server the server to retrieve the suffix on
|
||||
* @param world the world to retrieve the suffix on
|
||||
* @param includeGlobal if global nodes should be considered when retrieving the suffix
|
||||
* @return a suffix string, if the holder has one, or an empty string if not.
|
||||
* @throws NullPointerException if the holder is null
|
||||
*/
|
||||
public static String getSuffix(PermissionHolder holder, String server, String world, boolean includeGlobal) {
|
||||
return getChatMeta(false, holder, server, world, includeGlobal);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,8 +30,9 @@ import java.util.Optional;
|
||||
/**
|
||||
* Represents an immutable node object
|
||||
* <p> Use {@link LuckPermsApi#buildNode(String)} to get an instance.
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
@@ -246,19 +247,38 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
Map.Entry<Integer, String> getSuffix();
|
||||
|
||||
/**
|
||||
* Similar to {@link #equals(Object)}, except doesn't take note of the value
|
||||
* @param node the other node
|
||||
* @return true if the two nodes are almost equal
|
||||
* Checks if this Node is equal to another node
|
||||
* @param obj the other node
|
||||
* @return true if this node is equal to the other provided
|
||||
* @see #equalsIgnoringValue(Node) for a less strict implementation of this method
|
||||
*/
|
||||
boolean equalsIgnoringValue(Node node);
|
||||
boolean equals(Object obj);
|
||||
|
||||
/**
|
||||
* Similar to {@link #equals(Object)}, except doesn't take note of the expiry time or value
|
||||
* @param node the other node
|
||||
* Similar to {@link Node#equals(Object)}, except doesn't take note of the value
|
||||
* @param other the other node
|
||||
* @return true if the two nodes are almost equal
|
||||
*/
|
||||
boolean almostEquals(Node node);
|
||||
boolean equalsIgnoringValue(Node other);
|
||||
|
||||
/**
|
||||
* Similar to {@link Node#equals(Object)}, except doesn't take note of the expiry time or value
|
||||
* @param other the other node
|
||||
* @return true if the two nodes are almost equal
|
||||
*/
|
||||
boolean almostEquals(Node other);
|
||||
|
||||
/**
|
||||
* Similar to {@link Node#equals(Object)}, except doesn't take note of the value or if the node is temporary
|
||||
* @param other the other node
|
||||
* @return true if the two nodes are almost equal
|
||||
* @since 2.8
|
||||
*/
|
||||
boolean equalsIgnoringValueOrTemp(Node other);
|
||||
|
||||
/**
|
||||
* Builds a Node instance
|
||||
*/
|
||||
interface Builder {
|
||||
Builder setNegated(boolean negated);
|
||||
Builder setValue(boolean value);
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
/**
|
||||
* Wrapper interface for internal PermissionHolder (user/group) instances
|
||||
* Interface for internal PermissionHolder (user/group) instances
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface PermissionHolder {
|
||||
@@ -45,21 +45,21 @@ public interface PermissionHolder {
|
||||
/**
|
||||
* Gets an immutable Set of the objects permission nodes
|
||||
* @return an immutable set of permissions in priority order
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
SortedSet<Node> getPermissions();
|
||||
|
||||
/**
|
||||
* Similar to {@link #getPermissions()}, except excluding transient permissions
|
||||
* @return a set of nodes
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getEnduringPermissions();
|
||||
|
||||
/**
|
||||
* Similar to {@link #getPermissions()}, except excluding non-transient permissions
|
||||
* @return a set of nodes
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getTransientPermissions();
|
||||
|
||||
@@ -67,7 +67,7 @@ public interface PermissionHolder {
|
||||
/**
|
||||
* Gets an immutable set of the nodes that this object has and inherits
|
||||
* @return an immutable set of permissions
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getAllNodes();
|
||||
|
||||
@@ -84,7 +84,7 @@ public interface PermissionHolder {
|
||||
* @param node the node to check for
|
||||
* @return a Tristate for the holders permission status for the node
|
||||
* @throws NullPointerException if the node is null
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
Tristate hasPermission(Node node);
|
||||
|
||||
@@ -93,7 +93,7 @@ public interface PermissionHolder {
|
||||
* @param node the node to check for
|
||||
* @return a Tristate for the holders permission status for the node
|
||||
* @throws NullPointerException if the node is null
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
Tristate hasTransientPermission(Node node);
|
||||
|
||||
@@ -171,7 +171,7 @@ public interface PermissionHolder {
|
||||
* @param node the node to check for
|
||||
* @return a Tristate for the holders inheritance status for the node
|
||||
* @throws NullPointerException if the node is null
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
Tristate inheritsPermission(Node node);
|
||||
|
||||
@@ -249,7 +249,7 @@ public interface PermissionHolder {
|
||||
* @param node The node to be set
|
||||
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
void setPermission(Node node) throws ObjectAlreadyHasException;
|
||||
|
||||
@@ -267,7 +267,7 @@ public interface PermissionHolder {
|
||||
* @param node The node to be set
|
||||
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
void setTransientPermission(Node node) throws ObjectAlreadyHasException;
|
||||
|
||||
@@ -357,7 +357,7 @@ public interface PermissionHolder {
|
||||
* @param node The node to be unset
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node is null
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
void unsetPermission(Node node) throws ObjectLacksException;
|
||||
|
||||
@@ -366,7 +366,7 @@ public interface PermissionHolder {
|
||||
* @param node The node to be unset
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node is null
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
void unsetTransientPermission(Node node) throws ObjectLacksException;
|
||||
|
||||
@@ -498,7 +498,7 @@ public interface PermissionHolder {
|
||||
* @param possibleNodes a list of possible permissions for resolving wildcards
|
||||
* @param applyGroups if inherited group permissions should be included
|
||||
* @return a map of permissions
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
Map<String, Boolean> getPermissions(String server, String world, Map<String, String> extraContext, boolean includeGlobal, List<String> possibleNodes, boolean applyGroups);
|
||||
|
||||
@@ -513,7 +513,7 @@ public interface PermissionHolder {
|
||||
/**
|
||||
* Processes the nodes and returns the temporary ones.
|
||||
* @return a set of temporary nodes
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getTemporaryPermissionNodes();
|
||||
|
||||
@@ -528,7 +528,7 @@ public interface PermissionHolder {
|
||||
/**
|
||||
* Processes the nodes and returns the non-temporary ones.
|
||||
* @return a set of permanent nodes
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getPermanentPermissionNodes();
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* Represents the platform type that LuckPerms is running on
|
||||
* @since 2.7
|
||||
*/
|
||||
public enum PlatformType {
|
||||
|
||||
BUKKIT("Bukkit"),
|
||||
BUNGEE("Bungee"),
|
||||
SPONGE("Sponge"),
|
||||
|
||||
/**
|
||||
* @since 2.9
|
||||
*/
|
||||
STANDALONE("Standalone");
|
||||
|
||||
private final String friendlyName;
|
||||
|
||||
PlatformType(String friendlyName) {
|
||||
this.friendlyName = friendlyName;
|
||||
}
|
||||
|
||||
public String getFriendlyName() {
|
||||
return friendlyName;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper interface for internal Track instances
|
||||
* Interface for internal Track instances
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Track {
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Wrapper interface for internal User instances
|
||||
* Interface for internal User instances
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface User extends PermissionHolder {
|
||||
|
||||
@@ -25,7 +25,9 @@ package me.lucko.luckperms.api;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* This UuidCache is a means of allowing users to have the same internal UUID across a network of offline mode servers
|
||||
* 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 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.
|
||||
@@ -35,6 +37,7 @@ import java.util.UUID;
|
||||
*
|
||||
* <p> WARNING: THIS IS ONLY EFFECTIVE FOR ONLINE PLAYERS. USE THE DATASTORE METHODS FOR OFFLINE PLAYERS.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface UuidCache {
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@ import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.PermissionHolder;
|
||||
|
||||
/**
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
public class AbstractPermissionEvent extends TargetedEvent<PermissionHolder> {
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import me.lucko.luckperms.api.event.AbstractPermissionEvent;
|
||||
|
||||
/**
|
||||
* Called when a temporary permission node expires
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
public class PermissionNodeExpireEvent extends AbstractPermissionEvent {
|
||||
public PermissionNodeExpireEvent(PermissionHolder target, Node node) {
|
||||
|
||||
@@ -28,7 +28,7 @@ import me.lucko.luckperms.api.event.AbstractPermissionEvent;
|
||||
|
||||
/**
|
||||
* Called when a permission node is set on a holder
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
public class PermissionNodeSetEvent extends AbstractPermissionEvent {
|
||||
public PermissionNodeSetEvent(PermissionHolder target, Node node) {
|
||||
|
||||
@@ -28,7 +28,7 @@ import me.lucko.luckperms.api.event.AbstractPermissionEvent;
|
||||
|
||||
/**
|
||||
* Called when a permission node is unset from a holder
|
||||
* @since 1.6
|
||||
* @since 2.6
|
||||
*/
|
||||
public class PermissionNodeUnsetEvent extends AbstractPermissionEvent {
|
||||
public PermissionNodeUnsetEvent(PermissionHolder target, Node node) {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.exceptions;
|
||||
|
||||
/**
|
||||
* Thrown when a permission holding object doesn't / already has a permission or isn't / is already is a member of a group
|
||||
* @since 2.7
|
||||
*/
|
||||
public abstract class MembershipException extends Exception {
|
||||
}
|
||||
@@ -26,5 +26,5 @@ package me.lucko.luckperms.exceptions;
|
||||
* Thrown when a permission holding object already has a permission, is already a member of a group, or when a track
|
||||
* already contains a group.
|
||||
*/
|
||||
public class ObjectAlreadyHasException extends Exception {
|
||||
public class ObjectAlreadyHasException extends MembershipException {
|
||||
}
|
||||
@@ -26,5 +26,5 @@ package me.lucko.luckperms.exceptions;
|
||||
* Thrown when a permission holding object does not already have a permission, is not already a member of a group,
|
||||
* or when a track doesn't contain a group.
|
||||
*/
|
||||
public class ObjectLacksException extends Exception {
|
||||
public class ObjectLacksException extends MembershipException {
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.9-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>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</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>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>pl.project13.maven</groupId>
|
||||
<artifactId>git-commit-id-plugin</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>revision</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<injectAllReactorProjects>true</injectAllReactorProjects>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<!-- LuckPerms Bukkit -->
|
||||
<dependency>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<artifactId>luckperms-bukkit</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Shade gson and guava, as they are not included in earlier Bukkit releases -->
|
||||
<!-- gson -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.7</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- guava -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>19.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.6-SNAPSHOT</version>
|
||||
<version>2.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
<dependency>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<artifactId>luckperms-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
<version>2.8</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- BukkitAPI -->
|
||||
<dependency>
|
||||
|
||||
+13
-79
@@ -25,15 +25,11 @@ package me.lucko.luckperms.api.placeholders;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.util.TimeUtil;
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
import me.lucko.luckperms.api.Track;
|
||||
import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/*
|
||||
* PlaceholderAPI Expansion for LuckPerms, implemented using the LuckPerms API.
|
||||
@@ -51,7 +47,6 @@ import java.util.regex.Pattern;
|
||||
* - suffix
|
||||
* - meta_<node>
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
private static final String IDENTIFIER = "luckperms";
|
||||
private static final String PLUGIN_NAME = "LuckPerms";
|
||||
@@ -76,7 +71,7 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return api == null ? "null" : api.getVersion();
|
||||
return "2.8";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,7 +80,7 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
return "";
|
||||
}
|
||||
|
||||
Optional<User> u = api.getUserSafe(player.getUniqueId());
|
||||
Optional<User> u = api.getUserSafe(api.getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (!u.isPresent()) {
|
||||
return "";
|
||||
}
|
||||
@@ -128,17 +123,11 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
if (identifier.startsWith("expiry_time_") && identifier.length() > "expiry_time_".length()) {
|
||||
String node = identifier.substring("expiry_time_".length());
|
||||
|
||||
|
||||
long currentTime = System.currentTimeMillis() / 1000L;
|
||||
Map<Map.Entry<String, Boolean>, Long> temps = user.getTemporaryNodes();
|
||||
|
||||
for (Map.Entry<Map.Entry<String, Boolean>, Long> e : temps.entrySet()) {
|
||||
if (!e.getKey().getKey().equalsIgnoreCase(node)) {
|
||||
continue;
|
||||
for (Node n : user.getTemporaryPermissionNodes()) {
|
||||
if (n.getPermission().equalsIgnoreCase(node)) {
|
||||
return TimeUtil.getTime((int) (n.getExpiryUnixTime() - currentTime));
|
||||
}
|
||||
|
||||
return TimeUtil.getTime((int) (e.getValue() - currentTime));
|
||||
}
|
||||
|
||||
return "";
|
||||
@@ -146,42 +135,27 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
if (identifier.startsWith("group_expiry_time_") && identifier.length() > "group_expiry_time_".length()) {
|
||||
String node = "group." + identifier.substring("group_expiry_time_".length());
|
||||
|
||||
long currentTime = System.currentTimeMillis() / 1000L;
|
||||
Map<Map.Entry<String, Boolean>, Long> temps = user.getTemporaryNodes();
|
||||
|
||||
for (Map.Entry<Map.Entry<String, Boolean>, Long> e : temps.entrySet()) {
|
||||
if (!e.getKey().getKey().equalsIgnoreCase(node)) {
|
||||
continue;
|
||||
for (Node n : user.getTemporaryPermissionNodes()) {
|
||||
if (n.getPermission().equalsIgnoreCase(node)) {
|
||||
return TimeUtil.getTime((int) (n.getExpiryUnixTime() - currentTime));
|
||||
}
|
||||
|
||||
return TimeUtil.getTime((int) (e.getValue() - currentTime));
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
if (identifier.equalsIgnoreCase("prefix")) {
|
||||
return getChatMeta(PREFIX_PATTERN, user);
|
||||
return MetaUtils.getPrefix(user, null, null, true);
|
||||
}
|
||||
|
||||
if (identifier.equalsIgnoreCase("suffix")) {
|
||||
return getChatMeta(SUFFIX_PATTERN, user);
|
||||
return MetaUtils.getSuffix(user, null, null, true);
|
||||
}
|
||||
|
||||
if (identifier.startsWith("meta_") && identifier.length() > "meta_".length()) {
|
||||
String node = "meta." + escapeCharacters(identifier.substring("meta_".length())) + ".";
|
||||
Map<String, Boolean> nodes = user.getNodes();
|
||||
|
||||
for (Map.Entry<String, Boolean> e : nodes.entrySet()) {
|
||||
if (!e.getValue()) continue;
|
||||
if (!e.getKey().toLowerCase().startsWith(node)) continue;
|
||||
|
||||
String meta = e.getKey().substring(node.length());
|
||||
return unescapeCharacters(meta);
|
||||
}
|
||||
|
||||
return "";
|
||||
String node = identifier.substring("meta_".length());
|
||||
return MetaUtils.getMeta(user, null, null, node, "", true);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -205,44 +179,4 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
private static String formatBoolean(boolean b) {
|
||||
return b ? PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanFalse();
|
||||
}
|
||||
|
||||
private static String escapeCharacters(String s) {
|
||||
s = s.replace(".", "{SEP}");
|
||||
s = s.replace("/", "{FSEP}");
|
||||
s = s.replace("$", "{DSEP}");
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private static String unescapeCharacters(String s) {
|
||||
s = s.replace("{SEP}", ".");
|
||||
s = s.replace("{FSEP}", "/");
|
||||
s = s.replace("{DSEP}", "$");
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private static final Pattern PREFIX_PATTERN = Pattern.compile("(?i)prefix\\.\\d+\\..*");
|
||||
private static final Pattern SUFFIX_PATTERN = Pattern.compile("(?i)suffix\\.\\d+\\..*");
|
||||
private static final Pattern DOT_PATTERN = Pattern.compile("\\.");
|
||||
|
||||
private static String getChatMeta(Pattern pattern, User user) {
|
||||
int priority = 0;
|
||||
String meta = null;
|
||||
for (Map.Entry<String, Boolean> e : user.getLocalPermissions(null, null).entrySet()) {
|
||||
if (!e.getValue()) continue;
|
||||
|
||||
if (pattern.matcher(e.getKey()).matches()) {
|
||||
String[] parts = DOT_PATTERN.split(e.getKey(), 3);
|
||||
int p = Integer.parseInt(parts[1]);
|
||||
|
||||
if (meta == null || p > priority) {
|
||||
meta = parts[2];
|
||||
priority = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return meta == null ? "" : unescapeCharacters(meta);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.6-SNAPSHOT</version>
|
||||
<version>2.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -22,8 +22,12 @@
|
||||
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.commands.CommandManager;
|
||||
import me.lucko.luckperms.commands.Util;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -39,7 +43,12 @@ class BukkitCommand extends CommandManager implements CommandExecutor, TabExecut
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
onCommand(BukkitSenderFactory.get().wrap(sender), label, Arrays.asList(args), Callback.empty());
|
||||
onCommand(
|
||||
BukkitSenderFactory.get().wrap(sender),
|
||||
label,
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))),
|
||||
Callback.empty()
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,16 +23,18 @@
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.inject.Injector;
|
||||
import me.lucko.luckperms.inject.LPPermissible;
|
||||
import me.lucko.luckperms.users.BukkitUser;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.AbstractListener;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
class BukkitListener extends AbstractListener implements Listener {
|
||||
private final LPBukkitPlugin plugin;
|
||||
@@ -42,10 +44,10 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent e) {
|
||||
if (!plugin.getDatastore().isAcceptingLogins()) {
|
||||
// Datastore is disabled, prevent players from joining the server
|
||||
// The datastore is disabled, prevent players from joining the server
|
||||
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.toString());
|
||||
return;
|
||||
}
|
||||
@@ -53,7 +55,7 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
onAsyncLogin(e.getUniqueId(), e.getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerLogin(PlayerLoginEvent e) {
|
||||
final Player player = e.getPlayer();
|
||||
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
@@ -66,36 +68,55 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
if (user instanceof BukkitUser) {
|
||||
BukkitUser u = (BukkitUser) user;
|
||||
|
||||
PermissionAttachment attachment = player.addAttachment(plugin);
|
||||
try {
|
||||
BukkitUser.getPermissionsField().set(attachment, new ConcurrentHashMap<>());
|
||||
LPPermissible lpPermissible = new LPPermissible(player, plugin);
|
||||
Injector.inject(player, lpPermissible);
|
||||
u.setLpPermissible(lpPermissible);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
u.setAttachment(attachment);
|
||||
}
|
||||
|
||||
plugin.doAsync(user::refreshPermissions);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerJoin(PlayerJoinEvent e) {
|
||||
// Refresh permissions again
|
||||
plugin.getUserManager().getWorldCache().put(e.getPlayer().getUniqueId(), e.getPlayer().getWorld().getName());
|
||||
plugin.doAsync(() -> refreshPlayer(e.getPlayer().getUniqueId()));
|
||||
UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
plugin.getUserManager().getWorldCache().put(internal, e.getPlayer().getWorld().getName());
|
||||
plugin.doAsync(() -> refreshPlayer(internal));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerChangedWorld(PlayerChangedWorldEvent e) {
|
||||
plugin.getUserManager().getWorldCache().put(e.getPlayer().getUniqueId(), e.getPlayer().getWorld().getName());
|
||||
plugin.doAsync(() -> refreshPlayer(e.getPlayer().getUniqueId()));
|
||||
UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
plugin.getUserManager().getWorldCache().put(internal, e.getPlayer().getWorld().getName());
|
||||
plugin.doAsync(() -> refreshPlayer(internal));
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerQuit(PlayerQuitEvent e) {
|
||||
plugin.getUserManager().getWorldCache().remove(e.getPlayer().getUniqueId());
|
||||
plugin.getUserManager().getWorldCache().remove(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||
onLeave(e.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerCommand(PlayerCommandPreprocessEvent e) {
|
||||
if (plugin.getConfiguration().getEnableOps()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String s = e.getMessage()
|
||||
.replace("/", "")
|
||||
.replace("bukkit:", "")
|
||||
.replace("spigot:", "")
|
||||
.replace("minecraft:", "");
|
||||
|
||||
if (s.startsWith("op") || s.startsWith("deop")) {
|
||||
e.setCancelled(true);
|
||||
e.getPlayer().sendMessage(Message.OP_DISABLED.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,8 +34,8 @@ import java.util.UUID;
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class BukkitSenderFactory extends SenderFactory<CommandSender> {
|
||||
private static BukkitSenderFactory instance = null;
|
||||
public static BukkitSenderFactory get() {
|
||||
if (instance == null){
|
||||
public static synchronized BukkitSenderFactory get() {
|
||||
if (instance == null) {
|
||||
instance = new BukkitSenderFactory();
|
||||
}
|
||||
return instance;
|
||||
|
||||
@@ -25,6 +25,7 @@ package me.lucko.luckperms;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.implementation.ApiProvider;
|
||||
import me.lucko.luckperms.api.vault.VaultHook;
|
||||
import me.lucko.luckperms.commands.ConsecutiveExecutor;
|
||||
@@ -43,6 +44,8 @@ import me.lucko.luckperms.users.BukkitUserManager;
|
||||
import me.lucko.luckperms.utils.LogFactory;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@@ -132,6 +135,11 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
registerPermissions(getConfiguration().getCommandsAllowOp() ? PermissionDefault.OP : PermissionDefault.FALSE);
|
||||
if (!getConfiguration().getEnableOps()) {
|
||||
getServer().getOperators().forEach(o -> o.setOp(false));
|
||||
}
|
||||
|
||||
getLog().info("Successfully loaded.");
|
||||
}
|
||||
|
||||
@@ -161,8 +169,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Type.BUKKIT;
|
||||
public PlatformType getType() {
|
||||
return PlatformType.BUKKIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -186,8 +194,11 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Sender> getSenders() {
|
||||
return getServer().getOnlinePlayers().stream().map(p -> BukkitSenderFactory.get().wrap(p)).collect(Collectors.toList());
|
||||
public List<Sender> getNotifyListeners() {
|
||||
return getServer().getOnlinePlayers().stream()
|
||||
.map(p -> BukkitSenderFactory.get().wrap(p, Collections.singleton(me.lucko.luckperms.constants.Permission.LOG_NOTIFY)))
|
||||
.filter(me.lucko.luckperms.constants.Permission.LOG_NOTIFY::isAuthorized)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -217,6 +228,16 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
return getServer().getServicesManager().load(clazz);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public UUID getUUID(String playerName) {
|
||||
try {
|
||||
return getServer().getOfflinePlayer(playerName).getUniqueId();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPluginLoaded(String name) {
|
||||
return getServer().getPluginManager().isPluginEnabled(name);
|
||||
@@ -226,4 +247,34 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
public void runUpdateTask() {
|
||||
getServer().getScheduler().runTaskAsynchronously(this, new UpdateTask(this));
|
||||
}
|
||||
|
||||
private void registerPermissions(PermissionDefault def) {
|
||||
PluginManager pm = getServer().getPluginManager();
|
||||
|
||||
Map<String, List<String>> wildcards = new HashMap<>();
|
||||
List<String> all = new ArrayList<>();
|
||||
for (me.lucko.luckperms.constants.Permission p : me.lucko.luckperms.constants.Permission.values()) {
|
||||
pm.addPermission(new Permission(p.getNode(), def));
|
||||
if (p.getGroup() != null) {
|
||||
if (!wildcards.containsKey(p.getGroup())) {
|
||||
wildcards.put(p.getGroup(), new ArrayList<>());
|
||||
}
|
||||
wildcards.get(p.getGroup()).add(p.getTag());
|
||||
}
|
||||
|
||||
all.add(p.getNode());
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<String>> e : wildcards.entrySet()) {
|
||||
pm.addPermission(new Permission(
|
||||
"luckperms." + e.getKey() + ".*", def,
|
||||
e.getValue().stream()
|
||||
.map(tag -> "luckperms." + e.getKey() + "." + tag)
|
||||
.collect(Collectors.toMap(s -> s, s -> true))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
pm.addPermission(new Permission("luckperms.*", def, all.stream().collect(Collectors.toMap(s -> s, s -> true))));
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,10 @@ import me.lucko.luckperms.core.PermissionHolder;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.Contexts;
|
||||
import net.milkbowl.vault.chat.Chat;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import static me.lucko.luckperms.utils.ArgumentChecker.escapeCharacters;
|
||||
@@ -80,113 +82,35 @@ public class VaultChatHook extends Chat {
|
||||
node = escapeCharacters(node);
|
||||
value = escapeCharacters(value);
|
||||
|
||||
if (world == null || world.equals("")) {
|
||||
try {
|
||||
holder.setPermission("meta." + node + "." + value, true);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
|
||||
} else {
|
||||
try {
|
||||
holder.setPermission("meta." + node + "." + value, true, "global", world);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
Iterator<Node> nodes = holder.getNodes().iterator();
|
||||
while (nodes.hasNext()) {
|
||||
Node n = nodes.next();
|
||||
if (n.isMeta() && n.getMeta().getKey().equals(node)) {
|
||||
nodes.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Node.Builder metaNode = new me.lucko.luckperms.utils.Node.Builder("meta." + node + "." + value).setValue(true);
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
metaNode.setServer(perms.getServer());
|
||||
}
|
||||
if (world != null && !world.equals("")) {
|
||||
metaNode.setServer(perms.getServer()).setWorld(world);
|
||||
}
|
||||
|
||||
try {
|
||||
holder.setPermission(metaNode.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
|
||||
perms.objectSave(holder);
|
||||
}
|
||||
|
||||
private static int getMeta(PermissionHolder holder, String world, String node, int defaultValue) {
|
||||
private String getMeta(PermissionHolder holder, String world, String node, String defaultValue) {
|
||||
if (holder == null) return defaultValue;
|
||||
if (node.equals("")) return defaultValue;
|
||||
node = escapeCharacters(node);
|
||||
|
||||
for (Node n : holder.getPermissions()) {
|
||||
if (!n.isMeta()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map.Entry<String, String> meta = n.getMeta();
|
||||
if (meta.getKey().equalsIgnoreCase(node)) {
|
||||
|
||||
try {
|
||||
return Integer.parseInt(unescapeCharacters(meta.getValue()));
|
||||
} catch (Throwable t) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static double getMeta(PermissionHolder holder, String world, String node, double defaultValue) {
|
||||
if (holder == null) return defaultValue;
|
||||
if (node.equals("")) return defaultValue;
|
||||
node = escapeCharacters(node);
|
||||
|
||||
for (Node n : holder.getPermissions()) {
|
||||
if (!n.isMeta()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map.Entry<String, String> meta = n.getMeta();
|
||||
if (meta.getKey().equalsIgnoreCase(node)) {
|
||||
|
||||
try {
|
||||
return Double.parseDouble(unescapeCharacters(meta.getValue()));
|
||||
} catch (Throwable t) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static boolean getMeta(PermissionHolder holder, String world, String node, boolean defaultValue) {
|
||||
if (holder == null) return defaultValue;
|
||||
if (node.equals("")) return defaultValue;
|
||||
node = escapeCharacters(node);
|
||||
|
||||
for (Node n : holder.getPermissions()) {
|
||||
if (!n.isMeta()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map.Entry<String, String> meta = n.getMeta();
|
||||
if (meta.getKey().equalsIgnoreCase(node)) {
|
||||
|
||||
try {
|
||||
return Boolean.parseBoolean(unescapeCharacters(meta.getValue()));
|
||||
} catch (Throwable t) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static String getMeta(PermissionHolder holder, String world, String node, String defaultValue) {
|
||||
if (holder == null) return defaultValue;
|
||||
if (node.equals("")) return defaultValue;
|
||||
node = escapeCharacters(node);
|
||||
|
||||
for (Node n : holder.getPermissions()) {
|
||||
for (Node n : holder.getPermissions(true)) {
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
@@ -195,60 +119,71 @@ public class VaultChatHook extends Chat {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||
if (!n.shouldApplyOnServer(perms.getServer(), perms.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, perms.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map.Entry<String, String> meta = n.getMeta();
|
||||
if (meta.getKey().equalsIgnoreCase(node)) {
|
||||
|
||||
try {
|
||||
return unescapeCharacters(meta.getValue());
|
||||
} catch (Throwable t) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return unescapeCharacters(meta.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static String getChatMeta(boolean prefix, PermissionHolder holder, String world) {
|
||||
private void setChatMeta(boolean prefix, PermissionHolder holder, String value, String world) {
|
||||
if (holder == null) return;
|
||||
if (value.equals("")) return;
|
||||
|
||||
Node.Builder node = new me.lucko.luckperms.utils.Node.Builder(prefix ? "prefix" : "suffix" + ".1000." + escapeCharacters(value));
|
||||
node.setValue(true);
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
node.setServer(perms.getServer());
|
||||
}
|
||||
|
||||
if (world != null && !world.equals("")) {
|
||||
node.setServer(perms.getServer()).setWorld(world);
|
||||
}
|
||||
|
||||
try {
|
||||
holder.setPermission(node.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
|
||||
perms.objectSave(holder);
|
||||
}
|
||||
|
||||
private String getChatMeta(boolean prefix, PermissionHolder holder, String world) {
|
||||
if (holder == null) return "";
|
||||
|
||||
int priority = -1000;
|
||||
int priority = Integer.MIN_VALUE;
|
||||
String meta = null;
|
||||
|
||||
for (Node n : holder.getAllNodes(null)) {
|
||||
for (Node n : holder.getAllNodes(null, Contexts.allowAll())) {
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||
if (prefix ? !n.isPrefix() : !n.isSuffix()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prefix) {
|
||||
if (!n.isPrefix()) {
|
||||
continue;
|
||||
}
|
||||
if (!n.shouldApplyOnServer(perms.getServer(), perms.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map.Entry<Integer, String> prefixValue = n.getPrefix();
|
||||
if (prefixValue.getKey() > priority) {
|
||||
meta = prefixValue.getValue();
|
||||
priority = prefixValue.getKey();
|
||||
}
|
||||
} else {
|
||||
if (!n.isSuffix()) {
|
||||
continue;
|
||||
}
|
||||
if (!n.shouldApplyOnWorld(world, perms.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map.Entry<Integer, String> suffixValue = n.getSuffix();
|
||||
if (suffixValue.getKey() > priority) {
|
||||
meta = suffixValue.getValue();
|
||||
priority = suffixValue.getKey();
|
||||
}
|
||||
Map.Entry<Integer, String> value = prefix ? n.getPrefix() : n.getSuffix();
|
||||
if (value.getKey() > priority) {
|
||||
meta = value.getValue();
|
||||
priority = value.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,15 +197,7 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public void setPlayerPrefix(String world, @NonNull String player, @NonNull String prefix) {
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
if (user == null) return;
|
||||
|
||||
if (prefix.equals("")) return;
|
||||
|
||||
try {
|
||||
user.setPermission("prefix.1000." + escapeCharacters(prefix), true);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
|
||||
perms.objectSave(user);
|
||||
setChatMeta(true, user, prefix, world);
|
||||
}
|
||||
|
||||
public String getPlayerSuffix(String world, @NonNull String player) {
|
||||
@@ -280,15 +207,7 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public void setPlayerSuffix(String world, @NonNull String player, @NonNull String suffix) {
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
if (user == null) return;
|
||||
|
||||
if (suffix.equals("")) return;
|
||||
|
||||
try {
|
||||
user.setPermission("suffix.1000." + escapeCharacters(suffix), true);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
|
||||
perms.objectSave(user);
|
||||
setChatMeta(false, user, suffix, world);
|
||||
}
|
||||
|
||||
public String getGroupPrefix(String world, @NonNull String group) {
|
||||
@@ -298,15 +217,7 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public void setGroupPrefix(String world, @NonNull String group, @NonNull String prefix) {
|
||||
final Group g = plugin.getGroupManager().get(group);
|
||||
if (g == null) return;
|
||||
|
||||
if (prefix.equals("")) return;
|
||||
|
||||
try {
|
||||
g.setPermission("prefix.1000." + escapeCharacters(prefix), true);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
|
||||
perms.objectSave(g);
|
||||
setChatMeta(true, g, prefix, world);
|
||||
}
|
||||
|
||||
public String getGroupSuffix(String world, @NonNull String group) {
|
||||
@@ -316,20 +227,16 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public void setGroupSuffix(String world, @NonNull String group, @NonNull String suffix) {
|
||||
final Group g = plugin.getGroupManager().get(group);
|
||||
if (g == null) return;
|
||||
|
||||
if (suffix.equals("")) return;
|
||||
|
||||
try {
|
||||
g.setPermission("suffix.1000." + escapeCharacters(suffix), true);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
|
||||
perms.objectSave(g);
|
||||
setChatMeta(false, g, suffix, world);
|
||||
}
|
||||
|
||||
public int getPlayerInfoInteger(String world, @NonNull String player, @NonNull String node, int defaultValue) {
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
return getMeta(user, world, node, defaultValue);
|
||||
try {
|
||||
return Integer.parseInt(getMeta(user, world, node, String.valueOf(defaultValue)));
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPlayerInfoInteger(String world, @NonNull String player, @NonNull String node, int value) {
|
||||
@@ -339,7 +246,11 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public int getGroupInfoInteger(String world, @NonNull String group, @NonNull String node, int defaultValue) {
|
||||
final Group g = plugin.getGroupManager().get(group);
|
||||
return getMeta(g, world, node, defaultValue);
|
||||
try {
|
||||
return Integer.parseInt(getMeta(g, world, node, String.valueOf(defaultValue)));
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public void setGroupInfoInteger(String world, @NonNull String group, @NonNull String node, int value) {
|
||||
@@ -349,7 +260,11 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public double getPlayerInfoDouble(String world, @NonNull String player, @NonNull String node, double defaultValue) {
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
return getMeta(user, world, node, defaultValue);
|
||||
try {
|
||||
return Double.parseDouble(getMeta(user, world, node, String.valueOf(defaultValue)));
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPlayerInfoDouble(String world, @NonNull String player, @NonNull String node, double value) {
|
||||
@@ -359,7 +274,11 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public double getGroupInfoDouble(String world, @NonNull String group, @NonNull String node, double defaultValue) {
|
||||
final Group g = plugin.getGroupManager().get(group);
|
||||
return getMeta(g, world, node, defaultValue);
|
||||
try {
|
||||
return Double.parseDouble(getMeta(g, world, node, String.valueOf(defaultValue)));
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public void setGroupInfoDouble(String world, @NonNull String group, @NonNull String node, double value) {
|
||||
@@ -369,7 +288,11 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public boolean getPlayerInfoBoolean(String world, @NonNull String player, @NonNull String node, boolean defaultValue) {
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
return getMeta(user, world, node, defaultValue);
|
||||
String s = getMeta(user, world, node, String.valueOf(defaultValue));
|
||||
if (!s.equalsIgnoreCase("true") && !s.equalsIgnoreCase("false")) {
|
||||
return defaultValue;
|
||||
}
|
||||
return Boolean.parseBoolean(s);
|
||||
}
|
||||
|
||||
public void setPlayerInfoBoolean(String world, @NonNull String player, @NonNull String node, boolean value) {
|
||||
@@ -379,7 +302,11 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public boolean getGroupInfoBoolean(String world, @NonNull String group, @NonNull String node, boolean defaultValue) {
|
||||
final Group g = plugin.getGroupManager().get(group);
|
||||
return getMeta(g, world, node, defaultValue);
|
||||
String s = getMeta(g, world, node, String.valueOf(defaultValue));
|
||||
if (!s.equalsIgnoreCase("true") && !s.equalsIgnoreCase("false")) {
|
||||
return defaultValue;
|
||||
}
|
||||
return Boolean.parseBoolean(s);
|
||||
}
|
||||
|
||||
public void setGroupInfoBoolean(String world, @NonNull String group, @NonNull String node, boolean value) {
|
||||
|
||||
@@ -39,6 +39,8 @@ public class VaultHook {
|
||||
permissionHook = new VaultPermissionHook();
|
||||
}
|
||||
permissionHook.setPlugin(plugin);
|
||||
permissionHook.setServer(plugin.getConfiguration().getVaultServer());
|
||||
permissionHook.setIncludeGlobal(plugin.getConfiguration().getVaultIncludeGlobal());
|
||||
|
||||
if (chatHook == null) {
|
||||
chatHook = new VaultChatHook(permissionHook);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
package me.lucko.luckperms.api.vault;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
@@ -38,6 +39,14 @@ public class VaultPermissionHook extends Permission {
|
||||
@Setter
|
||||
private LPBukkitPlugin plugin;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String server = "global";
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean includeGlobal = true;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "LuckPerms";
|
||||
@@ -57,9 +66,9 @@ public class VaultPermissionHook extends Permission {
|
||||
if (object == null) return false;
|
||||
|
||||
if (world != null && !world.equals("")) {
|
||||
return object.hasPermission(permission, true, "global", world);
|
||||
return object.hasPermission(permission, true, server, world);
|
||||
} else {
|
||||
return object.hasPermission(permission, true);
|
||||
return object.hasPermission(permission, true, server);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,9 +77,9 @@ public class VaultPermissionHook extends Permission {
|
||||
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
object.setPermission(permission, true, "global", world);
|
||||
object.setPermission(permission, true, server, world);
|
||||
} else {
|
||||
object.setPermission(permission, true);
|
||||
object.setPermission(permission, true, server);
|
||||
}
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
|
||||
@@ -83,9 +92,9 @@ public class VaultPermissionHook extends Permission {
|
||||
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
object.unsetPermission(permission, "global", world);
|
||||
object.unsetPermission(permission, server, world);
|
||||
} else {
|
||||
object.unsetPermission(permission);
|
||||
object.unsetPermission(permission, server);
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
|
||||
@@ -147,7 +156,7 @@ public class VaultPermissionHook extends Permission {
|
||||
if (group1 == null) return false;
|
||||
|
||||
if (world != null && !world.equals("")) {
|
||||
return user.isInGroup(group1, "global", world);
|
||||
return user.isInGroup(group1, server, world);
|
||||
} else {
|
||||
return user.isInGroup(group1);
|
||||
}
|
||||
@@ -163,7 +172,7 @@ public class VaultPermissionHook extends Permission {
|
||||
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
user.addGroup(group, "global", world);
|
||||
user.addGroup(group, server, world);
|
||||
} else {
|
||||
user.addGroup(group);
|
||||
}
|
||||
@@ -182,7 +191,7 @@ public class VaultPermissionHook extends Permission {
|
||||
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
user.removeGroup(group, "global", world);
|
||||
user.removeGroup(group, server, world);
|
||||
} else {
|
||||
user.removeGroup(group);
|
||||
}
|
||||
@@ -195,7 +204,7 @@ public class VaultPermissionHook extends Permission {
|
||||
public String[] getPlayerGroups(String world, @NonNull String player) {
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
return (user == null) ? new String[0] :
|
||||
world != null && !world.equals("") ? user.getLocalGroups("global", world).toArray(new String[0]) :
|
||||
world != null && !world.equals("") ? user.getGroups(server, world, includeGlobal).toArray(new String[0]) :
|
||||
user.getGroupNames().toArray(new String[0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.inject;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Injects a {@link LPPermissible} into a {@link Player}
|
||||
*/
|
||||
@UtilityClass
|
||||
public class Injector {
|
||||
private static Field HUMAN_ENTITY_FIELD;
|
||||
|
||||
static {
|
||||
try {
|
||||
HUMAN_ENTITY_FIELD = Class.forName(getInternalClassName("entity.CraftHumanEntity")).getDeclaredField("perm");
|
||||
HUMAN_ENTITY_FIELD.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean inject(CommandSender sender, PermissibleBase permissible) {
|
||||
try {
|
||||
Field f = getPermField(sender);
|
||||
f.set(sender, permissible);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean unInject(CommandSender sender) {
|
||||
try {
|
||||
Permissible permissible = getPermissible(sender);
|
||||
if (permissible instanceof LPPermissible) {
|
||||
getPermField(sender).set(sender, new PermissibleBase(sender));
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static Permissible getPermissible(CommandSender sender) {
|
||||
try {
|
||||
Field f = getPermField(sender);
|
||||
return (Permissible) f.get(sender);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Field getPermField(CommandSender sender) {
|
||||
if (sender instanceof Player) {
|
||||
return HUMAN_ENTITY_FIELD;
|
||||
}
|
||||
throw new RuntimeException("Couldn't get perm field for sender " + sender.getClass().getName());
|
||||
}
|
||||
|
||||
private static String getInternalClassName(String className) {
|
||||
Class server = Bukkit.getServer().getClass();
|
||||
if (!server.getSimpleName().equals("CraftServer")) {
|
||||
throw new RuntimeException("Couldn't inject 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 "org.bukkit.craftbukkit" + version + className;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* 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.inject;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.utils.PermissionCalculator;
|
||||
import me.lucko.luckperms.utils.PermissionProcessor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.*;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Modified PermissibleBase for LuckPerms
|
||||
*/
|
||||
public class LPPermissible extends PermissibleBase {
|
||||
|
||||
@Getter
|
||||
private final CommandSender parent;
|
||||
|
||||
private final PermissionCalculator calculator;
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> luckPermsPermissions = new ConcurrentHashMap<>();
|
||||
private final List<PermissionAttachment> attachments = new LinkedList<>();
|
||||
private final Map<String, PermissionAttachmentInfo> attachmentPermissions = new HashMap<>();
|
||||
|
||||
public LPPermissible(@NonNull CommandSender sender, LuckPermsPlugin plugin) {
|
||||
super(sender);
|
||||
this.parent = sender;
|
||||
|
||||
List<PermissionProcessor> processors = new ArrayList<>(5);
|
||||
processors.add(new PermissionCalculator.MapProcessor(luckPermsPermissions));
|
||||
processors.add(new AttachmentProcessor(attachmentPermissions));
|
||||
if (plugin.getConfiguration().getApplyWildcards()) {
|
||||
processors.add(new PermissionCalculator.WildcardProcessor(luckPermsPermissions));
|
||||
}
|
||||
if (plugin.getConfiguration().getApplyRegex()) {
|
||||
processors.add(new PermissionCalculator.RegexProcessor(luckPermsPermissions));
|
||||
}
|
||||
processors.add(new BukkitDefaultsProcessor(parent::isOp));
|
||||
|
||||
calculator = new PermissionCalculator(plugin, parent.getName(), plugin.getConfiguration().getDebugPermissionChecks(), processors);
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
calculator.invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOp() {
|
||||
return parent.isOp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOp(boolean value) {
|
||||
parent.setOp(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(@NonNull String name) {
|
||||
return luckPermsPermissions.containsKey(name.toLowerCase()) || attachmentPermissions.containsKey(name.toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(@NonNull Permission perm) {
|
||||
return isPermissionSet(perm.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NonNull String name) {
|
||||
Tristate ts = calculator.getPermissionValue(name);
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
}
|
||||
|
||||
return Permission.DEFAULT_PERMISSION.getValue(isOp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NonNull Permission perm) {
|
||||
Tristate ts = calculator.getPermissionValue(perm.getName());
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
}
|
||||
|
||||
return perm.getDefault().getValue(isOp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(@NonNull Plugin plugin, @NonNull String name, boolean value) {
|
||||
if (!plugin.isEnabled()) {
|
||||
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is not enabled");
|
||||
}
|
||||
|
||||
PermissionAttachment result = addAttachment(plugin);
|
||||
result.setPermission(name, value);
|
||||
|
||||
recalculatePermissions();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(@NonNull Plugin plugin) {
|
||||
if (!plugin.isEnabled()) {
|
||||
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is not enabled");
|
||||
}
|
||||
|
||||
PermissionAttachment result = new PermissionAttachment(plugin, parent);
|
||||
|
||||
attachments.add(result);
|
||||
recalculatePermissions();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(@NonNull Plugin plugin, @NonNull String name, boolean value, int ticks) {
|
||||
if (!plugin.isEnabled()) {
|
||||
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is not enabled");
|
||||
}
|
||||
|
||||
PermissionAttachment result = addAttachment(plugin, ticks);
|
||||
if (result != null) {
|
||||
result.setPermission(name, value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(@NonNull Plugin plugin, int ticks) {
|
||||
if (!plugin.isEnabled()) {
|
||||
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is not enabled");
|
||||
}
|
||||
|
||||
PermissionAttachment result = addAttachment(plugin);
|
||||
if (Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new RemoveAttachmentRunnable(result), 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;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttachment(@NonNull PermissionAttachment attachment) {
|
||||
if (attachments.contains(attachment)) {
|
||||
attachments.remove(attachment);
|
||||
PermissionRemovedExecutor ex = attachment.getRemovalCallback();
|
||||
|
||||
if (ex != null) {
|
||||
ex.attachmentRemoved(attachment);
|
||||
}
|
||||
|
||||
recalculatePermissions();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Given attachment is not part of Permissible object " + parent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculatePermissions() {
|
||||
if (attachmentPermissions == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
attachmentPermissions.clear();
|
||||
Set<Permission> defaults = Bukkit.getServer().getPluginManager().getDefaultPermissions(isOp());
|
||||
Bukkit.getServer().getPluginManager().subscribeToDefaultPerms(isOp(), parent);
|
||||
|
||||
for (Permission perm : defaults) {
|
||||
String name = perm.getName().toLowerCase();
|
||||
|
||||
attachmentPermissions.put(name, new PermissionAttachmentInfo(parent, name, null, true));
|
||||
Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent);
|
||||
calculateChildPermissions(perm.getChildren(), false, null);
|
||||
}
|
||||
|
||||
for (PermissionAttachment attachment : attachments) {
|
||||
calculateChildPermissions(attachment.getPermissions(), false, attachment);
|
||||
}
|
||||
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void clearPermissions() {
|
||||
Set<String> perms = attachmentPermissions.keySet();
|
||||
|
||||
for (String name : perms) {
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromPermission(name, parent);
|
||||
}
|
||||
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(false, parent);
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(true, parent);
|
||||
|
||||
attachmentPermissions.clear();
|
||||
}
|
||||
|
||||
private void calculateChildPermissions(Map<String, Boolean> children, boolean invert, PermissionAttachment attachment) {
|
||||
for (Map.Entry<String, Boolean> e : children.entrySet()) {
|
||||
Permission perm = Bukkit.getServer().getPluginManager().getPermission(e.getKey());
|
||||
boolean value = e.getValue() ^ invert;
|
||||
String name = e.getKey().toLowerCase();
|
||||
|
||||
attachmentPermissions.put(name, new PermissionAttachmentInfo(parent, name, attachment, value));
|
||||
Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent);
|
||||
|
||||
if (perm != null) {
|
||||
calculateChildPermissions(perm.getChildren(), !value, attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
||||
Set<PermissionAttachmentInfo> perms = new HashSet<>();
|
||||
perms.addAll(attachmentPermissions.values());
|
||||
|
||||
perms.addAll(luckPermsPermissions.entrySet().stream()
|
||||
.map(e -> new PermissionAttachmentInfo(parent, e.getKey(), null, e.getValue()))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
private class RemoveAttachmentRunnable implements Runnable {
|
||||
private PermissionAttachment attachment;
|
||||
|
||||
private RemoveAttachmentRunnable(PermissionAttachment attachment) {
|
||||
this.attachment = attachment;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
attachment.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private static class AttachmentProcessor implements PermissionProcessor {
|
||||
|
||||
@Getter
|
||||
private final Map<String, PermissionAttachmentInfo> map;
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
if (map.containsKey(permission)) {
|
||||
return Tristate.fromBoolean(map.get(permission).getValue());
|
||||
}
|
||||
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private static class BukkitDefaultsProcessor implements PermissionProcessor {
|
||||
private final Supplier<Boolean> isOp;
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
Permission defPerm = Bukkit.getServer().getPluginManager().getPermission(permission);
|
||||
if (defPerm != null) {
|
||||
return Tristate.fromBoolean(defPerm.getDefault().getValue(isOp.get()));
|
||||
} else {
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,32 +27,20 @@ import lombok.Setter;
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.api.event.events.UserPermissionRefreshEvent;
|
||||
import me.lucko.luckperms.api.implementation.internal.UserLink;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
import me.lucko.luckperms.inject.LPPermissible;
|
||||
import me.lucko.luckperms.utils.Contexts;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitUser extends User {
|
||||
private static Field permissionsField = null;
|
||||
public static Field getPermissionsField() {
|
||||
if (permissionsField == null) {
|
||||
try {
|
||||
permissionsField = PermissionAttachment.class.getDeclaredField("permissions");
|
||||
permissionsField.setAccessible(true);
|
||||
} catch (SecurityException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return permissionsField;
|
||||
}
|
||||
|
||||
|
||||
private final LPBukkitPlugin plugin;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private PermissionAttachment attachment = null;
|
||||
private LPPermissible lpPermissible = null;
|
||||
|
||||
BukkitUser(UUID uuid, LPBukkitPlugin plugin) {
|
||||
super(uuid, plugin);
|
||||
@@ -66,17 +54,28 @@ public class BukkitUser extends User {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void refreshPermissions() {
|
||||
if (attachment == null) {
|
||||
public synchronized void refreshPermissions() {
|
||||
if (lpPermissible == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the permissions that should be applied. This is done async, who cares about how long it takes or how often it's done.
|
||||
Map<String, Boolean> toApply = getLocalPermissions(getPlugin().getConfiguration().getServer(), plugin.getUserManager().getWorldCache().get(getUuid()), null);
|
||||
Map<String, Boolean> toApply = exportNodes(
|
||||
new Contexts(
|
||||
getPlugin().getConfiguration().getServer(),
|
||||
plugin.getUserManager().getWorldCache().get(getUuid()),
|
||||
null,
|
||||
getPlugin().getConfiguration().getIncludeGlobalPerms(),
|
||||
getPlugin().getConfiguration().getIncludeGlobalWorldPerms(),
|
||||
true,
|
||||
getPlugin().getConfiguration().getApplyGlobalGroups(),
|
||||
getPlugin().getConfiguration().getApplyGlobalWorldGroups()
|
||||
),
|
||||
Collections.emptyList()
|
||||
);
|
||||
|
||||
try {
|
||||
// The map in the LP PermissionAttachment is a ConcurrentHashMap. We can modify it's contents async.
|
||||
Map<String, Boolean> existing = (Map<String, Boolean>) getPermissionsField().get(attachment);
|
||||
Map<String, Boolean> existing = lpPermissible.getLuckPermsPermissions();
|
||||
|
||||
boolean different = false;
|
||||
if (toApply.size() != existing.size()) {
|
||||
@@ -94,17 +93,30 @@ public class BukkitUser extends User {
|
||||
if (!different) return;
|
||||
|
||||
existing.clear();
|
||||
lpPermissible.invalidateCache();
|
||||
existing.putAll(toApply);
|
||||
|
||||
/* Must be called sync, as #recalculatePermissions is an unmodified Bukkit API call that is absolutely not thread safe.
|
||||
Shouldn't be too taxing on the server. This only gets called when permissions have actually changed,
|
||||
which is like once per user per login, assuming their permissions don't get modified. */
|
||||
plugin.doSync(() -> attachment.getPermissible().recalculatePermissions());
|
||||
if (plugin.getConfiguration().getAutoOp()) {
|
||||
boolean op = false;
|
||||
|
||||
for (Map.Entry<String, Boolean> e : toApply.entrySet()) {
|
||||
if (e.getKey().equalsIgnoreCase("luckperms.autoop") && e.getValue()) {
|
||||
op = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean finalOp = op;
|
||||
if (lpPermissible.isOp() != op) {
|
||||
final Permissible parent = lpPermissible.getParent();
|
||||
plugin.doSync(() -> parent.setOp(finalOp));
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getApiProvider().fireEventAsync(new UserPermissionRefreshEvent(new UserLink(this)));
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
plugin.getApiProvider().fireEventAsync(new UserPermissionRefreshEvent(new UserLink(this)));
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ package me.lucko.luckperms.users;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.inject.Injector;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -44,23 +45,20 @@ public class BukkitUserManager extends UserManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload(User user) {
|
||||
if (user != null) {
|
||||
public void preUnload(User user) {
|
||||
if (user instanceof BukkitUser) {
|
||||
BukkitUser u = (BukkitUser) user;
|
||||
Player player = plugin.getServer().getPlayer(plugin.getUuidCache().getExternalUUID(u.getUuid()));
|
||||
if (player != null) {
|
||||
if (u.getLpPermissible() != null) {
|
||||
Injector.unInject(player);
|
||||
u.setLpPermissible(null);
|
||||
}
|
||||
|
||||
if (user instanceof BukkitUser) {
|
||||
BukkitUser u = (BukkitUser) user;
|
||||
|
||||
if (u.getAttachment() != null) {
|
||||
Player player = plugin.getServer().getPlayer(plugin.getUuidCache().getExternalUUID(u.getUuid()));
|
||||
|
||||
if (player != null) {
|
||||
player.removeAttachment(u.getAttachment());
|
||||
}
|
||||
u.setAttachment(null);
|
||||
if (plugin.getConfiguration().getAutoOp()) {
|
||||
player.setOp(false);
|
||||
}
|
||||
}
|
||||
|
||||
getAll().remove(user.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,20 @@
|
||||
# The name of the server, used for server specific permissions. Set to 'global' to disable.
|
||||
server: global
|
||||
|
||||
# If users on this server should have their global permissions/groups applied.
|
||||
# If users on this server should have their global permissions applied.
|
||||
# If set to false, only server specific permissions will apply for users on this server
|
||||
include-global: true
|
||||
|
||||
# If users on this server should have their global world permissions applied.
|
||||
# If set to false, only world specific permissions will apply for users on this server
|
||||
include-global-world: true
|
||||
|
||||
# If users on this server should have global (non-server specific) groups applied
|
||||
apply-global-groups: true
|
||||
|
||||
# If users on this server should have global (non-world specific) groups applied
|
||||
apply-global-world-groups: true
|
||||
|
||||
# If this server is in offline or online mode.
|
||||
# This setting allows a player to have the same UUID across a network of offline mode/mixed servers.
|
||||
|
||||
@@ -22,28 +33,70 @@ include-global: true
|
||||
|
||||
# 2. You are only running one server instance using LuckPerms, (not a network)
|
||||
# In this case, set online-mode to true no matter what is set in server.properties. (we can just fallback to the servers uuid cache)
|
||||
|
||||
# 3. If your proxy is running in offline mode, and you are using PaperSpigot (https://ci.destroystokyo.com/job/PaperSpigot/),
|
||||
# you should set "bungee-online-mode" to false in the paper.yml, and set "online-mode" to true in all LuckPerms configs.
|
||||
# This approach is thoroughly recommended for offline mode networks.
|
||||
online-mode: true
|
||||
|
||||
# If the plugin should apply wildcard permissions.
|
||||
# If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered permissions matching
|
||||
# the wildcard. This will only work for plugins that define all of their permissions to the server.
|
||||
# the wildcard.
|
||||
apply-wildcards: true
|
||||
|
||||
# If the plugin should parse regex permissions.
|
||||
# If set to true, LuckPerms will detect regex permissions, marked with "r=" at the start of the node, and resolve &
|
||||
# apply all registered permissions matching the regex. This will only work for plugins that define all of their
|
||||
# permissions to the server.
|
||||
# apply all registered permissions matching the regex.
|
||||
apply-regex: true
|
||||
|
||||
# If the plugin should complete and apply shorthand permissions.
|
||||
# If set to true, LuckPerms will detect and expand shorthand node patterns.
|
||||
apply-shorthand: true
|
||||
|
||||
# If the plugin should send log notifications to users whenever permissions are modified.
|
||||
log-notify: true
|
||||
|
||||
# If LuckPerms should print to console every time a plugin checks if a player has a permission
|
||||
debug-permission-checks: false
|
||||
|
||||
# If the vanilla OP system is enabled. If set to false, all users will be de-opped, and the op/deop commands will be disabled.
|
||||
enable-ops: true
|
||||
|
||||
# If set to true, any user with the permission "luckperms.autoop" will automatically be granted server operator status.
|
||||
# This permission can be inherited, or set on specific servers/worlds, temporarily, etc.
|
||||
# Additionally, setting this to true will force the "enable-ops" option above to false. All users will be de-opped unless
|
||||
# they have the permission node, and the op/deop commands will be disabled.
|
||||
#
|
||||
# It is recommended that you use this option instead of assigning a single '*' permission.
|
||||
auto-op: false
|
||||
|
||||
# If opped players should be allowed to use LuckPerms commands. Set to false to only allow users who have the permissions access to the commands
|
||||
commands-allow-op: true
|
||||
|
||||
# The name of the server used within Vault operations. If you don't want Vault operations to be server specific, set this
|
||||
# to "global".
|
||||
vault-server: global
|
||||
|
||||
# If global permissions should be considered when retrieving meta or player groups
|
||||
vault-include-global: true
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, h2, flatfile, mongodb
|
||||
# Currently supported: mysql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL or MongoDB
|
||||
storage-method: h2
|
||||
|
||||
# This block enables support for split datastores.
|
||||
# Only touch this if you're sure that you know what you're doing.
|
||||
# I (the author) do not endorse nor recommend the use of this feature.
|
||||
split-storage:
|
||||
enabled: false
|
||||
methods:
|
||||
user: h2
|
||||
group: h2
|
||||
track: h2
|
||||
uuid: h2
|
||||
log: h2
|
||||
|
||||
data:
|
||||
address: localhost:3306
|
||||
database: minecraft
|
||||
@@ -52,4 +105,4 @@ data:
|
||||
|
||||
# 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
|
||||
sync-minutes: 3
|
||||
@@ -1,130 +1,16 @@
|
||||
name: LuckPerms
|
||||
author: Luck
|
||||
version: ${release.version}.${git.closest.tag.commit.count}
|
||||
main: me.lucko.luckperms.LPBukkitPlugin
|
||||
softdepend: [Vault, PermissionsEx, GroupManager, PowerfulPerms, zPermissions] # For migration
|
||||
description: A permissions plugin
|
||||
author: Luck
|
||||
website: https://github.com/lucko/LuckPerms
|
||||
|
||||
main: me.lucko.luckperms.LPBukkitPlugin
|
||||
softdepend: [Vault, PermissionsEx, GroupManager, PowerfulPerms, zPermissions, bPermissions] # For migration
|
||||
|
||||
commands:
|
||||
luckperms:
|
||||
description: Manage permissions
|
||||
aliases: [perms, permissions, lp, p, perm]
|
||||
permissions:
|
||||
luckperms.*:
|
||||
description: Gives access to all LuckPerms commands
|
||||
children:
|
||||
luckperms.sync: true
|
||||
luckperms.info: true
|
||||
luckperms.debug: true
|
||||
luckperms.import: true
|
||||
luckperms.creategroup: true
|
||||
luckperms.deletegroup: true
|
||||
luckperms.listgroups: true
|
||||
luckperms.createtrack: true
|
||||
luckperms.deletetrack: true
|
||||
luckperms.listtracks: true
|
||||
luckperms.user.info: true
|
||||
luckperms.user.getuuid: true
|
||||
luckperms.user.listnodes: true
|
||||
luckperms.user.haspermission: true
|
||||
luckperms.user.inheritspermission: true
|
||||
luckperms.user.setpermission: true
|
||||
luckperms.user.unsetpermission: true
|
||||
luckperms.user.addgroup: true
|
||||
luckperms.user.removegroup: true
|
||||
luckperms.user.settemppermission: true
|
||||
luckperms.user.unsettemppermission: true
|
||||
luckperms.user.addtempgroup: true
|
||||
luckperms.user.removetempgroup: true
|
||||
luckperms.user.setprimarygroup: true
|
||||
luckperms.user.showtracks: true
|
||||
luckperms.user.promote: true
|
||||
luckperms.user.demote: true
|
||||
luckperms.user.showpos: true
|
||||
luckperms.user.clear: true
|
||||
luckperms.group.info: true
|
||||
luckperms.group.listnodes: true
|
||||
luckperms.group.haspermission: true
|
||||
luckperms.group.inheritspermission: true
|
||||
luckperms.group.setpermission: true
|
||||
luckperms.group.unsetpermission: true
|
||||
luckperms.group.setinherit: true
|
||||
luckperms.group.unsetinherit: true
|
||||
luckperms.group.settemppermission: true
|
||||
luckperms.group.unsettemppermission: true
|
||||
luckperms.group.settempinherit: true
|
||||
luckperms.group.unsettempinherit: true
|
||||
luckperms.group.showtracks: true
|
||||
luckperms.group.clear: true
|
||||
luckperms.group.rename: true
|
||||
luckperms.track.info: true
|
||||
luckperms.track.append: true
|
||||
luckperms.track.insert: true
|
||||
luckperms.track.remove: true
|
||||
luckperms.track.clear: true
|
||||
luckperms.track.rename: true
|
||||
luckperms.log.export: true
|
||||
luckperms.log.userhistory: true
|
||||
luckperms.log.grouphistory: true
|
||||
luckperms.log.trackhistory: true
|
||||
luckperms.log.notify: true
|
||||
luckperms.log.recent: true
|
||||
luckperms.log.search: true
|
||||
luckperms.user.*:
|
||||
description: Gives access to all LuckPerms user commands
|
||||
children:
|
||||
luckperms.user.info: true
|
||||
luckperms.user.getuuid: true
|
||||
luckperms.user.listnodes: true
|
||||
luckperms.user.haspermission: true
|
||||
luckperms.user.inheritspermission: true
|
||||
luckperms.user.setpermission: true
|
||||
luckperms.user.unsetpermission: true
|
||||
luckperms.user.addgroup: true
|
||||
luckperms.user.removegroup: true
|
||||
luckperms.user.settemppermission: true
|
||||
luckperms.user.unsettemppermission: true
|
||||
luckperms.user.addtempgroup: true
|
||||
luckperms.user.removetempgroup: true
|
||||
luckperms.user.setprimarygroup: true
|
||||
luckperms.user.showtracks: true
|
||||
luckperms.user.promote: true
|
||||
luckperms.user.demote: true
|
||||
luckperms.user.showpos: true
|
||||
luckperms.user.clear: true
|
||||
luckperms.group.*:
|
||||
description: Gives access to all LuckPerms group commands
|
||||
children:
|
||||
luckperms.group.info: true
|
||||
luckperms.group.listnodes: true
|
||||
luckperms.group.haspermission: true
|
||||
luckperms.group.inheritspermission: true
|
||||
luckperms.group.setpermission: true
|
||||
luckperms.group.unsetpermission: true
|
||||
luckperms.group.setinherit: true
|
||||
luckperms.group.unsetinherit: true
|
||||
luckperms.group.settemppermission: true
|
||||
luckperms.group.unsettemppermission: true
|
||||
luckperms.group.settempinherit: true
|
||||
luckperms.group.unsettempinherit: true
|
||||
luckperms.group.showtracks: true
|
||||
luckperms.group.clear: true
|
||||
luckperms.group.rename: true
|
||||
luckperms.track.*:
|
||||
description: Gives access to all LuckPerms track commands
|
||||
children:
|
||||
luckperms.track.info: true
|
||||
luckperms.track.append: true
|
||||
luckperms.track.insert: true
|
||||
luckperms.track.remove: true
|
||||
luckperms.track.clear: true
|
||||
luckperms.track.rename: true
|
||||
luckperms.log.*:
|
||||
description: Gives access to all LuckPerms log commands
|
||||
children:
|
||||
luckperms.log.export: true
|
||||
luckperms.log.userhistory: true
|
||||
luckperms.log.grouphistory: true
|
||||
luckperms.log.trackhistory: true
|
||||
luckperms.log.notify: true
|
||||
luckperms.log.recent: true
|
||||
luckperms.log.search: true
|
||||
|
||||
|
||||
# Permissions are registered programmatically instead of here.
|
||||
+5
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.6-SNAPSHOT</version>
|
||||
<version>2.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -65,6 +65,10 @@
|
||||
<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>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
@@ -22,8 +22,12 @@
|
||||
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.commands.CommandManager;
|
||||
import me.lucko.luckperms.commands.Util;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
import net.md_5.bungee.api.plugin.TabExecutor;
|
||||
@@ -40,7 +44,12 @@ class BungeeCommand extends Command implements TabExecutor {
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
manager.onCommand(BungeeSenderFactory.get().wrap(sender), "bperms", Arrays.asList(args), Callback.empty());
|
||||
manager.onCommand(
|
||||
BungeeSenderFactory.get().wrap(sender),
|
||||
"bperms",
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))),
|
||||
Callback.empty()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,9 +33,6 @@ import net.md_5.bungee.api.event.*;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -52,22 +49,18 @@ public class BungeeListener extends AbstractListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerPermissionCheck(PermissionCheckEvent e) {
|
||||
if (!(e.getSender() instanceof ProxiedPlayer)) {
|
||||
e.setHasPermission(true);
|
||||
return;
|
||||
}
|
||||
|
||||
final ProxiedPlayer player = ((ProxiedPlayer) e.getSender());
|
||||
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (user == null) return;
|
||||
|
||||
|
||||
final String server = player.getServer() == null ? null : (player.getServer().getInfo() == null ? null : player.getServer().getInfo().getName());
|
||||
Map<String, Boolean> local = user.getLocalPermissions(plugin.getConfiguration().getServer(), server, null, Collections.singletonList(e.getPermission()));
|
||||
for (Map.Entry<String, Boolean> en : local.entrySet()) {
|
||||
if (en.getKey().equalsIgnoreCase(e.getPermission())) {
|
||||
e.setHasPermission(en.getValue());
|
||||
return;
|
||||
}
|
||||
BungeePlayerCache playerCache = plugin.getPlayerCache().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (playerCache == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.setHasPermission(playerCache.getPermissionValue(e.getPermission()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -109,23 +102,20 @@ public class BungeeListener extends AbstractListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerPostLogin(PostLoginEvent e) {
|
||||
final ProxiedPlayer player = e.getPlayer();
|
||||
final WeakReference<ProxiedPlayer> p = new WeakReference<>(player);
|
||||
final UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
final User user = plugin.getUserManager().get(internal);
|
||||
|
||||
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||
if (user == null) {
|
||||
plugin.getProxy().getScheduler().schedule(plugin, () -> {
|
||||
final ProxiedPlayer pl = p.get();
|
||||
if (pl != null) {
|
||||
pl.sendMessage(WARN_MESSAGE);
|
||||
}
|
||||
}, 3, TimeUnit.SECONDS);
|
||||
plugin.getProxy().getScheduler().schedule(plugin, () -> player.sendMessage(WARN_MESSAGE), 3, TimeUnit.SECONDS);
|
||||
} else {
|
||||
plugin.getPlayerCache().put(internal, new BungeePlayerCache(plugin, e.getPlayer().getName()));
|
||||
user.refreshPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerDisconnectEvent e) {
|
||||
plugin.getPlayerCache().remove(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||
onLeave(e.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.utils.PermissionCalculator;
|
||||
import me.lucko.luckperms.utils.PermissionProcessor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class BungeePlayerCache {
|
||||
|
||||
private final PermissionCalculator calculator;
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> permissions = new ConcurrentHashMap<>();
|
||||
|
||||
public BungeePlayerCache(LuckPermsPlugin plugin, String name) {
|
||||
List<PermissionProcessor> processors = new ArrayList<>(3);
|
||||
processors.add(new PermissionCalculator.MapProcessor(permissions));
|
||||
if (plugin.getConfiguration().getApplyWildcards()) {
|
||||
processors.add(new PermissionCalculator.WildcardProcessor(permissions));
|
||||
}
|
||||
if (plugin.getConfiguration().getApplyRegex()) {
|
||||
processors.add(new PermissionCalculator.RegexProcessor(permissions));
|
||||
}
|
||||
|
||||
calculator = new PermissionCalculator(plugin, name, plugin.getConfiguration().getDebugPermissionChecks(), processors);
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
calculator.invalidateCache();
|
||||
}
|
||||
|
||||
public boolean getPermissionValue(String permission) {
|
||||
return calculator.getPermissionValue(permission).asBoolean();
|
||||
}
|
||||
}
|
||||
@@ -35,8 +35,8 @@ import java.util.UUID;
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class BungeeSenderFactory extends SenderFactory<CommandSender> {
|
||||
private static BungeeSenderFactory instance = null;
|
||||
public static BungeeSenderFactory get() {
|
||||
if (instance == null){
|
||||
public static synchronized BungeeSenderFactory get() {
|
||||
if (instance == null) {
|
||||
instance = new BungeeSenderFactory();
|
||||
}
|
||||
return instance;
|
||||
|
||||
@@ -24,11 +24,13 @@ package me.lucko.luckperms;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.implementation.ApiProvider;
|
||||
import me.lucko.luckperms.commands.CommandManager;
|
||||
import me.lucko.luckperms.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.core.LPConfiguration;
|
||||
import me.lucko.luckperms.core.UuidCache;
|
||||
import me.lucko.luckperms.data.Importer;
|
||||
@@ -45,16 +47,14 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
private final Map<UUID, BungeePlayerCache> playerCache = new ConcurrentHashMap<>();
|
||||
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
|
||||
private LPConfiguration configuration;
|
||||
private UserManager userManager;
|
||||
@@ -135,8 +135,8 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Type.BUNGEE;
|
||||
public PlatformType getType() {
|
||||
return PlatformType.BUNGEE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -160,8 +160,11 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Sender> getSenders() {
|
||||
return getProxy().getPlayers().stream().map(p -> BungeeSenderFactory.get().wrap(p)).collect(Collectors.toList());
|
||||
public List<Sender> getNotifyListeners() {
|
||||
return getProxy().getPlayers().stream()
|
||||
.map(p -> BungeeSenderFactory.get().wrap(p, Collections.singleton(Permission.LOG_NOTIFY)))
|
||||
.filter(Permission.LOG_NOTIFY::isAuthorized)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -185,6 +188,11 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUUID(String playerName) {
|
||||
return null; // Not needed on Bungee
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPluginLoaded(String name) {
|
||||
return getProxy().getPluginManager().getPlugins().stream()
|
||||
|
||||
@@ -22,21 +22,80 @@
|
||||
|
||||
package me.lucko.luckperms.users;
|
||||
|
||||
import me.lucko.luckperms.BungeePlayerCache;
|
||||
import me.lucko.luckperms.LPBungeePlugin;
|
||||
import me.lucko.luckperms.api.event.events.UserPermissionRefreshEvent;
|
||||
import me.lucko.luckperms.api.implementation.internal.UserLink;
|
||||
import me.lucko.luckperms.utils.Contexts;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeUser extends User {
|
||||
private final LPBungeePlugin plugin;
|
||||
|
||||
BungeeUser(UUID uuid, LPBungeePlugin plugin) {
|
||||
super(uuid, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
BungeeUser(UUID uuid, String username, LPBungeePlugin plugin) {
|
||||
super(uuid, username, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshPermissions() {
|
||||
// Do nothing. Permissions are applied when needed in a listener.
|
||||
public synchronized void refreshPermissions() {
|
||||
ProxiedPlayer player = plugin.getProxy().getPlayer(plugin.getUuidCache().getExternalUUID(getUuid()));
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
BungeePlayerCache playerCache = plugin.getPlayerCache().get(getUuid());
|
||||
if (playerCache == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String server = player.getServer() == null ? null : (player.getServer().getInfo() == null ? null : player.getServer().getInfo().getName());
|
||||
|
||||
// Calculate the permissions that should be applied. This is done async.
|
||||
Map<String, Boolean> toApply = exportNodes(
|
||||
new Contexts(
|
||||
plugin.getConfiguration().getServer(),
|
||||
server,
|
||||
null,
|
||||
plugin.getConfiguration().getIncludeGlobalPerms(),
|
||||
plugin.getConfiguration().getIncludeGlobalWorldPerms(),
|
||||
true,
|
||||
plugin.getConfiguration().getApplyGlobalGroups(),
|
||||
plugin.getConfiguration().getApplyGlobalWorldGroups()
|
||||
),
|
||||
Collections.emptyList()
|
||||
);
|
||||
|
||||
Map<String, Boolean> existing = playerCache.getPermissions();
|
||||
|
||||
boolean different = false;
|
||||
if (toApply.size() != existing.size()) {
|
||||
different = true;
|
||||
} else {
|
||||
for (Map.Entry<String, Boolean> e : existing.entrySet()) {
|
||||
if (toApply.containsKey(e.getKey()) && toApply.get(e.getKey()) == e.getValue()) {
|
||||
continue;
|
||||
}
|
||||
different = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!different) return;
|
||||
|
||||
existing.clear();
|
||||
playerCache.invalidateCache();
|
||||
existing.putAll(toApply);
|
||||
|
||||
plugin.getApiProvider().fireEventAsync(new UserPermissionRefreshEvent(new UserLink(this)));
|
||||
}
|
||||
}
|
||||
@@ -34,15 +34,6 @@ public class BungeeUserManager extends UserManager {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload(User user) {
|
||||
if (user != null) {
|
||||
// Cannot clear the ProxiedPlayer's permission map, they're leaving so that will get GCed anyway
|
||||
// Calling getPermissions.clear() throws an UnsupportedOperationException
|
||||
getAll().remove(user.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(User user) {
|
||||
if (plugin.getProxy().getPlayer(plugin.getUuidCache().getExternalUUID(user.getUuid())) == null) {
|
||||
|
||||
@@ -8,9 +8,20 @@
|
||||
# The name of the server, used for server specific permissions. Set to 'global' to disable.
|
||||
server: bungee
|
||||
|
||||
# If users on this server should have their global permissions/groups applied.
|
||||
# If users on this server should have their global permissions applied.
|
||||
# If set to false, only server specific permissions will apply for users on this server
|
||||
include-global: false
|
||||
|
||||
# If users on this server should have their global world permissions applied.
|
||||
# If set to false, only world specific permissions will apply for users on this server
|
||||
include-global-world: true
|
||||
|
||||
# If users on this server should have global (non-server specific) groups applied
|
||||
apply-global-groups: true
|
||||
|
||||
# If users on this server should have global (non-world specific) groups applied
|
||||
apply-global-world-groups: true
|
||||
|
||||
# If this server is in offline or online mode.
|
||||
# This setting allows a player to have the same UUID across a network of offline mode/mixed servers.
|
||||
|
||||
@@ -22,28 +33,49 @@ include-global: false
|
||||
|
||||
# 2. You are only running one server instance using LuckPerms, (not a network)
|
||||
# In this case, set online-mode to true no matter what is set in server.properties. (we can just fallback to the servers uuid cache)
|
||||
|
||||
# 3. If your proxy is running in offline mode, and you are using PaperSpigot (https://ci.destroystokyo.com/job/PaperSpigot/),
|
||||
# you should set "bungee-online-mode" to false in the paper.yml, and set "online-mode" to true in all LuckPerms configs.
|
||||
# This approach is thoroughly recommended for offline mode networks.
|
||||
online-mode: true
|
||||
|
||||
# If the plugin should apply wildcard permissions.
|
||||
# If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered permissions matching
|
||||
# the wildcard. This will only work for plugins that define all of their permissions to the server.
|
||||
# the wildcard.
|
||||
apply-wildcards: true
|
||||
|
||||
# If the plugin should parse regex permissions.
|
||||
# If set to true, LuckPerms will detect regex permissions, marked with "r=" at the start of the node, and resolve &
|
||||
# apply all registered permissions matching the regex. This will only work for plugins that define all of their
|
||||
# permissions to the server.
|
||||
# apply all registered permissions matching the regex.
|
||||
apply-regex: true
|
||||
|
||||
# If the plugin should complete and apply shorthand permissions.
|
||||
# If set to true, LuckPerms will detect and expand shorthand node patterns.
|
||||
apply-shorthand: true
|
||||
|
||||
# If the plugin should send log notifications to users whenever permissions are modified.
|
||||
log-notify: true
|
||||
|
||||
# If LuckPerms should print to console every time a plugin checks if a player has a permission
|
||||
debug-permission-checks: false
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, h2, flatfile, mongodb
|
||||
# Currently supported: mysql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL or MongoDB
|
||||
storage-method: h2
|
||||
|
||||
# This block enables support for split datastores.
|
||||
# Only touch this if you're sure that you know what you're doing.
|
||||
# I (the author) do not endorse nor recommend the use of this feature.
|
||||
split-storage:
|
||||
enabled: false
|
||||
methods:
|
||||
user: h2
|
||||
group: h2
|
||||
track: h2
|
||||
uuid: h2
|
||||
log: h2
|
||||
|
||||
data:
|
||||
address: localhost:3306
|
||||
database: minecraft
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: LuckPerms
|
||||
author: Luck
|
||||
version: ${release.version}.${git.closest.tag.commit.count}
|
||||
main: me.lucko.luckperms.LPBungeePlugin
|
||||
softdepend: [PowerfulPerms] # For migration
|
||||
description: A permissions plugin
|
||||
author: Luck
|
||||
main: me.lucko.luckperms.LPBungeePlugin
|
||||
softdepends: [PowerfulPerms] # For migration
|
||||
+18
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.6-SNAPSHOT</version>
|
||||
<version>2.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -67,6 +67,13 @@
|
||||
<version>1.7.9</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- SnakeYAML -->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.14</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- gson -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
@@ -105,6 +112,10 @@
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.gravitydevelopment.updater</groupId>
|
||||
<artifactId>updater</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -125,6 +136,12 @@
|
||||
<version>3.0-dev-52</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.bananaco</groupId>
|
||||
<artifactId>bpermissions-api</artifactId>
|
||||
<version>2.12</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -23,6 +23,7 @@
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.implementation.ApiProvider;
|
||||
import me.lucko.luckperms.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
@@ -65,11 +66,10 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
|
||||
/**
|
||||
* @return the platform type
|
||||
*/
|
||||
Type getType();
|
||||
PlatformType getType();
|
||||
|
||||
/**
|
||||
* @return the main plugin directory
|
||||
@@ -103,7 +103,7 @@ public interface LuckPermsPlugin {
|
||||
/**
|
||||
* @return a {@link List} of senders online on the platform
|
||||
*/
|
||||
List<Sender> getSenders();
|
||||
List<Sender> getNotifyListeners();
|
||||
|
||||
/**
|
||||
* @return the console sender of the instance
|
||||
@@ -136,6 +136,13 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
Object getService(Class clazz);
|
||||
|
||||
/**
|
||||
* Used as a backup for migration
|
||||
* @param playerName the players name
|
||||
* @return a uuid if found, or null if not
|
||||
*/
|
||||
UUID getUUID(String playerName);
|
||||
|
||||
/**
|
||||
* Checks if a plugin is loaded on the platform
|
||||
* @param name the name of the plugin
|
||||
@@ -160,8 +167,4 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
void doSync(Runnable r);
|
||||
|
||||
|
||||
enum Type {
|
||||
BUKKIT, BUNGEE, SPONGE;
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ import java.util.stream.Collectors;
|
||||
import static me.lucko.luckperms.api.implementation.internal.Utils.checkNode;
|
||||
|
||||
/**
|
||||
* Provides static access to LuckPerms
|
||||
* Implements the LuckPerms API using the plugin instance
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class ApiProvider implements LuckPermsApi {
|
||||
@@ -67,7 +67,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public double getApiVersion() {
|
||||
return 1.6;
|
||||
return 2.9;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,6 +75,11 @@ public class ApiProvider implements LuckPermsApi {
|
||||
return plugin.getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformType getPlatformType() {
|
||||
return plugin.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerListener(@NonNull LPListener listener) {
|
||||
eventBus.register(listener);
|
||||
|
||||
+63
@@ -27,6 +27,8 @@ import me.lucko.luckperms.api.LPConfiguration;
|
||||
import me.lucko.luckperms.api.data.DatastoreConfiguration;
|
||||
import me.lucko.luckperms.api.data.MySQLConfiguration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link LPConfiguration} and {@link me.lucko.luckperms.core.LPConfiguration}
|
||||
*/
|
||||
@@ -59,6 +61,21 @@ public class LPConfigurationLink implements LPConfiguration {
|
||||
return master.getIncludeGlobalPerms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getIncludeGlobalWorldPerms() {
|
||||
return master.getIncludeGlobalWorldPerms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getApplyGlobalGroups() {
|
||||
return master.getApplyGlobalGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getApplyGlobalWorldGroups() {
|
||||
return master.getApplyGlobalWorldGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getOnlineMode() {
|
||||
return master.getOnlineMode();
|
||||
@@ -79,6 +96,41 @@ public class LPConfigurationLink implements LPConfiguration {
|
||||
return master.getApplyShorthand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getLogNotify() {
|
||||
return master.getLogNotify();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDebugPermissionChecks() {
|
||||
return master.getDebugPermissionChecks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getEnableOps() {
|
||||
return master.getEnableOps();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCommandsAllowOp() {
|
||||
return master.getCommandsAllowOp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAutoOp() {
|
||||
return master.getAutoOp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVaultServer() {
|
||||
return master.getVaultServer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getVaultIncludeGlobal() {
|
||||
return master.getVaultIncludeGlobal();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public MySQLConfiguration getDatabaseValues() {
|
||||
@@ -94,4 +146,15 @@ public class LPConfigurationLink implements LPConfiguration {
|
||||
public String getStorageMethod() {
|
||||
return master.getStorageMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSplitStorage() {
|
||||
return master.getSplitStorage();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Map<String, String> getSplitStorageOptions() {
|
||||
return master.getSplitStorageOptions();
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -29,6 +29,7 @@ import me.lucko.luckperms.api.PermissionHolder;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.utils.Contexts;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -52,7 +53,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
|
||||
@Override
|
||||
public SortedSet<Node> getPermissions() {
|
||||
return Collections.unmodifiableSortedSet(master.getPermissions());
|
||||
return Collections.unmodifiableSortedSet(master.getPermissions(false));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,7 +68,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
|
||||
@Override
|
||||
public Set<Node> getAllNodes() {
|
||||
return Collections.unmodifiableSet(master.getAllNodes(null));
|
||||
return Collections.unmodifiableSet(master.getAllNodes(Collections.emptyList(), Contexts.allowAll()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -252,7 +253,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getPermissions(String server, String world, Map<String, String> extraContext, boolean includeGlobal, List<String> possibleNodes, boolean applyGroups) {
|
||||
return master.exportNodes(server, world, extraContext, includeGlobal, applyGroups, possibleNodes);
|
||||
return master.exportNodes(new Contexts(server, world, extraContext, includeGlobal, includeGlobal, applyGroups, true, true), possibleNodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -61,6 +61,7 @@ public class CommandManager {
|
||||
.add(new InfoCommand())
|
||||
.add(new DebugCommand())
|
||||
.add(new ImportCommand())
|
||||
.add(new ExportCommand())
|
||||
.add(new QueueCommand())
|
||||
.add(new MigrationMainCommand())
|
||||
.add(new CreateGroup())
|
||||
|
||||
@@ -22,11 +22,14 @@
|
||||
|
||||
package me.lucko.luckperms.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.constants.Constants;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -35,7 +38,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public abstract class SenderFactory<T> implements Runnable {
|
||||
private final Map<T, List<String>> messages = new HashMap<>();
|
||||
//private final List<Map.Entry<T, String>> messages = new ArrayList<>();
|
||||
private final AtomicBoolean shouldSend = new AtomicBoolean(false);
|
||||
private final SenderFactory<T> factory = this;
|
||||
|
||||
protected abstract String getName(T t);
|
||||
@@ -44,50 +47,78 @@ public abstract class SenderFactory<T> implements Runnable {
|
||||
protected abstract boolean hasPermission(T t, String node);
|
||||
|
||||
public final Sender wrap(T t) {
|
||||
return new Sender() {
|
||||
final WeakReference<T> tRef = new WeakReference<>(t);
|
||||
return new SenderImp(t, null);
|
||||
}
|
||||
|
||||
// Cache these permissions, so they can be accessed async
|
||||
final Map<Permission, Boolean> perms = Arrays.stream(Permission.values())
|
||||
.map(p -> new AbstractMap.SimpleEntry<>(p, factory.hasPermission(t, p.getNode())))
|
||||
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
|
||||
|
||||
@Getter
|
||||
final String name = factory.getName(t);
|
||||
|
||||
@Getter
|
||||
final UUID uuid = factory.getUuid(t);
|
||||
|
||||
@Override
|
||||
public void sendMessage(String s) {
|
||||
final T t = tRef.get();
|
||||
if (t != null) {
|
||||
synchronized (messages) {
|
||||
if (!messages.containsKey(t)) {
|
||||
messages.put(t, new ArrayList<>());
|
||||
}
|
||||
|
||||
messages.get(t).add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Permission permission) {
|
||||
synchronized (perms) {
|
||||
return perms.get(permission);
|
||||
}
|
||||
}
|
||||
};
|
||||
public final Sender wrap(T t, Set<Permission> toCheck) {
|
||||
return new SenderImp(t, toCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
if (!shouldSend.getAndSet(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (messages) {
|
||||
if (!messages.isEmpty()) {
|
||||
messages.entrySet().forEach(e -> e.getValue().forEach(s -> factory.sendMessage(e.getKey(), s)));
|
||||
messages.clear();
|
||||
for (Map.Entry<T, List<String>> e : messages.entrySet()) {
|
||||
for (String s : e.getValue()) {
|
||||
factory.sendMessage(e.getKey(), s);
|
||||
}
|
||||
}
|
||||
|
||||
messages.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private class SenderImp implements Sender {
|
||||
private final WeakReference<T> tRef;
|
||||
|
||||
// Cache these permissions, so they can be accessed async
|
||||
private Map<Permission, Boolean> perms;
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
@Getter
|
||||
private final UUID uuid;
|
||||
|
||||
private final boolean console;
|
||||
|
||||
private SenderImp(T t, Set<Permission> toCheck) {
|
||||
this.tRef = new WeakReference<>(t);
|
||||
this.name = factory.getName(t);
|
||||
this.uuid = factory.getUuid(t);
|
||||
this.console = this.uuid.equals(Constants.getConsoleUUID()) || this.uuid.equals(Constants.getImporterUUID());
|
||||
|
||||
if (!this.console) {
|
||||
if (toCheck == null || toCheck.isEmpty()) {
|
||||
this.perms = ImmutableMap.copyOf(Arrays.stream(Permission.values())
|
||||
.collect(Collectors.toMap(p -> p, p -> factory.hasPermission(t, p.getNode()))));
|
||||
} else {
|
||||
this.perms = ImmutableMap.copyOf(toCheck.stream().collect(Collectors.toMap(p -> p, p -> factory.hasPermission(t, p.getNode()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String s) {
|
||||
final T t = tRef.get();
|
||||
if (t != null) {
|
||||
synchronized (messages) {
|
||||
if (!messages.containsKey(t)) {
|
||||
messages.put(t, new ArrayList<>());
|
||||
}
|
||||
|
||||
messages.get(t).add(s);
|
||||
}
|
||||
shouldSend.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Permission permission) {
|
||||
return console || perms.get(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,10 +110,11 @@ public abstract class SubCommand<T> {
|
||||
return permission.isAuthorized(sender);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
----------------------------------------------------------------------------------
|
||||
Utility methods used by #onTabComplete and #execute implementations in sub classes
|
||||
----------------------------------------------------------------------------------
|
||||
* ----------------------------------------------------------------------------------
|
||||
* Utility methods used by #onTabComplete and #execute implementations in sub classes
|
||||
* ----------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected static List<String> getGroupTabComplete(List<String> args, LuckPermsPlugin plugin) {
|
||||
|
||||
@@ -23,13 +23,12 @@
|
||||
package me.lucko.luckperms.commands;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.utils.DateUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
@UtilityClass
|
||||
public class Util {
|
||||
@@ -38,6 +37,22 @@ public class Util {
|
||||
sender.sendMessage(color(Message.PREFIX + message));
|
||||
}
|
||||
|
||||
public static List<String> stripQuotes(List<String> input) {
|
||||
input = new ArrayList<>(input);
|
||||
ListIterator<String> iterator = input.listIterator();
|
||||
while (iterator.hasNext()) {
|
||||
String value = iterator.next();
|
||||
if (!(value.length() >= 3)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value.charAt(0) == '"' && value.charAt(value.length() - 1) == '"') {
|
||||
iterator.set(value.substring(1, value.length() - 1));
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
public static String color(String s) {
|
||||
return translateAlternateColorCodes('&', s);
|
||||
}
|
||||
@@ -114,35 +129,53 @@ public class Util {
|
||||
return sb.delete(sb.length() - 6, sb.length()).toString();
|
||||
}
|
||||
|
||||
public static String permNodesToString(Map<String, Boolean> nodes) {
|
||||
if (nodes.isEmpty()) return "&6None";
|
||||
|
||||
public static String permNodesToString(SortedSet<Node> nodes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (Map.Entry<String, Boolean> e : nodes.entrySet()) {
|
||||
if (e.getValue()) {
|
||||
sb.append("&a").append(e.getKey()).append("&7, ");
|
||||
} else {
|
||||
sb.append("&c").append(e.getKey()).append("&7, ");
|
||||
for (Node node : nodes) {
|
||||
if (node.isTemporary()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sb.append("&6-> ").append(node.getValue() ? "&a" : "&c");
|
||||
sb.append(node.getPermission());
|
||||
if (node.isServerSpecific()) {
|
||||
sb.append(" &7(&f").append(node.getServer().get()).append("&7)");
|
||||
}
|
||||
if (node.isWorldSpecific()) {
|
||||
sb.append(" &7(&f").append(node.getWorld().get()).append("&7)");
|
||||
}
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
return sb.delete(sb.length() - 2, sb.length()).toString();
|
||||
if (sb.length() == 0) {
|
||||
return "&6None";
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String tempNodesToString(Map<Map.Entry<String, Boolean>, Long> nodes) {
|
||||
if (nodes.isEmpty()) return "&6None";
|
||||
|
||||
public static String tempNodesToString(SortedSet<Node> nodes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (Map.Entry<Map.Entry<String, Boolean>, Long> e : nodes.entrySet()) {
|
||||
if (e.getKey().getValue()) {
|
||||
sb.append("&a").append(e.getKey().getKey()).append("&6 - expires in ")
|
||||
.append(DateUtil.formatDateDiff(e.getValue())).append("\n");
|
||||
} else {
|
||||
sb.append("&c").append(e.getKey().getKey()).append("&6 - expires in ")
|
||||
.append(DateUtil.formatDateDiff(e.getValue())).append("\n");
|
||||
for (Node node : nodes) {
|
||||
if (!node.isTemporary()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sb.append("&6-> ").append(node.getValue() ? "&a" : "&c");
|
||||
sb.append(node.getPermission());
|
||||
if (node.isServerSpecific()) {
|
||||
sb.append(" &7(&f").append(node.getServer().get()).append("&7)");
|
||||
}
|
||||
if (node.isWorldSpecific()) {
|
||||
sb.append(" &7(&f").append(node.getWorld().get()).append("&7)");
|
||||
}
|
||||
|
||||
sb.append("&6 - expires in ").append(DateUtil.formatDateDiff(node.getExpiryUnixTime())).append("\n");
|
||||
}
|
||||
|
||||
if (sb.length() == 0) {
|
||||
return "&6None";
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
@@ -161,4 +194,25 @@ public class Util {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized MetaComparator getMetaComparator() {
|
||||
if (metaComparator == null) {
|
||||
metaComparator = new MetaComparator();
|
||||
}
|
||||
return metaComparator;
|
||||
}
|
||||
|
||||
|
||||
private static MetaComparator metaComparator = null;
|
||||
public class MetaComparator implements Comparator<Map.Entry<Integer, String>> {
|
||||
|
||||
@Override
|
||||
public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
|
||||
int result = Integer.compare(o1.getKey(), o2.getKey());
|
||||
if (result == 0) {
|
||||
result = o1.getValue().compareTo(o2.getValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,15 @@ public class GroupMainCommand extends MainCommand<Group> {
|
||||
.add(new GroupSetTempInherit())
|
||||
.add(new GroupUnsetTempInherit())
|
||||
.add(new GroupShowTracks())
|
||||
.add(new GroupChatMeta())
|
||||
.add(new GroupAddPrefix())
|
||||
.add(new GroupAddSuffix())
|
||||
.add(new GroupRemovePrefix())
|
||||
.add(new GroupRemoveSuffix())
|
||||
.add(new GroupAddTempPrefix())
|
||||
.add(new GroupAddTempSuffix())
|
||||
.add(new GroupRemoveTempPrefix())
|
||||
.add(new GroupRemoveTempSuffix())
|
||||
.add(new GroupClear())
|
||||
.add(new GroupRename())
|
||||
.build()
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupAddPrefix extends SubCommand<Group> {
|
||||
public GroupAddPrefix() {
|
||||
super("addprefix", "Adds a prefix to the group", "/%s group <group> addprefix <priority> <prefix> [server] [world]",
|
||||
Permission.GROUP_ADDPREFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.setPermission(node, true, server);
|
||||
Message.ADDPREFIX_SERVER_SUCCESS.send(sender, group.getName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.setPermission(node, true, server, world);
|
||||
Message.ADDPREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.setPermission(node, true);
|
||||
Message.ADDPREFIX_SUCCESS.send(sender, group.getName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, group.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupAddSuffix extends SubCommand<Group> {
|
||||
public GroupAddSuffix() {
|
||||
super("addsuffix", "Adds a suffix to the group", "/%s group <group> addsuffix <priority> <suffix> [server] [world]",
|
||||
Permission.GROUP_ADDSUFFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.setPermission(node, true, server);
|
||||
Message.ADDSUFFIX_SERVER_SUCCESS.send(sender, group.getName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addsuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.setPermission(node, true, server, world);
|
||||
Message.ADDSUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addsuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.setPermission(node, true);
|
||||
Message.ADDSUFFIX_SUCCESS.send(sender, group.getName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addsuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, group.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.utils.DateUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupAddTempPrefix extends SubCommand<Group> {
|
||||
public GroupAddTempPrefix() {
|
||||
super("addtempprefix", "Adds a prefix to the group temporarily", "/%s group <group> addtempprefix <priority> <prefix> <duration> [server] [world]",
|
||||
Permission.GROUP_ADD_TEMP_PREFIX, Predicate.notInRange(3, 5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
long duration;
|
||||
try {
|
||||
duration = Long.parseLong(args.get(2));
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
duration = DateUtil.parseDateDiff(args.get(2), true);
|
||||
} catch (DateUtil.IllegalDateException e1) {
|
||||
Message.ILLEGAL_DATE_ERROR.send(sender, args.get(2));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
if (DateUtil.shouldExpire(duration)) {
|
||||
Message.PAST_DATE_ERROR.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 4) {
|
||||
final String server = args.get(3).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 4) {
|
||||
group.setPermission(node, true, server, duration);
|
||||
Message.ADD_TEMP_PREFIX_SERVER_SUCCESS.send(sender, group.getName(), prefix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(4).toLowerCase();
|
||||
group.setPermission(node, true, server, world, duration);
|
||||
Message.ADD_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), prefix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_PREFIX_SUCCESS.send(sender, group.getName(), prefix, priority, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, group.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.utils.DateUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupAddTempSuffix extends SubCommand<Group> {
|
||||
public GroupAddTempSuffix() {
|
||||
super("addtempsuffix", "Adds a suffix to the group temporarily", "/%s group <group> addtempsuffix <priority> <suffix> <duration> [server] [world]",
|
||||
Permission.GROUP_ADD_TEMP_SUFFIX, Predicate.notInRange(3, 5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
long duration;
|
||||
try {
|
||||
duration = Long.parseLong(args.get(2));
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
duration = DateUtil.parseDateDiff(args.get(2), true);
|
||||
} catch (DateUtil.IllegalDateException e1) {
|
||||
Message.ILLEGAL_DATE_ERROR.send(sender, args.get(2));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
if (DateUtil.shouldExpire(duration)) {
|
||||
Message.PAST_DATE_ERROR.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 4) {
|
||||
final String server = args.get(3).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 4) {
|
||||
group.setPermission(node, true, server, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, group.getName(), suffix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(4).toLowerCase();
|
||||
group.setPermission(node, true, server, world, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), suffix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SUCCESS.send(sender, group.getName(), suffix, priority, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, group.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.Contexts;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class GroupChatMeta extends SubCommand<Group> {
|
||||
public GroupChatMeta() {
|
||||
super("chatmeta", "Displays a groups chat meta", "/%s group <group> chatmeta", Permission.GROUP_CHATMETA,
|
||||
Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
SortedSet<Map.Entry<Integer, String>> prefixes = new TreeSet<>(Util.getMetaComparator().reversed());
|
||||
SortedSet<Map.Entry<Integer, String>> suffixes = new TreeSet<>(Util.getMetaComparator().reversed());
|
||||
|
||||
for (Node node : group.getAllNodes(null, Contexts.allowAll())) {
|
||||
if (!node.isSuffix() && !node.isPrefix()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (node.isServerSpecific()) {
|
||||
if (node.isWorldSpecific()) {
|
||||
sb.append("&6W=").append(node.getWorld().get()).append(" ");
|
||||
}
|
||||
sb.append("&6S=").append(node.getServer().get()).append(" ");
|
||||
}
|
||||
|
||||
if (node.isPrefix()) {
|
||||
sb.append(node.getPrefix().getValue());
|
||||
prefixes.add(new AbstractMap.SimpleEntry<>(node.getPrefix().getKey(), sb.toString()));
|
||||
}
|
||||
|
||||
if (node.isSuffix()) {
|
||||
sb.append(node.getSuffix().getValue());
|
||||
suffixes.add(new AbstractMap.SimpleEntry<>(node.getSuffix().getKey(), sb.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
if (prefixes.isEmpty()) {
|
||||
Message.CHAT_META_PREFIX_NONE.send(sender, group.getName());
|
||||
} else {
|
||||
Message.CHAT_META_PREFIX_HEADER.send(sender, group.getName());
|
||||
for (Map.Entry<Integer, String> e : prefixes) {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (suffixes.isEmpty()) {
|
||||
Message.CHAT_META_SUFFIX_NONE.send(sender, group.getName());
|
||||
} else {
|
||||
Message.CHAT_META_SUFFIX_HEADER.send(sender, group.getName());
|
||||
for (Map.Entry<Integer, String> e : suffixes) {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -30,8 +30,6 @@ import me.lucko.luckperms.groups.Group;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static me.lucko.luckperms.core.PermissionHolder.exportToLegacy;
|
||||
|
||||
public class GroupListNodes extends SubCommand<Group> {
|
||||
public GroupListNodes() {
|
||||
super("listnodes", "Lists the permission nodes the group has", "/%s group <group> listnodes",
|
||||
@@ -40,8 +38,8 @@ public class GroupListNodes extends SubCommand<Group> {
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
Message.LISTNODES.send(sender, group.getName(), Util.permNodesToString(exportToLegacy(group.getPermanentNodes())));
|
||||
Message.LISTNODES_TEMP.send(sender, group.getName(), Util.tempNodesToString(group.getTemporaryNodesLegacy()));
|
||||
Message.LISTNODES.send(sender, group.getName(), Util.permNodesToString(group.getPermissions(false)));
|
||||
Message.LISTNODES_TEMP.send(sender, group.getName(), Util.tempNodesToString(group.getPermissions(false)));
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupRemovePrefix extends SubCommand<Group> {
|
||||
public GroupRemovePrefix() {
|
||||
super("removeprefix", "Removes a prefix from a group", "/%s group <group> removeprefix <priority> <prefix> [server] [world]",
|
||||
Permission.GROUP_REMOVEPREFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server);
|
||||
Message.REMOVEPREFIX_SERVER_SUCCESS.send(sender, group.getName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removeprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world);
|
||||
Message.REMOVEPREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removeprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node);
|
||||
Message.REMOVEPREFIX_SUCCESS.send(sender, group.getName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removeprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, group.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupRemoveSuffix extends SubCommand<Group> {
|
||||
public GroupRemoveSuffix() {
|
||||
super("removesuffix", "Removes a suffix from a group", "/%s group <group> removesuffix <priority> <suffix> [server] [world]",
|
||||
Permission.GROUP_REMOVESUFFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server);
|
||||
Message.REMOVESUFFIX_SERVER_SUCCESS.send(sender, group.getName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removesuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world);
|
||||
Message.REMOVESUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removesuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node);
|
||||
Message.REMOVESUFFIX_SUCCESS.send(sender, group.getName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removesuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, group.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupRemoveTempPrefix extends SubCommand<Group> {
|
||||
public GroupRemoveTempPrefix() {
|
||||
super("removetempprefix", "Removes a temporary prefix from a group", "/%s group <group> removetempprefix <priority> <prefix> [server] [world]",
|
||||
Permission.GROUP_REMOVE_TEMP_PREFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_SUCCESS.send(sender, group.getName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SUCCESS.send(sender, group.getName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, group.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupRemoveTempSuffix extends SubCommand<Group> {
|
||||
public GroupRemoveTempSuffix() {
|
||||
super("removetempsuffix", "Removes a temporary suffix from a group", "/%s group <group> removetempsuffix <priority> <suffix> [server] [world]",
|
||||
Permission.GROUP_REMOVE_TEMP_SUFFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, group.getName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SUCCESS.send(sender, group.getName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, group.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
@@ -53,7 +52,7 @@ public class GroupSetPermission extends SubCommand<Group> {
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.GROUP_USE_INHERIT.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
+1
-2
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
@@ -55,7 +54,7 @@ public class GroupSetTempPermission extends SubCommand<Group> {
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.GROUP_USE_INHERIT.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
+1
-2
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
@@ -52,7 +51,7 @@ public class GroupUnSetPermission extends SubCommand<Group> {
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.GROUP_USE_UNINHERIT.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
+1
-2
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
@@ -53,7 +52,7 @@ public class GroupUnsetTempPermission extends SubCommand<Group> {
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.GROUP_USE_UNINHERIT.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ public class LogExport extends SubCommand<Log> {
|
||||
break track;
|
||||
}
|
||||
|
||||
b.append("track ").append(e.getActedName()).append(" ").append(e.getAction());;
|
||||
b.append("track ").append(e.getActedName()).append(" ").append(e.getAction());
|
||||
}
|
||||
|
||||
data.add(b.toString());
|
||||
|
||||
@@ -66,6 +66,11 @@ public class MigrationMainCommand extends MainCommand<Object> {
|
||||
subCommands.add(new MigrationBungeePerms());
|
||||
} catch (Throwable ignored) {}
|
||||
|
||||
try {
|
||||
Class.forName("de.bananaco.bpermissions.api.WorldManager");
|
||||
subCommands.add(new MigrationBPermissions());
|
||||
} catch (Throwable ignored) {}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* 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.commands.migration.subcommands;
|
||||
|
||||
import de.bananaco.bpermissions.api.*;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Constants;
|
||||
import me.lucko.luckperms.core.PermissionHolder;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
import static me.lucko.luckperms.constants.Permission.MIGRATION;
|
||||
|
||||
public class MigrationBPermissions extends SubCommand<Object> {
|
||||
private static Field uConfigField;
|
||||
private static Method getConfigurationSectionMethod = null;
|
||||
private static Method getKeysMethod = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
uConfigField = Class.forName("de.bananaco.bpermissions.imp.YamlWorld").getDeclaredField("uconfig");
|
||||
uConfigField.setAccessible(true);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Set<String> getUsers(World world) {
|
||||
try {
|
||||
Object yamlWorldUsers = uConfigField.get(world);
|
||||
if (getConfigurationSectionMethod == null) {
|
||||
getConfigurationSectionMethod = yamlWorldUsers.getClass().getMethod("getConfigurationSection", String.class);
|
||||
getConfigurationSectionMethod.setAccessible(true);
|
||||
}
|
||||
|
||||
Object configSection = getConfigurationSectionMethod.invoke(yamlWorldUsers, "users");
|
||||
if (configSection == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
if (getKeysMethod == null) {
|
||||
getKeysMethod = configSection.getClass().getMethod("getKeys", boolean.class);
|
||||
getKeysMethod.setAccessible(true);
|
||||
}
|
||||
|
||||
return (Set<String>) getKeysMethod.invoke(configSection, false);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public MigrationBPermissions() {
|
||||
super("bpermissions", "Migration from bPermissions", "/%s migration bpermissions", MIGRATION, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) {
|
||||
final Logger log = plugin.getLog();
|
||||
|
||||
WorldManager worldManager = WorldManager.getInstance();
|
||||
if (worldManager == null) {
|
||||
log.severe("bPermissions Migration: Error -> bPermissions is not loaded.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
log.info("bPermissions Migration: Forcing the plugin to load all data. This could take a while.");
|
||||
for (World world : worldManager.getAllWorlds()) {
|
||||
Set<String> users = getUsers(world);
|
||||
if (users == null) {
|
||||
log.severe("bPermissions Migration: Couldn't get a list of users.");
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
users.forEach(s -> world.loadOne(s, CalculableType.USER));
|
||||
}
|
||||
|
||||
// Migrate one world at a time.
|
||||
log.info("bPermissions Migration: Starting world migration.");
|
||||
for (World world : worldManager.getAllWorlds()) {
|
||||
log.info("bPermissions Migration: Migrating world: " + world.getName());
|
||||
|
||||
// Migrate all groups
|
||||
log.info("bPermissions Migration: Starting group migration in world " + world.getName() + ".");
|
||||
int groupCount = 0;
|
||||
for (Calculable group : world.getAll(CalculableType.GROUP)) {
|
||||
groupCount++;
|
||||
String groupName = group.getName().toLowerCase();
|
||||
if (group.getName().equalsIgnoreCase(world.getDefaultGroup())) {
|
||||
groupName = "default";
|
||||
}
|
||||
|
||||
// Make a LuckPerms group for the one being migrated.
|
||||
plugin.getDatastore().createAndLoadGroup(groupName);
|
||||
me.lucko.luckperms.groups.Group lpGroup = plugin.getGroupManager().get(groupName);
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(lpGroup).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
migrateHolder(plugin, world, group, lpGroup);
|
||||
plugin.getDatastore().saveGroup(lpGroup);
|
||||
}
|
||||
log.info("bPermissions Migration: Migrated " + groupCount + " groups in world " + world.getName() + ".");
|
||||
|
||||
// Migrate all users
|
||||
log.info("bPermissions Migration: Starting user migration in world " + world.getName() + ".");
|
||||
int userCount = 0;
|
||||
for (Calculable user : world.getAll(CalculableType.USER)) {
|
||||
userCount++;
|
||||
|
||||
// There is no mention of UUIDs in the API. I assume that name = uuid. idk?
|
||||
UUID uuid;
|
||||
try {
|
||||
uuid = UUID.fromString(user.getName());
|
||||
} catch (IllegalArgumentException e) {
|
||||
uuid = plugin.getUUID(user.getName());
|
||||
}
|
||||
|
||||
if (uuid == null) {
|
||||
log.info("bPermissions Migration: Unable to migrate user " + user.getName() + ". Unable to get UUID.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make a LuckPerms user for the one being migrated.
|
||||
plugin.getDatastore().loadUser(uuid, "null");
|
||||
me.lucko.luckperms.users.User lpUser = plugin.getUserManager().get(uuid);
|
||||
|
||||
migrateHolder(plugin, world, user, lpUser);
|
||||
|
||||
plugin.getDatastore().saveUser(lpUser);
|
||||
plugin.getUserManager().cleanup(lpUser);
|
||||
}
|
||||
|
||||
log.info("bPermissions Migration: Migrated " + userCount + " users in world " + world.getName() + ".");
|
||||
}
|
||||
|
||||
log.info("bPermissions Migration: Success! Completed without any errors.");
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private static void migrateHolder(LuckPermsPlugin plugin, World world, Calculable c, PermissionHolder holder) {
|
||||
// Migrate the groups permissions in this world
|
||||
for (Permission p : c.getPermissions()) {
|
||||
try {
|
||||
holder.setPermission(p.name(), p.isTrue(), "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(holder).action("set " + p.name() + " " + p.isTrue() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Include any child permissions
|
||||
for (Map.Entry<String, Boolean> child : p.getChildren().entrySet()) {
|
||||
try {
|
||||
holder.setPermission(child.getKey(), child.getValue(), "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(holder).action("set " + child.getKey() + " " + child.getValue() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate any inherited groups
|
||||
for (Group parent : c.getGroups()) {
|
||||
try {
|
||||
holder.setPermission("group." + parent.getName(), true, "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(holder).action("setinherit " + parent.getName() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate existing meta
|
||||
for (Map.Entry<String, String> meta : c.getMeta().entrySet()) {
|
||||
if (meta.getKey().equalsIgnoreCase("prefix") || meta.getKey().equalsIgnoreCase("suffix")) {
|
||||
String chatMeta = ArgumentChecker.escapeCharacters(meta.getValue());
|
||||
try {
|
||||
holder.setPermission(meta.getKey().toLowerCase() + "." + c.getPriority() + "." + chatMeta, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(holder).action("set " + meta.getKey().toLowerCase() + "." + c.getPriority() + "." + chatMeta + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
holder.setPermission("meta." + meta.getKey() + "." + meta.getValue(), true, "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(holder).action("set meta." + meta.getKey() + "." + meta.getValue() + " true global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -123,6 +123,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveGroup(group);
|
||||
}
|
||||
|
||||
Map<UUID, Map<Map.Entry<String, String>, Boolean>> users = new HashMap<>();
|
||||
|
||||
+40
-54
@@ -24,6 +24,7 @@ package me.lucko.luckperms.commands.migration.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
@@ -43,41 +44,11 @@ import ru.tehkode.permissions.bukkit.PermissionsEx;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
|
||||
private static Class<?> bukkitPlayer = null;
|
||||
private static Method getUniqueIdMethod = null;
|
||||
private static Method getPlayerMethod = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
bukkitPlayer = Class.forName("org.bukkit.entity.Player");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (bukkitPlayer != null) {
|
||||
try {
|
||||
getUniqueIdMethod = bukkitPlayer.getMethod("getUniqueId");
|
||||
getUniqueIdMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
getPlayerMethod = PermissionUser.class.getMethod("getPlayer");
|
||||
getPlayerMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public MigrationPermissionsEx() {
|
||||
super("permissionsex", "Migration from PermissionsEx", "/%s migration permissionsex [world names]",
|
||||
Permission.MIGRATION, Predicate.alwaysFalse());
|
||||
@@ -92,7 +63,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
if (plugin.getType() != LuckPermsPlugin.Type.BUKKIT) {
|
||||
if (plugin.getType() != PlatformType.BUKKIT) {
|
||||
// Sponge uses a completely different version of PEX.
|
||||
log.severe("PEX import is not supported on this platform.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
@@ -123,9 +94,15 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
|
||||
// Migrate all groups.
|
||||
log.info("PermissionsEx Migration: Starting group migration.");
|
||||
|
||||
int maxGroupWeight = 0;
|
||||
int groupCount = 0;
|
||||
|
||||
for (PermissionGroup group : manager.getGroupList()) {
|
||||
int groupWeight = group.getWeight() * -1;
|
||||
groupCount ++;
|
||||
maxGroupWeight = Math.max(maxGroupWeight, groupWeight);
|
||||
|
||||
final String name = group.getName().toLowerCase();
|
||||
plugin.getDatastore().createAndLoadGroup(name);
|
||||
Group lpGroup = plugin.getGroupManager().get(name);
|
||||
@@ -141,7 +118,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
for (String node : group.getOwnPermissions(null)) {
|
||||
boolean value = true;
|
||||
if (node.startsWith("!")) {
|
||||
if (node.startsWith("-")) {
|
||||
node = node.substring(1);
|
||||
value = false;
|
||||
}
|
||||
@@ -166,7 +143,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
for (String world : worlds) {
|
||||
for (String node : group.getOwnPermissions(world)) {
|
||||
boolean value = true;
|
||||
if (node.startsWith("!")) {
|
||||
if (node.startsWith("-")) {
|
||||
node = node.substring(1);
|
||||
value = false;
|
||||
}
|
||||
@@ -224,10 +201,10 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
if (prefix != null && !prefix.equals("")) {
|
||||
prefix = ArgumentChecker.escapeCharacters(prefix);
|
||||
try {
|
||||
lpGroup.setPermission("prefix.50." + prefix, true);
|
||||
lpGroup.setPermission("prefix." + groupWeight + "." + prefix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(lpGroup).action("set prefix.50." + prefix + " true")
|
||||
.acted(lpGroup).action("set prefix." + groupWeight + "." + prefix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
@@ -239,10 +216,10 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
if (suffix != null && !suffix.equals("")) {
|
||||
suffix = ArgumentChecker.escapeCharacters(suffix);
|
||||
try {
|
||||
lpGroup.setPermission("suffix.50." + suffix, true);
|
||||
lpGroup.setPermission("suffix." + groupWeight + "." + suffix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(lpGroup).action("set suffix.50." + suffix + " true")
|
||||
.acted(lpGroup).action("set suffix." + groupWeight + "." + suffix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
@@ -251,6 +228,8 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveGroup(lpGroup);
|
||||
|
||||
}
|
||||
|
||||
log.info("PermissionsEx Migration: Migrated " + groupCount + " groups");
|
||||
@@ -258,25 +237,16 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
// Migrate all users
|
||||
log.info("PermissionsEx Migration: Starting user migration.");
|
||||
int userCount = 0;
|
||||
maxGroupWeight++;
|
||||
for (PermissionUser user : manager.getUsers()) {
|
||||
UUID u = null;
|
||||
|
||||
try {
|
||||
u = UUID.fromString(user.getIdentifier());
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
||||
u = ni.nameToUUID(user.getIdentifier());
|
||||
|
||||
if (u == null) {
|
||||
if (bukkitPlayer != null) {
|
||||
try {
|
||||
Object playerObj = getPlayerMethod.invoke(user);
|
||||
u = (UUID) getUniqueIdMethod.invoke(playerObj);
|
||||
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
u = plugin.getUUID(user.getIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +262,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
for (String node : user.getOwnPermissions(null)) {
|
||||
boolean value = true;
|
||||
if (node.startsWith("!")) {
|
||||
if (node.startsWith("-")) {
|
||||
node = node.substring(1);
|
||||
value = false;
|
||||
}
|
||||
@@ -317,7 +287,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
for (String world : worlds) {
|
||||
for (String node : user.getOwnPermissions(world)) {
|
||||
boolean value = true;
|
||||
if (node.startsWith("!")) {
|
||||
if (node.startsWith("-")) {
|
||||
node = node.substring(1);
|
||||
value = false;
|
||||
}
|
||||
@@ -375,10 +345,10 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
if (prefix != null && !prefix.equals("")) {
|
||||
prefix = ArgumentChecker.escapeCharacters(prefix);
|
||||
try {
|
||||
lpUser.setPermission("prefix.100." + prefix, true);
|
||||
lpUser.setPermission("prefix." + maxGroupWeight + "." + prefix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(lpUser).action("set prefix.100." + prefix + " true")
|
||||
.acted(lpUser).action("set prefix." + maxGroupWeight + "." + prefix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
@@ -390,10 +360,10 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
if (suffix != null && !suffix.equals("")) {
|
||||
suffix = ArgumentChecker.escapeCharacters(suffix);
|
||||
try {
|
||||
lpUser.setPermission("suffix.100." + suffix, true);
|
||||
lpUser.setPermission("suffix." + maxGroupWeight + "." + suffix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(lpUser).action("set suffix.100." + suffix + " true")
|
||||
.acted(lpUser).action("set suffix." + maxGroupWeight + "." + suffix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
@@ -402,6 +372,22 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
String primary = null;
|
||||
int weight = -100;
|
||||
for (PermissionGroup group : user.getOwnParents()) {
|
||||
if (group.getRank() > weight) {
|
||||
primary = group.getName();
|
||||
weight = group.getWeight();
|
||||
}
|
||||
}
|
||||
|
||||
if (primary != null) {
|
||||
try {
|
||||
lpUser.setPermission("group." + primary.toLowerCase(), true);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
lpUser.setPrimaryGroup(primary);
|
||||
}
|
||||
|
||||
plugin.getUserManager().cleanup(lpUser);
|
||||
plugin.getDatastore().saveUser(lpUser);
|
||||
}
|
||||
|
||||
+254
-180
@@ -23,14 +23,17 @@
|
||||
package me.lucko.luckperms.commands.migration.subcommands;
|
||||
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.*;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import lombok.Cleanup;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.commands.migration.subcommands.utils.LPResultRunnable;
|
||||
import me.lucko.luckperms.constants.Constants;
|
||||
import me.lucko.luckperms.core.PermissionHolder;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
@@ -45,39 +48,72 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static me.lucko.luckperms.constants.Permission.MIGRATION;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
/* <sadness>
|
||||
The PowerfulPerms API is a complete joke. Seriously, it would probably be easier reflecting into the actual plugin.
|
||||
Methods move about randomly every version...
|
||||
|
||||
What kind of API requires reflection to function with multiple versions...
|
||||
Doesn't that just defeat the whole god damn point of having an API in the first place?
|
||||
Whatever happened to the concept of depreciation and responsible API creation?
|
||||
I tried to keep reflection to a minimum, but in some places there's no other option.
|
||||
This class is a complete fucking mess for that reason. I sad now :(
|
||||
</sadness> */
|
||||
Whatever happened to depreciation?
|
||||
</sadness> */
|
||||
|
||||
private static Method getPlayerPermissionsMethod = null;
|
||||
private static Method getPlayerGroupsMethod = null;
|
||||
private static Method getGroupMethod = null;
|
||||
|
||||
// lol
|
||||
private static boolean superLegacy = false;
|
||||
private static boolean legacy = false;
|
||||
|
||||
static {
|
||||
try {
|
||||
getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerOwnGroups", UUID.class, ResultRunnable.class);
|
||||
getPlayerGroupsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
Class.forName("com.github.cheesesoftware.PowerfulPermsAPI.ResponseRunnable");
|
||||
legacy = true;
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
|
||||
if (legacy) {
|
||||
try {
|
||||
getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerGroups", UUID.class, ResultRunnable.class);
|
||||
getPlayerGroupsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
getPlayerPermissionsMethod = PermissionManager.class.getMethod("getPlayerOwnPermissions", UUID.class, ResultRunnable.class);
|
||||
getPlayerPermissionsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException ignored) {}
|
||||
} else {
|
||||
try {
|
||||
getPlayerPermissionsMethod = PermissionManager.class.getMethod("getPlayerOwnPermissions", UUID.class);
|
||||
getPlayerPermissionsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException ignored) {}
|
||||
}
|
||||
|
||||
try {
|
||||
getGroupMethod = CachedGroup.class.getMethod("getGroup");
|
||||
getGroupMethod.setAccessible(true);
|
||||
legacy = true;
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
superLegacy = true;
|
||||
} catch (NoSuchMethodException ignored) {}
|
||||
|
||||
if (!legacy) {
|
||||
try {
|
||||
getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerOwnGroups", UUID.class);
|
||||
getPlayerGroupsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerOwnGroups", UUID.class, ResultRunnable.class);
|
||||
getPlayerGroupsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
try {
|
||||
getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerGroups", UUID.class, ResultRunnable.class);
|
||||
getPlayerGroupsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +133,42 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
private static void getPlayerPermissions(PermissionManager manager, UUID uuid, Callback<List<Permission>> callback) {
|
||||
if (legacy) {
|
||||
try {
|
||||
getPlayerPermissionsMethod.invoke(manager, uuid, new LPResultRunnable<List<Permission>>() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onComplete(getResult());
|
||||
}
|
||||
});
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
ListenableFuture<List<Permission>> lf = (ListenableFuture<List<Permission>>) getPlayerPermissionsMethod.invoke(manager, uuid);
|
||||
try {
|
||||
if (lf.isDone()) {
|
||||
callback.onComplete(lf.get());
|
||||
} else {
|
||||
lf.addListener(() -> {
|
||||
try {
|
||||
callback.onComplete(lf.get());
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, Runnable::run);
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CommandResult run(LuckPermsPlugin plugin, List<String> args) {
|
||||
final Logger log = plugin.getLog();
|
||||
if (!plugin.isPluginLoaded("PowerfulPerms")) {
|
||||
@@ -168,7 +240,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
|
||||
// Groups first.
|
||||
log.info("PowerfulPerms Migration: Starting group migration.");
|
||||
Map<Integer, Group> groups = pm.getGroups();
|
||||
Map<Integer, Group> groups = pm.getGroups(); // All versions
|
||||
for (Group g : groups.values()) {
|
||||
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase());
|
||||
final me.lucko.luckperms.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
|
||||
@@ -181,16 +253,16 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
for (Permission p : g.getOwnPermissions()) {
|
||||
for (Permission p : g.getOwnPermissions()) { // All versions
|
||||
applyPerm(group, p, plugin);
|
||||
}
|
||||
|
||||
for (Group parent : g.getParents()) {
|
||||
for (Group parent : g.getParents()) { // All versions
|
||||
try {
|
||||
group.setPermission("group." + parent.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(group).action("setinherit " + parent.getName().toLowerCase())
|
||||
.acted(group).action("setinherit " + parent.getName().toLowerCase()) // All versions
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
@@ -216,156 +288,176 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
User user = plugin.getUserManager().get(uuid);
|
||||
|
||||
// Get a list of Permissions held by the user from the PP API.
|
||||
pm.getPlayerOwnPermissions(uuid, new LPResultRunnable<List<Permission>>() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<Permission> perms = this.getResult();
|
||||
perms.forEach(p -> applyPerm(user, p, plugin));
|
||||
getPlayerPermissions(pm, uuid, perms -> { // Changes each version
|
||||
perms.forEach(p -> applyPerm(user, p, plugin));
|
||||
|
||||
// Update the progress so the user can be saved and unloaded.
|
||||
synchronized (progress) {
|
||||
progress.get(uuid).countDown();
|
||||
if (progress.get(uuid).getCount() == 0) {
|
||||
plugin.getDatastore().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
// Update the progress so the user can be saved and unloaded.
|
||||
synchronized (progress) {
|
||||
progress.get(uuid).countDown();
|
||||
if (progress.get(uuid).getCount() == 0) {
|
||||
plugin.getDatastore().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// Migrate the user's groups to LuckPerms from PP.
|
||||
try {
|
||||
getPlayerGroupsMethod.invoke(pm, uuid, new LPResultRunnable<LinkedHashMap<String, List<CachedGroup>>>() {
|
||||
@Override
|
||||
public void run() {
|
||||
Map<String, List<CachedGroup>> groups = getResult();
|
||||
|
||||
for (Map.Entry<String, List<CachedGroup>> e : groups.entrySet()) {
|
||||
final String server;
|
||||
if (e.getKey() != null && (e.getKey().equals("") || e.getKey().equalsIgnoreCase("all"))) {
|
||||
server = null;
|
||||
} else {
|
||||
server = e.getKey();
|
||||
}
|
||||
|
||||
// This is horrible. So many random API changes through versions, no depreciation.
|
||||
if (legacy) {
|
||||
e.getValue().stream()
|
||||
.filter(cg -> !cg.isNegated())
|
||||
.map(cg -> {
|
||||
try {
|
||||
return (Group) getGroupMethod.invoke(cg);
|
||||
} catch (IllegalAccessException | InvocationTargetException e1) {
|
||||
e1.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.forEach(g -> {
|
||||
if (g != null) {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
e.getValue().stream()
|
||||
.filter(g -> !g.hasExpired() && !g.isNegated())
|
||||
.forEach(g -> {
|
||||
final Group group = pm.getGroup(g.getGroupId());
|
||||
if (g.willExpire()) {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Update the progress so the user can be saved and unloaded.
|
||||
synchronized (progress) {
|
||||
progress.get(uuid).countDown();
|
||||
if (progress.get(uuid).getCount() == 0) {
|
||||
plugin.getDatastore().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
}
|
||||
Callback<Map<String, List<CachedGroup>>> callback = groups1 -> {
|
||||
for (Map.Entry<String, List<CachedGroup>> e : groups1.entrySet()) {
|
||||
final String server;
|
||||
if (e.getKey() != null && (e.getKey().equals("") || e.getKey().equalsIgnoreCase("all"))) {
|
||||
server = null;
|
||||
} else {
|
||||
server = e.getKey();
|
||||
}
|
||||
});
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
log.info("PowerfulPerms Migration: Error");
|
||||
e.printStackTrace();
|
||||
|
||||
if (superLegacy) {
|
||||
e.getValue().stream()
|
||||
.filter(cg -> !cg.isNegated())
|
||||
.map(cg -> {
|
||||
try {
|
||||
return (Group) getGroupMethod.invoke(cg);
|
||||
} catch (IllegalAccessException | InvocationTargetException e1) {
|
||||
e1.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.forEach(g -> {
|
||||
if (g != null) {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
e.getValue().stream()
|
||||
.filter(g -> !g.hasExpired() && !g.isNegated())
|
||||
.forEach(g -> {
|
||||
final Group group = pm.getGroup(g.getGroupId());
|
||||
if (g.willExpire()) {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Update the progress so the user can be saved and unloaded.
|
||||
synchronized (progress) {
|
||||
progress.get(uuid).countDown();
|
||||
if (progress.get(uuid).getCount() == 0) {
|
||||
plugin.getDatastore().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!legacy) {
|
||||
try {
|
||||
ListenableFuture<LinkedHashMap<String, List<CachedGroup>>> future = (ListenableFuture<LinkedHashMap<String, List<CachedGroup>>>) getPlayerGroupsMethod.invoke(pm, uuid);
|
||||
try {
|
||||
if (future.isDone()) {
|
||||
callback.onComplete(future.get());
|
||||
} else {
|
||||
future.addListener(() -> {
|
||||
try {
|
||||
callback.onComplete(future.get());
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, Runnable::run);
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
log.info("PowerfulPerms Migration: Error");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
getPlayerGroupsMethod.invoke(pm, uuid, new LPResultRunnable<LinkedHashMap<String, List<CachedGroup>>>() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onComplete(getResult());
|
||||
}
|
||||
});
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
log.info("PowerfulPerms Migration: Error");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,7 +509,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
long expireAt = 0L;
|
||||
if (!legacy) {
|
||||
if (!superLegacy) {
|
||||
if (p.willExpire()) {
|
||||
expireAt = p.getExpirationDate().getTime() / 1000L;
|
||||
}
|
||||
@@ -508,22 +600,4 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default ResultRunnable, callbacks will always run in the same thread. (an async one, hopefully.)
|
||||
* @param <T> type
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public abstract class LPResultRunnable<T> extends ResultRunnable<T> {
|
||||
|
||||
public LPResultRunnable() {
|
||||
super();
|
||||
super.sameThread = true;
|
||||
}
|
||||
|
||||
public T getResult() {
|
||||
return super.result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+41
@@ -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.commands.migration.subcommands.utils;
|
||||
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.ResultRunnable;
|
||||
|
||||
/**
|
||||
* Overrides the default ResultRunnable, callbacks will always run in the same thread. (an async one, hopefully.)
|
||||
* @param <T> type
|
||||
*/
|
||||
public abstract class LPResultRunnable<T> extends ResultRunnable<T> {
|
||||
public LPResultRunnable() {
|
||||
super();
|
||||
super.sameThread = true;
|
||||
}
|
||||
|
||||
public T getResult() {
|
||||
return super.result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,6 +38,7 @@ public class DebugCommand extends SingleMainCommand {
|
||||
|
||||
@Override
|
||||
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
|
||||
plugin.getLog().info(sender.getName() + " used the debug command.");
|
||||
Message.DEBUG.send(sender,
|
||||
plugin.getPlayerCount(),
|
||||
plugin.getUserManager().getAll().size(),
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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.commands.misc;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SingleMainCommand;
|
||||
import me.lucko.luckperms.constants.Constants;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.storage.Datastore;
|
||||
import me.lucko.luckperms.tracks.Track;
|
||||
import me.lucko.luckperms.users.User;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ExportCommand extends SingleMainCommand {
|
||||
public ExportCommand() {
|
||||
super("Export", "/%s export <file>", 1, Permission.MIGRATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
|
||||
final Logger log = plugin.getLog();
|
||||
|
||||
if (!sender.getUuid().equals(Constants.getConsoleUUID())) {
|
||||
Message.MIGRATION_NOT_CONSOLE.send(sender);
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
File f = new File(plugin.getMainDir(), args.get(0));
|
||||
if (f.exists()) {
|
||||
Message.LOG_EXPORT_ALREADY_EXISTS.send(sender, f.getAbsolutePath());
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
try {
|
||||
f.createNewFile();
|
||||
} catch (IOException e) {
|
||||
Message.LOG_EXPORT_FAILURE.send(sender);
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
if (!Files.isWritable(f.toPath())) {
|
||||
Message.LOG_EXPORT_NOT_WRITABLE.send(sender, f.getAbsolutePath());
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
try (FileWriter fWriter = new FileWriter(f, true); BufferedWriter writer = new BufferedWriter(fWriter)) {
|
||||
log.info("Export: Starting export process.");
|
||||
|
||||
// Export Groups
|
||||
log.info("Export: Exporting all groups.");
|
||||
|
||||
// Create the groups first
|
||||
for (Group group : plugin.getGroupManager().getAll().values()) {
|
||||
write(writer, "/luckperms creategroup " + group.getName());
|
||||
}
|
||||
|
||||
int groupCount = 0;
|
||||
for (Group group : plugin.getGroupManager().getAll().values()) {
|
||||
groupCount++;
|
||||
for (Node node : group.getNodes()) {
|
||||
write(writer, nodeToString(node, group.getName(), true));
|
||||
}
|
||||
}
|
||||
log.info("Export: Exported " + groupCount + " groups.");
|
||||
|
||||
// Export tracks
|
||||
log.info("Export: Exporting all tracks.");
|
||||
|
||||
// Create the tracks first
|
||||
for (Track track : plugin.getTrackManager().getAll().values()) {
|
||||
write(writer, "/luckperms createtrack " + track.getName());
|
||||
}
|
||||
|
||||
int trackCount = 0;
|
||||
for (Track track : plugin.getTrackManager().getAll().values()) {
|
||||
trackCount++;
|
||||
for (String group : track.getGroups()) {
|
||||
write(writer, "/luckperms track " + track.getName() + " append " + group);
|
||||
}
|
||||
}
|
||||
log.info("Export: Exported " + trackCount + " tracks.");
|
||||
|
||||
// Export users
|
||||
log.info("Export: Exporting all users. Finding a list of unique users to export.");
|
||||
Datastore ds = plugin.getDatastore();
|
||||
Set<UUID> users = ds.getUniqueUsers();
|
||||
log.info("Export: Found " + users.size() + " unique users to export.");
|
||||
|
||||
int userCount = 0;
|
||||
for (UUID uuid : users) {
|
||||
userCount++;
|
||||
plugin.getDatastore().loadUser(uuid, "null");
|
||||
User user = plugin.getUserManager().get(uuid);
|
||||
|
||||
for (Node node : user.getNodes()) {
|
||||
if (node.isGroupNode() && node.getGroupName().equalsIgnoreCase("default")) {
|
||||
continue;
|
||||
}
|
||||
write(writer, nodeToString(node, user.getUuid().toString(), false));
|
||||
}
|
||||
|
||||
write(writer, "/luckperms user " + user.getUuid().toString() + " setprimarygroup " + user.getPrimaryGroup());
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
log.info("Export: Exported " + userCount + " users.");
|
||||
|
||||
try {
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Message.LOG_EXPORT_SUCCESS.send(sender, f.getAbsolutePath());
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAuthorized(Sender sender) {
|
||||
return sender.getUuid().equals(Constants.getConsoleUUID());
|
||||
}
|
||||
|
||||
private static void write(BufferedWriter writer, String s) {
|
||||
try {
|
||||
writer.write(s);
|
||||
writer.newLine();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static String nodeToString(Node node, String id, boolean group) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("/luckperms ").append(group ? "group " : "user ").append(id).append(" ");
|
||||
|
||||
if (node.isGroupNode()) {
|
||||
if (node.isTemporary()) {
|
||||
sb.append(group ? "settempinherit " : "addtempgroup ");
|
||||
sb.append(node.getGroupName());
|
||||
sb.append(" ").append(node.getExpiryUnixTime());
|
||||
} else {
|
||||
sb.append(group ? "setinherit " : "addgroup ");
|
||||
sb.append(node.getGroupName());
|
||||
}
|
||||
|
||||
if (node.isWorldSpecific()) {
|
||||
sb.append(" ").append(node.getServer().get()).append(" ").append(node.getWorld().get());
|
||||
} else if (node.isServerSpecific()) {
|
||||
sb.append(" ").append(node.getServer().get());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
sb.append(node.isTemporary() ? "settemp " : "set ");
|
||||
sb.append(node.getPermission()).append(" ").append(node.getValue());
|
||||
|
||||
if (node.isTemporary()) {
|
||||
sb.append(" ").append(node.getExpiryUnixTime());
|
||||
}
|
||||
|
||||
if (node.isWorldSpecific()) {
|
||||
sb.append(" ").append(node.getServer().get()).append(" ").append(node.getWorld().get());
|
||||
} else if (node.isServerSpecific()) {
|
||||
sb.append(" ").append(node.getServer().get());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -44,10 +44,14 @@ public class InfoCommand extends SingleMainCommand {
|
||||
final LPConfiguration c = plugin.getConfiguration();
|
||||
Message.INFO.send(sender,
|
||||
plugin.getVersion(),
|
||||
plugin.getType().getFriendlyName(),
|
||||
plugin.getDatastore().getName(),
|
||||
c.getServer(),
|
||||
c.getSyncTime(),
|
||||
formatBoolean(c.getIncludeGlobalPerms()),
|
||||
formatBoolean(c.getIncludeGlobalWorldPerms()),
|
||||
formatBoolean(c.getApplyGlobalGroups()),
|
||||
formatBoolean(c.getApplyGlobalWorldGroups()),
|
||||
formatBoolean(c.getOnlineMode()),
|
||||
formatBoolean(c.getApplyWildcards()),
|
||||
formatBoolean(c.getApplyRegex()),
|
||||
|
||||
@@ -57,6 +57,15 @@ public class UserMainCommand extends MainCommand<User> {
|
||||
.add(new UserPromote())
|
||||
.add(new UserDemote())
|
||||
.add(new UserShowPos())
|
||||
.add(new UserChatMeta())
|
||||
.add(new UserAddPrefix())
|
||||
.add(new UserAddSuffix())
|
||||
.add(new UserRemovePrefix())
|
||||
.add(new UserRemoveSuffix())
|
||||
.add(new UserAddTempPrefix())
|
||||
.add(new UserAddTempSuffix())
|
||||
.add(new UserRemoveTempPrefix())
|
||||
.add(new UserRemoveTempSuffix())
|
||||
.add(new UserClear())
|
||||
.build()
|
||||
);
|
||||
@@ -84,7 +93,10 @@ public class UserMainCommand extends MainCommand<User> {
|
||||
}
|
||||
}
|
||||
|
||||
if (!plugin.getDatastore().loadUser(u, "null")) {
|
||||
String name = plugin.getDatastore().getName(u);
|
||||
if (name == null) name = "null";
|
||||
|
||||
if (!plugin.getDatastore().loadUser(u, name)) {
|
||||
Message.LOADING_ERROR.send(sender);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserAddPrefix extends SubCommand<User> {
|
||||
public UserAddPrefix() {
|
||||
super("addprefix", "Adds a prefix to the user", "/%s user <user> addprefix <priority> <prefix> [server] [world]",
|
||||
Permission.USER_ADDPREFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
user.setPermission(node, true, server);
|
||||
Message.ADDPREFIX_SERVER_SUCCESS.send(sender, user.getName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
user.setPermission(node, true, server, world);
|
||||
Message.ADDPREFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.setPermission(node, true);
|
||||
Message.ADDPREFIX_SUCCESS.send(sender, user.getName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserAddSuffix extends SubCommand<User> {
|
||||
public UserAddSuffix() {
|
||||
super("addsuffix", "Adds a suffix to the user", "/%s user <user> addsuffix <priority> <suffix> [server] [world]",
|
||||
Permission.USER_ADDSUFFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
user.setPermission(node, true, server);
|
||||
Message.ADDSUFFIX_SERVER_SUCCESS.send(sender, user.getName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addsuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
user.setPermission(node, true, server, world);
|
||||
Message.ADDSUFFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addsuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.setPermission(node, true);
|
||||
Message.ADDSUFFIX_SUCCESS.send(sender, user.getName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addsuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.utils.DateUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserAddTempPrefix extends SubCommand<User> {
|
||||
public UserAddTempPrefix() {
|
||||
super("addtempprefix", "Adds a prefix to the user temporarily", "/%s user <user> addtempprefix <priority> <prefix> <duration> [server] [world]",
|
||||
Permission.USER_ADD_TEMP_PREFIX, Predicate.notInRange(3, 5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
long duration;
|
||||
try {
|
||||
duration = Long.parseLong(args.get(2));
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
duration = DateUtil.parseDateDiff(args.get(2), true);
|
||||
} catch (DateUtil.IllegalDateException e1) {
|
||||
Message.ILLEGAL_DATE_ERROR.send(sender, args.get(2));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
if (DateUtil.shouldExpire(duration)) {
|
||||
Message.PAST_DATE_ERROR.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 4) {
|
||||
final String server = args.get(3).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 4) {
|
||||
user.setPermission(node, true, server, duration);
|
||||
Message.ADD_TEMP_PREFIX_SERVER_SUCCESS.send(sender, user.getName(), prefix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(4).toLowerCase();
|
||||
user.setPermission(node, true, server, world, duration);
|
||||
Message.ADD_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), prefix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_PREFIX_SUCCESS.send(sender, user.getName(), prefix, priority, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.utils.DateUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserAddTempSuffix extends SubCommand<User> {
|
||||
public UserAddTempSuffix() {
|
||||
super("addtempsuffix", "Adds a suffix to the user temporarily", "/%s user <user> addtempsuffix <priority> <suffix> <duration> [server] [world]",
|
||||
Permission.USER_ADD_TEMP_SUFFIX, Predicate.notInRange(3, 5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
long duration;
|
||||
try {
|
||||
duration = Long.parseLong(args.get(2));
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
duration = DateUtil.parseDateDiff(args.get(2), true);
|
||||
} catch (DateUtil.IllegalDateException e1) {
|
||||
Message.ILLEGAL_DATE_ERROR.send(sender, args.get(2));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
if (DateUtil.shouldExpire(duration)) {
|
||||
Message.PAST_DATE_ERROR.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 4) {
|
||||
final String server = args.get(3).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 4) {
|
||||
user.setPermission(node, true, server, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, user.getName(), suffix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(4).toLowerCase();
|
||||
user.setPermission(node, true, server, world, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), suffix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SUCCESS.send(sender, user.getName(), suffix, priority, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.Contexts;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class UserChatMeta extends SubCommand<User> {
|
||||
public UserChatMeta() {
|
||||
super("chatmeta", "Displays a users chat meta", "/%s user <user> chatmeta", Permission.USER_CHATMETA,
|
||||
Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
SortedSet<Map.Entry<Integer, String>> prefixes = new TreeSet<>(Util.getMetaComparator().reversed());
|
||||
SortedSet<Map.Entry<Integer, String>> suffixes = new TreeSet<>(Util.getMetaComparator().reversed());
|
||||
|
||||
for (Node node : user.getAllNodes(null, Contexts.allowAll())) {
|
||||
if (!node.isSuffix() && !node.isPrefix()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (node.isServerSpecific()) {
|
||||
if (node.isWorldSpecific()) {
|
||||
sb.append("&6W=").append(node.getWorld().get()).append(" ");
|
||||
}
|
||||
sb.append("&6S=").append(node.getServer().get()).append(" ");
|
||||
}
|
||||
|
||||
if (node.isPrefix()) {
|
||||
sb.append(node.getPrefix().getValue());
|
||||
prefixes.add(new SimpleEntry<>(node.getPrefix().getKey(), sb.toString()));
|
||||
}
|
||||
|
||||
if (node.isSuffix()) {
|
||||
sb.append(node.getSuffix().getValue());
|
||||
suffixes.add(new SimpleEntry<>(node.getSuffix().getKey(), sb.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
if (prefixes.isEmpty()) {
|
||||
Message.CHAT_META_PREFIX_NONE.send(sender, user.getName());
|
||||
} else {
|
||||
Message.CHAT_META_PREFIX_HEADER.send(sender, user.getName());
|
||||
for (Map.Entry<Integer, String> e : prefixes) {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (suffixes.isEmpty()) {
|
||||
Message.CHAT_META_SUFFIX_NONE.send(sender, user.getName());
|
||||
} else {
|
||||
Message.CHAT_META_SUFFIX_HEADER.send(sender, user.getName());
|
||||
for (Map.Entry<Integer, String> e : suffixes) {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -30,8 +30,6 @@ import me.lucko.luckperms.users.User;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static me.lucko.luckperms.core.PermissionHolder.exportToLegacy;
|
||||
|
||||
public class UserListNodes extends SubCommand<User> {
|
||||
public UserListNodes() {
|
||||
super("listnodes", "Lists the permission nodes the user has", "/%s user <user> listnodes",
|
||||
@@ -40,8 +38,8 @@ public class UserListNodes extends SubCommand<User> {
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
Message.LISTNODES.send(sender, user.getName(), Util.permNodesToString(exportToLegacy(user.getPermanentNodes())));
|
||||
Message.LISTNODES_TEMP.send(sender, user.getName(), Util.tempNodesToString(user.getTemporaryNodesLegacy()));
|
||||
Message.LISTNODES.send(sender, user.getName(), Util.permNodesToString(user.getPermissions(false)));
|
||||
Message.LISTNODES_TEMP.send(sender, user.getName(), Util.tempNodesToString(user.getPermissions(false)));
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserRemovePrefix extends SubCommand<User> {
|
||||
public UserRemovePrefix() {
|
||||
super("removeprefix", "Removes a prefix from a user", "/%s user <user> removeprefix <priority> <prefix> [server] [world]",
|
||||
Permission.USER_REMOVEPREFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
user.unsetPermission(node, server);
|
||||
Message.REMOVEPREFIX_SERVER_SUCCESS.send(sender, user.getName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removeprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
user.unsetPermission(node, server, world);
|
||||
Message.REMOVEPREFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removeprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.unsetPermission(node);
|
||||
Message.REMOVEPREFIX_SUCCESS.send(sender, user.getName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removeprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserRemoveSuffix extends SubCommand<User> {
|
||||
public UserRemoveSuffix() {
|
||||
super("removesuffix", "Removes a suffix from a user", "/%s user <user> removesuffix <priority> <suffix> [server] [world]",
|
||||
Permission.USER_REMOVESUFFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
user.unsetPermission(node, server);
|
||||
Message.REMOVESUFFIX_SERVER_SUCCESS.send(sender, user.getName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removesuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
user.unsetPermission(node, server, world);
|
||||
Message.REMOVESUFFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removesuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.unsetPermission(node);
|
||||
Message.REMOVESUFFIX_SUCCESS.send(sender, user.getName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removesuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserRemoveTempPrefix extends SubCommand<User> {
|
||||
public UserRemoveTempPrefix() {
|
||||
super("removetempprefix", "Removes a temporary prefix from a user", "/%s user <user> removetempprefix <priority> <prefix> [server] [world]",
|
||||
Permission.USER_REMOVE_TEMP_PREFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
user.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_SUCCESS.send(sender, user.getName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removetempprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
user.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removetempprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.unsetPermission(node, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SUCCESS.send(sender, user.getName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removetempprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserRemoveTempSuffix extends SubCommand<User> {
|
||||
public UserRemoveTempSuffix() {
|
||||
super("removetempsuffix", "Removes a temporary suffix from a user", "/%s user <user> removetempsuffix <priority> <suffix> [server] [world]",
|
||||
Permission.USER_REMOVE_TEMP_SUFFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
user.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, user.getName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
user.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.unsetPermission(node, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SUCCESS.send(sender, user.getName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
@@ -54,7 +53,7 @@ public class UserSetPermission extends SubCommand<User> {
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.USER_USE_ADDGROUP.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
+5
-2
@@ -30,6 +30,7 @@ import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.users.User;
|
||||
|
||||
@@ -55,8 +56,10 @@ public class UserSetPrimaryGroup extends SubCommand<User> {
|
||||
}
|
||||
|
||||
if (!user.isInGroup(group)) {
|
||||
Message.USER_PRIMARYGROUP_ERROR_NOTMEMBER.send(sender, label);
|
||||
return CommandResult.STATE_ERROR;
|
||||
Message.USER_PRIMARYGROUP_ERROR_NOTMEMBER.send(sender, user.getName(), group.getName());
|
||||
try {
|
||||
user.addGroup(group);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
}
|
||||
|
||||
user.setPrimaryGroup(group.getName());
|
||||
|
||||
+1
-2
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
@@ -55,7 +54,7 @@ public class UserSetTempPermission extends SubCommand<User> {
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.USER_USE_ADDGROUP.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
+1
-2
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
@@ -52,7 +51,7 @@ public class UserUnSetPermission extends SubCommand<User> {
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.USER_USE_REMOVEGROUP.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
+1
-2
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
@@ -53,7 +52,7 @@ public class UserUnsetTempPermission extends SubCommand<User> {
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.USER_USE_REMOVEGROUP.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ public enum Message {
|
||||
PLAYER_ONLINE("&aOnline", false),
|
||||
PLAYER_OFFLINE("&cOffline", false),
|
||||
LOADING_ERROR("Permissions data could not be loaded. Please contact an administrator.", true),
|
||||
OP_DISABLED("&eThe vanilla OP system is disabled on this server.", false),
|
||||
LOG("&3LOG &3&l> %s", true),
|
||||
|
||||
COMMAND_NOT_RECOGNISED("Command not recognised.", true),
|
||||
@@ -122,10 +123,14 @@ public enum Message {
|
||||
UPDATE_TASK_RUN("&bRunning update task for all online users.", true),
|
||||
INFO(
|
||||
PREFIX + "&6Running &bLuckPerms v%s&6 by &bLuck&6." + "\n" +
|
||||
PREFIX + "&f-> &ePlatform: &6%s" + "\n" +
|
||||
PREFIX + "&f-> &eStorage Method: &6%s" + "\n" +
|
||||
PREFIX + "&f-> &eServer Name: &6%s" + "\n" +
|
||||
PREFIX + "&f-> &eSync Interval: &6%s minutes" + "\n" +
|
||||
PREFIX + "&f-> &eInclude Global Perms: &6%s" + "\n" +
|
||||
PREFIX + "&f-> &eInclude Global: &6%s" + "\n" +
|
||||
PREFIX + "&f-> &eInclude Global World: &6%s" + "\n" +
|
||||
PREFIX + "&f-> &eApply Global Groups: &6%s" + "\n" +
|
||||
PREFIX + "&f-> &eApply Global World Groups: &6%s" + "\n" +
|
||||
PREFIX + "&f-> &eOnline Mode: &6%s" + "\n" +
|
||||
PREFIX + "&f-> &eApply Wildcards: &6%s" + "\n" +
|
||||
PREFIX + "&f-> &eApply Regex: &6%s" + "\n" +
|
||||
@@ -168,6 +173,46 @@ public enum Message {
|
||||
ILLEGAL_DATE_ERROR("Could not parse date '%s'.", true),
|
||||
PAST_DATE_ERROR("You cannot set a date in the past!", true),
|
||||
|
||||
CHAT_META_PREFIX_HEADER("&e%s's Prefixes", true),
|
||||
CHAT_META_SUFFIX_HEADER("&e%s's Suffixes", true),
|
||||
CHAT_META_ENTRY("&d-> &e%s &6- &f\"%s&f\"", true),
|
||||
CHAT_META_PREFIX_NONE("&e%s has no prefixes.", true),
|
||||
CHAT_META_SUFFIX_NONE("&e%s has no suffixes.", true),
|
||||
|
||||
META_INVALID_PRIORITY("Invalid priority '%s'. Expected a number.", true),
|
||||
ALREADY_HAS_PREFIX("%s already has that prefix set.", true),
|
||||
ALREADY_HAS_SUFFIX("%s already has that suffix set.", true),
|
||||
DOES_NOT_HAVE_PREFIX("%s doesn't have that prefix set.", true),
|
||||
DOES_NOT_HAVE_SUFFIX("%s doesn't have that suffix set.", true),
|
||||
|
||||
ADDPREFIX_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a.", true),
|
||||
ADDPREFIX_SERVER_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a.", true),
|
||||
ADDPREFIX_SERVER_WORLD_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, world &b%s&a.", true),
|
||||
REMOVEPREFIX_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a at priority &b%s&a removed.", true),
|
||||
REMOVEPREFIX_SERVER_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a.", true),
|
||||
REMOVEPREFIX_SERVER_WORLD_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a, world &b%s&a.", true),
|
||||
|
||||
ADDSUFFIX_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a.", true),
|
||||
ADDSUFFIX_SERVER_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a.", true),
|
||||
ADDSUFFIX_SERVER_WORLD_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, world &b%s&a.", true),
|
||||
REMOVESUFFIX_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a at priority &b%s&a removed.", true),
|
||||
REMOVESUFFIX_SERVER_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a.", true),
|
||||
REMOVESUFFIX_SERVER_WORLD_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a, world &b%s&a.", true),
|
||||
|
||||
ADD_TEMP_PREFIX_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a for a duration of &b%s&a.", true),
|
||||
ADD_TEMP_PREFIX_SERVER_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, for a duration of &b%s&a.", true),
|
||||
ADD_TEMP_PREFIX_SERVER_WORLD_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, world &b%s&a, for a duration of &b%s&a.", true),
|
||||
REMOVE_TEMP_PREFIX_SUCCESS("&b%s&a had temporary prefix &f\"%s&f\"&a at priority &b%s&a removed.", true),
|
||||
REMOVE_TEMP_PREFIX_SERVER_SUCCESS("&b%s&a had temporary prefix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a.", true),
|
||||
REMOVE_TEMP_PREFIX_SERVER_WORLD_SUCCESS("&b%s&a had temporary prefix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a, world &b%s&a.", true),
|
||||
|
||||
ADD_TEMP_SUFFIX_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a for a duration of &b%s&a.", true),
|
||||
ADD_TEMP_SUFFIX_SERVER_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, for a duration of &b%s&a.", true),
|
||||
ADD_TEMP_SUFFIX_SERVER_WORLD_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, world &b%s&a, for a duration of &b%s&a.", true),
|
||||
REMOVE_TEMP_SUFFIX_SUCCESS("&b%s&a had temporary suffix &f\"%s&f\"&a at priority &b%s&a removed.", true),
|
||||
REMOVE_TEMP_SUFFIX_SERVER_SUCCESS("&b%s&a had temporary suffix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a.", true),
|
||||
REMOVE_TEMP_SUFFIX_SERVER_WORLD_SUCCESS("&b%s&a had temporary suffix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a, world &b%s&a.", true),
|
||||
|
||||
USER_INFO(
|
||||
PREFIX + "&d-> &eUser: &6%s" + "\n" +
|
||||
PREFIX + "&d-> &eUUID: &6%s" + "\n" +
|
||||
@@ -195,7 +240,7 @@ public enum Message {
|
||||
USER_REMOVEGROUP_ERROR_PRIMARY("You cannot remove a user from their primary group.", true),
|
||||
USER_PRIMARYGROUP_SUCCESS("&b%s&a's primary group was set to &b%s&a.", true),
|
||||
USER_PRIMARYGROUP_ERROR_ALREADYHAS("The user already has this group set as their primary group.", true),
|
||||
USER_PRIMARYGROUP_ERROR_NOTMEMBER("The user must be a member of the group first! Use &4/%s user <user> addgroup <group>", true),
|
||||
USER_PRIMARYGROUP_ERROR_NOTMEMBER("&b%s&a was not already a member of &b%s&a, adding them now.", true),
|
||||
USER_SHOWTRACKS_INFO("&aShowing tracks that contain the group '&b%s&a' (%s's primary group)", true),
|
||||
USER_PROMOTE_SUCCESS_PROMOTE("&aPromoting user along track &b%s&a from &b%s&a to &b%s&a.", true),
|
||||
USER_PROMOTE_SUCCESS_REMOVE("&b%s&a was removed from &b%s&a, added to &b%s&a, and their primary group was set to &b%s&a.", true),
|
||||
@@ -291,6 +336,7 @@ public enum Message {
|
||||
IMPORT_END_ERROR_HEADER(
|
||||
PREFIX + "&e(Import) &7------------> &6Showing Error #&e%s &7<------------" + "\n" +
|
||||
PREFIX + "&e(Import) &6Whilst executing: &fCommand #%s" + "\n" +
|
||||
PREFIX + "&e(Import) &6Command: &7%s" + "\n" +
|
||||
PREFIX + "&e(Import) &6Type: &f%s" + "\n" +
|
||||
PREFIX + "&e(Import) &6Output:",
|
||||
false
|
||||
|
||||
Loaded 100 of 151 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user