Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1606ac51b | ||
|
|
d13eb1a55d | ||
|
|
384fbf5464 | ||
|
|
4874f9d051 | ||
|
|
51732fa660 | ||
|
|
bb25632178 | ||
|
|
9a2cf82623 | ||
|
|
c0734fc29e | ||
|
|
c60067e733 | ||
|
|
6293634e36 | ||
|
|
a047695a84 | ||
|
|
db9d84ed76 | ||
|
|
e296b1df60 | ||
|
|
b72e5f5437 | ||
|
|
de09ae94b8 | ||
|
|
b36a33f015 | ||
|
|
d95891256b | ||
|
|
9c8097ecb9 | ||
|
|
18a3dfd604 | ||
|
|
59fd337e44 | ||
|
|
696cd235fd | ||
|
|
59c7efccb2 | ||
|
|
b031ebbffd | ||
|
|
67415babc2 | ||
|
|
563dd4683d | ||
|
|
e9131f729a | ||
|
|
c4ea626e33 | ||
|
|
fefba7976b | ||
|
|
2ce8555692 | ||
|
|
9fe9c386bb | ||
|
|
e8cd2c7548 | ||
|
|
158d8b086a | ||
|
|
1c534d7475 | ||
|
|
90f8dbe243 | ||
|
|
0c33b26fa9 | ||
|
|
d320679f69 | ||
|
|
8d5398b5a3 | ||
|
|
6cd8593fa5 | ||
|
|
5ebbc178a5 | ||
|
|
4f6e229943 | ||
|
|
3e846d9527 | ||
|
|
981d745b74 | ||
|
|
2dd0858960 | ||
|
|
f72819a664 | ||
|
|
5361b1e87b | ||
|
|
e15d03ed4e | ||
|
|
6c9041ce40 | ||
|
|
8da96e6e48 | ||
|
|
385aa6d438 | ||
|
|
79f24a5944 | ||
|
|
80570717f9 | ||
|
|
ebab79c4ca | ||
|
|
42882ebe11 | ||
|
|
d2de26f765 | ||
|
|
e2cebfbd16 | ||
|
|
a58cc6bdf3 | ||
|
|
36bc1553c0 | ||
|
|
17b06c39e9 | ||
|
|
ba2f6eb7be | ||
|
|
b93145f26d | ||
|
|
e88ea9c13d | ||
|
|
1275d0023d | ||
|
|
27f6f225c9 | ||
|
|
41362aa34a | ||
|
|
a99609e016 | ||
|
|
c0ea2d8ec3 | ||
|
|
bb6b31d715 | ||
|
|
21695dd2cb | ||
|
|
531835c948 | ||
|
|
77e3b351fd | ||
|
|
66f756575a | ||
|
|
7acc8bc7ed | ||
|
|
0a4d337a53 | ||
|
|
0198068a13 | ||
|
|
1c15f8462f | ||
|
|
3929ce0dfc | ||
|
|
7deeaf305d | ||
|
|
0f04c06e13 | ||
|
|
d1863fa714 | ||
|
|
46b122a167 | ||
|
|
ee3db1e5c5 | ||
|
|
bd830617c9 | ||
|
|
a9b6493091 | ||
|
|
9894e45516 | ||
|
|
2cfc82f3aa | ||
|
|
bb9eab0989 | ||
|
|
dc87ec1c82 | ||
|
|
98b7b65ce7 | ||
|
|
9f8f32b33e | ||
|
|
a80ec6d893 | ||
|
|
4d85930f5a | ||
|
|
f722f4112d |
No files matched your search
+151
-24
@@ -1,31 +1,27 @@
|
||||
# built application files
|
||||
*.jar
|
||||
# Created by https://www.gitignore.io/
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
logs/
|
||||
|
||||
# Eclipse project files
|
||||
.classpath
|
||||
.project
|
||||
|
||||
# Intellij project files
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
# User-specific stuff:
|
||||
.idea/
|
||||
*.iws
|
||||
/out/
|
||||
*.iml
|
||||
.idea_modules/
|
||||
|
||||
# Gradle
|
||||
.gradletasknamecache
|
||||
.gradle/
|
||||
build/
|
||||
bin/
|
||||
gradle/
|
||||
gradlew*
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Maven
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
@@ -34,4 +30,135 @@ pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
.mvn/timing.properties
|
||||
|
||||
|
||||
### Eclipse ###
|
||||
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
.recommenders
|
||||
|
||||
# Eclipse Core
|
||||
.project
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# PyDev specific (Python IDE for Eclipse)
|
||||
*.pydevproject
|
||||
|
||||
# CDT-specific (C/C++ Development Tooling)
|
||||
.cproject
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific (PHP Development Tools)
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# Tern plugin
|
||||
.tern-project
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
# STS (Spring Tool Suite)
|
||||
.springBeans
|
||||
|
||||
# Code Recommenders
|
||||
.recommenders/
|
||||
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
|
||||
### macOS ###
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
# Thumbnails
|
||||
._*
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
|
||||
### Windows ###
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
### Java ###
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
@@ -8,10 +8,14 @@ An advanced permissions implementation for Bukkit/Spigot, BungeeCord and Sponge.
|
||||
* **Wiki** - <https://github.com/lucko/LuckPerms/wiki>
|
||||
|
||||
## 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.
|
||||
LuckPerms is an advanced permissions implementation aiming to be a fast, reliable and flexible alternative to existing permission plugins. The project's main goals are centered around high performance and a wide feature set, filling the gaps of functionality and building upon existing features found in other plugins.
|
||||
|
||||
* [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 also includes an extensive API for developers, and support for a variety of Minecraft server software & data storage options.
|
||||
|
||||
See the charts below for a partial list of features & comparison with other providers.
|
||||
|
||||
* [Spigot Plugin Release Page](https://www.spigotmc.org/resources/luckperms-an-advanced-permissions-system.28140/ "Spigot Plugin Page")
|
||||
* [Sponge Plugin Release Page](https://forums.spongepowered.org/t/luckperms-an-advanced-permissions-system/14274 "Sponge Plugin Page")
|
||||
|
||||
## LuckPerms vs Other Plugins
|
||||
### Bukkit
|
||||
@@ -20,10 +24,11 @@ _Features checked on 23rd Aug 2016. If you find any inaccuracies, please do let
|
||||
### Sponge
|
||||

|
||||
_Features checked on 8th Oct 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
|
||||
LuckPerms is licensed under the permissive MIT license. See LICENSE.md for more info.
|
||||
|
||||
## Thanks to:
|
||||
## Sponsor
|
||||
[](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.13-SNAPSHOT</version>
|
||||
<version>2.15-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import java.util.Map;
|
||||
* @since 2.11
|
||||
*/
|
||||
public class Contexts {
|
||||
private static final Contexts ALLOW_ALL = new Contexts(ContextSet.empty(), true, true, true, true, true, true);
|
||||
public static final String SERVER_KEY = "server";
|
||||
public static final String WORLD_KEY = "world";
|
||||
|
||||
@@ -40,7 +41,7 @@ public class Contexts {
|
||||
* @return a context that will not apply any filters
|
||||
*/
|
||||
public static Contexts allowAll() {
|
||||
return new Contexts(ContextSet.empty(), true, true, true, true, true, true);
|
||||
return ALLOW_ALL;
|
||||
}
|
||||
|
||||
public static Contexts of(ContextSet context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
|
||||
|
||||
@@ -29,226 +29,50 @@ import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Interface for the internal Datastore instance
|
||||
* @deprecated as of version 2.14 in favour of {@link Storage}.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Deprecated
|
||||
public interface Datastore {
|
||||
|
||||
String getName();
|
||||
boolean isAcceptingLogins();
|
||||
|
||||
/**
|
||||
* Gets the {@link Sync} interface.
|
||||
*
|
||||
* All operations through this interface are called immediately and in the same thread as they are called.
|
||||
* Datastore operations are thread blocking, and Sync operations should not be called on the main server thread.
|
||||
* @return the sync interface
|
||||
*/
|
||||
@Deprecated
|
||||
Sync sync();
|
||||
|
||||
/**
|
||||
* Gets the {@link Async} interface.
|
||||
*
|
||||
* All operations through this interface are called in a new, separate asynchronous thread.
|
||||
* When the operation is complete, the provided callback method is called, in applicable, in the main server thread.
|
||||
* @return the async interface
|
||||
*/
|
||||
@Deprecated
|
||||
Async async();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* See the Oracle JavaDocs for usage of the Future class.
|
||||
* @return the future interface
|
||||
*/
|
||||
@Deprecated
|
||||
Future future();
|
||||
|
||||
/**
|
||||
* All operations through this interface are called immediately and in the same thread as they are called.
|
||||
* Datastore operations are thread blocking, and Sync operations should not be called on the main server thread.
|
||||
*/
|
||||
@Deprecated
|
||||
interface Sync {
|
||||
|
||||
/**
|
||||
* Saves an action to the datastore
|
||||
* @param entry the log entry to be saved
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if entry is null
|
||||
*/
|
||||
boolean logAction(LogEntry entry);
|
||||
|
||||
/**
|
||||
* Loads and returns the log from the datastore
|
||||
* @return a log instance, could be null
|
||||
*/
|
||||
Log getLog();
|
||||
|
||||
/**
|
||||
* Either loads or creates a user object, and loads it into the plugins internal storage
|
||||
* @param uuid the uuid of the user
|
||||
* @param username the users username. (if you want to specify <code>null</code> here, just input "null" as a string.)
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if uuid or username is null
|
||||
* @throws IllegalArgumentException if either of the parameters are invalid
|
||||
* @deprecated functionality of this method is taken on by {@link #loadUser(UUID, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean loadOrCreateUser(UUID uuid, String username);
|
||||
|
||||
/**
|
||||
* Loads a user from the datastore into the plugins internal storage.
|
||||
* @param uuid the uuid of the user to load
|
||||
* @return true if the user exists, and was loaded correctly.
|
||||
* @throws NullPointerException if uuid is null
|
||||
* @deprecated replaced by {@link #loadUser(UUID, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean loadUser(UUID uuid);
|
||||
|
||||
/**
|
||||
* Loads a user's data into the plugins internal storage.
|
||||
* @param uuid the uuid of the user to load
|
||||
* @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 2.6
|
||||
*/
|
||||
boolean loadUser(UUID uuid, String username);
|
||||
|
||||
/**
|
||||
* Saves a user object into the datastore. You should call this after you make any changes to a user.
|
||||
* @param user the user to save
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if user is null
|
||||
* @throws IllegalStateException if the user instance was not obtained from LuckPerms.
|
||||
*/
|
||||
boolean saveUser(User user);
|
||||
|
||||
/**
|
||||
* Removes users from the datastore who are "default". This is called every time the plugin loads.
|
||||
* @return true if the operation completed successfully
|
||||
* @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 2.6
|
||||
*/
|
||||
Set<UUID> getUniqueUsers();
|
||||
|
||||
/**
|
||||
* Creates and loads a group into the plugins internal storage
|
||||
* @param name the name of the group
|
||||
* @return true if the operation completed successfully
|
||||
* @throws NullPointerException if name is null
|
||||
* @throws IllegalArgumentException if the name is invalid
|
||||
*/
|
||||
boolean createAndLoadGroup(String name);
|
||||
|
||||
/**
|
||||
* Loads a group into the plugins internal storage.
|
||||
* @param name the name of the group
|
||||
* @return true if the operation completed successfully
|
||||
* @throws NullPointerException if name is null
|
||||
* @throws IllegalArgumentException if the name is invalid
|
||||
*/
|
||||
boolean loadGroup(String name);
|
||||
|
||||
/**
|
||||
* Loads all groups from the datastore into the plugins internal storage
|
||||
* @return true if the operation completed successfully.
|
||||
*/
|
||||
boolean loadAllGroups();
|
||||
|
||||
/**
|
||||
* Saves a group back to the datastore. You should call this after you make any changes to a group.
|
||||
* @param group the group to save
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
boolean saveGroup(Group group);
|
||||
|
||||
/**
|
||||
* Permanently deletes a group from the datastore
|
||||
* @param group the group to delete
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
boolean deleteGroup(Group group);
|
||||
|
||||
/**
|
||||
* Creates and loads a track into the plugins internal storage
|
||||
* @param name the name of the track
|
||||
* @return true if the operation completed successfully
|
||||
* @throws NullPointerException if name is null
|
||||
* @throws IllegalArgumentException if the name is invalid
|
||||
*/
|
||||
boolean createAndLoadTrack(String name);
|
||||
|
||||
/**
|
||||
* Loads a track into the plugins internal storage.
|
||||
* @param name the name of the track
|
||||
* @return true if the operation completed successfully
|
||||
* @throws NullPointerException if name is null
|
||||
* @throws IllegalArgumentException if the name is invalid
|
||||
*/
|
||||
boolean loadTrack(String name);
|
||||
|
||||
/**
|
||||
* Loads all tracks from the datastore into the plugins internal storage
|
||||
* @return true if the operation completed successfully.
|
||||
*/
|
||||
boolean loadAllTracks();
|
||||
|
||||
/**
|
||||
* Saves a track back to the datastore. You should call this after you make any changes to a track.
|
||||
* @param track the track to save
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if track is null
|
||||
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
|
||||
*/
|
||||
boolean saveTrack(Track track);
|
||||
|
||||
/**
|
||||
* Permanently deletes a track from the datastore
|
||||
* @param track the track to delete
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if track is null
|
||||
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
|
||||
*/
|
||||
boolean deleteTrack(Track track);
|
||||
|
||||
/**
|
||||
* Saves UUID caching data to the datastore
|
||||
* @param username the users username
|
||||
* @param uuid the users mojang unique id
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if either parameters are null
|
||||
* @throws IllegalArgumentException if the username is invalid
|
||||
*/
|
||||
boolean saveUUIDData(String username, UUID uuid);
|
||||
|
||||
/**
|
||||
* Gets a UUID from a username
|
||||
* @param username the corresponding username
|
||||
* @return a uuid object, could be null
|
||||
* @throws NullPointerException if either parameters are null
|
||||
* @throws IllegalArgumentException if the username is invalid
|
||||
*/
|
||||
UUID getUUID(String username);
|
||||
}
|
||||
|
||||
/**
|
||||
* All operations through this interface are called in a new, separate asynchronous thread.
|
||||
* When the operation is complete, the provided callback method is called, in applicable, in the main server thread.
|
||||
*
|
||||
* See {@link Sync} for method documentation.
|
||||
*/
|
||||
@Deprecated
|
||||
interface Async {
|
||||
void logAction(LogEntry entry, Callback<Boolean> callback);
|
||||
void getLog(Callback<Log> callback);
|
||||
@@ -274,13 +98,7 @@ public interface Datastore {
|
||||
void getUUID(String username, Callback<UUID> callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* See the Oracle JavaDocs for usage of the Future class.
|
||||
*
|
||||
* See {@link Sync} for method documentation.
|
||||
*/
|
||||
@Deprecated
|
||||
interface Future {
|
||||
java.util.concurrent.Future<Boolean> logAction(LogEntry entry);
|
||||
java.util.concurrent.Future<Log> getLog();
|
||||
|
||||
@@ -109,7 +109,9 @@ public interface LPConfiguration {
|
||||
/**
|
||||
* @return true if permission checks are being recorded / debugged
|
||||
* @since 2.9
|
||||
* @deprecated as this value is now always false. Functionality was replaced by the verbose command.
|
||||
*/
|
||||
@Deprecated
|
||||
boolean getDebugPermissionChecks();
|
||||
|
||||
/**
|
||||
|
||||
@@ -79,11 +79,27 @@ public interface LuckPermsApi {
|
||||
LPConfiguration getConfiguration();
|
||||
|
||||
/**
|
||||
* Gets a wrapped {@link Datastore} instance, with somewhat limited access
|
||||
* @return a datastore instance
|
||||
* Gets a wrapped {@link Storage} instance.
|
||||
* @return a storage instance
|
||||
* @since 2.14
|
||||
*/
|
||||
Storage getStorage();
|
||||
|
||||
/**
|
||||
* Gets a wrapped Datastore instance.
|
||||
* @return a datastore instance
|
||||
* @deprecated in favour of {@link #getStorage()}
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
Datastore getDatastore();
|
||||
|
||||
/**
|
||||
* Gets the messaging service in use on the platform, if present.
|
||||
* @return an optional that may contain a messaging service instance.
|
||||
*/
|
||||
Optional<MessagingService> getMessagingService();
|
||||
|
||||
/**
|
||||
* Gets the {@link Logger} wrapping used by the platform
|
||||
* @return the logger instance
|
||||
@@ -92,7 +108,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a wrapped {@link UuidCache} instance, providing read access to the LuckPerms internal uuid caching system
|
||||
* @return a uuidcache instance
|
||||
* @return a uuid cache instance
|
||||
*/
|
||||
UuidCache getUuidCache();
|
||||
|
||||
@@ -234,4 +250,12 @@ public interface LuckPermsApi {
|
||||
*/
|
||||
void registerContextListener(ContextListener<?> contextListener);
|
||||
|
||||
/**
|
||||
* Gets a calculated context instance for the user using the rules of the platform.
|
||||
* These values are calculated using the options in the configuration, and the provided calculators.
|
||||
* @param user the user to get contexts for
|
||||
* @return an optional containing contexts. Will return empty if the user is not online.
|
||||
*/
|
||||
Optional<Contexts> getContextForUser(User user);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Exposes any networking provider being used on the platform. e.g. Redis
|
||||
* @since 2.14
|
||||
*/
|
||||
public interface MessagingService {
|
||||
|
||||
/**
|
||||
* Uses the messaging service to inform other servers about changes.
|
||||
* This will push the update asynchronously, and this method will return almost immediately.
|
||||
*/
|
||||
void pushUpdate();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* 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 java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Interface for the internal Storage instance
|
||||
*
|
||||
* All methods return {@link CompletableFuture}s, which will be populated with the result once the data has been loaded
|
||||
* asynchronously. Care should be taken when using the methods to ensure that the main server thread is not blocked.
|
||||
*
|
||||
* Methods such as {@link CompletableFuture#get()} and equivalent should <strong>not</strong> be called on the main server thread.
|
||||
* If you need to use the result of these operations on the main server thread, please register a callback using
|
||||
* {@link CompletableFuture#thenAcceptAsync(Consumer, Executor)} and {@link #getSyncExecutor()}.
|
||||
*
|
||||
* @since 2.14
|
||||
*/
|
||||
public interface Storage {
|
||||
|
||||
/**
|
||||
* Get the name of the storage implementation.
|
||||
* @return the name of the implementation
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Return whether the storage instance is allowing logins on the platform.
|
||||
* @return true if logins are enabled
|
||||
*/
|
||||
boolean isAcceptingLogins();
|
||||
|
||||
/**
|
||||
* Returns an executor which will run all passed runnables on the main server thread.
|
||||
* @return an executor instance
|
||||
*/
|
||||
Executor getSyncExecutor();
|
||||
|
||||
/**
|
||||
* Returns an executor which will run all passed runnables asynchronously using the platforms scheduler and thread pools.
|
||||
* @return an executor instance
|
||||
*/
|
||||
Executor getAsyncExecutor();
|
||||
|
||||
/**
|
||||
* Saves an action to storage
|
||||
* @param entry the log entry to be saved
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if entry is null
|
||||
*/
|
||||
CompletableFuture<Boolean> logAction(LogEntry entry);
|
||||
|
||||
/**
|
||||
* Loads and returns the entire log from storage
|
||||
* @return a log instance, could be null if loading failed
|
||||
*/
|
||||
CompletableFuture<Log> getLog();
|
||||
|
||||
/**
|
||||
* Loads a user's data from the main storage into the plugins local storage.
|
||||
* @param uuid the uuid of the user to load
|
||||
* @param username the users username. (if you want to specify <code>null</code> here, just input "null" as a string.)
|
||||
* @return if the operation completed successfully
|
||||
* @throws NullPointerException if uuid or username is null
|
||||
*/
|
||||
CompletableFuture<Boolean> loadUser(UUID uuid, String username);
|
||||
|
||||
/**
|
||||
* Saves a user object back to storage. You should call this after you make any changes to a user.
|
||||
* @param user the user to save
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if user is null
|
||||
* @throws IllegalStateException if the user instance was not obtained from LuckPerms.
|
||||
*/
|
||||
CompletableFuture<Boolean> saveUser(User user);
|
||||
|
||||
/**
|
||||
* Removes users from the main storage who are "default". This is called every time the plugin loads.
|
||||
* @return true if the operation completed successfully
|
||||
*/
|
||||
CompletableFuture<Boolean> cleanupUsers();
|
||||
|
||||
/**
|
||||
* Gets a set all "unique" user UUIDs.
|
||||
* "Unique" meaning the user isn't just a member of the "default" group.
|
||||
* @return a set of uuids, or null if the operation failed.
|
||||
*/
|
||||
CompletableFuture<Set<UUID>> getUniqueUsers();
|
||||
|
||||
/**
|
||||
* Creates and loads a group into the plugins local storage
|
||||
* @param name the name of the group
|
||||
* @return true if the operation completed successfully
|
||||
* @throws NullPointerException if name is null
|
||||
* @throws IllegalArgumentException if the name is invalid
|
||||
*/
|
||||
CompletableFuture<Boolean> createAndLoadGroup(String name);
|
||||
|
||||
/**
|
||||
* Loads a group into the plugins local storage.
|
||||
* @param name the name of the group
|
||||
* @return true if the operation completed successfully
|
||||
* @throws NullPointerException if name is null
|
||||
* @throws IllegalArgumentException if the name is invalid
|
||||
*/
|
||||
CompletableFuture<Boolean> loadGroup(String name);
|
||||
|
||||
/**
|
||||
* Loads all groups from the storage into memory
|
||||
* @return true if the operation completed successfully.
|
||||
*/
|
||||
CompletableFuture<Boolean> loadAllGroups();
|
||||
|
||||
/**
|
||||
* Saves a group back to storage. You should call this after you make any changes to a group.
|
||||
* @param group the group to save
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
CompletableFuture<Boolean> saveGroup(Group group);
|
||||
|
||||
/**
|
||||
* Permanently deletes a group from storage.
|
||||
* @param group the group to delete
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
CompletableFuture<Boolean> deleteGroup(Group group);
|
||||
|
||||
/**
|
||||
* Creates and loads a track into the plugins local storage
|
||||
* @param name the name of the track
|
||||
* @return true if the operation completed successfully
|
||||
* @throws NullPointerException if name is null
|
||||
* @throws IllegalArgumentException if the name is invalid
|
||||
*/
|
||||
CompletableFuture<Boolean> createAndLoadTrack(String name);
|
||||
|
||||
/**
|
||||
* Loads a track into the plugins local storage.
|
||||
* @param name the name of the track
|
||||
* @return true if the operation completed successfully
|
||||
* @throws NullPointerException if name is null
|
||||
* @throws IllegalArgumentException if the name is invalid
|
||||
*/
|
||||
CompletableFuture<Boolean> loadTrack(String name);
|
||||
|
||||
/**
|
||||
* Loads all tracks from the storage into memory
|
||||
* @return true if the operation completed successfully.
|
||||
*/
|
||||
CompletableFuture<Boolean> loadAllTracks();
|
||||
|
||||
/**
|
||||
* Saves a track back to storage. You should call this after you make any changes to a track.
|
||||
* @param track the track to save
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if track is null
|
||||
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
|
||||
*/
|
||||
CompletableFuture<Boolean> saveTrack(Track track);
|
||||
|
||||
/**
|
||||
* Permanently deletes a track from storage
|
||||
* @param track the track to delete
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if track is null
|
||||
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
|
||||
*/
|
||||
CompletableFuture<Boolean> deleteTrack(Track track);
|
||||
|
||||
/**
|
||||
* Saves UUID caching data to the global cache
|
||||
* @param username the users username
|
||||
* @param uuid the users mojang unique id
|
||||
* @return true if the operation completed successfully.
|
||||
* @throws NullPointerException if either parameters are null
|
||||
* @throws IllegalArgumentException if the username is invalid
|
||||
*/
|
||||
CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid);
|
||||
|
||||
/**
|
||||
* Gets a UUID from a username
|
||||
* @param username the corresponding username
|
||||
* @return a uuid object, could be null
|
||||
* @throws NullPointerException if either parameters are null
|
||||
* @throws IllegalArgumentException if the username is invalid
|
||||
*/
|
||||
CompletableFuture<UUID> getUUID(String username);
|
||||
|
||||
}
|
||||
@@ -32,8 +32,8 @@ import java.util.UUID;
|
||||
* they first join the server, but this UUID will then not be consistent across the network. LuckPerms will instead check
|
||||
* the datastore cache, to get a UUID for a user that is consistent across an entire network.
|
||||
*
|
||||
* <p> If you want to get a user object from the datastore using the api on a server in offline mode, you will need to use this cache,
|
||||
* OR use Datastore#getUUID, for users that are not online.
|
||||
* <p> If you want to get a user object from the Storage using the api on a server in offline mode, you will need to use this cache,
|
||||
* OR use Storage#getUUID, for users that are not online.
|
||||
*
|
||||
* <p> WARNING: THIS IS ONLY EFFECTIVE FOR ONLINE PLAYERS. USE THE DATASTORE METHODS FOR OFFLINE PLAYERS.
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,7 @@ import java.util.stream.Collectors;
|
||||
* @since 2.13
|
||||
*/
|
||||
public class ContextSet {
|
||||
private static final ContextSet EMPTY = new ContextSet();
|
||||
|
||||
/**
|
||||
* Make a singleton ContextSet from a context pair
|
||||
@@ -112,7 +113,7 @@ public class ContextSet {
|
||||
* @return a new ContextSet
|
||||
*/
|
||||
public static ContextSet empty() {
|
||||
return new ContextSet();
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
final Set<Map.Entry<String, String>> contexts;
|
||||
@@ -303,4 +304,9 @@ public class ContextSet {
|
||||
public int hashCode() {
|
||||
return 59 + (this.contexts == null ? 43 : this.contexts.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ContextSet(contexts=" + this.contexts + ")";
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,9 @@ import java.util.function.Consumer;
|
||||
* A callback used to wait for the completion of asynchronous operations.
|
||||
* All callbacks are ran on the main server thread.
|
||||
* @param <T> the return type
|
||||
* @deprecated in favour of {@link Consumer}
|
||||
*/
|
||||
@Deprecated
|
||||
public interface Callback<T> {
|
||||
|
||||
/**
|
||||
@@ -55,4 +57,17 @@ public interface Callback<T> {
|
||||
return consumer::accept;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for converting old {@link Callback}s to use the new {@link me.lucko.luckperms.api.Storage} interface.
|
||||
* @param callback the callback to convert
|
||||
* @param <T> the return type
|
||||
* @return a consumer instance
|
||||
* @since 2.14
|
||||
* @deprecated in favour of just using {@link Consumer}s.
|
||||
*/
|
||||
@Deprecated
|
||||
static <T> Consumer<T> convertToConsumer(Callback<T> callback) {
|
||||
return callback::onComplete;
|
||||
}
|
||||
|
||||
}
|
||||
+13
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<version>2.15-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -75,6 +75,18 @@
|
||||
<pattern>com.google.gson</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.gson</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.jedis</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.jedis</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.util</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.util</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.apache.commons.pool2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.pool2</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<version>2.15-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<dependency>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<artifactId>luckperms-api</artifactId>
|
||||
<version>2.8</version>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- BukkitAPI -->
|
||||
|
||||
+41
-8
@@ -26,16 +26,20 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.util.TimeUtil;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import me.lucko.luckperms.api.caching.UserData;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/*
|
||||
* PlaceholderAPI Expansion for LuckPerms, implemented using the LuckPerms API.
|
||||
*
|
||||
* Placeholders:
|
||||
* - group_name
|
||||
* - groups
|
||||
* - has_permission_<node>
|
||||
* - inherits_permission_<node>
|
||||
* - in_group_<name>
|
||||
@@ -71,7 +75,14 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return "2.8";
|
||||
return "2.13";
|
||||
}
|
||||
|
||||
private Contexts makeContexts(Player player) {
|
||||
MutableContextSet contextSet = new MutableContextSet();
|
||||
contextSet.add("server", api.getConfiguration().getVaultServer());
|
||||
contextSet.add("world", player.getWorld().getName());// ignore world?
|
||||
return Contexts.of(contextSet.makeImmutable(), api.getConfiguration().getVaultIncludeGlobal(), true, true, true, true, player.isOp());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,14 +95,24 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
if (!u.isPresent()) {
|
||||
return "";
|
||||
}
|
||||
final User user = u.get();
|
||||
|
||||
Optional<UserData> d = user.getUserDataCache();
|
||||
if (!d.isPresent()) {
|
||||
return "";
|
||||
}
|
||||
final UserData data = d.get();
|
||||
|
||||
identifier = identifier.toLowerCase();
|
||||
final User user = u.get();
|
||||
|
||||
if (identifier.equalsIgnoreCase("group_name")) {
|
||||
return user.getPrimaryGroup();
|
||||
}
|
||||
|
||||
if (identifier.equalsIgnoreCase("groups")) {
|
||||
return user.getGroupNames().stream().collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
if (identifier.startsWith("has_permission_") && identifier.length() > "has_permission_".length()) {
|
||||
String node = identifier.substring("has_permission_".length());
|
||||
return formatBoolean(user.hasPermission(node, true));
|
||||
@@ -99,7 +120,7 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
if (identifier.startsWith("inherits_permission_") && identifier.length() > "inherits_permission_".length()) {
|
||||
String node = identifier.substring("inherits_permission_".length());
|
||||
return formatBoolean(user.inheritsPermission(node, true));
|
||||
return formatBoolean(data.getPermissionData(makeContexts(player)).getPermissionValue(node).asBoolean());
|
||||
}
|
||||
|
||||
if (identifier.startsWith("in_group_") && identifier.length() > "in_group_".length()) {
|
||||
@@ -109,7 +130,7 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
if (identifier.startsWith("inherits_group_") && identifier.length() > "inherits_group_".length()) {
|
||||
String groupName = identifier.substring("inherits_group_".length());
|
||||
return formatBoolean(user.getLocalGroups("global").contains(groupName));
|
||||
return formatBoolean(data.getPermissionData(makeContexts(player)).getPermissionValue("group." + groupName).asBoolean());
|
||||
}
|
||||
|
||||
if (identifier.startsWith("on_track_") && identifier.length() > "on_track_".length()) {
|
||||
@@ -125,7 +146,7 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
String node = identifier.substring("expiry_time_".length());
|
||||
long currentTime = System.currentTimeMillis() / 1000L;
|
||||
for (Node n : user.getTemporaryPermissionNodes()) {
|
||||
if (n.getPermission().equalsIgnoreCase(node)) {
|
||||
if (n.toSerializedNode().equalsIgnoreCase(node)) {
|
||||
return TimeUtil.getTime((int) (n.getExpiryUnixTime() - currentTime));
|
||||
}
|
||||
}
|
||||
@@ -146,16 +167,28 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
}
|
||||
|
||||
if (identifier.equalsIgnoreCase("prefix")) {
|
||||
return MetaUtils.getPrefix(user, null, null, true);
|
||||
String prefix = data.calculateMeta(makeContexts(player)).getPrefix();
|
||||
if (prefix == null) {
|
||||
prefix = "";
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
|
||||
if (identifier.equalsIgnoreCase("suffix")) {
|
||||
return MetaUtils.getSuffix(user, null, null, true);
|
||||
String suffix = data.calculateMeta(makeContexts(player)).getSuffix();
|
||||
if (suffix == null) {
|
||||
suffix = "";
|
||||
}
|
||||
return suffix;
|
||||
}
|
||||
|
||||
if (identifier.startsWith("meta_") && identifier.length() > "meta_".length()) {
|
||||
String node = identifier.substring("meta_".length());
|
||||
return MetaUtils.getMeta(user, null, null, node, "", true);
|
||||
String meta = data.getMetaData(makeContexts(player)).getMeta().get(node);
|
||||
if (meta == null) {
|
||||
meta = "";
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+54
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<version>2.15-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -70,6 +70,18 @@
|
||||
<pattern>org.h2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.h2</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.jedis</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.jedis</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.util</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.util</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.apache.commons.pool2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.pool2</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
@@ -129,5 +141,46 @@
|
||||
<version>1.16.10</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- **************Migration Plugins************** -->
|
||||
<dependency>
|
||||
<groupId>org.tyrannyofheaven.bukkit</groupId>
|
||||
<artifactId>zPermissions</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.tehkode</groupId>
|
||||
<artifactId>PermissionsEx</artifactId>
|
||||
<version>1.23</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.gravitydevelopment.updater</groupId>
|
||||
<artifactId>updater</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.cheesesoftware</groupId>
|
||||
<artifactId>PowerfulPermsAPI</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.anjocaido</groupId>
|
||||
<artifactId>GroupManager</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.bananaco</groupId>
|
||||
<artifactId>bpermissions-api</artifactId>
|
||||
<version>2.12</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -22,18 +22,22 @@
|
||||
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.bukkit.calculators.AttachmentProcessor;
|
||||
import me.lucko.luckperms.bukkit.calculators.ChildProcessor;
|
||||
import me.lucko.luckperms.bukkit.calculators.DefaultsProcessor;
|
||||
import me.lucko.luckperms.bukkit.inject.Injector;
|
||||
import me.lucko.luckperms.bukkit.inject.LPPermissible;
|
||||
import me.lucko.luckperms.common.calculators.*;
|
||||
import me.lucko.luckperms.bukkit.model.LPPermissible;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.calculators.PermissionCalculator;
|
||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||
import me.lucko.luckperms.common.calculators.processors.MapProcessor;
|
||||
import me.lucko.luckperms.common.calculators.processors.RegexProcessor;
|
||||
import me.lucko.luckperms.common.calculators.processors.WildcardProcessor;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@AllArgsConstructor
|
||||
@@ -41,23 +45,24 @@ public class BukkitCalculatorFactory implements CalculatorFactory {
|
||||
private final LPBukkitPlugin plugin;
|
||||
|
||||
@Override
|
||||
public PermissionCalculator build(Contexts contexts, User user, Map<String, Boolean> map) {
|
||||
public PermissionCalculator build(Contexts contexts, User user) {
|
||||
UUID uuid = plugin.getUuidCache().getExternalUUID(user.getUuid());
|
||||
|
||||
List<PermissionProcessor> processors = new ArrayList<>(5);
|
||||
processors.add(new MapProcessor(map));
|
||||
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
|
||||
processors.add(new MapProcessor());
|
||||
processors.add(new ChildProcessor(plugin.getChildPermissionProvider()));
|
||||
processors.add(new AttachmentProcessor(() -> {
|
||||
LPPermissible permissible = Injector.getPermissible(uuid);
|
||||
return permissible == null ? null : permissible.getAttachmentPermissions();
|
||||
}));
|
||||
if (plugin.getConfiguration().isApplyingWildcards()) {
|
||||
processors.add(new WildcardProcessor(map));
|
||||
processors.add(new WildcardProcessor());
|
||||
}
|
||||
if (plugin.getConfiguration().isApplyingRegex()) {
|
||||
processors.add(new RegexProcessor(map));
|
||||
processors.add(new RegexProcessor());
|
||||
}
|
||||
processors.add(new DefaultsProcessor(contexts.isOp(), plugin.getDefaultsProvider()));
|
||||
|
||||
return new PermissionCalculator(plugin, user.getName(), plugin.getConfiguration().isDebugPermissionChecks(), processors);
|
||||
return new PermissionCalculator(plugin, user.getName(), processors.build());
|
||||
}
|
||||
}
|
||||
@@ -24,10 +24,8 @@ package me.lucko.luckperms.bukkit;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.CommandManager;
|
||||
import me.lucko.luckperms.common.commands.Util;
|
||||
import me.lucko.luckperms.common.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Patterns;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@@ -38,24 +36,26 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
class BukkitCommand extends CommandManager implements CommandExecutor, TabExecutor {
|
||||
BukkitCommand(LuckPermsPlugin plugin) {
|
||||
private final LPBukkitPlugin plugin;
|
||||
|
||||
BukkitCommand(LPBukkitPlugin plugin) {
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
onCommand(
|
||||
BukkitSenderFactory.get(getPlugin()).wrap(sender),
|
||||
plugin.getSenderFactory().wrap(sender),
|
||||
label,
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))),
|
||||
Callback.empty()
|
||||
null
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
|
||||
return onTabComplete(BukkitSenderFactory.get(getPlugin()).wrap(sender), Arrays.asList(args));
|
||||
return onTabComplete(plugin.getSenderFactory().wrap(sender), Arrays.asList(args));
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import me.lucko.luckperms.bukkit.inject.Injector;
|
||||
import me.lucko.luckperms.bukkit.inject.LPPermissible;
|
||||
import me.lucko.luckperms.bukkit.model.LPPermissible;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.utils.AbstractListener;
|
||||
@@ -35,6 +35,7 @@ import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -48,7 +49,7 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent e) {
|
||||
if (!plugin.isStarted() || !plugin.getDatastore().isAcceptingLogins()) {
|
||||
if (!plugin.isStarted() || !plugin.getStorage().isAcceptingLogins()) {
|
||||
|
||||
// The datastore is disabled, prevent players from joining the server
|
||||
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.toString());
|
||||
@@ -61,7 +62,7 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerPreLoginMonitor(AsyncPlayerPreLoginEvent e) {
|
||||
if (plugin.isStarted() && plugin.getDatastore().isAcceptingLogins() && e.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
|
||||
if (plugin.isStarted() && plugin.getStorage().isAcceptingLogins() && e.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
|
||||
|
||||
// Login event was cancelled by another plugin
|
||||
onLeave(e.getUniqueId());
|
||||
@@ -106,7 +107,7 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST) // Allow other plugins to see data when this event gets called.
|
||||
@EventHandler(priority = EventPriority.MONITOR) // Allow other plugins to see data when this event gets called.
|
||||
public void onPlayerQuit(PlayerQuitEvent e) {
|
||||
final Player player = e.getPlayer();
|
||||
final UUID internal = plugin.getUuidCache().getUUID(player.getUniqueId());
|
||||
@@ -143,4 +144,11 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
e.getPlayer().sendMessage(Message.OP_DISABLED.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginEnable(PluginEnableEvent e) {
|
||||
if (e.getPlugin().getName().equalsIgnoreCase("Vault")) {
|
||||
plugin.tryVaultHook(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.SenderFactory;
|
||||
import me.lucko.luckperms.common.commands.sender.SenderFactory;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -31,19 +31,10 @@ import org.bukkit.entity.Player;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitSenderFactory extends SenderFactory<CommandSender> {
|
||||
private static BukkitSenderFactory instance = null;
|
||||
|
||||
private BukkitSenderFactory(LuckPermsPlugin plugin) {
|
||||
public BukkitSenderFactory(LuckPermsPlugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
public static synchronized BukkitSenderFactory get(LuckPermsPlugin plugin) {
|
||||
if (instance == null) {
|
||||
instance = new BukkitSenderFactory(plugin);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName(CommandSender sender) {
|
||||
if (sender instanceof Player) {
|
||||
|
||||
@@ -31,13 +31,14 @@ import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.bukkit.calculators.AutoOPListener;
|
||||
import me.lucko.luckperms.bukkit.calculators.DefaultsProvider;
|
||||
import me.lucko.luckperms.bukkit.model.ChildPermissionProvider;
|
||||
import me.lucko.luckperms.bukkit.model.DefaultsProvider;
|
||||
import me.lucko.luckperms.bukkit.vault.VaultHook;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.api.ApiProvider;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.config.LPConfiguration;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.contexts.ContextManager;
|
||||
@@ -45,13 +46,16 @@ import me.lucko.luckperms.common.contexts.ServerCalculator;
|
||||
import me.lucko.luckperms.common.core.UuidCache;
|
||||
import me.lucko.luckperms.common.data.Importer;
|
||||
import me.lucko.luckperms.common.groups.GroupManager;
|
||||
import me.lucko.luckperms.common.runnables.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.common.runnables.UpdateTask;
|
||||
import me.lucko.luckperms.common.storage.Datastore;
|
||||
import me.lucko.luckperms.common.messaging.RedisMessaging;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
import me.lucko.luckperms.common.storage.StorageFactory;
|
||||
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.common.tasks.UpdateTask;
|
||||
import me.lucko.luckperms.common.tracks.TrackManager;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.users.UserManager;
|
||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||
import me.lucko.luckperms.common.utils.DebugHandler;
|
||||
import me.lucko.luckperms.common.utils.LocaleManager;
|
||||
import me.lucko.luckperms.common.utils.LogFactory;
|
||||
import org.bukkit.World;
|
||||
@@ -65,10 +69,16 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
private ExecutorService executorService;
|
||||
private Executor syncExecutor;
|
||||
private Executor asyncExecutor;
|
||||
private VaultHook vaultHook = null;
|
||||
|
||||
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
|
||||
@@ -76,27 +86,78 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
private UserManager userManager;
|
||||
private GroupManager groupManager;
|
||||
private TrackManager trackManager;
|
||||
private Datastore datastore;
|
||||
private Storage storage;
|
||||
private RedisMessaging redisMessaging = null;
|
||||
private UuidCache uuidCache;
|
||||
private ApiProvider apiProvider;
|
||||
private Logger log;
|
||||
private Importer importer;
|
||||
private ConsecutiveExecutor consecutiveExecutor;
|
||||
private DefaultsProvider defaultsProvider;
|
||||
private ChildPermissionProvider childPermissionProvider;
|
||||
private LocaleManager localeManager;
|
||||
private ContextManager<Player> contextManager;
|
||||
private WorldCalculator worldCalculator;
|
||||
private CalculatorFactory calculatorFactory;
|
||||
private BufferedRequest<Void> updateTaskBuffer;
|
||||
private boolean started = false;
|
||||
private DebugHandler debugHandler;
|
||||
private BukkitSenderFactory senderFactory;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Used whilst the server is still starting
|
||||
executorService = Executors.newCachedThreadPool();
|
||||
asyncExecutor = executorService;
|
||||
syncExecutor = r -> getServer().getScheduler().runTask(this, r);
|
||||
|
||||
log = LogFactory.wrap(getLogger());
|
||||
debugHandler = new DebugHandler();
|
||||
senderFactory = new BukkitSenderFactory(this);
|
||||
|
||||
getLog().info("Loading configuration...");
|
||||
configuration = new BukkitConfig(this);
|
||||
|
||||
// setup the Bukkit defaults hook
|
||||
defaultsProvider = new DefaultsProvider();
|
||||
childPermissionProvider = new ChildPermissionProvider();
|
||||
|
||||
// give all plugins a chance to load their defaults, then refresh.
|
||||
getServer().getScheduler().runTaskLater(this, () -> {
|
||||
defaultsProvider.refresh();
|
||||
childPermissionProvider.setup();
|
||||
}, 1L);
|
||||
|
||||
// register events
|
||||
PluginManager pm = getServer().getPluginManager();
|
||||
pm.registerEvents(new BukkitListener(this), this);
|
||||
|
||||
// initialise datastore
|
||||
storage = StorageFactory.getInstance(this, "h2");
|
||||
|
||||
// initialise redis
|
||||
if (getConfiguration().isRedisEnabled()) {
|
||||
getLog().info("Loading redis...");
|
||||
redisMessaging = new RedisMessaging(this);
|
||||
try {
|
||||
redisMessaging.init(getConfiguration().getRedisAddress(), getConfiguration().getRedisPassword());
|
||||
getLog().info("Loaded redis successfully...");
|
||||
} catch (Exception e) {
|
||||
getLog().info("Couldn't load redis...");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// setup the update task buffer
|
||||
updateTaskBuffer = new BufferedRequest<Void>(1000L, this::doAsync) {
|
||||
@Override
|
||||
protected Void perform() {
|
||||
new UpdateTask(LPBukkitPlugin.this).run();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// load locale
|
||||
localeManager = new LocaleManager();
|
||||
File locale = new File(getDataFolder(), "lang.yml");
|
||||
if (locale.exists()) {
|
||||
@@ -108,13 +169,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
defaultsProvider = new DefaultsProvider();
|
||||
getServer().getScheduler().runTaskLater(this, () -> defaultsProvider.refresh(), 1L);
|
||||
|
||||
// register events
|
||||
PluginManager pm = getServer().getPluginManager();
|
||||
pm.registerEvents(new BukkitListener(this), this);
|
||||
|
||||
// register commands
|
||||
getLog().info("Registering commands...");
|
||||
BukkitCommand commandManager = new BukkitCommand(this);
|
||||
@@ -123,8 +177,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
main.setTabCompleter(commandManager);
|
||||
main.setAliases(Arrays.asList("perms", "lp", "permissions", "p", "perm"));
|
||||
|
||||
datastore = StorageFactory.getDatastore(this, "h2");
|
||||
|
||||
// load internal managers
|
||||
getLog().info("Loading internal permission managers...");
|
||||
uuidCache = new UuidCache(getConfiguration().isOnlineMode());
|
||||
userManager = new UserManager(this);
|
||||
@@ -140,58 +193,46 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
contextManager.registerCalculator(worldCalculator);
|
||||
contextManager.registerCalculator(new ServerCalculator<>(getConfiguration().getServer()));
|
||||
|
||||
// handle server operators
|
||||
if (getConfiguration().isAutoOp()) {
|
||||
contextManager.registerListener(new AutoOPListener());
|
||||
}
|
||||
|
||||
final LPBukkitPlugin i = this;
|
||||
updateTaskBuffer = new BufferedRequest<Void>(6000L, this::doAsync) {
|
||||
@Override
|
||||
protected Void perform() {
|
||||
getServer().getScheduler().runTaskAsynchronously(i, new UpdateTask(i));
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
int mins = getConfiguration().getSyncTime();
|
||||
if (mins > 0) {
|
||||
long ticks = mins * 60 * 20;
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, () -> updateTaskBuffer.request(), ticks, ticks);
|
||||
}
|
||||
|
||||
getServer().getScheduler().runTaskTimer(this, BukkitSenderFactory.get(this), 1L, 1L);
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, new ExpireTemporaryTask(this), 60L, 60L);
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, consecutiveExecutor, 20L, 20L);
|
||||
|
||||
// Provide vault support
|
||||
getLog().info("Attempting to hook into Vault...");
|
||||
try {
|
||||
if (getServer().getPluginManager().isPluginEnabled("Vault")) {
|
||||
vaultHook = new VaultHook();
|
||||
vaultHook.hook(this);
|
||||
getLog().info("Registered Vault permission & chat hook.");
|
||||
} else {
|
||||
getLog().info("Vault not found.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
getLog().severe("Error occurred whilst hooking into Vault.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
tryVaultHook(false);
|
||||
|
||||
// register with the LP API
|
||||
getLog().info("Registering API...");
|
||||
apiProvider = new ApiProvider(this);
|
||||
ApiHandler.registerProvider(apiProvider);
|
||||
getServer().getServicesManager().register(LuckPermsApi.class, apiProvider, this, ServicePriority.Normal);
|
||||
|
||||
// Run update task to refresh any online users
|
||||
getLog().info("Scheduling Update Task to refresh any online users.");
|
||||
updateTaskBuffer.request();
|
||||
|
||||
// schedule update tasks
|
||||
int mins = getConfiguration().getSyncTime();
|
||||
if (mins > 0) {
|
||||
long ticks = mins * 60 * 20;
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, () -> updateTaskBuffer.request(), 20L, ticks);
|
||||
}
|
||||
|
||||
// run an update instantly.
|
||||
updateTaskBuffer.requestDirectly();
|
||||
|
||||
// register tasks
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, new ExpireTemporaryTask(this), 60L, 60L);
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, consecutiveExecutor, 20L, 20L);
|
||||
|
||||
// register permissions
|
||||
registerPermissions(getConfiguration().isCommandsAllowOp() ? PermissionDefault.OP : PermissionDefault.FALSE);
|
||||
if (!getConfiguration().isOpsEnabled()) {
|
||||
getServer().getOperators().forEach(o -> o.setOp(false));
|
||||
}
|
||||
|
||||
// replace the temporary executor when the Bukkit one starts
|
||||
getServer().getScheduler().runTaskAsynchronously(this, () -> {
|
||||
asyncExecutor = r -> getServer().getScheduler().runTaskAsynchronously(this, r);
|
||||
});
|
||||
|
||||
started = true;
|
||||
getLog().info("Successfully loaded.");
|
||||
}
|
||||
@@ -200,7 +241,12 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
public void onDisable() {
|
||||
started = false;
|
||||
getLog().info("Closing datastore...");
|
||||
datastore.shutdown();
|
||||
storage.shutdown();
|
||||
|
||||
if (redisMessaging != null) {
|
||||
getLog().info("Closing redis...");
|
||||
redisMessaging.shutdown();
|
||||
}
|
||||
|
||||
getLog().info("Unregistering API...");
|
||||
ApiHandler.unregisterProvider();
|
||||
@@ -211,14 +257,35 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
public void tryVaultHook(boolean force) {
|
||||
if (vaultHook != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
getLog().info("Attempting to hook with Vault...");
|
||||
try {
|
||||
if (force || getServer().getPluginManager().isPluginEnabled("Vault")) {
|
||||
vaultHook = new VaultHook();
|
||||
vaultHook.hook(this);
|
||||
getLog().info("Registered Vault permission & chat hook.");
|
||||
} else {
|
||||
getLog().info("Vault not found.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
vaultHook = null;
|
||||
getLog().severe("Error occurred whilst hooking into Vault.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAsync(Runnable r) {
|
||||
getServer().getScheduler().runTaskAsynchronously(this, r);
|
||||
asyncExecutor.execute(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSync(Runnable r) {
|
||||
getServer().getScheduler().runTask(this, r);
|
||||
syncExecutor.execute(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -241,6 +308,28 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
return getDataFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer(User user) {
|
||||
return getServer().getPlayer(uuidCache.getExternalUUID(user.getUuid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Contexts getContextForUser(User user) {
|
||||
Player player = getPlayer(user);
|
||||
if (player == null) {
|
||||
return null;
|
||||
}
|
||||
return new Contexts(
|
||||
getContextManager().getApplicableContext(player),
|
||||
getConfiguration().isIncludingGlobalPerms(),
|
||||
getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
getConfiguration().isApplyingGlobalGroups(),
|
||||
getConfiguration().isApplyingGlobalWorldGroups(),
|
||||
player.isOp()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerCount() {
|
||||
return getServer().getOnlinePlayers().size();
|
||||
@@ -262,16 +351,15 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Sender> getNotifyListeners() {
|
||||
public List<Sender> getSenders() {
|
||||
return getServer().getOnlinePlayers().stream()
|
||||
.map(p -> BukkitSenderFactory.get(this).wrap(p, Collections.singleton(Permission.LOG_NOTIFY)))
|
||||
.filter(Permission.LOG_NOTIFY::isAuthorized)
|
||||
.map(p -> getSenderFactory().wrap(p))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sender getConsoleSender() {
|
||||
return BukkitSenderFactory.get(this).wrap(getServer().getConsoleSender());
|
||||
return getSenderFactory().wrap(getServer().getConsoleSender());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -324,12 +412,12 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
);
|
||||
|
||||
// Check for and include varying Vault config options
|
||||
try {
|
||||
assert getConfiguration().isVaultIncludingGlobal() == getConfiguration().isIncludingGlobalPerms();
|
||||
assert getConfiguration().isIncludingGlobalWorldPerms();
|
||||
assert getConfiguration().isApplyingGlobalGroups();
|
||||
assert getConfiguration().isApplyingGlobalWorldGroups();
|
||||
} catch (AssertionError e) {
|
||||
boolean vaultDiff = getConfiguration().isVaultIncludingGlobal() != getConfiguration().isIncludingGlobalPerms() ||
|
||||
!getConfiguration().isIncludingGlobalWorldPerms() ||
|
||||
!getConfiguration().isApplyingGlobalGroups() ||
|
||||
!getConfiguration().isApplyingGlobalWorldGroups();
|
||||
|
||||
if (vaultDiff) {
|
||||
contexts.addAll(c.stream()
|
||||
.map(map -> new Contexts(map, getConfiguration().isVaultIncludingGlobal(), true, true, true, true, op))
|
||||
.collect(Collectors.toSet())
|
||||
@@ -339,6 +427,24 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
return contexts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedHashMap<String, Object> getExtraInfo() {
|
||||
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("Vault Enabled", vaultHook != null);
|
||||
map.put("Vault Server", configuration.getVaultServer());
|
||||
map.put("Bukkit Defaults count", defaultsProvider.size());
|
||||
map.put("Bukkit Child Permissions count", childPermissionProvider.getPermissions().size());
|
||||
map.put("World Cache size", worldCalculator.getWorldCache().size());
|
||||
map.put("Vault Including Global", configuration.isVaultIncludingGlobal());
|
||||
map.put("Vault Ignoring World", configuration.isVaultIgnoreWorld());
|
||||
map.put("Vault Primary Group Overrides", configuration.isVaultPrimaryGroupOverrides());
|
||||
map.put("Vault Debug", configuration.isVaultDebug());
|
||||
map.put("OPs Enabled", configuration.isOpsEnabled());
|
||||
map.put("Auto OP", configuration.isAutoOp());
|
||||
map.put("Commands Allow OPs", configuration.isCommandsAllowOp());
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPlugin(String name) {
|
||||
return getServer().getPluginManager().getPlugin(name);
|
||||
|
||||
@@ -71,11 +71,11 @@ public class WorldCalculator extends ContextCalculator<Player> implements Listen
|
||||
|
||||
private String getWorld(Player player) {
|
||||
UUID internal = plugin.getUuidCache().getUUID(player.getUniqueId());
|
||||
if (!worldCache.containsKey(internal)) {
|
||||
String world = worldCache.get(internal);
|
||||
if (world == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String world = worldCache.get(internal);
|
||||
return plugin.getConfiguration().getWorldRewrites().getOrDefault(world, world);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,4 +48,9 @@ public class AttachmentProcessor implements PermissionProcessor {
|
||||
return pai == null ? Tristate.UNDEFINED : Tristate.fromBoolean(pai.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBacking(Map<String, Boolean> map) {
|
||||
// Do nothing, this doesn't use the backing
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,7 +24,7 @@ package me.lucko.luckperms.bukkit.calculators;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import me.lucko.luckperms.bukkit.inject.Injector;
|
||||
import me.lucko.luckperms.bukkit.inject.LPPermissible;
|
||||
import me.lucko.luckperms.bukkit.model.LPPermissible;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
+23
-37
@@ -20,49 +20,35 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.utils;
|
||||
package me.lucko.luckperms.bukkit.calculators;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.bukkit.model.ChildPermissionProvider;
|
||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||
|
||||
public class AbstractFuture<R> implements LPFuture<R> {
|
||||
private final CountDownLatch latch = new CountDownLatch(1);
|
||||
private R value;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public void complete(R r) {
|
||||
value = r;
|
||||
latch.countDown();
|
||||
@RequiredArgsConstructor
|
||||
public class ChildProcessor implements PermissionProcessor {
|
||||
private final ChildPermissionProvider provider;
|
||||
private Map<String, Boolean> childPermissions = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
Boolean b = childPermissions.get(permission);
|
||||
return b == null ? Tristate.UNDEFINED : Tristate.fromBoolean(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
// Not supported
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return latch.getCount() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R get() throws InterruptedException {
|
||||
latch.await();
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R get(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
|
||||
if (latch.await(timeout, unit)) {
|
||||
return value;
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
public void updateBacking(Map<String, Boolean> map) {
|
||||
childPermissions.clear();
|
||||
for (Map.Entry<String, Boolean> e : map.entrySet()) {
|
||||
Map<String, Boolean> children = provider.getPermissions().get(e);
|
||||
if (children != null) {
|
||||
childPermissions.putAll(children);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,10 +24,13 @@ package me.lucko.luckperms.bukkit.calculators;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.bukkit.model.DefaultsProvider;
|
||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.permissions.Permission;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class DefaultsProcessor implements PermissionProcessor {
|
||||
private final boolean isOp;
|
||||
@@ -43,4 +46,9 @@ public class DefaultsProcessor implements PermissionProcessor {
|
||||
Permission defPerm = Bukkit.getServer().getPluginManager().getPermission(permission);
|
||||
return defPerm == null ? Tristate.UNDEFINED : Tristate.fromBoolean(defPerm.getDefault().getValue(isOp));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBacking(Map<String, Boolean> map) {
|
||||
// Do nothing, this doesn't use the backing
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
package me.lucko.luckperms.bukkit.inject;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import me.lucko.luckperms.bukkit.model.LPPermissible;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
|
||||
+10
-9
@@ -20,19 +20,20 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.migration.subcommands;
|
||||
package me.lucko.luckperms.bukkit.migration;
|
||||
|
||||
import de.bananaco.bpermissions.api.*;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.SubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@@ -82,11 +83,11 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
public MigrationBPermissions() {
|
||||
super("bpermissions", "Migration from bPermissions", MIGRATION, Predicate.alwaysFalse(), null);
|
||||
super("bpermissions", "Migration from bPermissions", MIGRATION, Predicates.alwaysFalse(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) throws CommandException {
|
||||
final Logger log = plugin.getLog();
|
||||
|
||||
WorldManager worldManager = WorldManager.getInstance();
|
||||
@@ -121,7 +122,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
// Make a LuckPerms group for the one being migrated.
|
||||
plugin.getDatastore().createAndLoadGroup(groupName).getUnchecked();
|
||||
plugin.getStorage().createAndLoadGroup(groupName).join();
|
||||
me.lucko.luckperms.common.groups.Group lpGroup = plugin.getGroupManager().get(groupName);
|
||||
try {
|
||||
LogEntry.build()
|
||||
@@ -133,7 +134,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
migrateHolder(plugin, world, group, lpGroup);
|
||||
plugin.getDatastore().saveGroup(lpGroup);
|
||||
plugin.getStorage().saveGroup(lpGroup);
|
||||
}
|
||||
log.info("bPermissions Migration: Migrated " + groupCount + " groups in world " + world.getName() + ".");
|
||||
|
||||
@@ -157,12 +158,12 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
// Make a LuckPerms user for the one being migrated.
|
||||
plugin.getDatastore().loadUser(uuid, "null").getUnchecked();
|
||||
plugin.getStorage().loadUser(uuid, "null").join();
|
||||
me.lucko.luckperms.common.users.User lpUser = plugin.getUserManager().get(uuid);
|
||||
|
||||
migrateHolder(plugin, world, user, lpUser);
|
||||
|
||||
plugin.getDatastore().saveUser(lpUser);
|
||||
plugin.getStorage().saveUser(lpUser);
|
||||
plugin.getUserManager().cleanup(lpUser);
|
||||
}
|
||||
|
||||
+41
-37
@@ -20,15 +20,22 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.migration.subcommands;
|
||||
package me.lucko.luckperms.bukkit.migration;
|
||||
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.*;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.SubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import org.anjocaido.groupmanager.GlobalGroups;
|
||||
import org.anjocaido.groupmanager.GroupManager;
|
||||
import org.anjocaido.groupmanager.data.Group;
|
||||
@@ -36,19 +43,18 @@ import org.anjocaido.groupmanager.data.User;
|
||||
import org.anjocaido.groupmanager.dataholder.WorldDataHolder;
|
||||
import org.anjocaido.groupmanager.dataholder.worlds.WorldsHolder;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MigrationGroupManager extends SubCommand<Object> {
|
||||
public MigrationGroupManager() {
|
||||
super("groupmanager", "Migration from GroupManager", Permission.MIGRATION, Predicate.is(0),
|
||||
super("groupmanager", "Migration from GroupManager", Permission.MIGRATION, Predicates.is(0),
|
||||
Arg.list(Arg.create("world names...", false, "a list of worlds to migrate permissions from"))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) throws CommandException {
|
||||
final Logger log = plugin.getLog();
|
||||
if (!plugin.isPluginLoaded("GroupManager")) {
|
||||
log.severe("GroupManager Migration: Error -> GroupManager is not loaded.");
|
||||
@@ -63,17 +69,10 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
|
||||
// Migrate Global Groups
|
||||
log.info("GroupManager Migration: Starting Global Group migration.");
|
||||
|
||||
GlobalGroups gg;
|
||||
try {
|
||||
gg = (GlobalGroups) GroupManager.class.getMethod("getGlobalGroups").invoke(gm);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
GlobalGroups gg = GroupManager.getGlobalGroups();
|
||||
|
||||
for (Group g : gg.getGroupList()) {
|
||||
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase()).getUnchecked();
|
||||
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
|
||||
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
|
||||
try {
|
||||
LogEntry.build()
|
||||
@@ -121,33 +120,21 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveGroup(group);
|
||||
plugin.getStorage().saveGroup(group);
|
||||
}
|
||||
|
||||
Map<UUID, Map<Map.Entry<String, String>, Boolean>> users = new HashMap<>();
|
||||
Map<UUID, String> primaryGroups = new HashMap<>();
|
||||
Map<String, Map<Map.Entry<String, String>, Boolean>> groups = new HashMap<>();
|
||||
|
||||
WorldsHolder wh;
|
||||
try {
|
||||
wh = (WorldsHolder) GroupManager.class.getMethod("getWorldsHolder").invoke(gm);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
WorldsHolder wh = gm.getWorldsHolder();
|
||||
|
||||
// Collect data for all users and groups.
|
||||
log.info("GroupManager Migration: Starting user and group migration.");
|
||||
for (String world : worlds) {
|
||||
world = world.toLowerCase();
|
||||
|
||||
WorldDataHolder wdh;
|
||||
|
||||
try {
|
||||
wdh = (WorldDataHolder) WorldsHolder.class.getMethod("getWorldData", String.class).invoke(wh, world);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
WorldDataHolder wdh = wh.getWorldData(world);
|
||||
|
||||
for (Group g : wdh.getGroupList()) {
|
||||
groups.putIfAbsent(g.getName().toLowerCase(), new HashMap<>());
|
||||
@@ -193,7 +180,13 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
users.get(uuid).put(new AbstractMap.SimpleEntry<>(world, node), value);
|
||||
}
|
||||
|
||||
users.get(uuid).put(new AbstractMap.SimpleEntry<>(world, "group." + user.getGroupName().toLowerCase()), true);
|
||||
String finalWorld = world;
|
||||
users.get(uuid).putAll(user.subGroupListStringCopy().stream()
|
||||
.map(n -> "group." + n)
|
||||
.map(n -> new AbstractMap.SimpleEntry<>(finalWorld, n))
|
||||
.collect(Collectors.toMap(n -> n, n -> true))
|
||||
);
|
||||
primaryGroups.put(uuid, user.getGroupName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -202,7 +195,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
log.info("GroupManager Migration: Found a total of " + users.size() + " users and " + groups.size() + " groups.");
|
||||
|
||||
for (Map.Entry<String, Map<Map.Entry<String, String>, Boolean>> e : groups.entrySet()) {
|
||||
plugin.getDatastore().createAndLoadGroup(e.getKey()).getUnchecked();
|
||||
plugin.getStorage().createAndLoadGroup(e.getKey()).join();
|
||||
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(e.getKey());
|
||||
try {
|
||||
LogEntry.build()
|
||||
@@ -219,7 +212,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
// n.key.value = node
|
||||
// n.value = true/false
|
||||
try {
|
||||
group.setPermission("global-" + n.getKey().getKey() + "/" + n.getKey().getValue(), n.getValue());
|
||||
group.setPermission(NodeFactory.fromSerialisedNode("global-" + n.getKey().getKey() + "/" + n.getKey().getValue(), n.getValue()));
|
||||
|
||||
if (n.getKey().getValue().startsWith("group.")) {
|
||||
String groupName = n.getKey().getValue().substring(6);
|
||||
@@ -241,11 +234,11 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveGroup(group);
|
||||
plugin.getStorage().saveGroup(group);
|
||||
}
|
||||
|
||||
for (Map.Entry<UUID, Map<Map.Entry<String, String>, Boolean>> e : users.entrySet()) {
|
||||
plugin.getDatastore().loadUser(e.getKey(), "null").getUnchecked();
|
||||
plugin.getStorage().loadUser(e.getKey(), "null").join();
|
||||
me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(e.getKey());
|
||||
|
||||
for (Map.Entry<Map.Entry<String, String>, Boolean> n : e.getValue().entrySet()) {
|
||||
@@ -253,7 +246,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
// n.key.value = node
|
||||
// n.value = true/false
|
||||
try {
|
||||
user.setPermission("global-" + n.getKey().getKey() + "/" + n.getKey().getValue(), n.getValue());
|
||||
user.setPermission(NodeFactory.fromSerialisedNode("global-" + n.getKey().getKey() + "/" + n.getKey().getValue(), n.getValue()));
|
||||
|
||||
if (n.getKey().getValue().startsWith("group.")) {
|
||||
String group = n.getKey().getValue().substring(6);
|
||||
@@ -275,7 +268,18 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveUser(user);
|
||||
String primaryGroup = primaryGroups.get(e.getKey());
|
||||
if (primaryGroup != null) {
|
||||
try {
|
||||
user.setPermission("group." + primaryGroup, true);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
user.setPrimaryGroup(primaryGroup);
|
||||
try {
|
||||
user.unsetPermission("group.default");
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
}
|
||||
|
||||
plugin.getStorage().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
|
||||
+14
-16
@@ -20,18 +20,23 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.migration.subcommands;
|
||||
package me.lucko.luckperms.bukkit.migration;
|
||||
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.*;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.SubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.groups.Group;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import ru.tehkode.permissions.NativeInterface;
|
||||
import ru.tehkode.permissions.PermissionGroup;
|
||||
@@ -40,21 +45,20 @@ import ru.tehkode.permissions.PermissionUser;
|
||||
import ru.tehkode.permissions.bukkit.PermissionsEx;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
public MigrationPermissionsEx() {
|
||||
super("permissionsex", "Migration from PermissionsEx", Permission.MIGRATION, Predicate.alwaysFalse(),
|
||||
super("permissionsex", "Migration from PermissionsEx", Permission.MIGRATION, Predicates.alwaysFalse(),
|
||||
Arg.list(Arg.create("world names...", false, "a list of worlds to migrate permissions from"))
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) throws CommandException {
|
||||
final Logger log = plugin.getLog();
|
||||
if (!plugin.isPluginLoaded("PermissionsEx")) {
|
||||
log.severe("PermissionsEx Migration: Error -> PermissionsEx is not loaded.");
|
||||
@@ -72,13 +76,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
.collect(Collectors.toList());
|
||||
|
||||
PermissionsEx pex = (PermissionsEx) plugin.getPlugin("PermissionsEx");
|
||||
PermissionManager manager; // The compiler complains if you call the method directly, as Bukkit is not in this module.
|
||||
try {
|
||||
manager = (PermissionManager) PermissionsEx.class.getMethod("getPermissionsManager").invoke(pex);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
PermissionManager manager = pex.getPermissionsManager();
|
||||
|
||||
NativeInterface ni;
|
||||
try {
|
||||
@@ -102,7 +100,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
maxGroupWeight = Math.max(maxGroupWeight, groupWeight);
|
||||
|
||||
final String name = group.getName().toLowerCase();
|
||||
plugin.getDatastore().createAndLoadGroup(name).getUnchecked();
|
||||
plugin.getStorage().createAndLoadGroup(name).join();
|
||||
Group lpGroup = plugin.getGroupManager().get(name);
|
||||
try {
|
||||
LogEntry.build()
|
||||
@@ -226,7 +224,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveGroup(lpGroup);
|
||||
plugin.getStorage().saveGroup(lpGroup);
|
||||
|
||||
}
|
||||
|
||||
@@ -254,7 +252,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
userCount++;
|
||||
plugin.getDatastore().loadUser(u, "null").getUnchecked();
|
||||
plugin.getStorage().loadUser(u, "null").join();
|
||||
User lpUser = plugin.getUserManager().get(u);
|
||||
|
||||
try {
|
||||
@@ -387,7 +385,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
plugin.getUserManager().cleanup(lpUser);
|
||||
plugin.getDatastore().saveUser(lpUser);
|
||||
plugin.getStorage().saveUser(lpUser);
|
||||
}
|
||||
|
||||
log.info("PermissionsEx Migration: Migrated " + userCount + " users.");
|
||||
+15
-10
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.migration.subcommands;
|
||||
package me.lucko.luckperms.bukkit.migration;
|
||||
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.*;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
@@ -28,13 +28,18 @@ import com.zaxxer.hikari.HikariDataSource;
|
||||
import lombok.Cleanup;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.bukkit.migration.utils.LPResultRunnable;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.*;
|
||||
import me.lucko.luckperms.common.commands.migration.subcommands.utils.LPResultRunnable;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.SubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -116,7 +121,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
|
||||
|
||||
public MigrationPowerfulPerms() {
|
||||
super("powerfulperms", "Migration from PowerfulPerms", MIGRATION, Predicate.not(5),
|
||||
super("powerfulperms", "Migration from PowerfulPerms", MIGRATION, Predicates.not(5),
|
||||
Arg.list(
|
||||
Arg.create("address", true, "the address of the PP database"),
|
||||
Arg.create("database", true, "the name of the PP database"),
|
||||
@@ -128,7 +133,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) throws CommandException {
|
||||
try {
|
||||
return run(plugin, args);
|
||||
} catch (Throwable t) {
|
||||
@@ -246,7 +251,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
log.info("PowerfulPerms Migration: Starting group migration.");
|
||||
Map<Integer, Group> groups = pm.getGroups(); // All versions
|
||||
for (Group g : groups.values()) {
|
||||
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase()).getUnchecked();
|
||||
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
|
||||
final me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
|
||||
try {
|
||||
LogEntry.build()
|
||||
@@ -275,7 +280,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveGroup(group);
|
||||
plugin.getStorage().saveGroup(group);
|
||||
}
|
||||
log.info("PowerfulPerms Migration: Group migration complete.");
|
||||
|
||||
@@ -288,7 +293,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
progress.put(uuid, new CountDownLatch(2));
|
||||
|
||||
// Create a LuckPerms user for the UUID
|
||||
plugin.getDatastore().loadUser(uuid, "null").getUnchecked();
|
||||
plugin.getStorage().loadUser(uuid, "null").join();
|
||||
User user = plugin.getUserManager().get(uuid);
|
||||
|
||||
// Get a list of Permissions held by the user from the PP API.
|
||||
@@ -299,7 +304,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
synchronized (progress) {
|
||||
progress.get(uuid).countDown();
|
||||
if (progress.get(uuid).getCount() == 0) {
|
||||
plugin.getDatastore().saveUser(user);
|
||||
plugin.getStorage().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
}
|
||||
@@ -422,7 +427,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
synchronized (progress) {
|
||||
progress.get(uuid).countDown();
|
||||
if (progress.get(uuid).getCount() == 0) {
|
||||
plugin.getDatastore().saveUser(user);
|
||||
plugin.getStorage().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.migration;
|
||||
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.SubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.groups.Group;
|
||||
import me.lucko.luckperms.common.tracks.Track;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.ZPermissionsService;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.dao.PermissionService;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.EntityMetadata;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.Entry;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.Inheritance;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.PermissionEntity;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MigrationZPermissions extends SubCommand<Object> {
|
||||
public MigrationZPermissions() {
|
||||
super("zpermissions", "Migration from zPermissions", Permission.MIGRATION, Predicates.alwaysFalse(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) throws CommandException {
|
||||
final Logger log = plugin.getLog();
|
||||
if (!plugin.isPluginLoaded("zPermissions")) {
|
||||
log.severe("zPermissions Migration: Error -> zPermissions is not loaded.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
ZPermissionsService service = (ZPermissionsService) plugin.getService(ZPermissionsService.class);
|
||||
if (service == null) {
|
||||
log.severe("zPermissions Migration: Error -> zPermissions is not loaded.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
PermissionService internalService;
|
||||
|
||||
try {
|
||||
Field psField = service.getClass().getDeclaredField("permissionService");
|
||||
psField.setAccessible(true);
|
||||
internalService = (PermissionService) psField.get(service);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
// Migrate all groups
|
||||
log.info("zPermissions Migration: Starting group migration.");
|
||||
for (String g : service.getAllGroups()) {
|
||||
plugin.getStorage().createAndLoadGroup(g.toLowerCase()).join();
|
||||
Group group = plugin.getGroupManager().get(g.toLowerCase());
|
||||
|
||||
PermissionEntity entity = internalService.getEntity(g, null, true);
|
||||
migrateEntity(group, entity);
|
||||
|
||||
plugin.getStorage().saveGroup(group);
|
||||
}
|
||||
|
||||
// Migrate all tracks
|
||||
log.info("zPermissions Migration: Starting track migration.");
|
||||
for (String t : service.getAllTracks()) {
|
||||
plugin.getStorage().createAndLoadTrack(t.toLowerCase()).join();
|
||||
Track track = plugin.getTrackManager().get(t.toLowerCase());
|
||||
track.setGroups(service.getTrackGroups(t));
|
||||
plugin.getStorage().saveTrack(track);
|
||||
}
|
||||
|
||||
// Migrate all users.
|
||||
log.info("zPermissions Migration: Starting user migration.");
|
||||
for (UUID u : service.getAllPlayersUUID()) {
|
||||
plugin.getStorage().loadUser(u, "null").join();
|
||||
User user = plugin.getUserManager().get(u);
|
||||
|
||||
PermissionEntity entity = internalService.getEntity(null, u, false);
|
||||
migrateEntity(user, entity);
|
||||
|
||||
user.setPrimaryGroup(service.getPlayerPrimaryGroup(u));
|
||||
|
||||
plugin.getUserManager().cleanup(user);
|
||||
plugin.getStorage().saveUser(user);
|
||||
}
|
||||
|
||||
log.info("zPermissions Migration: Success! Completed without any errors.");
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private void migrateEntity(PermissionHolder group, PermissionEntity entity) {
|
||||
for (Entry e : entity.getPermissions()) {
|
||||
if (e.getWorld() != null) {
|
||||
try {
|
||||
group.setPermission(e.getPermission(), true, "global", e.getWorld().getName());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
} else {
|
||||
try {
|
||||
group.setPermission(e.getPermission(), true); // TODO handle negated.
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
for (Inheritance inheritance : entity.getInheritancesAsChild()) {
|
||||
if (!inheritance.getChild().getId().equals(entity.getId())) {
|
||||
new Throwable("Illegal inheritance").printStackTrace();
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
group.setPermission("group." + inheritance.getParent(), true);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
}
|
||||
|
||||
for (EntityMetadata metadata : entity.getMetadata()) {
|
||||
try {
|
||||
group.setPermission(NodeFactory.makeMetaNode(metadata.getName(), metadata.getStringValue()).build());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.migration.subcommands.utils;
|
||||
package me.lucko.luckperms.bukkit.migration.utils;
|
||||
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.ResultRunnable;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.model;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.permissions.Permission;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ChildPermissionProvider {
|
||||
|
||||
@Getter
|
||||
private ImmutableMap<Map.Entry<String, Boolean>, ImmutableMap<String, Boolean>> permissions = ImmutableMap.of();
|
||||
|
||||
public void setup() {
|
||||
ImmutableMap.Builder<Map.Entry<String, Boolean>, ImmutableMap<String, Boolean>> permissions = ImmutableMap.builder();
|
||||
|
||||
for (Permission permission : Bukkit.getServer().getPluginManager().getPermissions()) {
|
||||
// handle true
|
||||
Map<String, Boolean> children = new HashMap<>();
|
||||
resolveChildren(children, Collections.singletonMap(permission.getName(), true), false);
|
||||
permissions.put(Maps.immutableEntry(permission.getName().toLowerCase(), true), ImmutableMap.copyOf(children));
|
||||
|
||||
// handle false
|
||||
Map<String, Boolean> nChildren = new HashMap<>();
|
||||
resolveChildren(nChildren, Collections.singletonMap(permission.getName(), false), false);
|
||||
permissions.put(Maps.immutableEntry(permission.getName().toLowerCase(), false), ImmutableMap.copyOf(nChildren));
|
||||
}
|
||||
|
||||
this.permissions = permissions.build();
|
||||
}
|
||||
|
||||
private static void resolveChildren(Map<String, Boolean> accumulator, Map<String, Boolean> children, boolean invert) {
|
||||
for (Map.Entry<String, Boolean> e : children.entrySet()) {
|
||||
if (accumulator.containsKey(e.getKey())) {
|
||||
continue; // Prevent infinite loops
|
||||
}
|
||||
|
||||
Permission perm = Bukkit.getServer().getPluginManager().getPermission(e.getKey());
|
||||
boolean value = e.getValue() ^ invert;
|
||||
String lName = e.getKey().toLowerCase();
|
||||
|
||||
accumulator.put(lName, value);
|
||||
|
||||
if (perm != null) {
|
||||
resolveChildren(accumulator, perm.getChildren(), !value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.calculators;
|
||||
package me.lucko.luckperms.bukkit.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
@@ -102,6 +102,10 @@ public class DefaultsProvider {
|
||||
return b == null ? Tristate.UNDEFINED : Tristate.fromBoolean(b);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return op.size() + nonOp.size();
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private static class DummyPermissible implements Permissible {
|
||||
private final Runnable onRefresh;
|
||||
+3
-16
@@ -20,13 +20,12 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.inject;
|
||||
package me.lucko.luckperms.bukkit.model;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -67,7 +66,7 @@ public class LPPermissible extends PermissibleBase {
|
||||
|
||||
public Contexts calculateContexts() {
|
||||
return new Contexts(
|
||||
plugin.getContextManager().giveApplicableContext(parent, new MutableContextSet()),
|
||||
plugin.getContextManager().getApplicableContext(parent),
|
||||
plugin.getConfiguration().isIncludingGlobalPerms(),
|
||||
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
@@ -185,7 +184,7 @@ public class LPPermissible extends PermissibleBase {
|
||||
}
|
||||
|
||||
PermissionAttachment result = addAttachment(plugin);
|
||||
if (Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new RemoveAttachmentRunnable(result), ticks) == -1) {
|
||||
if (Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> result.remove(), ticks) == -1) {
|
||||
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add PermissionAttachment to " + parent + " for plugin " + plugin.getDescription().getFullName() + ": Scheduler returned -1");
|
||||
result.remove();
|
||||
return null;
|
||||
@@ -255,16 +254,4 @@ public class LPPermissible extends PermissibleBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class RemoveAttachmentRunnable implements Runnable {
|
||||
private PermissionAttachment attachment;
|
||||
|
||||
private RemoveAttachmentRunnable(PermissionAttachment attachment) {
|
||||
this.attachment = attachment;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
attachment.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,12 @@ import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.caching.MetaData;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.common.core.NodeBuilder;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.groups.Group;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import net.milkbowl.vault.chat.Chat;
|
||||
@@ -82,11 +85,8 @@ public class VaultChatHook extends Chat {
|
||||
perms.log("Setting meta: '" + node + "' for " + holder.getObjectName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
perms.getScheduler().scheduleTask(() -> {
|
||||
String k = escapeCharacters(node);
|
||||
String v = escapeCharacters(value);
|
||||
|
||||
List<Node> toRemove = holder.getNodes().stream()
|
||||
.filter(n -> n.isMeta() && n.getMeta().getKey().equals(k))
|
||||
.filter(n -> n.isMeta() && n.getMeta().getKey().equals(node))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
toRemove.forEach(n -> {
|
||||
@@ -95,7 +95,7 @@ public class VaultChatHook extends Chat {
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
Node.Builder metaNode = new me.lucko.luckperms.common.core.Node.Builder("meta." + k + "." + v).setValue(true);
|
||||
Node.Builder metaNode = NodeFactory.makeMetaNode(node, value).setValue(true);
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
metaNode.setServer(perms.getServer());
|
||||
}
|
||||
@@ -119,7 +119,7 @@ public class VaultChatHook extends Chat {
|
||||
perms.log("Setting " + (prefix ? "prefix" : "suffix") + " for " + holder.getObjectName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
perms.getScheduler().scheduleTask(() -> {
|
||||
Node.Builder node = new me.lucko.luckperms.common.core.Node.Builder(prefix ? "prefix" : "suffix" + ".1000." + escapeCharacters(value));
|
||||
Node.Builder node = new NodeBuilder(prefix ? "prefix" : "suffix" + ".1000." + escapeCharacters(value));
|
||||
node.setValue(true);
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
node.setServer(perms.getServer());
|
||||
@@ -215,7 +215,8 @@ public class VaultChatHook extends Chat {
|
||||
context.put("world", world);
|
||||
}
|
||||
|
||||
for (Node n : group.getAllNodes(null, new Contexts(ContextSet.fromMap(context), perms.isIncludeGlobal(), true, true, true, true, false))) {
|
||||
ExtractedContexts ec = ExtractedContexts.generate(new Contexts(ContextSet.fromMap(context), perms.isIncludeGlobal(), true, true, true, true, false));
|
||||
for (Node n : group.getAllNodes(null, ec)) {
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,11 @@ public class VaultHook {
|
||||
permissionHook.setPlugin(plugin);
|
||||
permissionHook.setServer(plugin.getConfiguration().getVaultServer());
|
||||
permissionHook.setIncludeGlobal(plugin.getConfiguration().isVaultIncludingGlobal());
|
||||
permissionHook.setIncludeGlobal(plugin.getConfiguration().isVaultIgnoreWorld());
|
||||
permissionHook.setIgnoreWorld(plugin.getConfiguration().isVaultIgnoreWorld());
|
||||
permissionHook.setPgo(plugin.getConfiguration().isVaultPrimaryGroupOverrides());
|
||||
permissionHook.setPgoCheckInherited(plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckInherited());
|
||||
permissionHook.setPgoCheckExists(plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckExists());
|
||||
permissionHook.setPgoCheckMemberOf(plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckMemberOf());
|
||||
permissionHook.setup();
|
||||
|
||||
if (chatHook == null) {
|
||||
|
||||
@@ -22,11 +22,15 @@
|
||||
|
||||
package me.lucko.luckperms.bukkit.vault;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.caching.PermissionData;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
@@ -43,33 +47,30 @@ import java.util.Map;
|
||||
* The LuckPerms Vault Permission implementation
|
||||
* Most lookups are cached.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class VaultPermissionHook extends Permission {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private LPBukkitPlugin plugin;
|
||||
|
||||
@Getter
|
||||
@Setter(value = AccessLevel.NONE)
|
||||
private VaultScheduler scheduler;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String server = "global";
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean includeGlobal = true;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean ignoreWorld = false;
|
||||
|
||||
// Primary Group override settings
|
||||
private boolean pgo = false;
|
||||
private boolean pgoCheckInherited = false;
|
||||
private boolean pgoCheckExists = true;
|
||||
private boolean pgoCheckMemberOf = true;
|
||||
|
||||
public void setup() {
|
||||
scheduler = new VaultScheduler(plugin);
|
||||
}
|
||||
|
||||
public void log(String s) {
|
||||
if (plugin.getConfiguration().isDebugPermissionChecks()) {
|
||||
if (plugin.getConfiguration().isVaultDebug()) {
|
||||
plugin.getLog().info("[VAULT] " + s);
|
||||
}
|
||||
}
|
||||
@@ -81,7 +82,7 @@ public class VaultPermissionHook extends Permission {
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return plugin.getDatastore().isAcceptingLogins();
|
||||
return plugin.getStorage().isAcceptingLogins();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,13 +132,12 @@ public class VaultPermissionHook extends Permission {
|
||||
*/
|
||||
void save(PermissionHolder holder) {
|
||||
if (holder instanceof User) {
|
||||
|
||||
plugin.getDatastore().saveUser(((User) holder), b -> {
|
||||
((User) holder).getRefreshBuffer().request();
|
||||
});
|
||||
plugin.getStorage().saveUser(((User) holder))
|
||||
.thenRunAsync(() -> ((User) holder).getRefreshBuffer().request(), plugin.getAsyncExecutor());
|
||||
}
|
||||
if (holder instanceof Group) {
|
||||
plugin.getDatastore().saveGroup(((Group) holder), b -> plugin.getUpdateTaskBuffer().request());
|
||||
plugin.getStorage().saveGroup(((Group) holder))
|
||||
.thenRunAsync(() -> plugin.getUpdateTaskBuffer().request(), plugin.getAsyncExecutor());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,9 +311,81 @@ public class VaultPermissionHook extends Permission {
|
||||
|
||||
@Override
|
||||
public String getPrimaryGroup(String world, @NonNull String player) {
|
||||
world = ignoreWorld ? null : world; // Correct world value
|
||||
log("Getting primary group of player: " + player);
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
return (user == null) ? null : user.getPrimaryGroup();
|
||||
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!pgo) {
|
||||
return user.getPrimaryGroup();
|
||||
}
|
||||
|
||||
if (pgoCheckInherited) {
|
||||
PermissionData data = user.getUserData().getPermissionData(createContext(server, world));
|
||||
for (Map.Entry<String, Boolean> e : data.getImmutableBacking().entrySet()) {
|
||||
if (!e.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!e.getKey().toLowerCase().startsWith("vault.primarygroup.")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String group = e.getKey().substring("vault.primarygroup.".length());
|
||||
if (pgoCheckExists) {
|
||||
if (!plugin.getGroupManager().isLoaded(group)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pgoCheckMemberOf) {
|
||||
if (data.getPermissionValue("group." + group) != Tristate.TRUE) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
} else {
|
||||
for (LocalizedNode node : user.getPermissions(true)) {
|
||||
if (!node.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!node.getPermission().toLowerCase().startsWith("vault.primarygroup.")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!node.shouldApplyOnServer(server, isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!node.shouldApplyOnWorld(world, true, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String group = node.getPermission().substring("vault.primarygroup.".length());
|
||||
if (pgoCheckExists) {
|
||||
if (!plugin.getGroupManager().isLoaded(group)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pgoCheckMemberOf) {
|
||||
if (!user.getLocalGroups(server, world, isIncludeGlobal()).contains(group.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback
|
||||
return user.getPrimaryGroup();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -46,9 +46,6 @@ online-mode: 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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -70,6 +67,11 @@ apply-regex: true
|
||||
# If set to true, LuckPerms will detect and expand shorthand node patterns.
|
||||
apply-shorthand: true
|
||||
|
||||
# Define special group weights for this server.
|
||||
# Default is just 0.
|
||||
group-weight:
|
||||
# admin: 10
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -112,6 +114,22 @@ vault-include-global: true
|
||||
# If Vault operations should ignore any world arguments if supplied.
|
||||
vault-ignore-world: false
|
||||
|
||||
# This block controls the Primary Group override feature
|
||||
# See the wiki for more information.
|
||||
vault-primary-groups-overrides:
|
||||
# If the feature is enabled
|
||||
enabled: false
|
||||
# If the check should query the user's inherited permissions.
|
||||
# (a value of false only checks the permissions they explicitly have)
|
||||
check-inherited-permissions: false
|
||||
# If LuckPerms should check if the group exists
|
||||
check-group-exists: true
|
||||
# If LuckPerms should check if the user is actually a member of the group
|
||||
check-user-member-of: true
|
||||
|
||||
# If LuckPerms should print debugging info to console when a plugin uses a Vault function
|
||||
vault-debug: false
|
||||
|
||||
# Mirrors world names. Whenever LuckPerms checks what world a user is in, if the world name is in this list, the value assigned
|
||||
# will be sent forward for permission calculation instead.
|
||||
world-rewrite:
|
||||
@@ -155,6 +173,19 @@ data:
|
||||
# e.g. if you're using sqlite or flatfile, this can be set to -1 to save resources.
|
||||
sync-minutes: 3
|
||||
|
||||
# Settings for Redis.
|
||||
#
|
||||
# If enabled and configured, LuckPerms will use the Redis PubSub system to inform other
|
||||
# connected servers of changes. Use the command "/luckperms networksync" to push changes.
|
||||
# Data is NOT stored on redis. It is only used as a messaging platform.
|
||||
#
|
||||
# If you decide to enable this feature, you should set "sync-minutes" to -1, as there is no need for LuckPerms
|
||||
# to poll the database for changes.
|
||||
redis:
|
||||
enabled: false
|
||||
address: localhost:6379
|
||||
password: ''
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,12 @@ author: Luck
|
||||
website: https://github.com/lucko/LuckPerms
|
||||
|
||||
main: me.lucko.luckperms.bukkit.LPBukkitPlugin
|
||||
softdepend: [Vault, PermissionsEx, GroupManager, PowerfulPerms, zPermissions, bPermissions] # For migration
|
||||
load: STARTUP
|
||||
|
||||
# This means that all plugins that (soft-)depend on Vault, depend on LuckPerms too.
|
||||
# It in turn fixes issues where plugins using Vault cache the provided instance when their plugin enables, or
|
||||
# when they check for the presence of a service provider, before LuckPerms has enabled.
|
||||
loadbefore: [Vault]
|
||||
|
||||
commands:
|
||||
luckperms:
|
||||
@@ -13,4 +18,5 @@ commands:
|
||||
aliases: [perms, permissions, lp, p, perm]
|
||||
|
||||
|
||||
# Permissions are registered programmatically instead of here.
|
||||
# Permissions are registered programmatically instead of here.
|
||||
# See: the last method in me.lucko.luckperms.bukkit.LPBukkitPlugin
|
||||
+20
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<version>2.15-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -69,6 +69,18 @@
|
||||
<pattern>org.sqlite</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.sqlite</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.jedis</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.jedis</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>redis.clients.util</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.util</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.apache.commons.pool2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.jedis.pool2</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
@@ -121,6 +133,13 @@
|
||||
<version>1.16.10</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- **************Migration Plugins************** -->
|
||||
<dependency>
|
||||
<groupId>net.alpenblock</groupId>
|
||||
<artifactId>BungeePerms</artifactId>
|
||||
<version>3.0-dev-52</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -22,30 +22,32 @@
|
||||
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.common.calculators.*;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.calculators.PermissionCalculator;
|
||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||
import me.lucko.luckperms.common.calculators.processors.MapProcessor;
|
||||
import me.lucko.luckperms.common.calculators.processors.RegexProcessor;
|
||||
import me.lucko.luckperms.common.calculators.processors.WildcardProcessor;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BungeeCalculatorFactory implements CalculatorFactory {
|
||||
private final LPBungeePlugin plugin;
|
||||
|
||||
@Override
|
||||
public PermissionCalculator build(Contexts contexts, User user, Map<String, Boolean> map) {
|
||||
List<PermissionProcessor> processors = new ArrayList<>(3);
|
||||
processors.add(new MapProcessor(map));
|
||||
public PermissionCalculator build(Contexts contexts, User user) {
|
||||
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
|
||||
processors.add(new MapProcessor());
|
||||
if (plugin.getConfiguration().isApplyingWildcards()) {
|
||||
processors.add(new WildcardProcessor(map));
|
||||
processors.add(new WildcardProcessor());
|
||||
}
|
||||
if (plugin.getConfiguration().isApplyingRegex()) {
|
||||
processors.add(new RegexProcessor(map));
|
||||
processors.add(new RegexProcessor());
|
||||
}
|
||||
|
||||
return new PermissionCalculator(plugin, user.getName(), plugin.getConfiguration().isDebugPermissionChecks(), processors);
|
||||
return new PermissionCalculator(plugin, user.getName(), processors.build());
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,8 @@ package me.lucko.luckperms.bungee;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.common.commands.CommandManager;
|
||||
import me.lucko.luckperms.common.commands.Util;
|
||||
import me.lucko.luckperms.common.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Patterns;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
@@ -35,25 +34,27 @@ import net.md_5.bungee.api.plugin.TabExecutor;
|
||||
import java.util.Arrays;
|
||||
|
||||
class BungeeCommand extends Command implements TabExecutor {
|
||||
private final LPBungeePlugin plugin;
|
||||
private final CommandManager manager;
|
||||
|
||||
BungeeCommand(CommandManager manager) {
|
||||
BungeeCommand(LPBungeePlugin plugin, CommandManager manager) {
|
||||
super("luckpermsbungee", null, "bperms", "lpb", "bpermissions", "bp", "bperm");
|
||||
this.plugin = plugin;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
manager.onCommand(
|
||||
BungeeSenderFactory.get(manager.getPlugin()).wrap(sender),
|
||||
plugin.getSenderFactory().wrap(sender),
|
||||
"bperms",
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))),
|
||||
Callback.empty()
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args) {
|
||||
return manager.onTabComplete(BungeeSenderFactory.get(manager.getPlugin()).wrap(sender), Arrays.asList(args));
|
||||
return manager.onTabComplete(plugin.getSenderFactory().wrap(sender), Arrays.asList(args));
|
||||
}
|
||||
}
|
||||
@@ -23,10 +23,10 @@
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.api.event.events.UserFirstLoginEvent;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.core.UuidCache;
|
||||
import me.lucko.luckperms.common.defaults.Rule;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.utils.AbstractListener;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
@@ -38,6 +38,7 @@ import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import net.md_5.bungee.event.EventPriority;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -72,7 +73,7 @@ public class BungeeListener extends AbstractListener implements Listener {
|
||||
}
|
||||
|
||||
Contexts contexts = new Contexts(
|
||||
plugin.getContextManager().giveApplicableContext(player, MutableContextSet.empty()),
|
||||
plugin.getContextManager().getApplicableContext(player),
|
||||
plugin.getConfiguration().isIncludingGlobalPerms(),
|
||||
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
@@ -84,7 +85,7 @@ public class BungeeListener extends AbstractListener implements Listener {
|
||||
e.setHasPermission(user.getUserData().getPermissionData(contexts).getPermissionValue(e.getPermission()).asBoolean());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerLogin(LoginEvent e) {
|
||||
/* Delay the login here, as we want to cache UUID data before the player is connected to a backend bukkit server.
|
||||
This means that a player will have the same UUID across the network, even if parts of the network are running in
|
||||
@@ -96,32 +97,45 @@ public class BungeeListener extends AbstractListener implements Listener {
|
||||
final PendingConnection c = e.getConnection();
|
||||
|
||||
if (!cache.isOnlineMode()) {
|
||||
UUID uuid = plugin.getDatastore().getUUID(c.getName()).getUnchecked();
|
||||
UUID uuid = plugin.getStorage().getUUID(c.getName()).join();
|
||||
if (uuid != null) {
|
||||
cache.addToCache(c.getUniqueId(), uuid);
|
||||
} else {
|
||||
// No previous data for this player
|
||||
plugin.getApiProvider().fireEventAsync(new UserFirstLoginEvent(c.getUniqueId(), c.getName()));
|
||||
cache.addToCache(c.getUniqueId(), c.getUniqueId());
|
||||
plugin.getDatastore().force().saveUUIDData(c.getName(), c.getUniqueId()).getUnchecked();
|
||||
plugin.getStorage().force().saveUUIDData(c.getName(), c.getUniqueId()).join();
|
||||
}
|
||||
} else {
|
||||
UUID uuid = plugin.getDatastore().getUUID(c.getName()).getUnchecked();
|
||||
UUID uuid = plugin.getStorage().getUUID(c.getName()).join();
|
||||
if (uuid == null) {
|
||||
plugin.getApiProvider().fireEventAsync(new UserFirstLoginEvent(c.getUniqueId(), c.getName()));
|
||||
}
|
||||
|
||||
// Online mode, no cache needed. This is just for name -> uuid lookup.
|
||||
plugin.getDatastore().force().saveUUIDData(c.getName(), c.getUniqueId()).getUnchecked();
|
||||
plugin.getStorage().force().saveUUIDData(c.getName(), c.getUniqueId()).join();
|
||||
}
|
||||
|
||||
// We have to make a new user on this thread whilst the connection is being held, or we get concurrency issues as the Bukkit server
|
||||
// and the BungeeCord server try to make a new user at the same time.
|
||||
plugin.getDatastore().force().loadUser(cache.getUUID(c.getUniqueId()), c.getName()).getUnchecked();
|
||||
plugin.getStorage().force().loadUser(cache.getUUID(c.getUniqueId()), c.getName()).join();
|
||||
User user = plugin.getUserManager().get(cache.getUUID(c.getUniqueId()));
|
||||
if (user == null) {
|
||||
plugin.getLog().warn("Failed to load user: " + c.getName());
|
||||
} else {
|
||||
// Setup defaults for the user
|
||||
boolean save = false;
|
||||
for (Rule rule : plugin.getConfiguration().getDefaultAssignments()) {
|
||||
if (rule.apply(user)) {
|
||||
save = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If they were given a default, persist the new assignments back to the storage.
|
||||
if (save) {
|
||||
plugin.getStorage().force().saveUser(user).join();
|
||||
}
|
||||
|
||||
user.setupData(false); // Pretty nasty calculation call. Sets up the caching system so data is ready when the user joins.
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.SenderFactory;
|
||||
import me.lucko.luckperms.common.commands.sender.SenderFactory;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
@@ -32,19 +32,10 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeSenderFactory extends SenderFactory<CommandSender> {
|
||||
private static BungeeSenderFactory instance = null;
|
||||
|
||||
private BungeeSenderFactory(LuckPermsPlugin plugin) {
|
||||
public BungeeSenderFactory(LuckPermsPlugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
public static synchronized BungeeSenderFactory get(LuckPermsPlugin plugin) {
|
||||
if (instance == null) {
|
||||
instance = new BungeeSenderFactory(plugin);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName(CommandSender sender) {
|
||||
if (sender instanceof ProxiedPlayer) {
|
||||
|
||||
@@ -34,21 +34,23 @@ import me.lucko.luckperms.common.api.ApiProvider;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.CommandManager;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.config.LPConfiguration;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.contexts.ContextManager;
|
||||
import me.lucko.luckperms.common.contexts.ServerCalculator;
|
||||
import me.lucko.luckperms.common.core.UuidCache;
|
||||
import me.lucko.luckperms.common.data.Importer;
|
||||
import me.lucko.luckperms.common.groups.GroupManager;
|
||||
import me.lucko.luckperms.common.runnables.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.common.runnables.UpdateTask;
|
||||
import me.lucko.luckperms.common.storage.Datastore;
|
||||
import me.lucko.luckperms.common.messaging.RedisMessaging;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
import me.lucko.luckperms.common.storage.StorageFactory;
|
||||
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.common.tasks.UpdateTask;
|
||||
import me.lucko.luckperms.common.tracks.TrackManager;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.users.UserManager;
|
||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||
import me.lucko.luckperms.common.utils.DebugHandler;
|
||||
import me.lucko.luckperms.common.utils.LocaleManager;
|
||||
import me.lucko.luckperms.common.utils.LogFactory;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
@@ -56,19 +58,26 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
private Executor executor;
|
||||
|
||||
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
|
||||
private LPConfiguration configuration;
|
||||
private UserManager userManager;
|
||||
private GroupManager groupManager;
|
||||
private TrackManager trackManager;
|
||||
private Datastore datastore;
|
||||
private Storage storage;
|
||||
private RedisMessaging redisMessaging = null;
|
||||
private UuidCache uuidCache;
|
||||
private ApiProvider apiProvider;
|
||||
private Logger log;
|
||||
@@ -78,14 +87,48 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
private ContextManager<ProxiedPlayer> contextManager;
|
||||
private CalculatorFactory calculatorFactory;
|
||||
private BufferedRequest<Void> updateTaskBuffer;
|
||||
private DebugHandler debugHandler;
|
||||
private BungeeSenderFactory senderFactory;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
executor = r -> getProxy().getScheduler().runAsync(this, r);
|
||||
log = LogFactory.wrap(getLogger());
|
||||
debugHandler = new DebugHandler();
|
||||
senderFactory = new BungeeSenderFactory(this);
|
||||
|
||||
getLog().info("Loading configuration...");
|
||||
configuration = new BungeeConfig(this);
|
||||
|
||||
// register events
|
||||
getProxy().getPluginManager().registerListener(this, new BungeeListener(this));
|
||||
|
||||
// initialise datastore
|
||||
storage = StorageFactory.getInstance(this, "h2");
|
||||
|
||||
// initialise redis
|
||||
if (getConfiguration().isRedisEnabled()) {
|
||||
getLog().info("Loading redis...");
|
||||
redisMessaging = new RedisMessaging(this);
|
||||
try {
|
||||
redisMessaging.init(getConfiguration().getRedisAddress(), getConfiguration().getRedisPassword());
|
||||
getLog().info("Loaded redis successfully...");
|
||||
} catch (Exception e) {
|
||||
getLog().info("Couldn't load redis...");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// setup the update task buffer
|
||||
updateTaskBuffer = new BufferedRequest<Void>(1000L, this::doAsync) {
|
||||
@Override
|
||||
protected Void perform() {
|
||||
new UpdateTask(LPBungeePlugin.this).run();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// load locale
|
||||
localeManager = new LocaleManager();
|
||||
File locale = new File(getDataFolder(), "lang.yml");
|
||||
if (locale.exists()) {
|
||||
@@ -97,19 +140,15 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
// register events
|
||||
getProxy().getPluginManager().registerListener(this, new BungeeListener(this));
|
||||
|
||||
// register commands
|
||||
getLog().info("Registering commands...");
|
||||
CommandManager commandManager = new CommandManager(this);
|
||||
getProxy().getPluginManager().registerCommand(this, new BungeeCommand(commandManager));
|
||||
getProxy().getPluginManager().registerCommand(this, new BungeeCommand(this, commandManager));
|
||||
|
||||
// disable the default Bungee /perms command so it gets handled by the Bukkit plugin
|
||||
getProxy().getDisabledCommands().add("perms");
|
||||
|
||||
datastore = StorageFactory.getDatastore(this, "h2");
|
||||
|
||||
// load internal managers
|
||||
getLog().info("Loading internal permission managers...");
|
||||
uuidCache = new UuidCache(getConfiguration().isOnlineMode());
|
||||
userManager = new UserManager(this);
|
||||
@@ -125,40 +164,36 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
contextManager.registerCalculator(serverCalculator);
|
||||
contextManager.registerCalculator(new ServerCalculator<>(getConfiguration().getServer()));
|
||||
|
||||
final LPBungeePlugin i = this;
|
||||
updateTaskBuffer = new BufferedRequest<Void>(6000L, this::doAsync) {
|
||||
@Override
|
||||
protected Void perform() {
|
||||
doAsync(new UpdateTask(i));
|
||||
return null;
|
||||
}
|
||||
};
|
||||
// register with the LP API
|
||||
getLog().info("Registering API...");
|
||||
apiProvider = new ApiProvider(this);
|
||||
ApiHandler.registerProvider(apiProvider);
|
||||
|
||||
// schedule update tasks
|
||||
int mins = getConfiguration().getSyncTime();
|
||||
if (mins > 0) {
|
||||
getProxy().getScheduler().schedule(this, new UpdateTask(this), mins, mins, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
// 20 times per second (once per "tick")
|
||||
getProxy().getScheduler().schedule(this, BungeeSenderFactory.get(this), 50L, 50L, TimeUnit.MILLISECONDS);
|
||||
// run an update instantly.
|
||||
updateTaskBuffer.requestDirectly();
|
||||
|
||||
// register tasks
|
||||
getProxy().getScheduler().schedule(this, new ExpireTemporaryTask(this), 3L, 3L, TimeUnit.SECONDS);
|
||||
getProxy().getScheduler().schedule(this, consecutiveExecutor, 1L, 1L, TimeUnit.SECONDS);
|
||||
|
||||
getLog().info("Registering API...");
|
||||
apiProvider = new ApiProvider(this);
|
||||
ApiHandler.registerProvider(apiProvider);
|
||||
|
||||
// Run update task to refresh any online users
|
||||
getLog().info("Scheduling Update Task to refresh any online users.");
|
||||
updateTaskBuffer.request();
|
||||
|
||||
getLog().info("Successfully loaded.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
getLog().info("Closing datastore...");
|
||||
datastore.shutdown();
|
||||
storage.shutdown();
|
||||
|
||||
if (redisMessaging != null) {
|
||||
getLog().info("Closing redis...");
|
||||
redisMessaging.shutdown();
|
||||
}
|
||||
|
||||
getLog().info("Unregistering API...");
|
||||
ApiHandler.unregisterProvider();
|
||||
@@ -179,6 +214,28 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
return getDataFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxiedPlayer getPlayer(User user) {
|
||||
return getProxy().getPlayer(uuidCache.getExternalUUID(user.getUuid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Contexts getContextForUser(User user) {
|
||||
ProxiedPlayer player = getPlayer(user);
|
||||
if (player == null) {
|
||||
return null;
|
||||
}
|
||||
return new Contexts(
|
||||
getContextManager().getApplicableContext(player),
|
||||
getConfiguration().isIncludingGlobalPerms(),
|
||||
getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
getConfiguration().isApplyingGlobalGroups(),
|
||||
getConfiguration().isApplyingGlobalWorldGroups(),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerCount() {
|
||||
return getProxy().getOnlineCount();
|
||||
@@ -200,16 +257,15 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Sender> getNotifyListeners() {
|
||||
public List<Sender> getSenders() {
|
||||
return getProxy().getPlayers().stream()
|
||||
.map(p -> BungeeSenderFactory.get(this).wrap(p, Collections.singleton(Permission.LOG_NOTIFY)))
|
||||
.filter(Permission.LOG_NOTIFY::isAuthorized)
|
||||
.map(p -> getSenderFactory().wrap(p))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sender getConsoleSender() {
|
||||
return BungeeSenderFactory.get(this).wrap(getProxy().getConsole());
|
||||
return getSenderFactory().wrap(getProxy().getConsole());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -271,7 +327,17 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
|
||||
@Override
|
||||
public void doSync(Runnable r) {
|
||||
r.run();
|
||||
doAsync(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getSyncExecutor() {
|
||||
return executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getAsyncExecutor() {
|
||||
return executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+11
-10
@@ -20,18 +20,19 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.migration.subcommands;
|
||||
package me.lucko.luckperms.bungee.migration;
|
||||
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.SubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import net.alpenblock.bungeeperms.*;
|
||||
|
||||
@@ -43,11 +44,11 @@ import java.util.Map;
|
||||
*/
|
||||
public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
public MigrationBungeePerms() {
|
||||
super("bungeeperms", "Migration from BungeePerms", Permission.MIGRATION, Predicate.alwaysFalse(), null);
|
||||
super("bungeeperms", "Migration from BungeePerms", Permission.MIGRATION, Predicates.alwaysFalse(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) throws CommandException {
|
||||
final Logger log = plugin.getLog();
|
||||
|
||||
BungeePerms bp = BungeePerms.getInstance();
|
||||
@@ -60,10 +61,10 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
log.info("BungeePerms Migration: Starting group migration.");
|
||||
int groupCount = 0;
|
||||
for (Group g : bp.getPermissionsManager().getBackEnd().loadGroups()) {
|
||||
groupCount ++;
|
||||
groupCount++;
|
||||
|
||||
// Make a LuckPerms group for the one being migrated
|
||||
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase()).getUnchecked();
|
||||
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
|
||||
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
|
||||
try {
|
||||
LogEntry.build()
|
||||
@@ -173,7 +174,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveGroup(group);
|
||||
plugin.getStorage().saveGroup(group);
|
||||
}
|
||||
|
||||
log.info("BungeePerms Migration: Migrated " + groupCount + " groups");
|
||||
@@ -187,7 +188,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
userCount++;
|
||||
|
||||
// Make a LuckPerms user for the one being migrated.
|
||||
plugin.getDatastore().loadUser(u.getUUID(), "null").getUnchecked();
|
||||
plugin.getStorage().loadUser(u.getUUID(), "null").join();
|
||||
me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(u.getUUID());
|
||||
|
||||
// Migrate global perms
|
||||
@@ -288,7 +289,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveUser(user);
|
||||
plugin.getStorage().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
|
||||
@@ -46,9 +46,6 @@ online-mode: 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
|
||||
|
||||
# Mirrors world names. Whenever LuckPerms checks what world a user is in, if the world name is in this list, the value assigned
|
||||
# will be sent forward for permission calculation instead.
|
||||
world-rewrite:
|
||||
@@ -80,6 +77,11 @@ apply-regex: true
|
||||
# If set to true, LuckPerms will detect and expand shorthand node patterns.
|
||||
apply-shorthand: true
|
||||
|
||||
# Define special group weights for this server.
|
||||
# Default is just 0.
|
||||
group-weight:
|
||||
# admin: 10
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -113,6 +115,19 @@ data:
|
||||
# e.g. if you're using sqlite or flatfile, this can be set to -1 to save resources.
|
||||
sync-minutes: 3
|
||||
|
||||
# Settings for Redis.
|
||||
#
|
||||
# If enabled and configured, LuckPerms will use the Redis PubSub system to inform other
|
||||
# connected servers of changes. Use the command "/luckpermsbungee networksync" to push changes.
|
||||
# Data is NOT stored on redis. It is only used as a messaging platform.
|
||||
#
|
||||
# If you decide to enable this feature, you should set "sync-minutes" to -1, as there is no need for LuckPerms
|
||||
# to poll the database for changes.
|
||||
redis:
|
||||
enabled: false
|
||||
address: localhost:6379
|
||||
password: ''
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+8
-48
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<version>2.15-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -39,6 +39,13 @@
|
||||
<version>2.5.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- Jedis -->
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>2.8.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- SQLite -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
@@ -95,53 +102,6 @@
|
||||
<version>1.16.10</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- **************Migration Plugins************** -->
|
||||
<dependency>
|
||||
<groupId>org.tyrannyofheaven.bukkit</groupId>
|
||||
<artifactId>zPermissions</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.tehkode</groupId>
|
||||
<artifactId>PermissionsEx</artifactId>
|
||||
<version>1.23</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.gravitydevelopment.updater</groupId>
|
||||
<artifactId>updater</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.cheesesoftware</groupId>
|
||||
<artifactId>PowerfulPermsAPI</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.anjocaido</groupId>
|
||||
<artifactId>GroupManager</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.alpenblock</groupId>
|
||||
<artifactId>BungeePerms</artifactId>
|
||||
<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>
|
||||
@@ -27,64 +27,168 @@ import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.common.api.ApiProvider;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.BaseCommand;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.config.LPConfiguration;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.contexts.ContextManager;
|
||||
import me.lucko.luckperms.common.core.UuidCache;
|
||||
import me.lucko.luckperms.common.data.Importer;
|
||||
import me.lucko.luckperms.common.groups.GroupManager;
|
||||
import me.lucko.luckperms.common.storage.Datastore;
|
||||
import me.lucko.luckperms.common.messaging.RedisMessaging;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
import me.lucko.luckperms.common.tracks.TrackManager;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.users.UserManager;
|
||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||
import me.lucko.luckperms.common.utils.DebugHandler;
|
||||
import me.lucko.luckperms.common.utils.LocaleManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Main internal interface for LuckPerms plugins, allowing the luckperms-common module to bind with the plugin instance.
|
||||
* Main internal interface for LuckPerms plugins, providing the base for abstraction throughout the project.
|
||||
*
|
||||
* All plugin platforms implement this interface.
|
||||
*/
|
||||
public interface LuckPermsPlugin {
|
||||
|
||||
/*
|
||||
* Access to all of the main internal manager classes
|
||||
/**
|
||||
* Gets the user manager instance for the platform
|
||||
* @return the user manager
|
||||
*/
|
||||
UserManager getUserManager();
|
||||
|
||||
/**
|
||||
* Gets the group manager instance for the platform
|
||||
* @return the group manager
|
||||
*/
|
||||
GroupManager getGroupManager();
|
||||
|
||||
/**
|
||||
* Gets the track manager instance for the platform
|
||||
* @return the track manager
|
||||
*/
|
||||
TrackManager getTrackManager();
|
||||
|
||||
/**
|
||||
* Gets the plugin's configuration
|
||||
* @return the plugin config
|
||||
*/
|
||||
LPConfiguration getConfiguration();
|
||||
Datastore getDatastore();
|
||||
|
||||
/**
|
||||
* Gets the primary data storage instance. This is likely to be wrapped with extra layers for caching, etc.
|
||||
* @return the storage handler instance
|
||||
*/
|
||||
Storage getStorage();
|
||||
|
||||
/**
|
||||
* Gets the redis messaging instance if present. Could return null if redis is not enabled.
|
||||
* @return the redis messaging service
|
||||
*/
|
||||
RedisMessaging getRedisMessaging();
|
||||
|
||||
/**
|
||||
* Gets a wrapped logger instance for the platform.
|
||||
* @return the plugin's logger
|
||||
*/
|
||||
Logger getLog();
|
||||
|
||||
/**
|
||||
* Gets the UUID caching store for the platform
|
||||
* @return the uuid cache
|
||||
*/
|
||||
UuidCache getUuidCache();
|
||||
|
||||
/**
|
||||
* Returns the class implementing the LuckPermsAPI on this platform.
|
||||
* @return the api
|
||||
*/
|
||||
ApiProvider getApiProvider();
|
||||
|
||||
/**
|
||||
* Gets the importer instance
|
||||
* @return the importer
|
||||
*/
|
||||
Importer getImporter();
|
||||
|
||||
/**
|
||||
* Gets the consecutive command executor instance
|
||||
* @return the consecutive executor
|
||||
*/
|
||||
ConsecutiveExecutor getConsecutiveExecutor();
|
||||
|
||||
/**
|
||||
* Gets the instance providing locale translations for the plugin
|
||||
* @return the locale manager
|
||||
*/
|
||||
LocaleManager getLocaleManager();
|
||||
|
||||
/**
|
||||
* Gets the context manager.
|
||||
* This object handles context accumulation for all players on the platform.
|
||||
* @return the context manager
|
||||
*/
|
||||
ContextManager getContextManager();
|
||||
|
||||
/**
|
||||
* Gets the class responsible for constructing PermissionCalculators on this platform.
|
||||
* @return the permission calculator factory
|
||||
*/
|
||||
CalculatorFactory getCalculatorFactory();
|
||||
|
||||
/**
|
||||
* Gets the verbose debug handler instance.
|
||||
* @return the debug handler instance
|
||||
*/
|
||||
DebugHandler getDebugHandler();
|
||||
|
||||
/**
|
||||
* Execute a runnable asynchronously
|
||||
* @param r the task to run
|
||||
*/
|
||||
void doAsync(Runnable r);
|
||||
|
||||
/**
|
||||
* Execute a runnable synchronously
|
||||
* @param r the task to run
|
||||
*/
|
||||
void doSync(Runnable r);
|
||||
|
||||
Executor getSyncExecutor();
|
||||
Executor getAsyncExecutor();
|
||||
|
||||
/**
|
||||
* Execute a runnable asynchronously on a loop
|
||||
* @param r the task to run
|
||||
* @param interval the time between runs in ticks
|
||||
*/
|
||||
void doAsyncRepeating(Runnable r, long interval);
|
||||
|
||||
/**
|
||||
* Gets a string of the plugin's version
|
||||
* @return the version of the plugin
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* Gets the platform type this instance of LuckPerms is running on.
|
||||
* @return the platform type
|
||||
*/
|
||||
PlatformType getType();
|
||||
|
||||
/**
|
||||
* Gets the plugins main directory
|
||||
* @return the main plugin directory
|
||||
*/
|
||||
File getMainDir();
|
||||
|
||||
/**
|
||||
* Gets the plugins main data storage directory
|
||||
* @return the platforms data folder
|
||||
*/
|
||||
File getDataFolder();
|
||||
@@ -99,6 +203,21 @@ public interface LuckPermsPlugin {
|
||||
return isOnline(external) ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a player object linked to this User. The returned object must be the same type
|
||||
* as the instance used in the platforms {@link ContextManager}
|
||||
* @param user the user instance
|
||||
* @return a player object, or null, if one couldn't be found.
|
||||
*/
|
||||
Object getPlayer(User user);
|
||||
|
||||
/**
|
||||
* Gets a calculated context instance for the user using the rules of the platform.
|
||||
* @param user the user instance
|
||||
* @return a contexts object, or null if one couldn't be generated
|
||||
*/
|
||||
Contexts getContextForUser(User user);
|
||||
|
||||
/**
|
||||
* Gets the number of users online on the platform
|
||||
* @return the number of users
|
||||
@@ -125,11 +244,13 @@ public interface LuckPermsPlugin {
|
||||
boolean isOnline(UUID external);
|
||||
|
||||
/**
|
||||
* Gets a list of online Senders on the platform
|
||||
* @return a {@link List} of senders online on the platform
|
||||
*/
|
||||
List<Sender> getNotifyListeners();
|
||||
List<Sender> getSenders();
|
||||
|
||||
/**
|
||||
* Gets the console.
|
||||
* @return the console sender of the instance
|
||||
*/
|
||||
Sender getConsoleSender();
|
||||
@@ -141,9 +262,21 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
Set<Contexts> getPreProcessContexts(boolean op);
|
||||
|
||||
default List<BaseCommand> getExtraCommands() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a map of extra information to be shown in the info command
|
||||
* @return a map of options, or null
|
||||
*/
|
||||
default LinkedHashMap<String, Object> getExtraInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a set of players ignoring logging output
|
||||
* @return a {@link Set} of uuids
|
||||
* @return a {@link Set} of {@link UUID}s
|
||||
*/
|
||||
Set<UUID> getIgnoringLogs();
|
||||
|
||||
@@ -162,7 +295,7 @@ public interface LuckPermsPlugin {
|
||||
Object getService(Class clazz);
|
||||
|
||||
/**
|
||||
* Used as a backup for migration
|
||||
* Gets the UUID of a player. Used as a backup for migration
|
||||
* @param playerName the players name
|
||||
* @return a uuid if found, or null if not
|
||||
*/
|
||||
@@ -176,27 +309,9 @@ public interface LuckPermsPlugin {
|
||||
boolean isPluginLoaded(String name);
|
||||
|
||||
/**
|
||||
* Runs an update task
|
||||
* Gets the update task buffer of the platform, used for scheduling and running update tasks.
|
||||
* @return the update task buffer instance
|
||||
*/
|
||||
BufferedRequest<Void> getUpdateTaskBuffer();
|
||||
|
||||
/**
|
||||
* Execute a runnable asynchronously
|
||||
* @param r the task to run
|
||||
*/
|
||||
void doAsync(Runnable r);
|
||||
|
||||
/**
|
||||
* Execute a runnable synchronously
|
||||
* @param r the task to run
|
||||
*/
|
||||
void doSync(Runnable r);
|
||||
|
||||
/**
|
||||
* Execute a runnable asynchronously on a loop
|
||||
* @param r the task to run
|
||||
* @param interval the time between runs in ticks
|
||||
*/
|
||||
void doAsyncRepeating(Runnable r, long interval);
|
||||
|
||||
}
|
||||
@@ -31,6 +31,8 @@ import me.lucko.luckperms.api.context.IContextCalculator;
|
||||
import me.lucko.luckperms.api.event.LPEvent;
|
||||
import me.lucko.luckperms.api.event.LPListener;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.api.internal.*;
|
||||
import me.lucko.luckperms.common.core.NodeBuilder;
|
||||
import me.lucko.luckperms.common.users.UserIdentifier;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -69,7 +71,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public double getApiVersion() {
|
||||
return 2.13;
|
||||
return 2.15;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,17 +96,28 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public LPConfiguration getConfiguration() {
|
||||
return new me.lucko.luckperms.common.api.internal.LPConfigurationLink(plugin.getConfiguration());
|
||||
return new LPConfigurationLink(plugin.getConfiguration());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Storage getStorage() {
|
||||
return new StorageLink(plugin, plugin.getStorage());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public Datastore getDatastore() {
|
||||
return new me.lucko.luckperms.common.api.internal.DatastoreLink(plugin, plugin.getDatastore());
|
||||
return new DatastoreLink(plugin, plugin.getStorage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<MessagingService> getMessagingService() {
|
||||
return Optional.ofNullable(plugin.getRedisMessaging());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UuidCache getUuidCache() {
|
||||
return new me.lucko.luckperms.common.api.internal.UuidCacheLink(plugin.getUuidCache());
|
||||
return new UuidCacheLink(plugin.getUuidCache());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,11 +128,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
@Override
|
||||
public User getUser(@NonNull UUID uuid) {
|
||||
final me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(uuid);
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new me.lucko.luckperms.common.api.internal.UserLink(user);
|
||||
return user == null ? null : new UserLink(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,11 +139,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
@Override
|
||||
public User getUser(@NonNull String name) {
|
||||
final me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(name);
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new me.lucko.luckperms.common.api.internal.UserLink(user);
|
||||
return user == null ? null : new UserLink(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,7 +149,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Set<User> getUsers() {
|
||||
return plugin.getUserManager().getAll().values().stream().map(me.lucko.luckperms.common.api.internal.UserLink::new).collect(Collectors.toSet());
|
||||
return plugin.getUserManager().getAll().values().stream().map(UserLink::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,18 +159,14 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public void cleanupUser(@NonNull User user) {
|
||||
me.lucko.luckperms.common.api.internal.Utils.checkUser(user);
|
||||
plugin.getUserManager().cleanup(((me.lucko.luckperms.common.api.internal.UserLink) user).getMaster());
|
||||
Utils.checkUser(user);
|
||||
plugin.getUserManager().cleanup(((UserLink) user).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group getGroup(@NonNull String name) {
|
||||
final me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(name);
|
||||
if (group == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new me.lucko.luckperms.common.api.internal.GroupLink(group);
|
||||
return group == null ? null : new GroupLink(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -175,7 +176,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Set<Group> getGroups() {
|
||||
return plugin.getGroupManager().getAll().values().stream().map(me.lucko.luckperms.common.api.internal.GroupLink::new).collect(Collectors.toSet());
|
||||
return plugin.getGroupManager().getAll().values().stream().map(GroupLink::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -186,11 +187,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
@Override
|
||||
public Track getTrack(@NonNull String name) {
|
||||
final me.lucko.luckperms.common.tracks.Track track = plugin.getTrackManager().get(name);
|
||||
if (track == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new me.lucko.luckperms.common.api.internal.TrackLink(track);
|
||||
return track == null ? null : new TrackLink(track);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -200,7 +197,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Set<Track> getTracks() {
|
||||
return plugin.getTrackManager().getAll().values().stream().map(me.lucko.luckperms.common.api.internal.TrackLink::new).collect(Collectors.toSet());
|
||||
return plugin.getTrackManager().getAll().values().stream().map(TrackLink::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -210,7 +207,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Node.Builder buildNode(@NonNull String permission) throws IllegalArgumentException {
|
||||
return new me.lucko.luckperms.common.core.Node.Builder(checkNode(permission));
|
||||
return new NodeBuilder(checkNode(permission));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -224,4 +221,10 @@ public class ApiProvider implements LuckPermsApi {
|
||||
public void registerContextListener(ContextListener<?> contextListener) {
|
||||
plugin.getContextManager().registerListener(contextListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Contexts> getContextForUser(User user) {
|
||||
Utils.checkUser(user);
|
||||
return Optional.ofNullable(plugin.getContextForUser(((UserLink) user).getMaster()));
|
||||
}
|
||||
}
|
||||
@@ -27,26 +27,29 @@ import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.utils.AbstractFuture;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.*;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Datastore} and {@link me.lucko.luckperms.common.storage.Datastore}
|
||||
* Provides a link between {@link Datastore} and {@link Storage}
|
||||
*
|
||||
* Note that this class only provides for the old deprecated interface, see {@link StorageLink} for the new one.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
@SuppressWarnings({"unused", "WeakerAccess", "deprecation"})
|
||||
public class DatastoreLink implements Datastore {
|
||||
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final me.lucko.luckperms.common.storage.Datastore master;
|
||||
private final Storage master;
|
||||
private final Async async;
|
||||
private final Sync sync;
|
||||
private final Future future;
|
||||
|
||||
public DatastoreLink(@NonNull LuckPermsPlugin plugin, @NonNull me.lucko.luckperms.common.storage.Datastore master) {
|
||||
public DatastoreLink(@NonNull LuckPermsPlugin plugin, @NonNull Storage master) {
|
||||
this.plugin = plugin;
|
||||
this.master = master;
|
||||
this.async = new Async(master);
|
||||
@@ -54,12 +57,10 @@ public class DatastoreLink implements Datastore {
|
||||
this.future = new Future(master);
|
||||
}
|
||||
|
||||
private static <T> Callback<T> checkCallback(Callback<T> c) {
|
||||
// If no callback was given, just send an empty one
|
||||
if (c == null) {
|
||||
c = Callback.empty();
|
||||
private <T> void registerCallback(CompletableFuture<T> fut, Callback<T> c) {
|
||||
if (c != null) {
|
||||
fut.thenAcceptAsync(Callback.convertToConsumer(c), plugin.getSyncExecutor());
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,68 +90,68 @@ public class DatastoreLink implements Datastore {
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Async implements Datastore.Async {
|
||||
private final me.lucko.luckperms.common.storage.Datastore master;
|
||||
private final me.lucko.luckperms.common.storage.Storage master;
|
||||
|
||||
@Override
|
||||
public void logAction(@NonNull LogEntry entry, Callback<Boolean> callback) {
|
||||
master.logAction(entry, checkCallback(callback));
|
||||
registerCallback(master.force().logAction(entry), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getLog(Callback<Log> callback) {
|
||||
master.getLog(log -> callback.onComplete(new LogLink(log)));
|
||||
public void getLog(@NonNull Callback<Log> callback) {
|
||||
master.force().getLog().thenAcceptAsync(log -> callback.onComplete(new LogLink(log)), plugin.getSyncExecutor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadOrCreateUser(@NonNull UUID uuid, @NonNull String username, Callback<Boolean> callback) {
|
||||
master.loadUser(uuid, checkUsername(username), checkCallback(callback));
|
||||
registerCallback(master.force().loadUser(uuid, checkUsername(username)) , callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadUser(@NonNull UUID uuid, Callback<Boolean> callback) {
|
||||
master.loadUser(uuid, "null", checkCallback(callback));
|
||||
registerCallback(master.force().loadUser(uuid, "null"), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadUser(@NonNull UUID uuid, @NonNull String username, Callback<Boolean> callback) {
|
||||
master.loadUser(uuid, checkUsername(username), checkCallback(callback));
|
||||
registerCallback(master.force().loadUser(uuid, checkUsername(username)), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveUser(@NonNull User user, Callback<Boolean> callback) {
|
||||
checkUser(user);
|
||||
master.saveUser(((UserLink) user).getMaster(), checkCallback(callback));
|
||||
registerCallback(master.force().saveUser(((UserLink) user).getMaster()), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanupUsers(Callback<Boolean> callback) {
|
||||
master.cleanupUsers(checkCallback(callback));
|
||||
registerCallback(master.force().cleanupUsers(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getUniqueUsers(Callback<Set<UUID>> callback) {
|
||||
master.getUniqueUsers(checkCallback(callback));
|
||||
registerCallback(master.force().getUniqueUsers(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAndLoadGroup(@NonNull String name, Callback<Boolean> callback) {
|
||||
master.createAndLoadGroup(checkName(name), checkCallback(callback));
|
||||
registerCallback(master.force().createAndLoadGroup(checkName(name)), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadGroup(@NonNull String name, Callback<Boolean> callback) {
|
||||
master.loadGroup(checkName(name), checkCallback(callback));
|
||||
registerCallback(master.force().loadGroup(checkName(name)), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadAllGroups(Callback<Boolean> callback) {
|
||||
master.loadAllGroups(checkCallback(callback));
|
||||
registerCallback(master.force().loadAllGroups(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveGroup(@NonNull Group group, Callback<Boolean> callback) {
|
||||
checkGroup(group);
|
||||
master.saveGroup(((GroupLink) group).getMaster(), checkCallback(callback));
|
||||
registerCallback(master.force().saveGroup(((GroupLink) group).getMaster()), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -159,59 +160,59 @@ public class DatastoreLink implements Datastore {
|
||||
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
|
||||
throw new IllegalArgumentException("Cannot delete the default group.");
|
||||
}
|
||||
master.deleteGroup(((GroupLink) group).getMaster(), checkCallback(callback));
|
||||
registerCallback(master.force().deleteGroup(((GroupLink) group).getMaster()), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAndLoadTrack(@NonNull String name, Callback<Boolean> callback) {
|
||||
master.createAndLoadTrack(checkName(name), checkCallback(callback));
|
||||
registerCallback(master.force().createAndLoadTrack(checkName(name)), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadTrack(@NonNull String name, Callback<Boolean> callback) {
|
||||
master.loadTrack(checkName(name), checkCallback(callback));
|
||||
registerCallback(master.force().loadTrack(checkName(name)), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadAllTracks(Callback<Boolean> callback) {
|
||||
master.loadAllTracks(checkCallback(callback));
|
||||
registerCallback(master.force().loadAllTracks(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveTrack(@NonNull Track track, Callback<Boolean> callback) {
|
||||
checkTrack(track);
|
||||
master.saveTrack(((TrackLink) track).getMaster(), checkCallback(callback));
|
||||
registerCallback(master.force().saveTrack(((TrackLink) track).getMaster()), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTrack(@NonNull Track track, Callback<Boolean> callback) {
|
||||
checkTrack(track);
|
||||
master.deleteTrack(((TrackLink) track).getMaster(), checkCallback(callback));
|
||||
registerCallback(master.force().deleteTrack(((TrackLink) track).getMaster()), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveUUIDData(@NonNull String username, @NonNull UUID uuid, Callback<Boolean> callback) {
|
||||
master.saveUUIDData(checkUsername(username), uuid, checkCallback(callback));
|
||||
registerCallback(master.force().saveUUIDData(checkUsername(username), uuid), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getUUID(@NonNull String username, Callback<UUID> callback) {
|
||||
master.getUUID(checkUsername(username), checkCallback(callback));
|
||||
registerCallback(master.force().getUUID(checkUsername(username)), callback);
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Sync implements Datastore.Sync {
|
||||
private final me.lucko.luckperms.common.storage.Datastore master;
|
||||
private final Storage master;
|
||||
|
||||
@Override
|
||||
public boolean logAction(@NonNull LogEntry entry) {
|
||||
return master.logAction(entry).getUnchecked();
|
||||
return master.force().logAction(entry).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Log getLog() {
|
||||
me.lucko.luckperms.common.data.Log log = master.getLog().getUnchecked();
|
||||
me.lucko.luckperms.common.data.Log log = master.force().getLog().join();
|
||||
if (log == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -220,54 +221,54 @@ public class DatastoreLink implements Datastore {
|
||||
|
||||
@Override
|
||||
public boolean loadOrCreateUser(@NonNull UUID uuid, @NonNull String username) {
|
||||
return master.loadUser(uuid, checkUsername(username)).getUnchecked();
|
||||
return master.force().loadUser(uuid, checkUsername(username)).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadUser(@NonNull UUID uuid) {
|
||||
return master.loadUser(uuid, "null").getUnchecked();
|
||||
return master.force().loadUser(uuid, "null").join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadUser(@NonNull UUID uuid, @NonNull String username) {
|
||||
return master.loadUser(uuid, checkUsername(username)).getUnchecked();
|
||||
return master.force().loadUser(uuid, checkUsername(username)).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveUser(@NonNull User user) {
|
||||
checkUser(user);
|
||||
return master.saveUser(((UserLink) user).getMaster()).getUnchecked();
|
||||
return master.force().saveUser(((UserLink) user).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cleanupUsers() {
|
||||
return master.cleanupUsers().getUnchecked();
|
||||
return master.force().cleanupUsers().join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getUniqueUsers() {
|
||||
return master.getUniqueUsers().getUnchecked();
|
||||
return master.force().getUniqueUsers().join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadGroup(@NonNull String name) {
|
||||
return master.createAndLoadGroup(checkName(name)).getUnchecked();
|
||||
return master.force().createAndLoadGroup(checkName(name)).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadGroup(@NonNull String name) {
|
||||
return master.loadGroup(checkName(name)).getUnchecked();
|
||||
return master.force().loadGroup(checkName(name)).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadAllGroups() {
|
||||
return master.loadAllGroups().getUnchecked();
|
||||
return master.force().loadAllGroups().join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveGroup(@NonNull Group group) {
|
||||
checkGroup(group);
|
||||
return master.saveGroup(((GroupLink) group).getMaster()).getUnchecked();
|
||||
return master.force().saveGroup(((GroupLink) group).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -276,113 +277,111 @@ public class DatastoreLink implements Datastore {
|
||||
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
|
||||
throw new IllegalArgumentException("Cannot delete the default group.");
|
||||
}
|
||||
return master.deleteGroup(((GroupLink) group).getMaster()).getUnchecked();
|
||||
return master.force().deleteGroup(((GroupLink) group).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadTrack(@NonNull String name) {
|
||||
return master.createAndLoadTrack(checkName(name)).getUnchecked();
|
||||
return master.force().createAndLoadTrack(checkName(name)).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadTrack(@NonNull String name) {
|
||||
return master.loadTrack(checkName(name)).getUnchecked();
|
||||
return master.force().loadTrack(checkName(name)).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadAllTracks() {
|
||||
return master.loadAllTracks().getUnchecked();
|
||||
return master.force().loadAllTracks().join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveTrack(@NonNull Track track) {
|
||||
checkTrack(track);
|
||||
return master.saveTrack(((TrackLink) track).getMaster()).getUnchecked();
|
||||
return master.force().saveTrack(((TrackLink) track).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteTrack(@NonNull Track track) {
|
||||
checkTrack(track);
|
||||
return master.deleteTrack(((TrackLink) track).getMaster()).getUnchecked();
|
||||
return master.force().deleteTrack(((TrackLink) track).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveUUIDData(@NonNull String username, @NonNull UUID uuid) {
|
||||
return master.saveUUIDData(checkUsername(username), uuid).getUnchecked();
|
||||
return master.force().saveUUIDData(checkUsername(username), uuid).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUUID(@NonNull String username) {
|
||||
return master.getUUID(checkUsername(username)).getUnchecked();
|
||||
return master.force().getUUID(checkUsername(username)).join();
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Future implements Datastore.Future {
|
||||
private final me.lucko.luckperms.common.storage.Datastore master;
|
||||
private final Storage master;
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> logAction(@NonNull LogEntry entry) {
|
||||
return master.logAction(entry);
|
||||
return master.force().logAction(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Log> getLog() {
|
||||
AbstractFuture<Log> fut = new AbstractFuture<>();
|
||||
master.getLog(log -> fut.complete(new LogLink(log)));
|
||||
return fut;
|
||||
return master.force().getLog().thenApply(log -> log == null ? null : new LogLink(log));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadOrCreateUser(@NonNull UUID uuid, @NonNull String username) {
|
||||
return master.loadUser(uuid, checkUsername(username));
|
||||
return master.force().loadUser(uuid, checkUsername(username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadUser(@NonNull UUID uuid) {
|
||||
return master.loadUser(uuid, "null");
|
||||
return master.force().loadUser(uuid, "null");
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadUser(@NonNull UUID uuid, @NonNull String username) {
|
||||
return master.loadUser(uuid, checkUsername(username));
|
||||
return master.force().loadUser(uuid, checkUsername(username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> saveUser(@NonNull User user) {
|
||||
checkUser(user);
|
||||
return master.saveUser(((UserLink) user).getMaster());
|
||||
return master.force().saveUser(((UserLink) user).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> cleanupUsers() {
|
||||
return master.cleanupUsers();
|
||||
return master.force().cleanupUsers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Set<UUID>> getUniqueUsers() {
|
||||
return master.getUniqueUsers();
|
||||
return master.force().getUniqueUsers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> createAndLoadGroup(@NonNull String name) {
|
||||
return master.createAndLoadGroup(checkName(name));
|
||||
return master.force().createAndLoadGroup(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadGroup(@NonNull String name) {
|
||||
return master.loadGroup(checkName(name));
|
||||
return master.force().loadGroup(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadAllGroups() {
|
||||
return master.loadAllGroups();
|
||||
return master.force().loadAllGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> saveGroup(@NonNull Group group) {
|
||||
checkGroup(group);
|
||||
return master.saveGroup(((GroupLink) group).getMaster());
|
||||
return master.force().saveGroup(((GroupLink) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -391,44 +390,44 @@ public class DatastoreLink implements Datastore {
|
||||
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
|
||||
throw new IllegalArgumentException("Cannot delete the default group.");
|
||||
}
|
||||
return master.deleteGroup(((GroupLink) group).getMaster());
|
||||
return master.force().deleteGroup(((GroupLink) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> createAndLoadTrack(@NonNull String name) {
|
||||
return master.createAndLoadTrack(checkName(name));
|
||||
return master.force().createAndLoadTrack(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadTrack(@NonNull String name) {
|
||||
return master.loadTrack(checkName(name));
|
||||
return master.force().loadTrack(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadAllTracks() {
|
||||
return master.loadAllTracks();
|
||||
return master.force().loadAllTracks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> saveTrack(@NonNull Track track) {
|
||||
checkTrack(track);
|
||||
return master.saveTrack(((TrackLink) track).getMaster());
|
||||
return master.force().saveTrack(((TrackLink) track).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> deleteTrack(@NonNull Track track) {
|
||||
checkTrack(track);
|
||||
return master.deleteTrack(((TrackLink) track).getMaster());
|
||||
return master.force().deleteTrack(((TrackLink) track).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> saveUUIDData(@NonNull String username, @NonNull UUID uuid) {
|
||||
return master.saveUUIDData(checkUsername(username), uuid);
|
||||
return master.force().saveUUIDData(checkUsername(username), uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<UUID> getUUID(@NonNull String username) {
|
||||
return master.getUUID(checkUsername(username));
|
||||
return master.force().getUUID(checkUsername(username));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ public class LPConfigurationLink implements LPConfiguration {
|
||||
|
||||
@Override
|
||||
public boolean getDebugPermissionChecks() {
|
||||
return master.isDebugPermissionChecks();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-5
@@ -26,6 +26,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
@@ -40,8 +41,6 @@ import static me.lucko.luckperms.common.core.PermissionHolder.exportToLegacy;
|
||||
@SuppressWarnings("unused")
|
||||
@AllArgsConstructor
|
||||
public class PermissionHolderLink implements PermissionHolder {
|
||||
|
||||
@NonNull
|
||||
private final me.lucko.luckperms.common.core.PermissionHolder master;
|
||||
|
||||
@Override
|
||||
@@ -66,17 +65,17 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
|
||||
@Override
|
||||
public Set<Node> getAllNodes() {
|
||||
return Collections.unmodifiableSet(master.getAllNodes(null, Contexts.allowAll()));
|
||||
return Collections.unmodifiableSet(master.getAllNodes(null, ExtractedContexts.generate(Contexts.allowAll())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<LocalizedNode> getAllNodes(@NonNull Contexts contexts) {
|
||||
return master.getAllNodes(null, contexts);
|
||||
return master.getAllNodes(null, ExtractedContexts.generate(contexts));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<LocalizedNode> getAllNodesFiltered(@NonNull Contexts contexts) {
|
||||
return master.getAllNodesFiltered(contexts);
|
||||
return master.getAllNodesFiltered(ExtractedContexts.generate(contexts));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.*;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Storage} and {@link me.lucko.luckperms.common.storage.Storage}
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class StorageLink implements Storage {
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final me.lucko.luckperms.common.storage.Storage master;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return master.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptingLogins() {
|
||||
return master.isAcceptingLogins();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getSyncExecutor() {
|
||||
return plugin.getSyncExecutor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getAsyncExecutor() {
|
||||
return plugin.getAsyncExecutor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> logAction(@NonNull LogEntry entry) {
|
||||
return master.force().logAction(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Log> getLog() {
|
||||
return master.force().getLog().thenApply(log -> log == null ? null : new LogLink(log));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> loadUser(UUID uuid, String username) {
|
||||
return master.force().loadUser(uuid, checkUsername(username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveUser(User user) {
|
||||
checkUser(user);
|
||||
return master.force().saveUser(((UserLink) user).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> cleanupUsers() {
|
||||
return master.force().cleanupUsers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Set<UUID>> getUniqueUsers() {
|
||||
return master.force().getUniqueUsers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> createAndLoadGroup(String name) {
|
||||
return master.force().createAndLoadGroup(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> loadGroup(String name) {
|
||||
return master.force().loadGroup(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> loadAllGroups() {
|
||||
return master.force().loadAllGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveGroup(Group group) {
|
||||
checkGroup(group);
|
||||
return master.force().saveGroup(((GroupLink) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> deleteGroup(Group group) {
|
||||
checkGroup(group);
|
||||
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
|
||||
throw new IllegalArgumentException("Cannot delete the default group.");
|
||||
}
|
||||
return master.force().deleteGroup(((GroupLink) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> createAndLoadTrack(String name) {
|
||||
return master.force().createAndLoadTrack(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> loadTrack(String name) {
|
||||
return master.force().loadTrack(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> loadAllTracks() {
|
||||
return master.force().loadAllTracks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveTrack(Track track) {
|
||||
checkTrack(track);
|
||||
return master.force().saveTrack(((TrackLink) track).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> deleteTrack(Track track) {
|
||||
checkTrack(track);
|
||||
return master.force().deleteTrack(((TrackLink) track).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid) {
|
||||
return master.force().saveUUIDData(checkUsername(username), uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<UUID> getUUID(String username) {
|
||||
return master.force().getUUID(checkUsername(username));
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.Track;
|
||||
@@ -32,57 +33,51 @@ import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
public class Utils {
|
||||
|
||||
public static void checkUser(User user) {
|
||||
if (!(user instanceof UserLink)) {
|
||||
throw new IllegalStateException("User instance cannot be handled by this implementation.");
|
||||
}
|
||||
Preconditions.checkState(user instanceof UserLink, "User instance cannot be handled by this implementation.");
|
||||
}
|
||||
|
||||
public static void checkGroup(Group group) {
|
||||
if (!(group instanceof GroupLink)) {
|
||||
throw new IllegalStateException("Group instance cannot be handled by this implementation.");
|
||||
}
|
||||
Preconditions.checkState(group instanceof GroupLink, "Group instance cannot be handled by this implementation.");
|
||||
}
|
||||
|
||||
public static void checkTrack(Track track) {
|
||||
if (!(track instanceof TrackLink)) {
|
||||
throw new IllegalStateException("Track instance cannot be handled by this implementation.");
|
||||
}
|
||||
Preconditions.checkState(track instanceof TrackLink, "Track instance cannot be handled by this implementation.");
|
||||
}
|
||||
|
||||
public static String checkUsername(String s) {
|
||||
if (ArgumentChecker.checkUsername(s)) {
|
||||
throw new IllegalArgumentException("Invalid username entry '" + s + "'. Usernames must be less than 16 chars" +
|
||||
" and only contain 'a-z A-Z 1-9 _'.");
|
||||
}
|
||||
Preconditions.checkArgument(
|
||||
!ArgumentChecker.checkUsername(s),
|
||||
"Invalid username entry '" + s + "'. Usernames must be less than 16 chars and only contain 'a-z A-Z 1-9 _'."
|
||||
);
|
||||
return s;
|
||||
}
|
||||
|
||||
public static String checkName(String s) {
|
||||
if (ArgumentChecker.checkName(s)) {
|
||||
throw new IllegalArgumentException("Invalid name entry '" + s + "'. Names must be less than 37 chars" +
|
||||
" and only contain 'a-z A-Z 1-9'.");
|
||||
}
|
||||
Preconditions.checkArgument(
|
||||
!ArgumentChecker.checkName(s),
|
||||
"Invalid name entry '" + s + "'. Names must be less than 37 chars and only contain 'a-z A-Z 1-9'."
|
||||
);
|
||||
return s.toLowerCase();
|
||||
}
|
||||
|
||||
public static String checkServer(String s) {
|
||||
if (ArgumentChecker.checkServer(s)) {
|
||||
throw new IllegalArgumentException("Invalid server entry '" + s + "'. Server names can only contain alphanumeric characters.");
|
||||
}
|
||||
Preconditions.checkArgument(
|
||||
!ArgumentChecker.checkServer(s),
|
||||
"Invalid server entry '" + s + "'. Server names can only contain alphanumeric characters."
|
||||
);
|
||||
return s;
|
||||
}
|
||||
|
||||
public static String checkNode(String s) {
|
||||
if (ArgumentChecker.checkNode(s)) {
|
||||
throw new IllegalArgumentException("Invalid node entry '" + s + "'. Nodes cannot contain '/' or '$' characters.");
|
||||
}
|
||||
Preconditions.checkArgument(
|
||||
!ArgumentChecker.checkNode(s),
|
||||
"Invalid node entry '" + s + "'. Nodes cannot contain '/' or '$' characters."
|
||||
);
|
||||
return s;
|
||||
}
|
||||
|
||||
public static long checkTime(long l) {
|
||||
if (ArgumentChecker.checkTime(l)) {
|
||||
throw new IllegalArgumentException("Unix time '" + l + "' is invalid, as it has already passed.");
|
||||
}
|
||||
Preconditions.checkArgument(!ArgumentChecker.checkTime(l), "Unix time '" + l + "' is invalid, as it has already passed.");
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.UuidCache;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -35,12 +36,12 @@ public class UuidCacheLink implements UuidCache {
|
||||
private final me.lucko.luckperms.common.core.UuidCache master;
|
||||
|
||||
@Override
|
||||
public UUID getUUID(UUID external) {
|
||||
public UUID getUUID(@NonNull UUID external) {
|
||||
return master.getUUID(external);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getExternalUUID(UUID internal) {
|
||||
public UUID getExternalUUID(@NonNull UUID internal) {
|
||||
return master.getExternalUUID(internal);
|
||||
}
|
||||
}
|
||||
@@ -24,143 +24,67 @@ package me.lucko.luckperms.common.caching;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import me.lucko.luckperms.api.caching.MetaData;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* Holds a user's cached meta for a given context
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class MetaCache implements MetaData {
|
||||
private final Contexts contexts;
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
private final SortedMap<Integer, String> prefixes = new TreeMap<>(Comparator.reverseOrder());
|
||||
private final SortedMap<Integer, String> suffixes = new TreeMap<>(Comparator.reverseOrder());
|
||||
@Getter
|
||||
private Map<String, String> meta = ImmutableMap.of();
|
||||
|
||||
private final Map<String, String> meta = new HashMap<>();
|
||||
@Getter
|
||||
private SortedMap<Integer, String> prefixes = ImmutableSortedMap.of();
|
||||
|
||||
public void loadMeta(SortedSet<LocalizedNode> nodes) {
|
||||
invalidateCache();
|
||||
@Getter
|
||||
private SortedMap<Integer, String> suffixes = ImmutableSortedMap.of();
|
||||
|
||||
MutableContextSet contexts = MutableContextSet.fromSet(this.contexts.getContexts());
|
||||
String server = contexts.getValues("server").stream().findAny().orElse(null);
|
||||
String world = contexts.getValues("world").stream().findAny().orElse(null);
|
||||
contexts.removeAll("server");
|
||||
contexts.removeAll("world");
|
||||
|
||||
for (LocalizedNode ln : nodes) {
|
||||
Node n = ln.getNode();
|
||||
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.isMeta() && !n.isPrefix() && n.isSuffix()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnServer(server, this.contexts.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, this.contexts.isIncludeGlobalWorld(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyWithContext(contexts, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n.isPrefix()) {
|
||||
Map.Entry<Integer, String> value = n.getPrefix();
|
||||
synchronized (this.prefixes) {
|
||||
if (!this.prefixes.containsKey(value.getKey())) {
|
||||
this.prefixes.put(value.getKey(), value.getValue());
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n.isSuffix()) {
|
||||
Map.Entry<Integer, String> value = n.getSuffix();
|
||||
synchronized (this.suffixes) {
|
||||
if (!this.suffixes.containsKey(value.getKey())) {
|
||||
this.suffixes.put(value.getKey(), value.getValue());
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n.isMeta()) {
|
||||
Map.Entry<String, String> meta = n.getMeta();
|
||||
synchronized (this.meta) {
|
||||
if (!this.meta.containsKey(meta.getKey())) {
|
||||
this.meta.put(meta.getKey(), meta.getValue());
|
||||
}
|
||||
}
|
||||
this.meta.put(meta.getKey(), meta.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void invalidateCache() {
|
||||
synchronized (meta) {
|
||||
meta.clear();
|
||||
}
|
||||
synchronized (prefixes) {
|
||||
prefixes.clear();
|
||||
}
|
||||
synchronized (suffixes) {
|
||||
suffixes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMeta() {
|
||||
synchronized (meta) {
|
||||
return ImmutableMap.copyOf(meta);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedMap<Integer, String> getPrefixes() {
|
||||
synchronized (prefixes) {
|
||||
return ImmutableSortedMap.copyOfSorted(prefixes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedMap<Integer, String> getSuffixes() {
|
||||
synchronized (suffixes) {
|
||||
return ImmutableSortedMap.copyOfSorted(suffixes);
|
||||
public void loadMeta(MetaHolder meta) {
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
this.meta = ImmutableMap.copyOf(meta.getMeta());
|
||||
this.prefixes = ImmutableSortedMap.copyOfSorted(meta.getPrefixes());
|
||||
this.suffixes = ImmutableSortedMap.copyOfSorted(meta.getSuffixes());
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefix() {
|
||||
synchronized (prefixes) {
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
if (prefixes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return prefixes.get(prefixes.firstKey());
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuffix() {
|
||||
synchronized (suffixes) {
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
if (suffixes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return suffixes.get(suffixes.firstKey());
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.caching;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Holds temporary mutable meta whilst this object is passed up the inheritance tree to accumulate meta from parents
|
||||
*/
|
||||
@Getter
|
||||
@ToString
|
||||
public class MetaHolder {
|
||||
|
||||
private final Map<String, String> meta = new HashMap<>();
|
||||
private final SortedMap<Integer, String> prefixes = new TreeMap<>(Comparator.reverseOrder());
|
||||
private final SortedMap<Integer, String> suffixes = new TreeMap<>(Comparator.reverseOrder());
|
||||
|
||||
public void accumulateNode(Node n) {
|
||||
if (n.isMeta()) {
|
||||
Map.Entry<String, String> entry = n.getMeta();
|
||||
if (!meta.containsKey(entry.getKey())) {
|
||||
meta.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (n.isPrefix()) {
|
||||
Map.Entry<Integer, String> value = n.getPrefix();
|
||||
if (!prefixes.containsKey(value.getKey())) {
|
||||
prefixes.put(value.getKey(), value.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (n.isSuffix()) {
|
||||
Map.Entry<Integer, String> value = n.getSuffix();
|
||||
if (!suffixes.containsKey(value.getKey())) {
|
||||
suffixes.put(value.getKey(), value.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -53,7 +53,8 @@ public class PermissionCache implements PermissionData {
|
||||
|
||||
public PermissionCache(Contexts contexts, User user, CalculatorFactory calculatorFactory) {
|
||||
permissions = new ConcurrentHashMap<>();
|
||||
calculator = calculatorFactory.build(contexts, user, permissions);
|
||||
calculator = calculatorFactory.build(contexts, user);
|
||||
calculator.updateBacking(permissions); // Initial setup.
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,6 +65,7 @@ public class PermissionCache implements PermissionData {
|
||||
public void setPermissions(Map<String, Boolean> permissions) {
|
||||
this.permissions.clear();
|
||||
this.permissions.putAll(permissions);
|
||||
calculator.updateBacking(this.permissions);
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import me.lucko.luckperms.api.caching.PermissionData;
|
||||
import me.lucko.luckperms.api.caching.UserData;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@@ -78,7 +79,7 @@ public class UserCache implements UserData {
|
||||
|
||||
@Override
|
||||
public ListenableFuture<MetaCache> reload(Contexts contexts, MetaCache oldData) {
|
||||
oldData.loadMeta(user.getAllNodes(null, contexts));
|
||||
oldData.loadMeta(user.accumulateMeta(null, null, ExtractedContexts.generate(contexts)));
|
||||
return Futures.immediateFuture(oldData);
|
||||
}
|
||||
});
|
||||
@@ -102,8 +103,8 @@ public class UserCache implements UserData {
|
||||
|
||||
@Override
|
||||
public MetaCache calculateMeta(@NonNull Contexts contexts) {
|
||||
MetaCache data = new MetaCache(contexts);
|
||||
data.loadMeta(user.getAllNodes(null, contexts));
|
||||
MetaCache data = new MetaCache();
|
||||
data.loadMeta(user.accumulateMeta(null, null, ExtractedContexts.generate(contexts)));
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,13 +25,11 @@ package me.lucko.luckperms.common.calculators;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Creates a calculator instance given a set of contexts
|
||||
*/
|
||||
public interface CalculatorFactory {
|
||||
|
||||
PermissionCalculator build(Contexts contexts, User user, Map<String, Boolean> map);
|
||||
PermissionCalculator build(Contexts contexts, User user);
|
||||
|
||||
}
|
||||
+8
-6
@@ -30,6 +30,7 @@ import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Calculates and caches permissions
|
||||
@@ -38,7 +39,6 @@ import java.util.List;
|
||||
public class PermissionCalculator {
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final String objectName;
|
||||
private final boolean debug;
|
||||
private final List<PermissionProcessor> processors;
|
||||
|
||||
private final LoadingCache<String, Tristate> cache = CacheBuilder.newBuilder()
|
||||
@@ -56,11 +56,7 @@ public class PermissionCalculator {
|
||||
public Tristate getPermissionValue(String permission) {
|
||||
permission = permission.toLowerCase();
|
||||
Tristate t = cache.getUnchecked(permission);
|
||||
|
||||
if (debug) {
|
||||
plugin.getLog().info("Checking if " + objectName + " has permission: " + permission + " - (" + t.toString() + ")");
|
||||
}
|
||||
|
||||
plugin.getDebugHandler().printOutput(objectName, permission, t);
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -76,4 +72,10 @@ public class PermissionCalculator {
|
||||
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
public synchronized void updateBacking(Map<String, Boolean> map) {
|
||||
for (PermissionProcessor processor : processors) {
|
||||
processor.updateBacking(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,11 @@ package me.lucko.luckperms.common.calculators;
|
||||
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface PermissionProcessor {
|
||||
|
||||
Tristate hasPermission(String permission);
|
||||
void updateBacking(Map<String, Boolean> map);
|
||||
|
||||
}
|
||||
+10
-7
@@ -20,23 +20,26 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.calculators;
|
||||
package me.lucko.luckperms.common.calculators.processors;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class MapProcessor implements PermissionProcessor {
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> map;
|
||||
private Map<String, Boolean> map = null;
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
Boolean b = map.get(permission);
|
||||
return b == null ? Tristate.UNDEFINED : Tristate.fromBoolean(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBacking(Map<String, Boolean> map) {
|
||||
if (this.map == null) {
|
||||
this.map = map;
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
-16
@@ -20,37 +20,44 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.calculators;
|
||||
package me.lucko.luckperms.common.calculators.processors;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||
import me.lucko.luckperms.common.constants.Patterns;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class RegexProcessor implements PermissionProcessor {
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> map;
|
||||
private Map<String, Boolean> regexPermissions = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
for (Map.Entry<String, Boolean> e : map.entrySet()) {
|
||||
if (e.getKey().toLowerCase().startsWith("r=")) {
|
||||
Pattern p = Patterns.compile(e.getKey().substring(2));
|
||||
if (p == null) {
|
||||
continue;
|
||||
}
|
||||
for (Map.Entry<String, Boolean> e : regexPermissions.entrySet()) {
|
||||
Pattern p = Patterns.compile(e.getKey());
|
||||
if (p == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p.matcher(permission).matches()) {
|
||||
return Tristate.fromBoolean(e.getValue());
|
||||
}
|
||||
if (p.matcher(permission).matches()) {
|
||||
return Tristate.fromBoolean(e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBacking(Map<String, Boolean> map) {
|
||||
regexPermissions.clear();
|
||||
for (Map.Entry<String, Boolean> e : map.entrySet()) {
|
||||
if (!e.getKey().startsWith("r=") && !e.getKey().startsWith("R=")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
regexPermissions.put(e.getKey().substring(2), e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-7
@@ -20,19 +20,15 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.calculators;
|
||||
package me.lucko.luckperms.common.calculators.processors;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class WildcardProcessor implements PermissionProcessor {
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> map;
|
||||
private Map<String, Boolean> map = null;
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
@@ -65,4 +61,11 @@ public class WildcardProcessor implements PermissionProcessor {
|
||||
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBacking(Map<String, Boolean> map) {
|
||||
if (this.map == null) {
|
||||
this.map = map;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,11 +43,7 @@ public class Arg {
|
||||
private final String description;
|
||||
|
||||
public String asPrettyString() {
|
||||
if (required) {
|
||||
return "&8<&7" + name + "&8>";
|
||||
} else {
|
||||
return "&8[&7" + name + "&8]";
|
||||
}
|
||||
return required ? "&8<&7" + name + "&8>" : "&8[&7" + name + "&8]";
|
||||
}
|
||||
|
||||
}
|
||||
+8
-11
@@ -22,20 +22,17 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Wrapper interface to represent a CommandSender/CommandSource within the luckperms-common command implementations.
|
||||
*/
|
||||
public interface Sender {
|
||||
public abstract class BaseCommand<T, S> extends Command<T, S> {
|
||||
|
||||
LuckPermsPlugin getPlatform();
|
||||
String getName();
|
||||
UUID getUuid();
|
||||
void sendMessage(String s);
|
||||
boolean hasPermission(Permission permission);
|
||||
public BaseCommand(String name, String description, Permission permission, Predicate<Integer> argumentCheck, List<Arg> args, List<Command<S, ?>> children) {
|
||||
super(name, description, permission, argumentCheck, args, children);
|
||||
}
|
||||
|
||||
public abstract String getUsage();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public abstract class Command<T, S> {
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
@Getter
|
||||
private final String description;
|
||||
|
||||
// Could be null
|
||||
private final Permission permission;
|
||||
|
||||
@Getter
|
||||
private final Predicate<Integer> argumentCheck;
|
||||
|
||||
// Could be null
|
||||
private final List<Arg> args;
|
||||
|
||||
// Could be null
|
||||
private final List<Command<S, ?>> children;
|
||||
|
||||
public Command(String name, String description, Permission permission, Predicate<Integer> argumentCheck, List<Arg> args, List<Command<S, ?>> children) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.permission = permission;
|
||||
this.argumentCheck = argumentCheck;
|
||||
this.args = args == null ? null : ImmutableList.copyOf(args);
|
||||
this.children = children == null ? null : ImmutableList.copyOf(children);
|
||||
}
|
||||
|
||||
public Command(String name, String description, Permission permission, Predicate<Integer> argumentCheck, List<Arg> args) {
|
||||
this(name, description, permission, argumentCheck, args, null);
|
||||
}
|
||||
|
||||
public Command(String name, String description, Predicate<Integer> argumentCheck) {
|
||||
this(name, description, null, argumentCheck, null, null);
|
||||
}
|
||||
|
||||
public abstract CommandResult execute(LuckPermsPlugin plugin, Sender sender, T t, List<String> args, String label) throws CommandException;
|
||||
|
||||
public List<String> tabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public abstract void sendUsage(Sender sender, String label);
|
||||
public abstract void sendDetailedUsage(Sender sender, String label);
|
||||
|
||||
public boolean isAuthorized(Sender sender) {
|
||||
return permission == null || permission.isAuthorized(sender);
|
||||
}
|
||||
|
||||
public Optional<Permission> getPermission() {
|
||||
return Optional.ofNullable(permission);
|
||||
}
|
||||
|
||||
public Optional<List<Arg>> getArgs() {
|
||||
return Optional.ofNullable(args);
|
||||
}
|
||||
|
||||
public Optional<List<Command<S, ?>>> getChildren() {
|
||||
return Optional.ofNullable(children);
|
||||
}
|
||||
|
||||
}
|
||||
+5
-10
@@ -20,16 +20,11 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.utils;
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public interface LPFuture<T> extends Future<T> {
|
||||
|
||||
default T getUnchecked() {
|
||||
return Futures.getUnchecked(this);
|
||||
}
|
||||
/**
|
||||
* Exception to be thrown if there is an error processing a command
|
||||
*/
|
||||
public class CommandException extends Exception {
|
||||
|
||||
}
|
||||
@@ -23,9 +23,7 @@
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.group.CreateGroup;
|
||||
import me.lucko.luckperms.common.commands.group.DeleteGroup;
|
||||
@@ -34,46 +32,58 @@ import me.lucko.luckperms.common.commands.group.ListGroups;
|
||||
import me.lucko.luckperms.common.commands.log.LogMainCommand;
|
||||
import me.lucko.luckperms.common.commands.migration.MigrationMainCommand;
|
||||
import me.lucko.luckperms.common.commands.misc.*;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.track.CreateTrack;
|
||||
import me.lucko.luckperms.common.commands.track.DeleteTrack;
|
||||
import me.lucko.luckperms.common.commands.track.ListTracks;
|
||||
import me.lucko.luckperms.common.commands.track.TrackMainCommand;
|
||||
import me.lucko.luckperms.common.commands.user.UserMainCommand;
|
||||
import me.lucko.luckperms.common.commands.usersbulkedit.UsersBulkEditMainCommand;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class CommandManager {
|
||||
@Getter
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
@Getter
|
||||
private final List<MainCommand> mainCommands = ImmutableList.<MainCommand>builder()
|
||||
.add(new UserMainCommand())
|
||||
.add(new GroupMainCommand())
|
||||
.add(new TrackMainCommand())
|
||||
.add(new LogMainCommand())
|
||||
.add(new SyncCommand())
|
||||
.add(new InfoCommand())
|
||||
.add(new DebugCommand())
|
||||
.add(new ImportCommand())
|
||||
.add(new ExportCommand())
|
||||
.add(new QueueCommand())
|
||||
.add(new MigrationMainCommand())
|
||||
.add(new UsersBulkEditMainCommand())
|
||||
.add(new CreateGroup())
|
||||
.add(new DeleteGroup())
|
||||
.add(new ListGroups())
|
||||
.add(new CreateTrack())
|
||||
.add(new DeleteTrack())
|
||||
.add(new ListTracks())
|
||||
.build();
|
||||
private final List<BaseCommand> mainCommands;
|
||||
|
||||
public CommandManager(LuckPermsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
ImmutableList.Builder<BaseCommand> l = ImmutableList.builder();
|
||||
l.add(new UserMainCommand())
|
||||
.add(new GroupMainCommand())
|
||||
.add(new TrackMainCommand())
|
||||
.addAll(plugin.getExtraCommands())
|
||||
.add(new LogMainCommand())
|
||||
.add(new SyncCommand())
|
||||
.add(new NetworkSyncCommand())
|
||||
.add(new InfoCommand())
|
||||
.add(new VerboseCommand())
|
||||
.add(new ImportCommand())
|
||||
.add(new ExportCommand())
|
||||
.add(new QueueCommand())
|
||||
.add(new MigrationMainCommand())
|
||||
.add(new UsersBulkEditMainCommand())
|
||||
.add(new CreateGroup())
|
||||
.add(new DeleteGroup())
|
||||
.add(new ListGroups())
|
||||
.add(new CreateTrack())
|
||||
.add(new DeleteTrack())
|
||||
.add(new ListTracks());
|
||||
|
||||
mainCommands = l.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic on command method to be called from the command executor object of the platform
|
||||
@@ -83,10 +93,12 @@ public class CommandManager {
|
||||
* @param args the arguments provided
|
||||
* @param result the callback to be called when the command has fully executed
|
||||
*/
|
||||
public void onCommand(Sender sender, String label, List<String> args, Callback<CommandResult> result) {
|
||||
public void onCommand(Sender sender, String label, List<String> args, Consumer<CommandResult> result) {
|
||||
plugin.doAsync(() -> {
|
||||
CommandResult r = onCommand(sender, label, args);
|
||||
plugin.doSync(() -> result.onComplete(r));
|
||||
if (result != null) {
|
||||
plugin.doSync(() -> result.accept(r));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -97,51 +109,93 @@ public class CommandManager {
|
||||
* @param args the arguments provided
|
||||
* @return if the command was successful
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public CommandResult onCommand(Sender sender, String label, List<String> args) {
|
||||
// Handle no arguments
|
||||
if (args.size() == 0) {
|
||||
sendCommandUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
Optional<MainCommand> o = mainCommands.stream()
|
||||
// Look for the main command.
|
||||
Optional<BaseCommand> o = mainCommands.stream()
|
||||
.filter(m -> m.getName().equalsIgnoreCase(args.get(0)))
|
||||
.limit(1)
|
||||
.findAny();
|
||||
|
||||
// Main command not found
|
||||
if (!o.isPresent()) {
|
||||
sendCommandUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final MainCommand main = o.get();
|
||||
// Check the Sender has permission to use the main command.
|
||||
final Command main = o.get();
|
||||
if (!main.isAuthorized(sender)) {
|
||||
sendCommandUsage(sender, label);
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
if (main.getRequiredArgsLength() == 0) {
|
||||
try {
|
||||
return main.execute(plugin, sender, null, label);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
}
|
||||
List<String> arguments = new ArrayList<>(args);
|
||||
handleRewrites(arguments);
|
||||
arguments.remove(0); // remove the main command arg.
|
||||
|
||||
if (args.size() == 1) {
|
||||
// Check the correct number of args were given for the main command
|
||||
if (main.getArgumentCheck().test(arguments.size())) {
|
||||
main.sendUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
List<String> arguments = new ArrayList<>(args);
|
||||
handleRewrites(arguments);
|
||||
|
||||
// Try to execute the command.
|
||||
CommandResult result;
|
||||
try {
|
||||
return main.execute(plugin, sender, arguments.subList(1, arguments.size()), label);
|
||||
result = main.execute(plugin, sender, null, arguments, label);
|
||||
} catch (CommandException e) {
|
||||
result = handleException(e, sender, label, main);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
result = CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static CommandResult handleException(CommandException e, Sender sender, String label, Command command) {
|
||||
if (e instanceof ArgumentUtils.ArgumentException) {
|
||||
if (e instanceof ArgumentUtils.DetailedUsageException) {
|
||||
command.sendDetailedUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (e instanceof ArgumentUtils.UseInheritException) {
|
||||
Message.USE_INHERIT_COMMAND.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (e instanceof ArgumentUtils.InvalidServerException) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (e instanceof ArgumentUtils.PastDateException) {
|
||||
Message.PAST_DATE_ERROR.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (e instanceof ArgumentUtils.InvalidDateException) {
|
||||
Message.ILLEGAL_DATE_ERROR.send(sender, ((ArgumentUtils.InvalidDateException) e).getInvalidDate());
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (e instanceof ArgumentUtils.InvalidPriorityException) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, ((ArgumentUtils.InvalidPriorityException) e).getInvalidPriority());
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
// Not something we can catch.
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,24 +206,29 @@ public class CommandManager {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> onTabComplete(Sender sender, List<String> args) {
|
||||
final List<MainCommand> mains = mainCommands.stream()
|
||||
final List<Command> mains = mainCommands.stream()
|
||||
.filter(m -> m.isAuthorized(sender))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Not yet past the point of entering a main command
|
||||
if (args.size() <= 1) {
|
||||
|
||||
// Nothing yet entered
|
||||
if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) {
|
||||
return mains.stream()
|
||||
.map(m -> m.getName().toLowerCase())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// Started typing a main command
|
||||
return mains.stream()
|
||||
.map(m -> m.getName().toLowerCase())
|
||||
.filter(s -> s.startsWith(args.get(0).toLowerCase()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
Optional<MainCommand> o = mains.stream()
|
||||
// Find a main command matching the first arg
|
||||
Optional<Command> o = mains.stream()
|
||||
.filter(m -> m.getName().equalsIgnoreCase(args.get(0)))
|
||||
.limit(1)
|
||||
.findAny();
|
||||
@@ -178,7 +237,8 @@ public class CommandManager {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return o.get().onTabComplete(sender, args.subList(1, args.size()), plugin);
|
||||
// Pass the processing onto the main command
|
||||
return o.get().tabComplete(plugin, sender, args.subList(1, args.size()));
|
||||
}
|
||||
|
||||
private void sendCommandUsage(Sender sender, String label) {
|
||||
@@ -194,7 +254,6 @@ public class CommandManager {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String s = args.get(2).toLowerCase();
|
||||
switch (s) {
|
||||
// Provide aliases
|
||||
@@ -204,6 +263,7 @@ public class CommandManager {
|
||||
args.remove(2);
|
||||
args.add(2, "permission");
|
||||
break;
|
||||
case "chat":
|
||||
case "m":
|
||||
args.remove(2);
|
||||
args.add(2, "meta");
|
||||
@@ -212,12 +272,19 @@ public class CommandManager {
|
||||
case "inherit":
|
||||
case "inheritances":
|
||||
case "group":
|
||||
case "groups":
|
||||
case "rank":
|
||||
case "ranks":
|
||||
case "parents":
|
||||
args.remove(2);
|
||||
args.add(2, "parent");
|
||||
break;
|
||||
|
||||
// Provide backwards compatibility
|
||||
case "setprimarygroup":
|
||||
args.remove(2);
|
||||
args.add(2, "switchprimarygroup");
|
||||
break;
|
||||
case "listnodes":
|
||||
args.remove(2);
|
||||
args.add(2, "permission");
|
||||
@@ -229,6 +296,16 @@ public class CommandManager {
|
||||
case "unsettemp":
|
||||
args.add(2, "permission");
|
||||
break;
|
||||
case "haspermission":
|
||||
args.remove(2);
|
||||
args.add(2, "permission");
|
||||
args.add(3, "check");
|
||||
break;
|
||||
case "inheritspermission":
|
||||
args.remove(2);
|
||||
args.add(2, "permission");
|
||||
args.add(3, "checkinherits");
|
||||
break;
|
||||
case "listgroups":
|
||||
args.remove(2);
|
||||
args.add(2, "parent");
|
||||
@@ -240,6 +317,11 @@ public class CommandManager {
|
||||
args.add(2, "parent");
|
||||
args.add(3, "add");
|
||||
break;
|
||||
case "setgroup":
|
||||
args.remove(2);
|
||||
args.add(2, "parent");
|
||||
args.add(3, "set");
|
||||
break;
|
||||
case "removegroup":
|
||||
case "unsetinherit":
|
||||
args.remove(2);
|
||||
@@ -273,6 +355,22 @@ public class CommandManager {
|
||||
case "removetempsuffix":
|
||||
args.add(2, "meta");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Provide lazy set rewrite
|
||||
boolean lazySet = (
|
||||
args.size() >= 6 &&
|
||||
args.get(2).equalsIgnoreCase("permission") &&
|
||||
args.get(3).toLowerCase().startsWith("set") &&
|
||||
(args.get(5).equalsIgnoreCase("none") || args.get(5).equalsIgnoreCase("0"))
|
||||
);
|
||||
|
||||
if (lazySet) {
|
||||
args.remove(5);
|
||||
args.remove(3);
|
||||
args.add(3, "unset");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,13 +34,13 @@ public enum CommandResult {
|
||||
INVALID_ARGS(false),
|
||||
NO_PERMISSION(false);
|
||||
|
||||
private boolean booleanValue;
|
||||
private boolean value;
|
||||
|
||||
public boolean booleanValue() {
|
||||
return booleanValue;
|
||||
public boolean asBoolean() {
|
||||
return value;
|
||||
}
|
||||
|
||||
static CommandResult of(boolean b) {
|
||||
public static CommandResult of(boolean b) {
|
||||
return b ? SUCCESS : FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ package me.lucko.luckperms.common.commands;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -22,11 +22,12 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -34,50 +35,27 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public abstract class MainCommand<T> {
|
||||
public abstract class MainCommand<T> extends BaseCommand<Void, T> {
|
||||
|
||||
/**
|
||||
* The name of the main command
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The command usage
|
||||
*/
|
||||
private final String usage;
|
||||
|
||||
/**
|
||||
* How many arguments are required for the command to run
|
||||
*/
|
||||
private final int requiredArgsLength;
|
||||
|
||||
/**
|
||||
* A list of the sub commands under this main command
|
||||
*/
|
||||
@Getter
|
||||
private final List<SubCommand<T>> subCommands;
|
||||
private final String usage;
|
||||
private final int minArgs; // equals 1 if the command doesn't take a mid argument, e.g. /lp user <USER> sub-command....
|
||||
|
||||
MainCommand(String name, String usage, int requiredArgsLength) {
|
||||
this(name, usage, requiredArgsLength, ImmutableList.of());
|
||||
public MainCommand(String name, String description, String usage, int minArgs, List<Command<T, ?>> children) {
|
||||
super(name, description, null, Predicates.alwaysFalse(), null, children);
|
||||
this.usage = usage;
|
||||
this.minArgs = minArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this main command is ran
|
||||
* @param plugin a link to the main plugin instance
|
||||
* @param sender the sender to executed the command
|
||||
* @param args the stripped arguments given
|
||||
* @param label the command label used
|
||||
*/
|
||||
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
|
||||
if (args.size() < requiredArgsLength) {
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Void v, List<String> args, String label) throws CommandException {
|
||||
if (args.size() < minArgs) {
|
||||
sendUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
Optional<SubCommand<T>> o = getSubCommands().stream()
|
||||
.filter(s -> s.getName().equalsIgnoreCase(args.get(requiredArgsLength - 1)))
|
||||
Optional<Command<T, ?>> o = getSubCommands().stream()
|
||||
.filter(s -> s.getName().equalsIgnoreCase(args.get(minArgs - 1)))
|
||||
.limit(1)
|
||||
.findAny();
|
||||
|
||||
@@ -86,26 +64,32 @@ public abstract class MainCommand<T> {
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final SubCommand<T> sub = o.get();
|
||||
final Command<T, ?> sub = o.get();
|
||||
if (!sub.isAuthorized(sender)) {
|
||||
Message.COMMAND_NO_PERMISSION.send(sender);
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
List<String> strippedArgs = new ArrayList<>();
|
||||
if (args.size() > requiredArgsLength) {
|
||||
strippedArgs.addAll(args.subList(requiredArgsLength, args.size()));
|
||||
if (args.size() > minArgs) {
|
||||
strippedArgs.addAll(args.subList(minArgs, args.size()));
|
||||
}
|
||||
|
||||
if (sub.getIsArgumentInvalid().test(strippedArgs.size())) {
|
||||
sub.sendDetailedUsage(sender);
|
||||
if (sub.getArgumentCheck().test(strippedArgs.size())) {
|
||||
sub.sendDetailedUsage(sender, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String name = args.get(0).toLowerCase();
|
||||
T t = getTarget(name, plugin, sender);
|
||||
if (t != null) {
|
||||
CommandResult result = sub.execute(plugin, sender, t, strippedArgs, label);
|
||||
CommandResult result;
|
||||
try {
|
||||
result = sub.execute(plugin, sender, t, strippedArgs, label);
|
||||
} catch (CommandException e) {
|
||||
result = CommandManager.handleException(e, sender, label, sub);
|
||||
}
|
||||
|
||||
cleanup(t, plugin);
|
||||
return result;
|
||||
}
|
||||
@@ -113,61 +97,9 @@ public abstract class MainCommand<T> {
|
||||
return CommandResult.LOADING_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the object the command is acting upon, and runs the callback if successful
|
||||
* @param target the name of the object to be looked up
|
||||
* @param plugin a link to the main plugin instance
|
||||
* @param sender the user who send the command (used to send error messages if the lookup was unsuccessful)
|
||||
*/
|
||||
protected abstract T getTarget(String target, LuckPermsPlugin plugin, Sender sender);
|
||||
|
||||
protected abstract void cleanup(T t, LuckPermsPlugin plugin);
|
||||
|
||||
/**
|
||||
* Get a list of {@link T} objects for tab completion
|
||||
* @param plugin a link to the main plugin instance
|
||||
* @return a list of strings
|
||||
*/
|
||||
protected abstract List<String> getObjects(LuckPermsPlugin plugin);
|
||||
|
||||
/**
|
||||
* Send the command usage to a sender
|
||||
* @param sender the sender to send the usage to
|
||||
* @param label the command label used
|
||||
*/
|
||||
protected void sendUsage(Sender sender, String label) {
|
||||
if (getSubCommands().isEmpty()) {
|
||||
Util.sendPluginMessage(sender, "&3> &a" + String.format(getUsage(), label));
|
||||
return;
|
||||
}
|
||||
|
||||
List<SubCommand> subs = getSubCommands().stream()
|
||||
.filter(s -> s.isAuthorized(sender))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (subs.size() > 0) {
|
||||
Util.sendPluginMessage(sender, "&b" + getName() + " Sub Commands: &7(" + String.format(getUsage(), label) + " ...)");
|
||||
|
||||
for (SubCommand s : subs) {
|
||||
s.sendUsage(sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
Message.COMMAND_NO_PERMISSION.send(sender);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a sender has permission to use this command
|
||||
* @param sender the sender trying to use the command
|
||||
* @return true if the sender can use the command
|
||||
*/
|
||||
protected boolean isAuthorized(Sender sender) {
|
||||
return getSubCommands().stream().filter(sc -> sc.isAuthorized(sender)).count() != 0;
|
||||
}
|
||||
|
||||
protected List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
|
||||
final List<String> objects = getObjects(plugin);
|
||||
@Override
|
||||
public List<String> tabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
final List<String> objects = getTargets(plugin);
|
||||
|
||||
if (args.size() <= 1) {
|
||||
if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) {
|
||||
@@ -179,7 +111,7 @@ public abstract class MainCommand<T> {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
final List<SubCommand<T>> subs = getSubCommands().stream()
|
||||
final List<Command<T, ?>> subs = getSubCommands().stream()
|
||||
.filter(s -> s.isAuthorized(sender))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -196,7 +128,7 @@ public abstract class MainCommand<T> {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
Optional<SubCommand<T>> o = subs.stream()
|
||||
Optional<Command<T, ?>> o = subs.stream()
|
||||
.filter(s -> s.getName().equalsIgnoreCase(args.get(1)))
|
||||
.limit(1)
|
||||
.findAny();
|
||||
@@ -205,6 +137,56 @@ public abstract class MainCommand<T> {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return o.get().onTabComplete(plugin, sender, args.subList(2, args.size()));
|
||||
return o.get().tabComplete(plugin, sender, args.subList(2, args.size()));
|
||||
}
|
||||
|
||||
protected abstract List<String> getTargets(LuckPermsPlugin plugin);
|
||||
protected abstract T getTarget(String target, LuckPermsPlugin plugin, Sender sender);
|
||||
protected abstract void cleanup(T t, LuckPermsPlugin plugin);
|
||||
|
||||
@Override
|
||||
public void sendUsage(Sender sender, String label) {
|
||||
/*
|
||||
if (getSubCommands().isEmpty()) {
|
||||
Util.sendPluginMessage(sender, "&3> &a" + String.format(getUsage(), label));
|
||||
return;
|
||||
*/
|
||||
|
||||
List<Command> subs = getSubCommands().stream()
|
||||
.filter(s -> s.isAuthorized(sender))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (subs.size() > 0) {
|
||||
Util.sendPluginMessage(sender, "&b" + getName() + " Sub Commands: &7(" + String.format(usage, label) + " ...)");
|
||||
|
||||
for (Command s : subs) {
|
||||
s.sendUsage(sender, label);
|
||||
}
|
||||
|
||||
} else {
|
||||
Message.COMMAND_NO_PERMISSION.send(sender);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDetailedUsage(Sender sender, String label) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthorized(Sender sender) {
|
||||
return getSubCommands().stream().filter(sc -> sc.isAuthorized(sender)).count() != 0;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public Optional<List<Command<T, ?>>> getChildren() {
|
||||
return super.getChildren();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<Command<T, ?>> getSubCommands() {
|
||||
return getChildren().get();
|
||||
}
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Factory class to make a thread-safe sender instance
|
||||
* @param <T> the command sender type
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public abstract class SenderFactory<T> implements Runnable {
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final Map<T, List<String>> messages = new HashMap<>();
|
||||
private final AtomicBoolean shouldSend = new AtomicBoolean(false);
|
||||
private final SenderFactory<T> factory = this;
|
||||
|
||||
protected abstract String getName(T t);
|
||||
protected abstract UUID getUuid(T t);
|
||||
protected abstract void sendMessage(T t, String s);
|
||||
protected abstract boolean hasPermission(T t, String node);
|
||||
|
||||
public final Sender wrap(T t) {
|
||||
return new SenderImp(plugin, t, null);
|
||||
}
|
||||
|
||||
public final Sender wrap(T t, Set<Permission> toCheck) {
|
||||
return new SenderImp(plugin, t, toCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
if (!shouldSend.getAndSet(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (messages) {
|
||||
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;
|
||||
|
||||
@Getter
|
||||
private final LuckPermsPlugin platform;
|
||||
|
||||
private SenderImp(LuckPermsPlugin platform, T t, Set<Permission> toCheck) {
|
||||
this.platform = platform;
|
||||
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) {
|
||||
this.perms = ((toCheck == null || toCheck.isEmpty()) ? Arrays.stream(Permission.values()) : toCheck.stream())
|
||||
.collect(ImmutableCollectors.toImmutableMap(p -> p, p -> {
|
||||
for (String s : p.getNodes()) {
|
||||
if (factory.hasPermission(t, s)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public abstract class SingleCommand extends BaseCommand<Void, Void> {
|
||||
|
||||
@Getter
|
||||
private final String usage;
|
||||
|
||||
public SingleCommand(String name, String description, String usage, Permission permission, Predicate<Integer> argumentCheck, List<Arg> args) {
|
||||
super(name, description, permission, argumentCheck, args, null);
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Void v, List<String> args, String label) throws CommandException {
|
||||
return execute(plugin, sender, args, label);
|
||||
}
|
||||
|
||||
public abstract CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) throws CommandException;
|
||||
|
||||
@Override
|
||||
public void sendUsage(Sender sender, String label) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (getArgs().isPresent()) {
|
||||
sb.append("&3 - &7");
|
||||
for (Arg arg : getArgs().get()) {
|
||||
sb.append(arg.asPrettyString()).append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
Util.sendPluginMessage(sender, "&3> &a" + getName().toLowerCase() + sb.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDetailedUsage(Sender sender, String label) {
|
||||
Util.sendPluginMessage(sender, "&3&lCommand Usage &3- &b" + getName());
|
||||
Util.sendPluginMessage(sender, "&b> &7" + getDescription());
|
||||
if (getArgs().isPresent()) {
|
||||
Util.sendPluginMessage(sender, "&3Arguments:");
|
||||
for (Arg arg : getArgs().get()) {
|
||||
Util.sendPluginMessage(sender, "&b- " + arg.asPrettyString() + "&3 -> &7" + arg.getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An extension of {@link MainCommand} for implementations without any subcommands
|
||||
*/
|
||||
public class SingleMainCommand extends MainCommand<Object> {
|
||||
private final Permission permission;
|
||||
|
||||
public SingleMainCommand(String name, String usage, int requiredArgsLength, Permission permission) {
|
||||
super(name, usage, requiredArgsLength);
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
|
||||
// Do nothing, allow the implementation to override this
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getTarget(String target, LuckPermsPlugin plugin, Sender sender) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanup(Object o, LuckPermsPlugin plugin) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getObjects(LuckPermsPlugin plugin) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SubCommand<Object>> getSubCommands() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAuthorized(Sender sender) {
|
||||
return permission.isAuthorized(sender);
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,10 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.groups.Group;
|
||||
@@ -43,93 +43,45 @@ import java.util.stream.Collectors;
|
||||
* Abstract SubCommand class
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public abstract class SubCommand<T> {
|
||||
public abstract class SubCommand<T> extends Command<T, Void> {
|
||||
|
||||
/**
|
||||
* The name of the sub command
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* A brief description of what the sub command does
|
||||
*/
|
||||
private final String description;
|
||||
|
||||
/**
|
||||
* The permission needed to use this command
|
||||
*/
|
||||
private final Permission permission;
|
||||
|
||||
/**
|
||||
* Predicate to test if the argument length given is invalid
|
||||
*/
|
||||
private final Predicate<? super Integer> isArgumentInvalid;
|
||||
|
||||
private final ImmutableList<Arg> args;
|
||||
|
||||
/**
|
||||
* Called when this sub command is ran
|
||||
* @param plugin a link to the main plugin instance
|
||||
* @param sender the sender to executed the command
|
||||
* @param t the object the command is operating on
|
||||
* @param args the stripped arguments given
|
||||
* @param label the command label used
|
||||
*/
|
||||
public abstract CommandResult execute(LuckPermsPlugin plugin, Sender sender, T t, List<String> args, String label);
|
||||
|
||||
/**
|
||||
* Returns a list of suggestions, which are empty by default. Sub classes that give tab complete suggestions override
|
||||
* this method to give their own list.
|
||||
* @param plugin the plugin instance
|
||||
* @param sender who is tab completing
|
||||
* @param args the arguments so far
|
||||
* @return a list of suggestions
|
||||
*/
|
||||
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
return Collections.emptyList();
|
||||
public SubCommand(String name, String description, Permission permission, Predicate<Integer> argumentCheck, List<Arg> args) {
|
||||
super(name, description, permission, argumentCheck, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the command usage to a sender
|
||||
* @param sender the sender to send the usage to
|
||||
*/
|
||||
public void sendUsage(Sender sender) {
|
||||
String usage = "";
|
||||
if (args != null) {
|
||||
usage += "&3 - &7";
|
||||
for (Arg arg : args) {
|
||||
usage += arg.asPrettyString() + " ";
|
||||
@Override
|
||||
public void sendUsage(Sender sender, String label) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (getArgs().isPresent()) {
|
||||
sb.append("&3 - &7");
|
||||
for (Arg arg : getArgs().get()) {
|
||||
sb.append(arg.asPrettyString()).append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
Util.sendPluginMessage(sender, "&3> &a" + getName().toLowerCase() + usage);
|
||||
Util.sendPluginMessage(sender, "&3> &a" + getName().toLowerCase() + sb.toString());
|
||||
}
|
||||
|
||||
public void sendDetailedUsage(Sender sender) {
|
||||
@Override
|
||||
public void sendDetailedUsage(Sender sender, String label) {
|
||||
Util.sendPluginMessage(sender, "&3&lCommand Usage &3- &b" + getName());
|
||||
Util.sendPluginMessage(sender, "&b> &7" + getDescription());
|
||||
if (args != null) {
|
||||
if (getArgs().isPresent()) {
|
||||
Util.sendPluginMessage(sender, "&3Arguments:");
|
||||
for (Arg arg : args) {
|
||||
for (Arg arg : getArgs().get()) {
|
||||
Util.sendPluginMessage(sender, "&b- " + arg.asPrettyString() + "&3 -> &7" + arg.getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a sender has permission to use this command
|
||||
* @param sender the sender trying to use the command
|
||||
* @return true if the sender can use the command
|
||||
*/
|
||||
public boolean isAuthorized(Sender sender) {
|
||||
return permission.isAuthorized(sender);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------------
|
||||
* Utility methods used by #onTabComplete and #execute implementations in sub classes
|
||||
* Utility methods used by #tabComplete and #execute implementations in sub classes
|
||||
* ----------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -162,32 +114,35 @@ public abstract class SubCommand<T> {
|
||||
}
|
||||
|
||||
public static void save(User user, Sender sender, LuckPermsPlugin plugin) {
|
||||
if (plugin.getDatastore().saveUser(user).getUnchecked()) {
|
||||
boolean success = plugin.getStorage().force().saveUser(user).join();
|
||||
user.getRefreshBuffer().requestDirectly();
|
||||
|
||||
if (success) {
|
||||
Message.USER_SAVE_SUCCESS.send(sender);
|
||||
} else {
|
||||
Message.USER_SAVE_ERROR.send(sender);
|
||||
}
|
||||
|
||||
user.getRefreshBuffer().request().getUnchecked();
|
||||
}
|
||||
|
||||
public static void save(Group group, Sender sender, LuckPermsPlugin plugin) {
|
||||
if (plugin.getDatastore().saveGroup(group).getUnchecked()) {
|
||||
boolean success = plugin.getStorage().force().saveGroup(group).join();
|
||||
plugin.getUpdateTaskBuffer().requestDirectly();
|
||||
|
||||
if (success) {
|
||||
Message.GROUP_SAVE_SUCCESS.send(sender);
|
||||
} else {
|
||||
Message.GROUP_SAVE_ERROR.send(sender);
|
||||
}
|
||||
|
||||
plugin.getUpdateTaskBuffer().request();
|
||||
}
|
||||
|
||||
public static void save(Track track, Sender sender, LuckPermsPlugin plugin) {
|
||||
if (plugin.getDatastore().saveTrack(track).getUnchecked()) {
|
||||
boolean success = plugin.getStorage().force().saveTrack(track).join();
|
||||
plugin.getUpdateTaskBuffer().requestDirectly();
|
||||
|
||||
if (success) {
|
||||
Message.TRACK_SAVE_SUCCESS.send(sender);
|
||||
} else {
|
||||
Message.TRACK_SAVE_ERROR.send(sender);
|
||||
}
|
||||
|
||||
plugin.getUpdateTaskBuffer().request();
|
||||
}
|
||||
}
|
||||
+65
-21
@@ -22,11 +22,16 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands.generic;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.*;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.SubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -34,29 +39,24 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SecondaryMainCommand<T extends PermissionHolder> extends SubCommand<T> {
|
||||
public class SharedMainCommand<T extends PermissionHolder> extends SubCommand<T> {
|
||||
private boolean user;
|
||||
private final List<SecondarySubCommand> secondaryCommands;
|
||||
private final List<SharedSubCommand> secondaryCommands;
|
||||
|
||||
public SecondaryMainCommand(String name, String description, boolean user, List<SecondarySubCommand> secondaryCommands) {
|
||||
super(name, description, null, Predicate.alwaysFalse(),
|
||||
!name.equals("Meta") ? ImmutableList.copyOf(secondaryCommands.stream()
|
||||
.map(s -> Arg.create(s.getName(), false, s.getDescription()))
|
||||
.collect(Collectors.toList())
|
||||
) : null
|
||||
);
|
||||
public SharedMainCommand(String name, String description, boolean user, List<SharedSubCommand> secondaryCommands) {
|
||||
super(name, description, null, Predicates.alwaysFalse(), null);
|
||||
this.secondaryCommands = secondaryCommands;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, T t, List<String> args, String label) {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, T t, List<String> args, String label) throws CommandException {
|
||||
if (args.size() == 0) {
|
||||
sendUsageDetailed(sender, user, label);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
Optional<SecondarySubCommand> o = secondaryCommands.stream()
|
||||
Optional<SharedSubCommand> o = secondaryCommands.stream()
|
||||
.filter(s -> s.getName().equalsIgnoreCase(args.get(0)))
|
||||
.limit(1)
|
||||
.findAny();
|
||||
@@ -66,7 +66,7 @@ public class SecondaryMainCommand<T extends PermissionHolder> extends SubCommand
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final SecondarySubCommand sub = o.get();
|
||||
final SharedSubCommand sub = o.get();
|
||||
if (!sub.isAuthorized(sender, user)) {
|
||||
Message.COMMAND_NO_PERMISSION.send(sender);
|
||||
return CommandResult.NO_PERMISSION;
|
||||
@@ -82,12 +82,56 @@ public class SecondaryMainCommand<T extends PermissionHolder> extends SubCommand
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
return sub.execute(plugin, sender, t, strippedArgs);
|
||||
CommandResult result;
|
||||
try {
|
||||
result = sub.execute(plugin, sender, t, strippedArgs);
|
||||
} catch (CommandException e) {
|
||||
result = handleException(e, sender, sub);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static CommandResult handleException(CommandException e, Sender sender, SharedSubCommand command) {
|
||||
if (e instanceof ArgumentUtils.ArgumentException) {
|
||||
if (e instanceof ArgumentUtils.DetailedUsageException) {
|
||||
command.sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (e instanceof ArgumentUtils.UseInheritException) {
|
||||
Message.USE_INHERIT_COMMAND.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (e instanceof ArgumentUtils.InvalidServerException) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (e instanceof ArgumentUtils.PastDateException) {
|
||||
Message.PAST_DATE_ERROR.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (e instanceof ArgumentUtils.InvalidDateException) {
|
||||
Message.ILLEGAL_DATE_ERROR.send(sender, ((ArgumentUtils.InvalidDateException) e).getInvalidDate());
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (e instanceof ArgumentUtils.InvalidPriorityException) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, ((ArgumentUtils.InvalidPriorityException) e).getInvalidPriority());
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
// Not something we can catch.
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
final List<SecondarySubCommand> subs = secondaryCommands.stream()
|
||||
public List<String> tabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
final List<SharedSubCommand> subs = secondaryCommands.stream()
|
||||
.filter(s -> s.isAuthorized(sender, user))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -104,7 +148,7 @@ public class SecondaryMainCommand<T extends PermissionHolder> extends SubCommand
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
Optional<SecondarySubCommand> o = subs.stream()
|
||||
Optional<SharedSubCommand> o = subs.stream()
|
||||
.filter(s -> s.getName().equalsIgnoreCase(args.get(0)))
|
||||
.limit(1)
|
||||
.findAny();
|
||||
@@ -118,7 +162,7 @@ public class SecondaryMainCommand<T extends PermissionHolder> extends SubCommand
|
||||
|
||||
@Override
|
||||
public boolean isAuthorized(Sender sender) {
|
||||
for (SecondarySubCommand subCommand : secondaryCommands) {
|
||||
for (SharedSubCommand subCommand : secondaryCommands) {
|
||||
if (subCommand.isAuthorized(sender, user)) {
|
||||
return true;
|
||||
}
|
||||
@@ -127,7 +171,7 @@ public class SecondaryMainCommand<T extends PermissionHolder> extends SubCommand
|
||||
}
|
||||
|
||||
private void sendUsageDetailed(Sender sender, boolean user, String label) {
|
||||
List<SecondarySubCommand> subs = secondaryCommands.stream()
|
||||
List<SharedSubCommand> subs = secondaryCommands.stream()
|
||||
.filter(s -> s.isAuthorized(sender, user))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -138,7 +182,7 @@ public class SecondaryMainCommand<T extends PermissionHolder> extends SubCommand
|
||||
Util.sendPluginMessage(sender, "&b" + getName() + " Sub Commands: &7(" + String.format("/%s group <group> " + getName().toLowerCase() + " ...)", label));
|
||||
}
|
||||
|
||||
for (SecondarySubCommand s : subs) {
|
||||
for (SharedSubCommand s : subs) {
|
||||
s.sendUsage(sender);
|
||||
}
|
||||
|
||||
+12
-7
@@ -26,7 +26,12 @@ import com.google.common.collect.ImmutableList;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.*;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.SubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.groups.Group;
|
||||
@@ -38,7 +43,7 @@ import java.util.function.Predicate;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public abstract class SecondarySubCommand {
|
||||
public abstract class SharedSubCommand {
|
||||
|
||||
/**
|
||||
* The name of the sub command
|
||||
@@ -63,22 +68,22 @@ public abstract class SecondarySubCommand {
|
||||
|
||||
private final ImmutableList<Arg> args;
|
||||
|
||||
public abstract CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args);
|
||||
public abstract CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException;
|
||||
|
||||
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public void sendUsage(Sender sender) {
|
||||
String usage = "";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (args != null) {
|
||||
usage += "&3 - &7";
|
||||
sb.append("&3 - &7");
|
||||
for (Arg arg : args) {
|
||||
usage += arg.asPrettyString() + " ";
|
||||
sb.append(arg.asPrettyString()).append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
Util.sendPluginMessage(sender, "&3> &a" + getName() + usage);
|
||||
Util.sendPluginMessage(sender, "&3> &a" + getName() + sb.toString());
|
||||
}
|
||||
|
||||
public void sendDetailedUsage(Sender sender) {
|
||||
+4
-4
@@ -23,13 +23,13 @@
|
||||
package me.lucko.luckperms.common.commands.generic.meta;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondaryMainCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedMainCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
|
||||
public class CommandMeta<T extends PermissionHolder> extends SecondaryMainCommand<T> {
|
||||
public class CommandMeta<T extends PermissionHolder> extends SharedMainCommand<T> {
|
||||
public CommandMeta(boolean user) {
|
||||
super("Meta", "Edit metadata values", user, ImmutableList.<SecondarySubCommand>builder()
|
||||
super("Meta", "Edit metadata values", user, ImmutableList.<SharedSubCommand>builder()
|
||||
.add(new MetaInfo())
|
||||
.add(new MetaSet())
|
||||
.add(new MetaUnset())
|
||||
|
||||
+29
-39
@@ -25,22 +25,26 @@ package me.lucko.luckperms.common.commands.generic.meta;
|
||||
import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaAddPrefix extends SecondarySubCommand {
|
||||
public class MetaAddPrefix extends SharedSubCommand {
|
||||
public MetaAddPrefix() {
|
||||
super("addprefix", "Adds a prefix", Permission.USER_META_ADDPREFIX, Permission.GROUP_META_ADDPREFIX, Predicate.notInRange(2, 4),
|
||||
super("addprefix", "Adds a prefix", Permission.USER_META_ADDPREFIX, Permission.GROUP_META_ADDPREFIX,
|
||||
Predicates.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the prefix at"),
|
||||
Arg.create("prefix", true, "the prefix string"),
|
||||
@@ -51,51 +55,37 @@ public class MetaAddPrefix extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
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;
|
||||
}
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String prefix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
final String node = "prefix." + priority + "." + MetaUtils.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) {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
holder.setPermission(node, true);
|
||||
Message.ADDPREFIX_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority);
|
||||
break;
|
||||
case SERVER:
|
||||
holder.setPermission(node, true, server);
|
||||
Message.ADDPREFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
holder.setPermission(node, true, server, world);
|
||||
Message.ADDPREFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
holder.setPermission(node, true);
|
||||
Message.ADDPREFIX_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addprefix " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
|
||||
+29
-39
@@ -25,22 +25,26 @@ package me.lucko.luckperms.common.commands.generic.meta;
|
||||
import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaAddSuffix extends SecondarySubCommand {
|
||||
public class MetaAddSuffix extends SharedSubCommand {
|
||||
public MetaAddSuffix() {
|
||||
super("addsuffix", "Adds a suffix", Permission.USER_META_ADDSUFFIX, Permission.GROUP_META_ADDSUFFIX, Predicate.notInRange(2, 4),
|
||||
super("addsuffix", "Adds a suffix", Permission.USER_META_ADDSUFFIX, Permission.GROUP_META_ADDSUFFIX,
|
||||
Predicates.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the suffix at"),
|
||||
Arg.create("suffix", true, "the suffix string"),
|
||||
@@ -51,51 +55,37 @@ public class MetaAddSuffix extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
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;
|
||||
}
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String suffix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
final String node = "suffix." + priority + "." + MetaUtils.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) {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
holder.setPermission(node, true);
|
||||
Message.ADDSUFFIX_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority);
|
||||
break;
|
||||
case SERVER:
|
||||
holder.setPermission(node, true, server);
|
||||
Message.ADDSUFFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addsuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
holder.setPermission(node, true, server, world);
|
||||
Message.ADDSUFFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addsuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
holder.setPermission(node, true);
|
||||
Message.ADDSUFFIX_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addsuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addsuffix " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
|
||||
+38
-58
@@ -25,23 +25,27 @@ package me.lucko.luckperms.common.commands.generic.meta;
|
||||
import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.DateUtil;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaAddTempPrefix extends SecondarySubCommand {
|
||||
public class MetaAddTempPrefix extends SharedSubCommand {
|
||||
public MetaAddTempPrefix() {
|
||||
super("addtempprefix", "Adds a prefix temporarily", Permission.USER_META_ADDTEMP_PREFIX, Permission.GROUP_META_ADDTEMP_PREFIX, Predicate.notInRange(3, 5),
|
||||
super("addtempprefix", "Adds a prefix temporarily", Permission.USER_META_ADDTEMP_PREFIX,
|
||||
Permission.GROUP_META_ADDTEMP_PREFIX, Predicates.notInRange(3, 5),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the prefix at"),
|
||||
Arg.create("prefix", true, "the prefix string"),
|
||||
@@ -53,68 +57,44 @@ public class MetaAddTempPrefix extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
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;
|
||||
}
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String prefix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
long duration = ArgumentUtils.handleDuration(2, args);
|
||||
String server = ArgumentUtils.handleServer(3, args);
|
||||
String world = ArgumentUtils.handleWorld(4, args);
|
||||
|
||||
final String node = "prefix." + priority + "." + MetaUtils.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) {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
holder.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_PREFIX_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority,
|
||||
DateUtil.formatDateDiff(duration)
|
||||
);
|
||||
break;
|
||||
case SERVER:
|
||||
holder.setPermission(node, true, server, duration);
|
||||
Message.ADD_TEMP_PREFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addtempprefix " + priority + " " + args.get(1) + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(4).toLowerCase();
|
||||
Message.ADD_TEMP_PREFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority,
|
||||
server, DateUtil.formatDateDiff(duration)
|
||||
);
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
holder.setPermission(node, true, server, world, duration);
|
||||
Message.ADD_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addtempprefix " + priority + " " + args.get(1) + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
holder.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_PREFIX_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addtempprefix " + priority + " " + args.get(1) + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
Message.ADD_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority,
|
||||
server, world, DateUtil.formatDateDiff(duration)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addtempprefix " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
|
||||
+38
-58
@@ -25,23 +25,27 @@ package me.lucko.luckperms.common.commands.generic.meta;
|
||||
import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.DateUtil;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaAddTempSuffix extends SecondarySubCommand {
|
||||
public class MetaAddTempSuffix extends SharedSubCommand {
|
||||
public MetaAddTempSuffix() {
|
||||
super("addtempsuffix", "Adds a suffix temporarily", Permission.USER_META_ADDTEMP_SUFFIX, Permission.GROUP_META_ADDTEMP_SUFFIX, Predicate.notInRange(3, 5),
|
||||
super("addtempsuffix", "Adds a suffix temporarily", Permission.USER_META_ADDTEMP_SUFFIX,
|
||||
Permission.GROUP_META_ADDTEMP_SUFFIX, Predicates.notInRange(3, 5),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the suffix at"),
|
||||
Arg.create("suffix", true, "the suffix string"),
|
||||
@@ -53,68 +57,44 @@ public class MetaAddTempSuffix extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
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;
|
||||
}
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String suffix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
long duration = ArgumentUtils.handleDuration(2, args);
|
||||
String server = ArgumentUtils.handleServer(3, args);
|
||||
String world = ArgumentUtils.handleWorld(4, args);
|
||||
|
||||
final String node = "suffix." + priority + "." + MetaUtils.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) {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
holder.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority,
|
||||
DateUtil.formatDateDiff(duration)
|
||||
);
|
||||
break;
|
||||
case SERVER:
|
||||
holder.setPermission(node, true, server, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addtempsuffix " + priority + " " + args.get(1) + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(4).toLowerCase();
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority,
|
||||
server, DateUtil.formatDateDiff(duration)
|
||||
);
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
holder.setPermission(node, true, server, world, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addtempsuffix " + priority + " " + args.get(1) + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
holder.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addtempsuffix " + priority + " " + args.get(1) + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority,
|
||||
server, world, DateUtil.formatDateDiff(duration)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta addtempsuffix " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
|
||||
+24
-22
@@ -24,22 +24,24 @@ package me.lucko.luckperms.common.commands.generic.meta;
|
||||
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaClear extends SecondarySubCommand {
|
||||
public class MetaClear extends SharedSubCommand {
|
||||
public MetaClear() {
|
||||
super("clear", "Clears all chat meta", Permission.USER_META_CLEAR, Permission.GROUP_META_CLEAR, Predicate.notInRange(0, 2),
|
||||
super("clear", "Clears all chat meta", Permission.USER_META_CLEAR, Permission.GROUP_META_CLEAR, Predicates.notInRange(0, 2),
|
||||
Arg.list(
|
||||
Arg.create("server", false, "the server name to filter by"),
|
||||
Arg.create("world", false, "the world name to filter by")
|
||||
@@ -48,25 +50,22 @@ public class MetaClear extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
int before = holder.getNodes().size();
|
||||
|
||||
if (args.size() == 0) {
|
||||
holder.clearMeta();
|
||||
} else {
|
||||
final String server = args.get(0);
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
String server = ArgumentUtils.handleServer(0, args);
|
||||
String world = ArgumentUtils.handleWorld(1, args);
|
||||
|
||||
if (args.size() == 2) {
|
||||
final String world = args.get(1);
|
||||
holder.clearMeta(server, world);
|
||||
|
||||
} else {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
holder.clearMeta();
|
||||
break;
|
||||
case SERVER:
|
||||
holder.clearMeta(server);
|
||||
}
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
holder.clearMeta(server, world);
|
||||
break;
|
||||
}
|
||||
|
||||
int changed = before - holder.getNodes().size();
|
||||
@@ -76,7 +75,10 @@ public class MetaClear extends SecondarySubCommand {
|
||||
Message.META_CLEAR_SUCCESS.send(sender, holder.getFriendlyName(), changed);
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder).action("meta clear " + args.stream().collect(Collectors.joining(" "))).build().submit(plugin, sender);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta clear " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
+56
-31
@@ -23,50 +23,44 @@
|
||||
package me.lucko.luckperms.common.commands.generic.meta;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.Util;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MetaInfo extends SecondarySubCommand {
|
||||
public class MetaInfo extends SharedSubCommand {
|
||||
public MetaInfo() {
|
||||
super("info", "Shows all chat meta", Permission.USER_META_INFO, Permission.GROUP_META_INFO, Predicate.alwaysFalse(), null);
|
||||
super("info", "Shows all chat meta", Permission.USER_META_INFO, Permission.GROUP_META_INFO, Predicates.alwaysFalse(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
SortedSet<Map.Entry<Integer, String>> prefixes = new TreeSet<>(Util.getMetaComparator().reversed());
|
||||
SortedSet<Map.Entry<Integer, String>> suffixes = new TreeSet<>(Util.getMetaComparator().reversed());
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
SortedSet<Map.Entry<Integer, LocalizedNode>> prefixes = new TreeSet<>(Util.META_COMPARATOR.reversed());
|
||||
SortedSet<Map.Entry<Integer, LocalizedNode>> suffixes = new TreeSet<>(Util.META_COMPARATOR.reversed());
|
||||
Set<LocalizedNode> meta = new HashSet<>();
|
||||
|
||||
for (Node node : holder.getAllNodes(null, Contexts.allowAll())) {
|
||||
if (!node.isSuffix() && !node.isPrefix()) {
|
||||
// Collect data
|
||||
for (LocalizedNode node : holder.getAllNodes(null, ExtractedContexts.generate(Contexts.allowAll()))) {
|
||||
if (!node.isSuffix() && !node.isPrefix() && !node.isMeta()) {
|
||||
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()));
|
||||
prefixes.add(new AbstractMap.SimpleEntry<>(node.getPrefix().getKey(), node));
|
||||
} else if (node.isSuffix()) {
|
||||
suffixes.add(new AbstractMap.SimpleEntry<>(node.getSuffix().getKey(), node));
|
||||
} else if (node.isMeta()) {
|
||||
meta.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,8 +68,14 @@ public class MetaInfo extends SecondarySubCommand {
|
||||
Message.CHAT_META_PREFIX_NONE.send(sender, holder.getFriendlyName());
|
||||
} else {
|
||||
Message.CHAT_META_PREFIX_HEADER.send(sender, holder.getFriendlyName());
|
||||
for (Map.Entry<Integer, String> e : prefixes) {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue());
|
||||
for (Map.Entry<Integer, LocalizedNode> e : prefixes) {
|
||||
String location = processLocation(e.getValue(), holder);
|
||||
if (e.getValue().isServerSpecific() || e.getValue().isWorldSpecific() || !e.getValue().getContexts().isEmpty()) {
|
||||
String context = Util.getNodeContextDescription(e.getValue());
|
||||
Message.CHAT_META_ENTRY_WITH_CONTEXT.send(sender, e.getKey(), e.getValue().getPrefix().getValue(), location, context);
|
||||
} else {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue().getPrefix().getValue(), location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,11 +83,36 @@ public class MetaInfo extends SecondarySubCommand {
|
||||
Message.CHAT_META_SUFFIX_NONE.send(sender, holder.getFriendlyName());
|
||||
} else {
|
||||
Message.CHAT_META_SUFFIX_HEADER.send(sender, holder.getFriendlyName());
|
||||
for (Map.Entry<Integer, String> e : suffixes) {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue());
|
||||
for (Map.Entry<Integer, LocalizedNode> e : suffixes) {
|
||||
String location = processLocation(e.getValue(), holder);
|
||||
if (e.getValue().isServerSpecific() || e.getValue().isWorldSpecific() || !e.getValue().getContexts().isEmpty()) {
|
||||
String context = Util.getNodeContextDescription(e.getValue());
|
||||
Message.CHAT_META_ENTRY_WITH_CONTEXT.send(sender, e.getKey(), e.getValue().getSuffix().getValue(), location, context);
|
||||
} else {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue().getSuffix().getValue(), location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (meta.isEmpty()) {
|
||||
Message.META_NONE.send(sender, holder.getFriendlyName());
|
||||
} else {
|
||||
Message.META_HEADER.send(sender, holder.getFriendlyName());
|
||||
for (LocalizedNode m : meta) {
|
||||
String location = processLocation(m, holder);
|
||||
if (m.isServerSpecific() || m.isWorldSpecific() || !m.getContexts().isEmpty()) {
|
||||
String context = Util.getNodeContextDescription(m);
|
||||
Message.META_ENTRY_WITH_CONTEXT.send(sender, m.getMeta().getKey(), m.getMeta().getValue(), location, context);
|
||||
} else {
|
||||
Message.META_ENTRY.send(sender, m.getMeta().getKey(), m.getMeta().getValue(), location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private static String processLocation(LocalizedNode node, PermissionHolder holder) {
|
||||
return node.getLocation().equalsIgnoreCase(holder.getObjectName()) ? "self" : node.getLocation();
|
||||
}
|
||||
}
|
||||
+41
-67
@@ -26,23 +26,27 @@ import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaRemovePrefix extends SecondarySubCommand {
|
||||
public class MetaRemovePrefix extends SharedSubCommand {
|
||||
public MetaRemovePrefix() {
|
||||
super("removeprefix", "Removes a prefix", Permission.USER_META_REMOVEPREFIX, Permission.GROUP_META_REMOVEPREFIX, Predicate.notInRange(2, 4),
|
||||
super("removeprefix", "Removes a prefix", Permission.USER_META_REMOVEPREFIX, Permission.GROUP_META_REMOVEPREFIX,
|
||||
Predicates.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the prefix at"),
|
||||
Arg.create("prefix", true, "the prefix string"),
|
||||
@@ -53,32 +57,14 @@ public class MetaRemovePrefix extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
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;
|
||||
}
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String prefix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
// Handle bulk removal
|
||||
if (prefix.equalsIgnoreCase("null")) {
|
||||
String server = null;
|
||||
String world = null;
|
||||
|
||||
if (args.size() >= 3) {
|
||||
server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 3) {
|
||||
world = args.get(3).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
List<Node> toRemove = new ArrayList<>();
|
||||
for (Node node : holder.getNodes()) {
|
||||
if (!node.isPrefix()) continue;
|
||||
@@ -111,48 +97,36 @@ public class MetaRemovePrefix extends SecondarySubCommand {
|
||||
Message.BULK_CHANGE_SUCCESS.send(sender, toRemove.size());
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
} else {
|
||||
final String node = "prefix." + priority + "." + MetaUtils.escapeCharacters(prefix);
|
||||
|
||||
final String node = "prefix." + priority + "." + MetaUtils.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) {
|
||||
holder.unsetPermission(node, server);
|
||||
Message.REMOVEPREFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removeprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
holder.unsetPermission(node, server, world);
|
||||
Message.REMOVEPREFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removeprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
holder.unsetPermission(node);
|
||||
Message.REMOVEPREFIX_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removeprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
break;
|
||||
case SERVER:
|
||||
holder.unsetPermission(node, server);
|
||||
Message.REMOVEPREFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server);
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
holder.unsetPermission(node, server, world);
|
||||
Message.REMOVEPREFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server, world);
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removeprefix " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
-67
@@ -26,23 +26,27 @@ import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaRemoveSuffix extends SecondarySubCommand {
|
||||
public class MetaRemoveSuffix extends SharedSubCommand {
|
||||
public MetaRemoveSuffix() {
|
||||
super("removesuffix", "Removes a suffix", Permission.USER_META_REMOVESUFFIX, Permission.GROUP_META_REMOVESUFFIX, Predicate.notInRange(2, 4),
|
||||
super("removesuffix", "Removes a suffix", Permission.USER_META_REMOVESUFFIX, Permission.GROUP_META_REMOVESUFFIX,
|
||||
Predicates.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the suffix at"),
|
||||
Arg.create("suffix", true, "the suffix string"),
|
||||
@@ -53,32 +57,14 @@ public class MetaRemoveSuffix extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
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;
|
||||
}
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String suffix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
// Handle bulk removal
|
||||
if (suffix.equalsIgnoreCase("null")) {
|
||||
String server = null;
|
||||
String world = null;
|
||||
|
||||
if (args.size() >= 3) {
|
||||
server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 3) {
|
||||
world = args.get(3).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
List<Node> toRemove = new ArrayList<>();
|
||||
for (Node node : holder.getNodes()) {
|
||||
if (!node.isSuffix()) continue;
|
||||
@@ -111,48 +97,36 @@ public class MetaRemoveSuffix extends SecondarySubCommand {
|
||||
Message.BULK_CHANGE_SUCCESS.send(sender, toRemove.size());
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
} else {
|
||||
final String node = "suffix." + priority + "." + MetaUtils.escapeCharacters(suffix);
|
||||
|
||||
final String node = "suffix." + priority + "." + MetaUtils.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) {
|
||||
holder.unsetPermission(node, server);
|
||||
Message.REMOVESUFFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removesuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
holder.unsetPermission(node, server, world);
|
||||
Message.REMOVESUFFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removesuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
holder.unsetPermission(node);
|
||||
Message.REMOVESUFFIX_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removesuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
break;
|
||||
case SERVER:
|
||||
holder.unsetPermission(node, server);
|
||||
Message.REMOVESUFFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server);
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
holder.unsetPermission(node, server, world);
|
||||
Message.REMOVESUFFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server, world);
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removesuffix " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
-67
@@ -26,23 +26,26 @@ import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaRemoveTempPrefix extends SecondarySubCommand {
|
||||
public class MetaRemoveTempPrefix extends SharedSubCommand {
|
||||
public MetaRemoveTempPrefix() {
|
||||
super("removetempprefix", "Removes a temporary prefix", Permission.USER_META_REMOVETEMP_PREFIX, Permission.GROUP_META_REMOVETEMP_PREFIX, Predicate.notInRange(2, 4),
|
||||
super("removetempprefix", "Removes a temporary prefix", Permission.USER_META_REMOVETEMP_PREFIX, Permission.GROUP_META_REMOVETEMP_PREFIX, Predicates.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the prefix at"),
|
||||
Arg.create("prefix", true, "the prefix string"),
|
||||
@@ -53,32 +56,14 @@ public class MetaRemoveTempPrefix extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
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;
|
||||
}
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String prefix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
// Handle bulk removal
|
||||
if (prefix.equalsIgnoreCase("null")) {
|
||||
String server = null;
|
||||
String world = null;
|
||||
|
||||
if (args.size() >= 3) {
|
||||
server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 3) {
|
||||
world = args.get(3).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
List<Node> toRemove = new ArrayList<>();
|
||||
for (Node node : holder.getNodes()) {
|
||||
if (!node.isPrefix()) continue;
|
||||
@@ -111,48 +96,36 @@ public class MetaRemoveTempPrefix extends SecondarySubCommand {
|
||||
Message.BULK_CHANGE_SUCCESS.send(sender, toRemove.size());
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
} else {
|
||||
final String node = "prefix." + priority + "." + MetaUtils.escapeCharacters(prefix);
|
||||
|
||||
final String node = "prefix." + priority + "." + MetaUtils.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) {
|
||||
holder.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removetempprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
holder.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removetempprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
holder.unsetPermission(node, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removetempprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
break;
|
||||
case SERVER:
|
||||
holder.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server);
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
holder.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), prefix, priority, server, world);
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removetempprefix " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
-67
@@ -26,23 +26,26 @@ import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaRemoveTempSuffix extends SecondarySubCommand {
|
||||
public class MetaRemoveTempSuffix extends SharedSubCommand {
|
||||
public MetaRemoveTempSuffix() {
|
||||
super("removetempsuffix", "Removes a temporary suffix", Permission.USER_META_REMOVETEMP_SUFFIX, Permission.GROUP_META_REMOVETEMP_SUFFIX, Predicate.notInRange(2, 4),
|
||||
super("removetempsuffix", "Removes a temporary suffix", Permission.USER_META_REMOVETEMP_SUFFIX, Permission.GROUP_META_REMOVETEMP_SUFFIX, Predicates.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the suffix at"),
|
||||
Arg.create("suffix", true, "the suffix string"),
|
||||
@@ -53,32 +56,14 @@ public class MetaRemoveTempSuffix extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
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;
|
||||
}
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
int priority = ArgumentUtils.handlePriority(0, args);
|
||||
String suffix = ArgumentUtils.handleNodeWithoutCheck(1, args);
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
// Handle bulk removal
|
||||
if (suffix.equalsIgnoreCase("null")) {
|
||||
String server = null;
|
||||
String world = null;
|
||||
|
||||
if (args.size() >= 3) {
|
||||
server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 3) {
|
||||
world = args.get(3).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
List<Node> toRemove = new ArrayList<>();
|
||||
for (Node node : holder.getNodes()) {
|
||||
if (!node.isSuffix()) continue;
|
||||
@@ -111,48 +96,36 @@ public class MetaRemoveTempSuffix extends SecondarySubCommand {
|
||||
Message.BULK_CHANGE_SUCCESS.send(sender, toRemove.size());
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
} else {
|
||||
final String node = "suffix." + priority + "." + MetaUtils.escapeCharacters(suffix);
|
||||
|
||||
final String node = "suffix." + priority + "." + MetaUtils.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) {
|
||||
holder.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removetempsuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
holder.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removetempsuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
holder.unsetPermission(node, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removetempsuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
break;
|
||||
case SERVER:
|
||||
holder.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server);
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
holder.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), suffix, priority, server, world);
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta removetempsuffix " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,26 +22,29 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands.generic.meta;
|
||||
|
||||
import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.Node;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaSet extends SecondarySubCommand {
|
||||
public class MetaSet extends SharedSubCommand {
|
||||
public MetaSet() {
|
||||
super("set", "Sets a meta value", Permission.USER_META_SET, Permission.GROUP_META_SET, Predicate.notInRange(2, 4),
|
||||
super("set", "Sets a meta value", Permission.USER_META_SET, Permission.GROUP_META_SET, Predicates.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("key", true, "the key to set"),
|
||||
Arg.create("value", true, "the value to set"),
|
||||
@@ -52,27 +55,14 @@ public class MetaSet extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
String key = MetaUtils.escapeCharacters(args.get(0));
|
||||
String value = MetaUtils.escapeCharacters(args.get(1));
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
String key = args.get(0);
|
||||
String value = args.get(1);
|
||||
|
||||
String node = "meta." + key + "." + value;
|
||||
String server = null;
|
||||
String world = null;
|
||||
String server = ArgumentUtils.handleServer(2, args);
|
||||
String world = ArgumentUtils.handleWorld(3, args);
|
||||
|
||||
if (args.size() >= 3) {
|
||||
server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 3) {
|
||||
world = args.get(3).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
me.lucko.luckperms.api.Node n = new Node.Builder(node).setServer(server).setWorld(world).build();
|
||||
Node n = NodeFactory.makeMetaNode(key, value).setServer(server).setWorld(world).build();
|
||||
|
||||
if (holder.hasPermission(n).asBoolean()) {
|
||||
Message.ALREADY_HAS_META.send(sender, holder.getFriendlyName());
|
||||
@@ -85,25 +75,22 @@ public class MetaSet extends SecondarySubCommand {
|
||||
holder.setPermission(n);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
|
||||
if (server == null) {
|
||||
Message.SET_META_SUCCESS.send(sender, key, value, holder.getFriendlyName());
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta set " + key + " " + value)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
if (world == null) {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
Message.SET_META_SUCCESS.send(sender, key, value, holder.getFriendlyName());
|
||||
break;
|
||||
case SERVER:
|
||||
Message.SET_META_SERVER_SUCCESS.send(sender, key, value, holder.getFriendlyName(), server);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta set " + key + " " + value + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
Message.SET_META_SERVER_WORLD_SUCCESS.send(sender, key, value, holder.getFriendlyName(), server, world);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta set " + key + " " + value + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta set " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
+30
-60
@@ -22,27 +22,30 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands.generic.meta;
|
||||
|
||||
import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.Node;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.DateUtil;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaSetTemp extends SecondarySubCommand {
|
||||
public class MetaSetTemp extends SharedSubCommand {
|
||||
public MetaSetTemp() {
|
||||
super("settemp", "Sets a meta value temporarily", Permission.USER_META_SETTEMP, Permission.GROUP_META_SETTEMP, Predicate.notInRange(3, 5),
|
||||
super("settemp", "Sets a meta value temporarily", Permission.USER_META_SETTEMP, Permission.GROUP_META_SETTEMP, Predicates.notInRange(3, 5),
|
||||
Arg.list(
|
||||
Arg.create("key", true, "the key to set"),
|
||||
Arg.create("value", true, "the value to set"),
|
||||
@@ -54,44 +57,14 @@ public class MetaSetTemp extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> 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;
|
||||
}
|
||||
}
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
String key = args.get(0);
|
||||
String value = args.get(1);
|
||||
long duration = ArgumentUtils.handleDuration(2, args);
|
||||
String server = ArgumentUtils.handleServer(3, args);
|
||||
String world = ArgumentUtils.handleWorld(4, args);
|
||||
|
||||
if (DateUtil.shouldExpire(duration)) {
|
||||
Message.PAST_DATE_ERROR.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
String key = MetaUtils.escapeCharacters(args.get(0));
|
||||
String value = MetaUtils.escapeCharacters(args.get(1));
|
||||
|
||||
String node = "meta." + key + "." + value;
|
||||
String server = null;
|
||||
String world = null;
|
||||
|
||||
if (args.size() >= 3) {
|
||||
server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 3) {
|
||||
world = args.get(3).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
me.lucko.luckperms.api.Node n = new Node.Builder(node).setServer(server).setWorld(world).setExpiry(duration).build();
|
||||
Node n = NodeFactory.makeMetaNode(key, value).setServer(server).setWorld(world).setExpiry(duration).build();
|
||||
|
||||
if (holder.hasPermission(n).asBoolean()) {
|
||||
Message.ALREADY_HAS_META.send(sender, holder.getFriendlyName());
|
||||
@@ -104,25 +77,22 @@ public class MetaSetTemp extends SecondarySubCommand {
|
||||
holder.setPermission(n);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
|
||||
if (server == null) {
|
||||
Message.SET_META_TEMP_SUCCESS.send(sender, key, value, holder.getFriendlyName(), DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta settemp " + key + " " + value + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
if (world == null) {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
Message.SET_META_TEMP_SUCCESS.send(sender, key, value, holder.getFriendlyName(), DateUtil.formatDateDiff(duration));
|
||||
break;
|
||||
case SERVER:
|
||||
Message.SET_META_TEMP_SERVER_SUCCESS.send(sender, key, value, holder.getFriendlyName(), server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta settemp " + key + " " + value + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
Message.SET_META_TEMP_SERVER_WORLD_SUCCESS.send(sender, key, value, holder.getFriendlyName(), server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta settemp " + key + " " + value + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta settemp " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
+22
-31
@@ -22,25 +22,27 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands.generic.meta;
|
||||
|
||||
import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaUnset extends SecondarySubCommand {
|
||||
public class MetaUnset extends SharedSubCommand {
|
||||
public MetaUnset() {
|
||||
super("unset", "Unsets a meta value", Permission.USER_META_UNSET, Permission.GROUP_META_UNSET, Predicate.notInRange(1, 3),
|
||||
super("unset", "Unsets a meta value", Permission.USER_META_UNSET, Permission.GROUP_META_UNSET,
|
||||
Predicates.notInRange(1, 3),
|
||||
Arg.list(
|
||||
Arg.create("key", true, "the key to unset"),
|
||||
Arg.create("server", false, "the server to remove the meta pair on"),
|
||||
@@ -50,38 +52,27 @@ public class MetaUnset extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
String key = MetaUtils.escapeCharacters(args.get(0));
|
||||
|
||||
String server = null;
|
||||
String world = null;
|
||||
|
||||
if (args.size() >= 2) {
|
||||
server = args.get(1).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 2) {
|
||||
world = args.get(2).toLowerCase();
|
||||
}
|
||||
}
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
String key = args.get(0);
|
||||
String server = ArgumentUtils.handleServer(1, args);
|
||||
String world = ArgumentUtils.handleWorld(2, args);
|
||||
|
||||
holder.clearMetaKeys(key, server, world, false);
|
||||
|
||||
if (server == null) {
|
||||
Message.UNSET_META_SUCCESS.send(sender, key, holder.getFriendlyName());
|
||||
} else {
|
||||
if (world == null) {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
Message.UNSET_META_SUCCESS.send(sender, key, holder.getFriendlyName());
|
||||
break;
|
||||
case SERVER:
|
||||
Message.UNSET_META_SERVER_SUCCESS.send(sender, key, holder.getFriendlyName(), server);
|
||||
} else {
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
Message.UNSET_META_SERVER_WORLD_SUCCESS.send(sender, key, holder.getFriendlyName(), server, world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta unset " + args.stream().collect(Collectors.joining(" ")))
|
||||
.action("meta unset " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
|
||||
+22
-31
@@ -22,25 +22,27 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands.generic.meta;
|
||||
|
||||
import me.lucko.luckperms.api.MetaUtils;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaUnsetTemp extends SecondarySubCommand {
|
||||
public class MetaUnsetTemp extends SharedSubCommand {
|
||||
public MetaUnsetTemp() {
|
||||
super("unsettemp", "Unsets a temporary meta value", Permission.USER_META_UNSETTEMP, Permission.GROUP_META_UNSETTEMP, Predicate.notInRange(1, 3),
|
||||
super("unsettemp", "Unsets a temporary meta value", Permission.USER_META_UNSETTEMP, Permission.GROUP_META_UNSETTEMP,
|
||||
Predicates.notInRange(1, 3),
|
||||
Arg.list(
|
||||
Arg.create("key", true, "the key to unset"),
|
||||
Arg.create("server", false, "the server to remove the meta pair on"),
|
||||
@@ -50,38 +52,27 @@ public class MetaUnsetTemp extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
String key = MetaUtils.escapeCharacters(args.get(0));
|
||||
|
||||
String server = null;
|
||||
String world = null;
|
||||
|
||||
if (args.size() >= 2) {
|
||||
server = args.get(1).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 2) {
|
||||
world = args.get(2).toLowerCase();
|
||||
}
|
||||
}
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
String key = args.get(0);
|
||||
String server = ArgumentUtils.handleServer(1, args);
|
||||
String world = ArgumentUtils.handleWorld(2, args);
|
||||
|
||||
holder.clearMetaKeys(key, server, world, true);
|
||||
|
||||
if (server == null) {
|
||||
Message.UNSET_META_TEMP_SUCCESS.send(sender, key, holder.getFriendlyName());
|
||||
} else {
|
||||
if (world == null) {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
Message.UNSET_META_TEMP_SUCCESS.send(sender, key, holder.getFriendlyName());
|
||||
break;
|
||||
case SERVER:
|
||||
Message.UNSET_META_TEMP_SERVER_SUCCESS.send(sender, key, holder.getFriendlyName(), server);
|
||||
} else {
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
Message.UNSET_META_TEMP_SERVER_WORLD_SUCCESS.send(sender, key, holder.getFriendlyName(), server, world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("meta unsettemp " + args.stream().collect(Collectors.joining(" ")))
|
||||
.action("meta unsettemp " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.generic.other;
|
||||
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.SubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class HolderShowTracks<T extends PermissionHolder> extends SubCommand<T> {
|
||||
public HolderShowTracks(boolean user) {
|
||||
super("showtracks", "Lists the tracks that the object is on",
|
||||
user ? Permission.USER_SHOWTRACKS : Permission.GROUP_SHOWTRACKS, Predicates.alwaysFalse(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, T holder, List<String> args, String label) throws CommandException {
|
||||
if (!plugin.getStorage().loadAllTracks().join()) {
|
||||
Message.TRACKS_LOAD_ERROR.send(sender);
|
||||
return CommandResult.LOADING_ERROR;
|
||||
}
|
||||
|
||||
Set<Node> nodes = holder.getNodes().stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.filter(Node::isPermanent)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (Node node : nodes) {
|
||||
String name = node.getGroupName();
|
||||
|
||||
plugin.getTrackManager().getAll().values().stream()
|
||||
.filter(t -> t.containsGroup(name))
|
||||
.forEach(t -> sb.append("&a")
|
||||
.append(t.getName())
|
||||
.append(": ")
|
||||
.append(Util.listToArrowSep(t.getGroups(), name))
|
||||
.append(Util.getNodeContextDescription(node))
|
||||
.append("\n")
|
||||
);
|
||||
}
|
||||
|
||||
if (sb.length() == 0) {
|
||||
Message.LIST_TRACKS_EMPTY.send(sender, holder.getFriendlyName());
|
||||
return CommandResult.SUCCESS;
|
||||
} else {
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
Message.LIST_TRACKS.send(sender, holder.getFriendlyName(), sb.toString());
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -23,14 +23,15 @@
|
||||
package me.lucko.luckperms.common.commands.generic.parent;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondaryMainCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedMainCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
|
||||
public class CommandParent<T extends PermissionHolder> extends SecondaryMainCommand<T> {
|
||||
public class CommandParent<T extends PermissionHolder> extends SharedMainCommand<T> {
|
||||
public CommandParent(boolean user) {
|
||||
super("Parent", "Edit inheritances", user, ImmutableList.<SecondarySubCommand>builder()
|
||||
super("Parent", "Edit inheritances", user, ImmutableList.<SharedSubCommand>builder()
|
||||
.add(new ParentInfo())
|
||||
.add(new ParentSet())
|
||||
.add(new ParentAdd())
|
||||
.add(new ParentRemove())
|
||||
.add(new ParentAddTemp())
|
||||
|
||||
+29
-39
@@ -24,26 +24,29 @@ package me.lucko.luckperms.common.commands.generic.parent;
|
||||
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
import me.lucko.luckperms.common.commands.CommandException;
|
||||
import me.lucko.luckperms.common.commands.CommandResult;
|
||||
import me.lucko.luckperms.common.commands.Predicate;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
|
||||
import me.lucko.luckperms.common.commands.generic.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
|
||||
import me.lucko.luckperms.common.commands.utils.ContextHelper;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.PermissionHolder;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.groups.Group;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.lucko.luckperms.common.commands.SubCommand.getGroupTabComplete;
|
||||
|
||||
public class ParentAdd extends SecondarySubCommand {
|
||||
public class ParentAdd extends SharedSubCommand {
|
||||
public ParentAdd() {
|
||||
super("add", "Sets another group for the object to inherit permissions from",
|
||||
Permission.USER_PARENT_ADD, Permission.GROUP_PARENT_ADD, Predicate.notInRange(1, 3),
|
||||
super("add", "Sets another group for the object to inherit permissions from", Permission.USER_PARENT_ADD,
|
||||
Permission.GROUP_PARENT_ADD, Predicates.notInRange(1, 3),
|
||||
Arg.list(
|
||||
Arg.create("group", true, "the group to inherit from"),
|
||||
Arg.create("server", false, "the server to inherit the group on"),
|
||||
@@ -53,15 +56,12 @@ public class ParentAdd extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
|
||||
String groupName = args.get(0).toLowerCase();
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) throws CommandException {
|
||||
String groupName = ArgumentUtils.handleName(0, args);
|
||||
String server = ArgumentUtils.handleServer(1, args);
|
||||
String world = ArgumentUtils.handleWorld(2, args);
|
||||
|
||||
if (ArgumentChecker.checkNode(groupName)) {
|
||||
sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
|
||||
if (!plugin.getStorage().loadGroup(groupName).join()) {
|
||||
Message.GROUP_DOES_NOT_EXIST.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
@@ -73,38 +73,28 @@ public class ParentAdd extends SecondarySubCommand {
|
||||
}
|
||||
|
||||
try {
|
||||
if (args.size() >= 2) {
|
||||
final String server = args.get(1).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
switch (ContextHelper.determine(server, world)) {
|
||||
case NONE:
|
||||
holder.setInheritGroup(group);
|
||||
Message.SET_INHERIT_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName());
|
||||
break;
|
||||
case SERVER:
|
||||
holder.setInheritGroup(group, server);
|
||||
Message.SET_INHERIT_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName(), server);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("parent add " + group.getName() + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(2).toLowerCase();
|
||||
break;
|
||||
case SERVER_AND_WORLD:
|
||||
holder.setInheritGroup(group, server, world);
|
||||
Message.SET_INHERIT_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName(), server, world);
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("parent add " + group.getName() + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
holder.setInheritGroup(group);
|
||||
Message.SET_INHERIT_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName());
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("parent add " + group.getName())
|
||||
.build().submit(plugin, sender);
|
||||
break;
|
||||
}
|
||||
|
||||
LogEntry.build().actor(sender).acted(holder)
|
||||
.action("parent add " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_INHERITS.send(sender, holder.getFriendlyName(), group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
|
||||
Loaded 100 of 264 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user