Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aea44fc8bc | ||
|
|
c0da9d49d9 | ||
|
|
ce42573f43 | ||
|
|
148fe4c729 | ||
|
|
32fd484b58 | ||
|
|
7d24e748b7 | ||
|
|
f1a1612f5d | ||
|
|
6501e5cf8d | ||
|
|
cd4a684613 | ||
|
|
d06fda6d9d | ||
|
|
139010e75b | ||
|
|
7638b07e34 | ||
|
|
f7bf4416c9 | ||
|
|
2b96b656a9 | ||
|
|
0fe251b6ec | ||
|
|
a1afc70bcb | ||
|
|
ced3e6959c | ||
|
|
1c229d54d9 | ||
|
|
dd50193c18 | ||
|
|
ab0f9bbdbd | ||
|
|
055d181c67 | ||
|
|
7042c45deb | ||
|
|
960c2291b6 | ||
|
|
773bfe1407 | ||
|
|
a23f995717 | ||
|
|
bd509b3c75 | ||
|
|
a0f8ba9afb | ||
|
|
a71e040c6d | ||
|
|
454abec468 | ||
|
|
96035d5257 | ||
|
|
9f2b59f2a2 | ||
|
|
a54046907d | ||
|
|
2ce5679373 | ||
|
|
2dad9f84fc | ||
|
|
a81a361a93 | ||
|
|
4660e68abf | ||
|
|
f8a77cf809 | ||
|
|
0abe9598f6 | ||
|
|
20de713716 | ||
|
|
9dbef6acc2 | ||
|
|
4c93bf7cf0 | ||
|
|
a8fea0fc49 | ||
|
|
2d5975d6e3 | ||
|
|
6874cfd5b1 | ||
|
|
d34013396a | ||
|
|
a35b0915ab | ||
|
|
b35f3b4375 | ||
|
|
f4f9612789 | ||
|
|
bfc79c6051 | ||
|
|
d3e60487bb | ||
|
|
f36f411a8d | ||
|
|
35f4aea69f | ||
|
|
8795383e7c | ||
|
|
fc4750706b | ||
|
|
0ae59bd3e6 | ||
|
|
61fd14c816 | ||
|
|
c7d3d87b09 | ||
|
|
5e68f7b58c | ||
|
|
8a692200d5 | ||
|
|
829eacb0fb | ||
|
|
9aeca91f22 | ||
|
|
1bdb512826 | ||
|
|
060fa6e5f7 | ||
|
|
171a54c0fc | ||
|
|
17406b448d | ||
|
|
b4b661a3ad | ||
|
|
4857969ca4 | ||
|
|
d9d01e09aa | ||
|
|
dadca97d8a | ||
|
|
8afba8b53d | ||
|
|
85dac1184c | ||
|
|
4167460d28 | ||
|
|
1d8a60749d | ||
|
|
31a597ca81 | ||
|
|
e5e77ffec5 | ||
|
|
41c3df41b4 | ||
|
|
053066f1a7 | ||
|
|
21135dac07 | ||
|
|
22ccce3208 | ||
|
|
70aa3964ee | ||
|
|
167489823a | ||
|
|
d1426f1b37 | ||
|
|
7dcdc59c8e | ||
|
|
1e13ee87af | ||
|
|
5101c1a759 | ||
|
|
74bb079625 | ||
|
|
2da7979d94 | ||
|
|
4ecb2c7c27 | ||
|
|
251f51b01c | ||
|
|
2fba9b83af | ||
|
|
1c97cb3cec | ||
|
|
25511f898c | ||
|
|
d820f153a9 | ||
|
|
77b06acad4 | ||
|
|
6760a96527 | ||
|
|
257f426ab9 | ||
|
|
3771a50f30 | ||
|
|
85ee211172 | ||
|
|
1b7a66b41a | ||
|
|
8f9a1aa931 | ||
|
|
8b60fd0e55 | ||
|
|
cd7b3b4f6e | ||
|
|
83b0f62d59 | ||
|
|
dd3a78ada8 | ||
|
|
307e2b889c | ||
|
|
a063f7664d | ||
|
|
b1ab857592 | ||
|
|
2b8bbc434f | ||
|
|
c6878c27b9 | ||
|
|
02ff4a4acb | ||
|
|
23f757e916 | ||
|
|
f0ababa409 | ||
|
|
331ff341f3 | ||
|
|
793a84edfb | ||
|
|
2893d4aebd | ||
|
|
b7ac7680d9 | ||
|
|
18dd59ed0f | ||
|
|
443906da55 | ||
|
|
a9f29da4f8 | ||
|
|
cf456cff81 | ||
|
|
69b3c96e09 | ||
|
|
61eb86b3a0 | ||
|
|
f0ad32bc37 | ||
|
|
aeeb2820f9 | ||
|
|
2d88405d69 | ||
|
|
f32ed5db89 | ||
|
|
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").
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<version>2.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -27,13 +27,17 @@ import me.lucko.luckperms.api.LuckPermsApi;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Static access to LuckPerms
|
||||
* Singleton for the {@link LuckPermsApi}.
|
||||
*
|
||||
* <p> Ideally, the ServiceManager for the platform should be used to obtain and cache an instance, however, this can be
|
||||
* used if you need static access.
|
||||
*/
|
||||
public final class LuckPerms {
|
||||
private static LuckPermsApi api = null;
|
||||
|
||||
/**
|
||||
* Gets an instance of {@link LuckPermsApi}
|
||||
* Gets an instance of {@link LuckPermsApi}, throwing {@link IllegalStateException} if the API is not loaded.
|
||||
*
|
||||
* @return an api instance
|
||||
* @throws IllegalStateException if the api is not loaded
|
||||
*/
|
||||
@@ -45,8 +49,11 @@ public final class LuckPerms {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of {@link LuckPermsApi} safely. Unlike {@link LuckPerms#getApi}, this method will not throw an
|
||||
* {@link IllegalStateException} if the api is not loaded, rather return an empty {@link Optional}.
|
||||
* Gets an instance of {@link LuckPermsApi} safely.
|
||||
*
|
||||
* <p> Unlike {@link LuckPerms#getApi}, this method will not throw an {@link IllegalStateException} if the API is
|
||||
* not loaded, rather return an empty {@link Optional}.
|
||||
*
|
||||
* @return an optional api instance
|
||||
*/
|
||||
public static Optional<LuckPermsApi> getApiSafe() {
|
||||
|
||||
@@ -27,40 +27,30 @@ import me.lucko.luckperms.api.context.ContextSet;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents the context and options for a permission lookup.
|
||||
* All values are immutable.
|
||||
* Context and options for a permission lookup.
|
||||
*
|
||||
* <p> All values are immutable.
|
||||
*
|
||||
* @since 2.11
|
||||
*/
|
||||
public class Contexts {
|
||||
public static final String SERVER_KEY = "server";
|
||||
public static final String WORLD_KEY = "world";
|
||||
private static final Contexts ALLOW_ALL = new Contexts(ContextSet.empty(), true, true, true, true, true, true);
|
||||
|
||||
/**
|
||||
* Gets a context that will allow all nodes
|
||||
*
|
||||
* @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) {
|
||||
return new Contexts(context, includeGlobal, includeGlobalWorld, applyGroups, applyGlobalGroups, applyGlobalWorldGroups, op);
|
||||
}
|
||||
|
||||
public Contexts(ContextSet context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
|
||||
if (context == null) {
|
||||
throw new NullPointerException("context");
|
||||
}
|
||||
|
||||
this.context = context.makeImmutable();
|
||||
this.includeGlobal = includeGlobal;
|
||||
this.includeGlobalWorld = includeGlobalWorld;
|
||||
this.applyGroups = applyGroups;
|
||||
this.applyGlobalGroups = applyGlobalGroups;
|
||||
this.applyGlobalWorldGroups = applyGlobalWorldGroups;
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public static Contexts of(Map<String, String> context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups) {
|
||||
@@ -73,17 +63,6 @@ public class Contexts {
|
||||
return new Contexts(context, includeGlobal, includeGlobalWorld, applyGroups, applyGlobalGroups, applyGlobalWorldGroups, op);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Contexts(Map<String, String> context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
|
||||
this(context == null ? null : ContextSet.fromMap(context), includeGlobal, includeGlobalWorld, applyGroups, applyGlobalGroups, applyGlobalWorldGroups, op);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public Contexts(Map<String, String> context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups) {
|
||||
this(context, includeGlobal, includeGlobalWorld, applyGroups, applyGlobalGroups, applyGlobalWorldGroups, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* The contexts that apply for this lookup
|
||||
* The keys for servers and worlds are defined as static values.
|
||||
@@ -92,6 +71,7 @@ public class Contexts {
|
||||
|
||||
/**
|
||||
* The mode to parse defaults on Bukkit
|
||||
*
|
||||
* @since 2.12
|
||||
*/
|
||||
private final boolean op;
|
||||
@@ -121,8 +101,34 @@ public class Contexts {
|
||||
*/
|
||||
private final boolean applyGlobalWorldGroups;
|
||||
|
||||
public Contexts(ContextSet context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
|
||||
if (context == null) {
|
||||
throw new NullPointerException("context");
|
||||
}
|
||||
|
||||
this.context = context.makeImmutable();
|
||||
this.includeGlobal = includeGlobal;
|
||||
this.includeGlobalWorld = includeGlobalWorld;
|
||||
this.applyGroups = applyGroups;
|
||||
this.applyGlobalGroups = applyGlobalGroups;
|
||||
this.applyGlobalWorldGroups = applyGlobalWorldGroups;
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Contexts(Map<String, String> context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
|
||||
this(context == null ? null : ContextSet.fromMap(context), includeGlobal, includeGlobalWorld, applyGroups, applyGlobalGroups, applyGlobalWorldGroups, op);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public Contexts(Map<String, String> context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups) {
|
||||
this(context, includeGlobal, includeGlobalWorld, applyGroups, applyGlobalGroups, applyGlobalWorldGroups, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the contexts that apply for this lookup
|
||||
*
|
||||
* @return an immutable set of context key value pairs
|
||||
* @since 2.13
|
||||
*/
|
||||
@@ -132,6 +138,7 @@ public class Contexts {
|
||||
|
||||
/**
|
||||
* Gets the contexts that apply for this lookup
|
||||
*
|
||||
* @return an immutable map of context key value pairs
|
||||
* @deprecated in favour of {@link #getContexts()}
|
||||
*/
|
||||
@@ -142,6 +149,7 @@ public class Contexts {
|
||||
|
||||
/**
|
||||
* Gets if OP defaults should be included
|
||||
*
|
||||
* @return true if op defaults should be included
|
||||
*/
|
||||
public boolean isOp() {
|
||||
@@ -150,6 +158,7 @@ public class Contexts {
|
||||
|
||||
/**
|
||||
* Gets if global or non server specific nodes should be applied
|
||||
*
|
||||
* @return true if global or non server specific nodes should be applied
|
||||
*/
|
||||
public boolean isIncludeGlobal() {
|
||||
@@ -158,6 +167,7 @@ public class Contexts {
|
||||
|
||||
/**
|
||||
* Gets if global or non world specific nodes should be applied
|
||||
*
|
||||
* @return true if global or non world specific nodes should be applied
|
||||
*/
|
||||
public boolean isIncludeGlobalWorld() {
|
||||
@@ -166,6 +176,7 @@ public class Contexts {
|
||||
|
||||
/**
|
||||
* Gets if parent groups should be applied
|
||||
*
|
||||
* @return true if parent groups should be applied
|
||||
*/
|
||||
public boolean isApplyGroups() {
|
||||
@@ -174,6 +185,7 @@ public class Contexts {
|
||||
|
||||
/**
|
||||
* Gets if global or non server specific group memberships should be applied
|
||||
*
|
||||
* @return true if global or non server specific group memberships should be applied
|
||||
*/
|
||||
public boolean isApplyGlobalGroups() {
|
||||
@@ -182,6 +194,7 @@ public class Contexts {
|
||||
|
||||
/**
|
||||
* Gets if global or non world specific group memberships should be applied
|
||||
*
|
||||
* @return true if global or non world specific group memberships should be applied
|
||||
*/
|
||||
public boolean isApplyGlobalWorldGroups() {
|
||||
@@ -206,6 +219,7 @@ public class Contexts {
|
||||
|
||||
/**
|
||||
* Check for equality
|
||||
*
|
||||
* @param o the other
|
||||
* @return true if equal
|
||||
* @since 2.12
|
||||
@@ -228,6 +242,7 @@ public class Contexts {
|
||||
|
||||
/**
|
||||
* Gets the hashcode
|
||||
*
|
||||
* @return the hashcode
|
||||
* @since 2.12
|
||||
*/
|
||||
|
||||
@@ -28,281 +28,158 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Interface for the internal Datastore instance
|
||||
* Deprecated Storage interface. Use {@link Storage} instead.
|
||||
*
|
||||
* @deprecated as of version 2.14 in favour of {@link Storage}.
|
||||
*/
|
||||
@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);
|
||||
|
||||
@Deprecated
|
||||
void loadOrCreateUser(UUID uuid, String username, Callback<Boolean> callback);
|
||||
|
||||
@Deprecated
|
||||
void loadUser(UUID uuid, Callback<Boolean> callback);
|
||||
|
||||
void loadUser(UUID uuid, String username, Callback<Boolean> callback);
|
||||
|
||||
void saveUser(User user, Callback<Boolean> callback);
|
||||
|
||||
void cleanupUsers(Callback<Boolean> callback);
|
||||
|
||||
void getUniqueUsers(Callback<Set<UUID>> callback);
|
||||
|
||||
void createAndLoadGroup(String name, Callback<Boolean> callback);
|
||||
|
||||
void loadGroup(String name, Callback<Boolean> callback);
|
||||
|
||||
void loadAllGroups(Callback<Boolean> callback);
|
||||
|
||||
void saveGroup(Group group, Callback<Boolean> callback);
|
||||
|
||||
void deleteGroup(Group group, Callback<Boolean> callback);
|
||||
|
||||
void createAndLoadTrack(String name, Callback<Boolean> callback);
|
||||
|
||||
void loadTrack(String name, Callback<Boolean> callback);
|
||||
|
||||
void loadAllTracks(Callback<Boolean> callback);
|
||||
|
||||
void saveTrack(Track track, Callback<Boolean> callback);
|
||||
|
||||
void deleteTrack(Track track, Callback<Boolean> callback);
|
||||
|
||||
void saveUUIDData(String username, UUID uuid, Callback<Boolean> callback);
|
||||
|
||||
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();
|
||||
|
||||
@Deprecated
|
||||
java.util.concurrent.Future<Boolean> loadOrCreateUser(UUID uuid, String username);
|
||||
|
||||
@Deprecated
|
||||
java.util.concurrent.Future<Boolean> loadUser(UUID uuid);
|
||||
|
||||
java.util.concurrent.Future<Boolean> loadUser(UUID uuid, String username);
|
||||
|
||||
java.util.concurrent.Future<Boolean> saveUser(User user);
|
||||
|
||||
java.util.concurrent.Future<Boolean> cleanupUsers();
|
||||
|
||||
java.util.concurrent.Future<Set<UUID>> getUniqueUsers();
|
||||
|
||||
java.util.concurrent.Future<Boolean> createAndLoadGroup(String name);
|
||||
|
||||
java.util.concurrent.Future<Boolean> loadGroup(String name);
|
||||
|
||||
java.util.concurrent.Future<Boolean> loadAllGroups();
|
||||
|
||||
java.util.concurrent.Future<Boolean> saveGroup(Group group);
|
||||
|
||||
java.util.concurrent.Future<Boolean> deleteGroup(Group group);
|
||||
|
||||
java.util.concurrent.Future<Boolean> createAndLoadTrack(String name);
|
||||
|
||||
java.util.concurrent.Future<Boolean> loadTrack(String name);
|
||||
|
||||
java.util.concurrent.Future<Boolean> loadAllTracks();
|
||||
|
||||
java.util.concurrent.Future<Boolean> saveTrack(Track track);
|
||||
|
||||
java.util.concurrent.Future<Boolean> deleteTrack(Track track);
|
||||
|
||||
java.util.concurrent.Future<Boolean> saveUUIDData(String username, UUID uuid);
|
||||
|
||||
java.util.concurrent.Future<UUID> getUUID(String username);
|
||||
}
|
||||
}
|
||||
@@ -26,212 +26,237 @@ import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/**
|
||||
* Interface for internal Group instances
|
||||
* A group which holds permission data.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Group extends PermissionHolder {
|
||||
|
||||
/**
|
||||
* Get the name of the group
|
||||
*
|
||||
* @return the name of the group
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Check to see if a group inherits a group
|
||||
*
|
||||
* @param group The group to check membership of
|
||||
* @return true if the group inherits the other group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
boolean inheritsGroup(Group group);
|
||||
|
||||
/**
|
||||
* Check to see if the group inherits a group on a specific server
|
||||
* @param group The group to check membership of
|
||||
*
|
||||
* @param group The group to check membership of
|
||||
* @param server The server to check on
|
||||
* @return true if the group inherits the group on the server
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
*/
|
||||
boolean inheritsGroup(Group group, String server);
|
||||
|
||||
/**
|
||||
* Check to see if the group inherits a group on a specific server and world
|
||||
* @param group The group to check membership of
|
||||
*
|
||||
* @param group The group to check membership of
|
||||
* @param server The server to check on
|
||||
* @param world The world to check on
|
||||
* @param world The world to check on
|
||||
* @return true if the group inherits the group on the server and world
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server or world is invalid
|
||||
*/
|
||||
boolean inheritsGroup(Group group, String server, String world);
|
||||
|
||||
/**
|
||||
* Make this group inherit another group
|
||||
*
|
||||
* @param group the group to be inherited
|
||||
* @throws ObjectAlreadyHasException if the group already inherits the group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
void setInheritGroup(Group group) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Make this group inherit another group on a specific server
|
||||
* @param group the group to be inherited
|
||||
*
|
||||
* @param group the group to be inherited
|
||||
* @param server The server to inherit the group on
|
||||
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
*/
|
||||
void setInheritGroup(Group group, String server) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Make this group inherit another group on a specific server and world
|
||||
* @param group the group to be inherited
|
||||
*
|
||||
* @param group the group to be inherited
|
||||
* @param server The server to inherit the group on
|
||||
* @param world The world to inherit the group on
|
||||
* @param world The world to inherit the group on
|
||||
* @throws ObjectAlreadyHasException if the group already inherits the group on that server and world
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server or world is invalid
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server or world is invalid
|
||||
*/
|
||||
void setInheritGroup(Group group, String server, String world) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Make this group inherit another group temporarily
|
||||
* @param group the group to be inherited
|
||||
*
|
||||
* @param group the group to be inherited
|
||||
* @param expireAt the unix time when the group should expire
|
||||
* @throws ObjectAlreadyHasException if the group already inherits the group temporarily
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past
|
||||
*/
|
||||
void setInheritGroup(Group group, long expireAt) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Make this group inherit another group on a specific server temporarily
|
||||
* @param group the group to be inherited
|
||||
* @param server The server inherit add the group on
|
||||
*
|
||||
* @param group the group to be inherited
|
||||
* @param server The server inherit add the group on
|
||||
* @param expireAt when the group should expire
|
||||
* @throws ObjectAlreadyHasException if the group already inherits the group on that server temporarily
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server is invalid
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server is invalid
|
||||
*/
|
||||
void setInheritGroup(Group group, String server, long expireAt) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Make this group inherit another group on a specific server and world temporarily
|
||||
* @param group the group to be inherited
|
||||
* @param server The server to inherit the group on
|
||||
* @param world The world to inherit the group on
|
||||
*
|
||||
* @param group the group to be inherited
|
||||
* @param server The server to inherit the group on
|
||||
* @param world The world to inherit the group on
|
||||
* @param expireAt when the group should expire
|
||||
* @throws ObjectAlreadyHasException if the group already inherits the group on that server and world temporarily
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server/world is invalid
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server/world is invalid
|
||||
*/
|
||||
void setInheritGroup(Group group, String server, String world, long expireAt) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Remove a previously set inheritance rule
|
||||
*
|
||||
* @param group the group to uninherit
|
||||
* @throws ObjectLacksException if the group does not already inherit the group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws ObjectLacksException if the group does not already inherit the group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
void unsetInheritGroup(Group group) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Remove a previously set inheritance rule
|
||||
* @param group the group to uninherit
|
||||
*
|
||||
* @param group the group to uninherit
|
||||
* @param temporary if the group being removed is temporary
|
||||
* @throws ObjectLacksException if the group does not already inherit the group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws ObjectLacksException if the group does not already inherit the group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
void unsetInheritGroup(Group group, boolean temporary) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Remove a previously set inheritance rule on a specific server
|
||||
* @param group the group to uninherit
|
||||
*
|
||||
* @param group the group to uninherit
|
||||
* @param server The server to remove the group on
|
||||
* @throws ObjectLacksException if the group does not already inherit the group on that server
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws ObjectLacksException if the group does not already inherit the group on that server
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
*/
|
||||
void unsetInheritGroup(Group group, String server) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Remove a previously set inheritance rule on a specific server and world
|
||||
* @param group the group to uninherit
|
||||
*
|
||||
* @param group the group to uninherit
|
||||
* @param server The server to remove the group on
|
||||
* @param world The world to remove the group on
|
||||
* @throws ObjectLacksException if the group does not already inherit the group
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @param world The world to remove the group on
|
||||
* @throws ObjectLacksException if the group does not already inherit the group
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server or world is invalid
|
||||
*/
|
||||
void unsetInheritGroup(Group group, String server, String world) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Remove a previously set inheritance rule on a specific server
|
||||
* @param group the group to uninherit
|
||||
* @param server The server to remove the group on
|
||||
*
|
||||
* @param group the group to uninherit
|
||||
* @param server The server to remove the group on
|
||||
* @param temporary if the group being removed is temporary
|
||||
* @throws ObjectLacksException if the group does not already inherit the group
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws ObjectLacksException if the group does not already inherit the group
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server is invalid
|
||||
*/
|
||||
void unsetInheritGroup(Group group, String server, boolean temporary) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Remove a previously set inheritance rule on a specific server and world
|
||||
* @param group the group to uninherit
|
||||
* @param server The server to remove the group on
|
||||
* @param world The world to remove the group on
|
||||
*
|
||||
* @param group the group to uninherit
|
||||
* @param server The server to remove the group on
|
||||
* @param world The world to remove the group on
|
||||
* @param temporary if the group being removed was set temporarily
|
||||
* @throws ObjectLacksException if the group does not already inherit the group
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws ObjectLacksException if the group does not already inherit the group
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server/world is invalid
|
||||
*/
|
||||
void unsetInheritGroup(Group group, String server, String world, boolean temporary) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Clear all of the groups permission nodes
|
||||
*/
|
||||
void clearNodes();
|
||||
|
||||
/**
|
||||
* Get a {@link List} of all of the groups the group inherits, on all servers
|
||||
*
|
||||
* @return a {@link List} of group names
|
||||
*/
|
||||
List<String> getGroupNames();
|
||||
|
||||
/**
|
||||
* Get a {@link List} of the groups the group inherits on a specific server
|
||||
*
|
||||
* @param server the server to check
|
||||
* @param world the world to check
|
||||
* @return a {@link List} of group names
|
||||
* @throws NullPointerException if the server or world is null
|
||||
* @throws NullPointerException if the server is null
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
*/
|
||||
List<String> getLocalGroups(String server);
|
||||
|
||||
|
||||
/**
|
||||
* Get a {@link List} of the groups the group inherits on a specific server and world
|
||||
*
|
||||
* @param server the server to check
|
||||
* @param world the world to check
|
||||
* @return a {@link List} of group names
|
||||
* @throws NullPointerException if the server or world is null
|
||||
* @throws IllegalArgumentException if the server or world is invalid
|
||||
*/
|
||||
List<String> getLocalGroups(String server, String world);
|
||||
|
||||
/**
|
||||
* Get a {@link List} of the groups the group inherits on a specific server
|
||||
* @param server the server to check
|
||||
* @return a {@link List} of group names
|
||||
* @throws NullPointerException if the server is null
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
* Gets the weight of this group, is present.
|
||||
*
|
||||
* @return the group weight
|
||||
* @since 2.17
|
||||
*/
|
||||
List<String> getLocalGroups(String server);
|
||||
OptionalInt getWeight();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalLong;
|
||||
|
||||
/**
|
||||
* A relationship between a Holder and a permission
|
||||
*
|
||||
* @param <T> the identifier type of the holder
|
||||
* @since 2.17
|
||||
*/
|
||||
public interface HeldPermission<T> {
|
||||
|
||||
/**
|
||||
* Gets the holder of the permission
|
||||
*
|
||||
* @return the holder
|
||||
*/
|
||||
T getHolder();
|
||||
|
||||
/**
|
||||
* Gets the permission being held
|
||||
*
|
||||
* @return the permission
|
||||
*/
|
||||
String getPermission();
|
||||
|
||||
/**
|
||||
* Gets the value of the permission
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
boolean getValue();
|
||||
|
||||
/**
|
||||
* Gets the server where the permission is held
|
||||
*
|
||||
* @return the server
|
||||
*/
|
||||
Optional<String> getServer();
|
||||
|
||||
/**
|
||||
* Gets the world where the permission is held
|
||||
*
|
||||
* @return the world
|
||||
*/
|
||||
Optional<String> getWorld();
|
||||
|
||||
/**
|
||||
* Gets the time in unix time when the permission will expire
|
||||
*
|
||||
* @return the expiry time
|
||||
*/
|
||||
OptionalLong getExpiry();
|
||||
|
||||
/**
|
||||
* Gets the context for the permission.
|
||||
*
|
||||
* @return the context
|
||||
*/
|
||||
Multimap<String, String> getContext();
|
||||
|
||||
/**
|
||||
* Converts this permission into a Node
|
||||
*
|
||||
* @return a Node copy of this permission
|
||||
*/
|
||||
Node asNode();
|
||||
|
||||
}
|
||||
@@ -28,22 +28,24 @@ import me.lucko.luckperms.api.data.MySQLConfiguration;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A wrapper interface for the internal LuckPerms configuration, providing read only access.
|
||||
* Read-only access to the LuckPerms configuration settings
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface LPConfiguration {
|
||||
|
||||
/**
|
||||
* Returns the name of this server
|
||||
* @return the name of this server
|
||||
*/
|
||||
String getServer();
|
||||
|
||||
/**
|
||||
* Returns how often a sync task will run in minutes
|
||||
* @return how often a sync task will run in minutes
|
||||
*/
|
||||
int getSyncTime();
|
||||
|
||||
/**
|
||||
* Returns the default group, in a node representation
|
||||
* @return the default group, in a node representation
|
||||
* @deprecated as of 2.6, the default group is always "default"
|
||||
*/
|
||||
@@ -51,6 +53,7 @@ public interface LPConfiguration {
|
||||
String getDefaultGroupNode();
|
||||
|
||||
/**
|
||||
* Returns the name of the default group
|
||||
* @return the name of the default group
|
||||
* @deprecated as of 2.6, the default group is always "default"
|
||||
*/
|
||||
@@ -58,91 +61,109 @@ public interface LPConfiguration {
|
||||
String getDefaultGroupName();
|
||||
|
||||
/**
|
||||
* Returns if the users on this server will have their global permissions applied
|
||||
* @return if the users on this server will have their global permissions applied
|
||||
*/
|
||||
boolean getIncludeGlobalPerms();
|
||||
|
||||
/**
|
||||
* Returns if the users on this server will have their global world permissions applied
|
||||
* @return if the users on this server will have their global world permissions applied
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getIncludeGlobalWorldPerms();
|
||||
|
||||
/**
|
||||
* Returns true if the platform is applying global groups
|
||||
* @return true if the platform is applying global groups
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getApplyGlobalGroups();
|
||||
|
||||
/**
|
||||
* Returns true if the platform is applying global world groups
|
||||
* @return true if the platform is applying global world groups
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getApplyGlobalWorldGroups();
|
||||
|
||||
/**
|
||||
* @return the online mode setting in the config
|
||||
* Returns the online mode setting
|
||||
* @return the online mode setting
|
||||
*/
|
||||
boolean getOnlineMode();
|
||||
|
||||
/**
|
||||
* Returns if LuckPerms is applying wildcard permissions
|
||||
* @return if LuckPerms is applying wildcard permissions
|
||||
*/
|
||||
boolean getApplyWildcards();
|
||||
|
||||
/**
|
||||
* Returns if LuckPerms is resolving and applying regex permissions
|
||||
* @return if LuckPerms is resolving and applying regex permissions
|
||||
*/
|
||||
boolean getApplyRegex();
|
||||
|
||||
/**
|
||||
* Returns if LuckPerms is expanding shorthand permissions
|
||||
* @return if LuckPerms is expanding shorthand permissions
|
||||
*/
|
||||
boolean getApplyShorthand();
|
||||
|
||||
/**
|
||||
* Returns if LuckPerms will send notifications to users when permissions are modified
|
||||
* @return if LuckPerms will send notifications to users when permissions are modified
|
||||
* @since 2.7
|
||||
*/
|
||||
boolean getLogNotify();
|
||||
|
||||
/**
|
||||
* Returns true if permission checks are being recorded / debugged
|
||||
* @return true if permission checks are being recorded / debugged
|
||||
* @since 2.9
|
||||
* @deprecated as this value is now always false. Functionality was replaced by the verbose command.
|
||||
*/
|
||||
@Deprecated
|
||||
boolean getDebugPermissionChecks();
|
||||
|
||||
/**
|
||||
* Returns true if the vanilla op system is enabled
|
||||
* @return true if the vanilla op system is enabled
|
||||
* @since 2.8
|
||||
*/
|
||||
boolean getEnableOps();
|
||||
|
||||
/**
|
||||
* Returns true if opped players are allowed to use LuckPerms commands
|
||||
* @return true if opped players are allowed to use LuckPerms commands
|
||||
* @since 2.8
|
||||
*/
|
||||
boolean getCommandsAllowOp();
|
||||
|
||||
/**
|
||||
* Returns true if auto op is enabled
|
||||
* @return true if auto op is enabled
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getAutoOp();
|
||||
|
||||
/**
|
||||
* Returns the name of the server used within Vault operations
|
||||
* @return the name of the server used within Vault operations
|
||||
* @since 2.7
|
||||
*/
|
||||
String getVaultServer();
|
||||
|
||||
/**
|
||||
* Returns true if global permissions should be considered when retrieving meta or player groups
|
||||
* @return true if global permissions should be considered when retrieving meta or player groups
|
||||
* @since 2.7
|
||||
*/
|
||||
boolean getVaultIncludeGlobal();
|
||||
|
||||
/**
|
||||
* Returns the database values set in the configuration
|
||||
* @return the database values set in the configuration
|
||||
* @deprecated use {@link #getDatastoreConfig()}
|
||||
*/
|
||||
@@ -151,24 +172,28 @@ public interface LPConfiguration {
|
||||
MySQLConfiguration getDatabaseValues();
|
||||
|
||||
/**
|
||||
* Returns the values set for data storage in the configuration
|
||||
* @return the values set for data storage in the configuration
|
||||
*/
|
||||
DatastoreConfiguration getDatastoreConfig();
|
||||
|
||||
/**
|
||||
* Returns the storage method string from the configuration
|
||||
* @return the storage method string from the configuration
|
||||
*/
|
||||
String getStorageMethod();
|
||||
|
||||
/**
|
||||
* Returns true if split storage is enabled
|
||||
* @return true if split storage is enabled
|
||||
* @since 2.7
|
||||
*/
|
||||
boolean getSplitStorage();
|
||||
|
||||
/**
|
||||
* @return a map of split storage options, where the key is the storage section, and the value is the storage method.
|
||||
* For example: key = user, value = json
|
||||
* Returns a map of split storage options
|
||||
* @return a map of split storage options, where the key is the storage section, and the value is the storage
|
||||
* method. For example: key = user, value = json
|
||||
* @since 2.7
|
||||
*/
|
||||
Map<String, String> getSplitStorageOptions();
|
||||
|
||||
@@ -23,19 +23,22 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* Represents a Node and where it was inherited from.
|
||||
* A node with a traceable origin
|
||||
*
|
||||
* @since 2.11
|
||||
*/
|
||||
public interface LocalizedNode extends Node {
|
||||
|
||||
/**
|
||||
* Gets the node
|
||||
* Gets the delegate node
|
||||
*
|
||||
* @return the node this instance is representing
|
||||
*/
|
||||
Node getNode();
|
||||
|
||||
/**
|
||||
* Gets the location where the {@link Node} is inherited from
|
||||
*
|
||||
* @return where the node was inherited from. Will not return null.
|
||||
* @see PermissionHolder#getObjectName()
|
||||
*/
|
||||
|
||||
@@ -28,9 +28,10 @@ import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents the internal LuckPerms log.
|
||||
* All content internally is immutable. You can add to the log using the {@link Datastore}, and then request an updated copy.
|
||||
*
|
||||
* <p> The returned instance provides a copy of the data at the time of retrieval. Any changes made to log entries will
|
||||
* only apply to this instance of the log. You can add to the log using the {@link Storage}, and then request an updated copy.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Log {
|
||||
|
||||
/**
|
||||
@@ -45,8 +46,11 @@ public interface Log {
|
||||
|
||||
/**
|
||||
* Gets the recent content separated by page
|
||||
*
|
||||
* @param pageNo the page number
|
||||
* @return the page content
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getRecentMaxPages()}}
|
||||
*/
|
||||
SortedMap<Integer, LogEntry> getRecent(int pageNo);
|
||||
|
||||
@@ -64,9 +68,12 @@ public interface Log {
|
||||
|
||||
/**
|
||||
* Gets the recent content for the uuid, separated into pages
|
||||
*
|
||||
* @param pageNo the page number
|
||||
* @param actor the uuid of the actor to filter by
|
||||
* @param actor the uuid of the actor to filter by
|
||||
* @return the page content
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getRecentMaxPages(UUID)}}
|
||||
*/
|
||||
SortedMap<Integer, LogEntry> getRecent(int pageNo, UUID actor);
|
||||
|
||||
@@ -85,9 +92,12 @@ public interface Log {
|
||||
|
||||
/**
|
||||
* Gets the user history content, separated by pages
|
||||
*
|
||||
* @param pageNo the page number
|
||||
* @param uuid the uuid of the acted user to filter by
|
||||
* @param uuid the uuid of the acted user to filter by
|
||||
* @return the page content
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getUserHistoryMaxPages(UUID)}}
|
||||
*/
|
||||
SortedMap<Integer, LogEntry> getUserHistory(int pageNo, UUID uuid);
|
||||
|
||||
@@ -97,7 +107,7 @@ public interface Log {
|
||||
*/
|
||||
int getUserHistoryMaxPages(UUID uuid);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param name the name to filter by
|
||||
* @return all content in this log where the group = name
|
||||
@@ -106,9 +116,12 @@ public interface Log {
|
||||
|
||||
/**
|
||||
* Gets the group history content, separated by pages
|
||||
*
|
||||
* @param pageNo the page number
|
||||
* @param name the name of the acted group to filter by
|
||||
* @param name the name of the acted group to filter by
|
||||
* @return the page content
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getGroupHistoryMaxPages(String)}}
|
||||
*/
|
||||
SortedMap<Integer, LogEntry> getGroupHistory(int pageNo, String name);
|
||||
|
||||
@@ -127,8 +140,9 @@ public interface Log {
|
||||
|
||||
/**
|
||||
* Gets the track history content, separated by pages
|
||||
*
|
||||
* @param pageNo the page number
|
||||
* @param name the name of the acted track to filter by
|
||||
* @param name the name of the acted track to filter by
|
||||
* @return the page content
|
||||
*/
|
||||
SortedMap<Integer, LogEntry> getTrackHistory(int pageNo, String name);
|
||||
@@ -136,9 +150,12 @@ public interface Log {
|
||||
/**
|
||||
* @param name the name to filter by
|
||||
* @return the max page number allowed in the {@link #getTrackHistory(int, String)} method
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getTrackHistoryMaxPages(String)}}
|
||||
*/
|
||||
int getTrackHistoryMaxPages(String name);
|
||||
|
||||
|
||||
/**
|
||||
* @param query the query to filter by
|
||||
* @return all content in this log where the content matches query
|
||||
@@ -147,9 +164,12 @@ public interface Log {
|
||||
|
||||
/**
|
||||
* Gets the search content, separated by pages
|
||||
*
|
||||
* @param pageNo the page number
|
||||
* @param query the query to filter by
|
||||
* @param query the query to filter by
|
||||
* @return the page content
|
||||
* @throws IllegalArgumentException if the pageNo is less than 1
|
||||
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getSearchMaxPages(String)}}
|
||||
*/
|
||||
SortedMap<Integer, LogEntry> getSearch(int pageNo, String query);
|
||||
|
||||
|
||||
@@ -25,16 +25,17 @@ package me.lucko.luckperms.api;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents a single entry in a log
|
||||
* A single entry in the log
|
||||
*
|
||||
* <p> Implements {@link Comparable} ordering based upon the timestamp of the entry.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class LogEntry implements Comparable<LogEntry> {
|
||||
private static final String FORMAT = "&8(&e%s&8) [&a%s&8] (&b%s&8) &7--> &f%s";
|
||||
|
||||
public static LogEntryBuilder builder() {
|
||||
return new LogEntryBuilder();
|
||||
}
|
||||
|
||||
private static final String FORMAT = "&8(&e%s&8) [&a%s&8] (&b%s&8) &7--> &f%s";
|
||||
|
||||
private long timestamp;
|
||||
private UUID actor;
|
||||
private String actorName;
|
||||
@@ -100,63 +101,69 @@ public class LogEntry implements Comparable<LogEntry> {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public UUID getActor() {
|
||||
return actor;
|
||||
}
|
||||
|
||||
public String getActorName() {
|
||||
return actorName;
|
||||
}
|
||||
|
||||
public char getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public UUID getActed() {
|
||||
return acted;
|
||||
}
|
||||
|
||||
public String getActedName() {
|
||||
return actedName;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public UUID getActor() {
|
||||
return actor;
|
||||
}
|
||||
|
||||
void setActor(UUID actor) {
|
||||
this.actor = actor;
|
||||
}
|
||||
|
||||
public String getActorName() {
|
||||
return actorName;
|
||||
}
|
||||
|
||||
void setActorName(String actorName) {
|
||||
this.actorName = actorName;
|
||||
}
|
||||
|
||||
public char getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
void setType(char type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public UUID getActed() {
|
||||
return acted;
|
||||
}
|
||||
|
||||
void setActed(UUID acted) {
|
||||
this.acted = acted;
|
||||
}
|
||||
|
||||
public String getActedName() {
|
||||
return actedName;
|
||||
}
|
||||
|
||||
void setActedName(String actedName) {
|
||||
this.actedName = actedName;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
void setAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LogEntry(timestamp=" + this.getTimestamp() + ", actor=" + this.getActor() + ", actorName=" +
|
||||
this.getActorName() + ", type=" + this.getType() + ", acted=" + this.getActed() + ", actedName=" +
|
||||
this.getActedName() + ", action=" + this.getAction() + ")";
|
||||
return "LogEntry(" +
|
||||
"timestamp=" + this.getTimestamp() + ", " +
|
||||
"actor=" + this.getActor() + ", " +
|
||||
"actorName=" + this.getActorName() + ", " +
|
||||
"type=" + this.getType() + ", " +
|
||||
"acted=" + this.getActed() + ", " +
|
||||
"actedName=" + this.getActedName() + ", " +
|
||||
"action=" + this.getAction() +
|
||||
")";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,41 +172,25 @@ public class LogEntry implements Comparable<LogEntry> {
|
||||
if (!(o instanceof LogEntry)) return false;
|
||||
final LogEntry other = (LogEntry) o;
|
||||
if (this.getTimestamp() != other.getTimestamp()) return false;
|
||||
final Object this$actor = this.getActor();
|
||||
final Object other$actor = other.getActor();
|
||||
if (this$actor == null ? other$actor != null : !this$actor.equals(other$actor)) return false;
|
||||
final Object this$actorName = this.getActorName();
|
||||
final Object other$actorName = other.getActorName();
|
||||
if (this$actorName == null ? other$actorName != null : !this$actorName.equals(other$actorName)) return false;
|
||||
if (this.getActor() == null ? other.getActor() != null : !this.getActor().equals(other.getActor())) return false;
|
||||
if (this.getActorName() == null ? other.getActorName() != null : !this.getActorName().equals(other.getActorName())) return false;
|
||||
if (this.getType() != other.getType()) return false;
|
||||
final Object this$acted = this.getActed();
|
||||
final Object other$acted = other.getActed();
|
||||
if (this$acted == null ? other$acted != null : !this$acted.equals(other$acted)) return false;
|
||||
final Object this$actedName = this.getActedName();
|
||||
final Object other$actedName = other.getActedName();
|
||||
if (this$actedName == null ? other$actedName != null : !this$actedName.equals(other$actedName)) return false;
|
||||
final Object this$action = this.getAction();
|
||||
final Object other$action = other.getAction();
|
||||
return this$action == null ? other$action == null : this$action.equals(other$action);
|
||||
if (this.getActed() == null ? other.getActed() != null : !this.getActed().equals(other.getActed())) return false;
|
||||
if (this.getActedName() == null ? other.getActedName() != null : !this.getActedName().equals(other.getActedName())) return false;
|
||||
return this.getAction() == null ? other.getAction() == null : this.getAction().equals(other.getAction());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 59;
|
||||
int result = 1;
|
||||
final long $timestamp = this.getTimestamp();
|
||||
result = result * PRIME + (int) ($timestamp >>> 32 ^ $timestamp);
|
||||
final Object $actor = this.getActor();
|
||||
result = result * PRIME + ($actor == null ? 43 : $actor.hashCode());
|
||||
final Object $actorName = this.getActorName();
|
||||
result = result * PRIME + ($actorName == null ? 43 : $actorName.hashCode());
|
||||
result = result * PRIME + (int) (this.getTimestamp() >>> 32 ^ this.getTimestamp());
|
||||
result = result * PRIME + (this.getActor() == null ? 43 : this.getActor().hashCode());
|
||||
result = result * PRIME + (this.getActorName() == null ? 43 : this.getActorName().hashCode());
|
||||
result = result * PRIME + this.getType();
|
||||
final Object $acted = this.getActed();
|
||||
result = result * PRIME + ($acted == null ? 43 : $acted.hashCode());
|
||||
final Object $actedName = this.getActedName();
|
||||
result = result * PRIME + ($actedName == null ? 43 : $actedName.hashCode());
|
||||
final Object $action = this.getAction();
|
||||
result = result * PRIME + ($action == null ? 43 : $action.hashCode());
|
||||
result = result * PRIME + (this.getActed() == null ? 43 : this.getActed().hashCode());
|
||||
result = result * PRIME + (this.getActedName() == null ? 43 : this.getActedName().hashCode());
|
||||
result = result * PRIME + (this.getAction() == null ? 43 : this.getAction().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -214,6 +205,7 @@ public class LogEntry implements Comparable<LogEntry> {
|
||||
protected LogEntryBuilder getThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static abstract class AbstractLogEntryBuilder<T extends LogEntry, B extends AbstractLogEntryBuilder<T, B>> {
|
||||
@@ -226,6 +218,7 @@ public class LogEntry implements Comparable<LogEntry> {
|
||||
}
|
||||
|
||||
protected abstract T createObj();
|
||||
|
||||
protected abstract B getThis();
|
||||
|
||||
public long getTimestamp() {
|
||||
@@ -310,9 +303,15 @@ public class LogEntry implements Comparable<LogEntry> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LogEntry.LogEntryBuilder(timestamp=" + getTimestamp() + ", actor=" + getActor() + ", actorName=" +
|
||||
getActorName() + ", type=" + getType() + ", acted=" + getActed() + ", actedName=" + getActedName() +
|
||||
", action=" + getAction() + ")";
|
||||
return "LogEntry.LogEntryBuilder(" +
|
||||
"timestamp=" + this.getTimestamp() + ", " +
|
||||
"actor=" + this.getActor() + ", " +
|
||||
"actorName=" + this.getActorName() + ", " +
|
||||
"type=" + this.getType() + ", " +
|
||||
"acted=" + this.getActed() + ", " +
|
||||
"actedName=" + this.getActedName() + ", " +
|
||||
"action=" + this.getAction() +
|
||||
")";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,15 +23,17 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* A wrapper interface for platform logger instances.
|
||||
* A wrapper interface for platform logger instances
|
||||
*
|
||||
* <p> Bukkit/Bungee both use java.util.logging, and Sponge uses org.slf4j. This class wraps those classes so the commons
|
||||
* module can access a logger.
|
||||
* <p> Bukkit/Bungee both use java.util.logging, and Sponge uses org.slf4j. This class wraps those classes so the
|
||||
* commons module can access a logger.
|
||||
*/
|
||||
public interface Logger {
|
||||
|
||||
void info(String s);
|
||||
|
||||
void warn(String s);
|
||||
|
||||
void severe(String s);
|
||||
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.IContextCalculator;
|
||||
import me.lucko.luckperms.api.event.LPListener;
|
||||
|
||||
@@ -31,9 +32,8 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* The root API interface in LuckPerms
|
||||
* The root API interface for LuckPerms
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
@@ -60,6 +60,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Registers a listener to be sent LuckPerms events
|
||||
*
|
||||
* @param listener the listener instance
|
||||
* @throws NullPointerException if the listener is null
|
||||
*/
|
||||
@@ -67,6 +68,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Unregisters a previously registered listener from the EventBus
|
||||
*
|
||||
* @param listener the listener instance to unregister
|
||||
* @throws NullPointerException if the listener is null
|
||||
*/
|
||||
@@ -74,30 +76,53 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a wrapped {@link LPConfiguration} instance, with read only access
|
||||
*
|
||||
* @return a configuration instance
|
||||
*/
|
||||
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
|
||||
*/
|
||||
Logger getLogger();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* Gets a wrapped user object from the user storage
|
||||
*
|
||||
* @param uuid the uuid of the user to get
|
||||
* @return a {@link User} object, if one matching the uuid is loaded, or null if not
|
||||
* @throws NullPointerException if the uuid is null
|
||||
@@ -106,6 +131,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a wrapped user object from the user storage. This method does not return null, unlike {@link #getUser(UUID)}
|
||||
*
|
||||
* @param uuid the uuid of the user to get
|
||||
* @return an optional {@link User} object
|
||||
* @throws NullPointerException if the uuid is null
|
||||
@@ -114,6 +140,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a wrapped user object from the user storage
|
||||
*
|
||||
* @param name the username of the user to get
|
||||
* @return a {@link User} object, if one matching the uuid is loaded, or null if not
|
||||
* @throws NullPointerException if the name is null
|
||||
@@ -121,7 +148,9 @@ public interface LuckPermsApi {
|
||||
User getUser(String name);
|
||||
|
||||
/**
|
||||
* Gets a wrapped user object from the user storage. This method does not return null, unlike {@link #getUser(String)}
|
||||
* Gets a wrapped user object from the user storage. This method does not return null, unlike {@link
|
||||
* #getUser(String)}
|
||||
*
|
||||
* @param name the username of the user to get
|
||||
* @return an optional {@link User} object
|
||||
* @throws NullPointerException if the name is null
|
||||
@@ -130,12 +159,14 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a set of all loaded users.
|
||||
*
|
||||
* @return a {@link Set} of {@link User} objects
|
||||
*/
|
||||
Set<User> getUsers();
|
||||
|
||||
/**
|
||||
* Check if a user is loaded in memory
|
||||
*
|
||||
* @param uuid the uuid to check for
|
||||
* @return true if the user is loaded
|
||||
* @throws NullPointerException if the uuid is null
|
||||
@@ -144,6 +175,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Unload a user from the internal storage, if they're not currently online.
|
||||
*
|
||||
* @param user the user to unload
|
||||
* @throws NullPointerException if the user is null
|
||||
* @since 2.6
|
||||
@@ -152,6 +184,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a wrapped group object from the group storage
|
||||
*
|
||||
* @param name the name of the group to get
|
||||
* @return a {@link Group} object, if one matching the name exists, or null if not
|
||||
* @throws NullPointerException if the name is null
|
||||
@@ -160,6 +193,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a wrapped group object from the group storage. This method does not return null, unlike {@link #getGroup}
|
||||
*
|
||||
* @param name the name of the group to get
|
||||
* @return an optional {@link Group} object
|
||||
* @throws NullPointerException if the name is null
|
||||
@@ -168,12 +202,14 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a set of all loaded groups.
|
||||
*
|
||||
* @return a {@link Set} of {@link Group} objects
|
||||
*/
|
||||
Set<Group> getGroups();
|
||||
|
||||
/**
|
||||
* Check if a group is loaded in memory
|
||||
*
|
||||
* @param name the name to check for
|
||||
* @return true if the group is loaded
|
||||
* @throws NullPointerException if the name is null
|
||||
@@ -182,6 +218,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a wrapped track object from the track storage
|
||||
*
|
||||
* @param name the name of the track to get
|
||||
* @return a {@link Track} object, if one matching the name exists, or null if not
|
||||
* @throws NullPointerException if the name is null
|
||||
@@ -190,6 +227,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a wrapped track object from the track storage. This method does not return null, unlike {@link #getTrack}
|
||||
*
|
||||
* @param name the name of the track to get
|
||||
* @return an optional {@link Track} object
|
||||
* @throws NullPointerException if the name is null
|
||||
@@ -198,30 +236,41 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets a set of all loaded tracks.
|
||||
*
|
||||
* @return a {@link Set} of {@link Track} objects
|
||||
*/
|
||||
Set<Track> getTracks();
|
||||
|
||||
/**
|
||||
* Check if a track is loaded in memory
|
||||
*
|
||||
* @param name the name to check for
|
||||
* @return true if the track is loaded
|
||||
* @throws NullPointerException if the name is null
|
||||
*/
|
||||
boolean isTrackLoaded(String name);
|
||||
|
||||
/**
|
||||
* Gets the node factory instance for the platform
|
||||
*
|
||||
* @return the node factory
|
||||
*/
|
||||
NodeFactory getNodeFactory();
|
||||
|
||||
/**
|
||||
* Returns a permission builder instance
|
||||
*
|
||||
* @param permission the main permission node to build
|
||||
* @return a {@link Node.Builder} instance
|
||||
* @throws IllegalArgumentException if the permission is invalid
|
||||
* @throws NullPointerException if the permission is null
|
||||
* @throws NullPointerException if the permission is null
|
||||
* @since 2.6
|
||||
*/
|
||||
Node.Builder buildNode(String permission) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Register a custom context calculator to the server
|
||||
*
|
||||
* @param contextCalculator the context calculator to register. The type MUST be the player class of the platform.
|
||||
* @throws ClassCastException if the type is not the player class of the platform.
|
||||
*/
|
||||
@@ -229,9 +278,29 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Registers a custom context listener to the server,
|
||||
*
|
||||
* @param contextListener the context listener to register. The type MUST be the player class of the platform.
|
||||
* @throws ClassCastException if the type is not the player class of the platform.
|
||||
*/
|
||||
void registerContextListener(ContextListener<?> contextListener);
|
||||
|
||||
/**
|
||||
* Gets a calculated context instance for the user using the rules of the platform.
|
||||
*
|
||||
* <p> These values are calculated using the options in the configuration, and the provided calculators.
|
||||
*
|
||||
* @param user the user to get contexts for
|
||||
* @return an optional containing contexts. Will return empty if the user is not online.
|
||||
*/
|
||||
Optional<Contexts> getContextForUser(User user);
|
||||
|
||||
/**
|
||||
* Gets set of contexts applicable to a player using the platforms {@link IContextCalculator}s.
|
||||
*
|
||||
* @param player the player to calculate for. Must be the player instance for the platform.
|
||||
* @return a set of contexts.
|
||||
* @since 2.17
|
||||
*/
|
||||
ContextSet getContextForPlayer(Object player);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* A means to push changes to other servers using the platforms networking
|
||||
*
|
||||
* @since 2.14
|
||||
*/
|
||||
public interface MessagingService {
|
||||
|
||||
/**
|
||||
* Uses the messaging service to inform other servers about changes.
|
||||
*
|
||||
* <p> This will push the update asynchronously, and this method will return immediately. Calling this method is
|
||||
* equivalent to running "/lp networksync", except will not sync this server.
|
||||
*/
|
||||
void pushUpdate();
|
||||
|
||||
}
|
||||
@@ -32,14 +32,14 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* A collection of utilities to help retrieve meta values for {@link PermissionHolder}s
|
||||
*
|
||||
* @since 2.7
|
||||
*/
|
||||
public class MetaUtils {
|
||||
|
||||
private MetaUtils(){}
|
||||
|
||||
/**
|
||||
* Escapes special characters used within LuckPerms, so the string can be saved without issues
|
||||
*
|
||||
* @param s the string to escape
|
||||
* @return an escaped string
|
||||
* @throws NullPointerException if the string is null
|
||||
@@ -48,7 +48,7 @@ public class MetaUtils {
|
||||
if (s == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
|
||||
s = s.replace(".", "{SEP}");
|
||||
s = s.replace("/", "{FSEP}");
|
||||
s = s.replace("$", "{DSEP}");
|
||||
@@ -58,6 +58,7 @@ public class MetaUtils {
|
||||
|
||||
/**
|
||||
* Unescapes special characters used within LuckPerms, the inverse of {@link #escapeCharacters(String)}
|
||||
*
|
||||
* @param s the string to unescape
|
||||
* @return an unescaped string
|
||||
* @throws NullPointerException if the string is null
|
||||
@@ -66,7 +67,7 @@ public class MetaUtils {
|
||||
if (s == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
|
||||
s = s.replace("{SEP}", ".");
|
||||
s = s.replace("{FSEP}", "/");
|
||||
s = s.replace("{DSEP}", "$");
|
||||
@@ -76,19 +77,20 @@ public class MetaUtils {
|
||||
|
||||
/**
|
||||
* Sets a meta value on a holder
|
||||
*
|
||||
* @param holder the holder to apply the meta node to
|
||||
* @param server the server to apply the meta on, can be null
|
||||
* @param world the world to apply the meta on, can be null
|
||||
* @param node the meta node
|
||||
* @param value the meta value
|
||||
* @throws NullPointerException if the holder, node or value is null
|
||||
* @param world the world to apply the meta on, can be null
|
||||
* @param node the meta node
|
||||
* @param value the meta value
|
||||
* @throws NullPointerException if the holder, node or value is null
|
||||
* @throws IllegalArgumentException if the node or value is empty
|
||||
*/
|
||||
public static void setMeta(PermissionHolder holder, String server, String world, String node, String value) {
|
||||
if (holder == null) {
|
||||
throw new NullPointerException("holder");
|
||||
}
|
||||
|
||||
|
||||
if (node == null) {
|
||||
throw new NullPointerException("node");
|
||||
}
|
||||
@@ -108,7 +110,7 @@ public class MetaUtils {
|
||||
if (server == null || server.equals("")) {
|
||||
server = "global";
|
||||
}
|
||||
|
||||
|
||||
node = escapeCharacters(node);
|
||||
value = escapeCharacters(value);
|
||||
|
||||
@@ -118,11 +120,12 @@ public class MetaUtils {
|
||||
toRemove.add(n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (Node n : toRemove) {
|
||||
try {
|
||||
holder.unsetPermission(n);
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
} catch (ObjectLacksException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
Node.Builder metaNode = LuckPerms.getApi().buildNode("meta." + node + "." + value).setValue(true);
|
||||
@@ -135,19 +138,21 @@ public class MetaUtils {
|
||||
|
||||
try {
|
||||
holder.setPermission(metaNode.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a meta value for the holder
|
||||
* @param holder the holder to get the meta from
|
||||
* @param server the server to retrieve the meta on, can be null
|
||||
* @param world the world to retrieve the meta on, can be null
|
||||
* @param node the node to get
|
||||
* @param defaultValue the default value to return if the node is not set
|
||||
*
|
||||
* @param holder the holder to get the meta from
|
||||
* @param server the server to retrieve the meta on, can be null
|
||||
* @param world the world to retrieve the meta on, can be null
|
||||
* @param node the node to get
|
||||
* @param defaultValue the default value to return if the node is not set
|
||||
* @param includeGlobal if global nodes should be considered when retrieving the meta
|
||||
* @return a meta string, or the default value if the user does not have the meta node
|
||||
* @throws NullPointerException if the holder or node is null
|
||||
* @throws NullPointerException if the holder or node is null
|
||||
* @throws IllegalArgumentException if the node is empty
|
||||
*/
|
||||
public static String getMeta(PermissionHolder holder, String server, String world, String node, String defaultValue, boolean includeGlobal) {
|
||||
@@ -217,17 +222,19 @@ public class MetaUtils {
|
||||
|
||||
try {
|
||||
holder.setPermission(node.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a prefix to a holder on a specific server and world
|
||||
* @param holder the holder to set the prefix for
|
||||
* @param prefix the prefix value
|
||||
*
|
||||
* @param holder the holder to set the prefix for
|
||||
* @param prefix the prefix value
|
||||
* @param priority the priority to set the prefix at
|
||||
* @param server the server to set the prefix on, can be null
|
||||
* @param world the world to set the prefix on, can be null
|
||||
* @throws NullPointerException if the holder is null
|
||||
* @param server the server to set the prefix on, can be null
|
||||
* @param world the world to set the prefix on, can be null
|
||||
* @throws NullPointerException if the holder is null
|
||||
* @throws IllegalArgumentException if the prefix is null or empty
|
||||
*/
|
||||
public static void setPrefix(PermissionHolder holder, String prefix, int priority, String server, String world) {
|
||||
@@ -236,12 +243,13 @@ public class MetaUtils {
|
||||
|
||||
/**
|
||||
* Adds a suffix to a holder on a specific server and world
|
||||
* @param holder the holder to set the suffix for
|
||||
* @param suffix the suffix value
|
||||
*
|
||||
* @param holder the holder to set the suffix for
|
||||
* @param suffix the suffix value
|
||||
* @param priority the priority to set the suffix at
|
||||
* @param server the server to set the suffix on, can be null
|
||||
* @param world the world to set the suffix on, can be null
|
||||
* @throws NullPointerException if the holder is null
|
||||
* @param server the server to set the suffix on, can be null
|
||||
* @param world the world to set the suffix on, can be null
|
||||
* @throws NullPointerException if the holder is null
|
||||
* @throws IllegalArgumentException if the suffix is null or empty
|
||||
*/
|
||||
public static void setSuffix(PermissionHolder holder, String suffix, int priority, String server, String world) {
|
||||
@@ -272,7 +280,7 @@ public class MetaUtils {
|
||||
if (!n.shouldApplyOnWorld(world, includeGlobal, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (prefix ? !n.isPrefix() : !n.isSuffix()) {
|
||||
continue;
|
||||
}
|
||||
@@ -289,9 +297,10 @@ public class MetaUtils {
|
||||
|
||||
/**
|
||||
* Returns a holders highest priority prefix, if they have one
|
||||
* @param holder the holder
|
||||
* @param server the server to retrieve the prefix on
|
||||
* @param world the world to retrieve the prefix on
|
||||
*
|
||||
* @param holder the holder
|
||||
* @param server the server to retrieve the prefix on
|
||||
* @param world the world to retrieve the prefix on
|
||||
* @param includeGlobal if global nodes should be considered when retrieving the prefix
|
||||
* @return a prefix string, if the holder has one, or an empty string if not.
|
||||
* @throws NullPointerException if the holder is null
|
||||
@@ -302,9 +311,10 @@ public class MetaUtils {
|
||||
|
||||
/**
|
||||
* Returns a holders highest priority suffix, if they have one
|
||||
* @param holder the holder
|
||||
* @param server the server to retrieve the suffix on
|
||||
* @param world the world to retrieve the suffix on
|
||||
*
|
||||
* @param holder the holder
|
||||
* @param server the server to retrieve the suffix on
|
||||
* @param world the world to retrieve the suffix on
|
||||
* @param includeGlobal if global nodes should be considered when retrieving the suffix
|
||||
* @return a suffix string, if the holder has one, or an empty string if not.
|
||||
* @throws NullPointerException if the holder is null
|
||||
@@ -312,5 +322,8 @@ public class MetaUtils {
|
||||
public static String getSuffix(PermissionHolder holder, String server, String world, boolean includeGlobal) {
|
||||
return getChatMeta(false, holder, server, world, includeGlobal);
|
||||
}
|
||||
|
||||
|
||||
private MetaUtils() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,14 +24,19 @@ package me.lucko.luckperms.api;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents an immutable node object
|
||||
* An immutable permission node
|
||||
*
|
||||
* <p> Use {@link LuckPermsApi#buildNode(String)} to get an instance.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
@@ -41,6 +46,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Get what value the permission is set to. A negated node would return <code>false</code>.
|
||||
*
|
||||
* @return the permission's value
|
||||
*/
|
||||
@Override
|
||||
@@ -59,18 +65,21 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
/**
|
||||
* If this node is set to override explicitly.
|
||||
* This value does not persist across saves, and is therefore only useful for transient nodes
|
||||
*
|
||||
* @return true if this node is set to override explicitly
|
||||
*/
|
||||
boolean isOverride();
|
||||
|
||||
/**
|
||||
* Gets the server this node applies on, if the node is server specific
|
||||
*
|
||||
* @return an {@link Optional} containing the server, if one is defined
|
||||
*/
|
||||
Optional<String> getServer();
|
||||
|
||||
/**
|
||||
* Gets the world this node applies on, if the node is world specific
|
||||
*
|
||||
* @return an {@link Optional} containing the world, if one is defined
|
||||
*/
|
||||
Optional<String> getWorld();
|
||||
@@ -87,25 +96,28 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* If this node should apply on a specific server
|
||||
* @param server the name of the server
|
||||
*
|
||||
* @param server the name of the server
|
||||
* @param includeGlobal if global permissions should apply
|
||||
* @param applyRegex if regex should be applied
|
||||
* @param applyRegex if regex should be applied
|
||||
* @return true if the node should apply
|
||||
*/
|
||||
boolean shouldApplyOnServer(String server, boolean includeGlobal, boolean applyRegex);
|
||||
|
||||
/**
|
||||
* If this node should apply on a specific world
|
||||
* @param world the name of the world
|
||||
*
|
||||
* @param world the name of the world
|
||||
* @param includeGlobal if global permissions should apply
|
||||
* @param applyRegex if regex should be applied
|
||||
* @param applyRegex if regex should be applied
|
||||
* @return true if the node should apply
|
||||
*/
|
||||
boolean shouldApplyOnWorld(String world, boolean includeGlobal, boolean applyRegex);
|
||||
|
||||
/**
|
||||
* If this node should apply in the given context
|
||||
* @param context the context key value pairs
|
||||
*
|
||||
* @param context the context key value pairs
|
||||
* @param worldAndServer if world and server contexts should be checked
|
||||
* @return true if the node should apply
|
||||
* @since 2.13
|
||||
@@ -114,6 +126,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* If this node should apply in the given context
|
||||
*
|
||||
* @param context the context key value pairs
|
||||
* @return true if the node should apply
|
||||
* @since 2.13
|
||||
@@ -122,7 +135,8 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* If this node should apply in the given context
|
||||
* @param context the context key value pairs
|
||||
*
|
||||
* @param context the context key value pairs
|
||||
* @param worldAndServer if world and server contexts should be checked
|
||||
* @return true if the node should apply
|
||||
* @deprecated in favour of {@link #shouldApplyWithContext(ContextSet, boolean)}
|
||||
@@ -134,6 +148,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* If this node should apply in the given context
|
||||
*
|
||||
* @param context the context key value pairs
|
||||
* @return true if the node should apply
|
||||
* @deprecated in favour of {@link #shouldApplyWithContext(ContextSet)}
|
||||
@@ -145,7 +160,8 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Similar to {@link #shouldApplyOnServer(String, boolean, boolean)}, except this method accepts a List
|
||||
* @param servers the list of servers
|
||||
*
|
||||
* @param servers the list of servers
|
||||
* @param includeGlobal if global permissions should apply
|
||||
* @return true if the node should apply
|
||||
*/
|
||||
@@ -153,7 +169,8 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Similar to {@link #shouldApplyOnWorld(String, boolean, boolean)}, except this method accepts a List
|
||||
* @param worlds the list of world
|
||||
*
|
||||
* @param worlds the list of world
|
||||
* @param includeGlobal if global permissions should apply
|
||||
* @return true if the node should apply
|
||||
*/
|
||||
@@ -161,6 +178,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Resolves a list of wildcards that match this node
|
||||
*
|
||||
* @param possibleNodes a list of possible permission nodes
|
||||
* @return a list of permissions that match this wildcard
|
||||
*/
|
||||
@@ -168,6 +186,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Resolves any shorthand parts of this node and returns the full list
|
||||
*
|
||||
* @return a list of full nodes
|
||||
*/
|
||||
List<String> resolveShorthand();
|
||||
@@ -225,6 +244,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Converts this node into a serialized form
|
||||
*
|
||||
* @return a serialized node string
|
||||
*/
|
||||
String toSerializedNode();
|
||||
@@ -247,6 +267,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Gets the level of this wildcard, higher is more specific
|
||||
*
|
||||
* @return the wildcard level
|
||||
* @throws IllegalStateException if this is not a wildcard
|
||||
*/
|
||||
@@ -259,6 +280,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Gets the meta value from this node
|
||||
*
|
||||
* @return the meta value
|
||||
* @throws IllegalStateException if this node is not a meta node
|
||||
*/
|
||||
@@ -271,6 +293,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Gets the prefix value from this node
|
||||
*
|
||||
* @return the prefix value
|
||||
* @throws IllegalStateException if this node is a not a prefix node
|
||||
*/
|
||||
@@ -283,6 +306,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Gets the suffix value from this node
|
||||
*
|
||||
* @return the suffix value
|
||||
* @throws IllegalStateException if this node is a not a suffix node
|
||||
*/
|
||||
@@ -290,6 +314,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Checks if this Node is equal to another node
|
||||
*
|
||||
* @param obj the other node
|
||||
* @return true if this node is equal to the other provided
|
||||
* @see #equalsIgnoringValue(Node) for a less strict implementation of this method
|
||||
@@ -298,6 +323,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Similar to {@link Node#equals(Object)}, except doesn't take note of the value
|
||||
*
|
||||
* @param other the other node
|
||||
* @return true if the two nodes are almost equal
|
||||
*/
|
||||
@@ -305,6 +331,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Similar to {@link Node#equals(Object)}, except doesn't take note of the expiry time or value
|
||||
*
|
||||
* @param other the other node
|
||||
* @return true if the two nodes are almost equal
|
||||
*/
|
||||
@@ -312,6 +339,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Similar to {@link Node#equals(Object)}, except doesn't take note of the value or if the node is temporary
|
||||
*
|
||||
* @param other the other node
|
||||
* @return true if the two nodes are almost equal
|
||||
* @since 2.8
|
||||
@@ -323,6 +351,7 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
*/
|
||||
interface Builder {
|
||||
Builder setNegated(boolean negated);
|
||||
|
||||
Builder setValue(boolean value);
|
||||
|
||||
/**
|
||||
@@ -332,13 +361,21 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
Builder setOverride(boolean override);
|
||||
|
||||
Builder setExpiry(long expireAt);
|
||||
|
||||
Builder setWorld(String world);
|
||||
|
||||
Builder setServer(String server) throws IllegalArgumentException;
|
||||
|
||||
Builder withExtraContext(String key, String value);
|
||||
|
||||
Builder withExtraContext(Map<String, String> map);
|
||||
|
||||
Builder withExtraContext(Set<Map.Entry<String, String>> context);
|
||||
|
||||
Builder withExtraContext(Map.Entry<String, String> entry);
|
||||
|
||||
Builder withExtraContext(ContextSet set);
|
||||
|
||||
Node build();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* Builds {@link Node} instances
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
public interface NodeFactory {
|
||||
|
||||
/**
|
||||
* Creates a node from a serialised node string
|
||||
*
|
||||
* @param serialisedPermission the serialised permission string
|
||||
* @param value the value of the node
|
||||
* @return a node instance
|
||||
* @throws NullPointerException if the permission is null
|
||||
*/
|
||||
Node fromSerialisedNode(String serialisedPermission, boolean value);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new node builder from a given base permission string
|
||||
*
|
||||
* @param permission the permission
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the permission is null
|
||||
*/
|
||||
Node.Builder newBuilder(String permission);
|
||||
|
||||
/**
|
||||
* Creates a node builder instance from an existing node
|
||||
*
|
||||
* @param other the other node
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the other node is null
|
||||
*/
|
||||
Node.Builder newBuilderFromExisting(Node other);
|
||||
|
||||
/**
|
||||
* Creates a node builder from a serialised node string
|
||||
* @param serialisedPermission the serialised permission string
|
||||
* @param value the value of the node
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the permission is null
|
||||
*/
|
||||
Node.Builder newBuilderFromSerialisedNode(String serialisedPermission, boolean value);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a node builder from a key value pair
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the key or value is null
|
||||
*/
|
||||
Node.Builder makeMetaNode(String key, String value);
|
||||
|
||||
/**
|
||||
* Creates a node builder from a prefix string and priority
|
||||
*
|
||||
* @param priority the priority
|
||||
* @param prefix the prefix string
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the prefix is null
|
||||
*/
|
||||
Node.Builder makePrefixNode(int priority, String prefix);
|
||||
|
||||
/**
|
||||
* Creates a node builder from a prefix string and priority
|
||||
*
|
||||
* @param priority the priority
|
||||
* @param suffix the suffix string
|
||||
* @return a node builder instance
|
||||
* @throws NullPointerException if the suffix is null
|
||||
*/
|
||||
Node.Builder makeSuffixNode(int priority, String suffix);
|
||||
|
||||
}
|
||||
@@ -31,41 +31,52 @@ import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
/**
|
||||
* Interface for internal PermissionHolder (user/group) instances
|
||||
* An object capable of holding permissions
|
||||
*
|
||||
* <p> Any changes made will be lost unless the instance is saved back to the {@link Storage}.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* @return the identifier for this object. either a uuid string or name
|
||||
* However, you should really just use {@link User#getUuid()}, {@link User#getName()} or {@link Group#getName()}
|
||||
* Gets the objects name
|
||||
*
|
||||
* <p> {@link User#getUuid()}, {@link User#getName()} or {@link Group#getName()} should normally be used instead of
|
||||
* this method.
|
||||
*
|
||||
* @return the identifier for this object. Either a uuid string or name.
|
||||
*/
|
||||
String getObjectName();
|
||||
|
||||
/**
|
||||
* Gets an immutable Set of the objects permission nodes
|
||||
* Gets a sorted set of all held permissions.
|
||||
*
|
||||
* @return an immutable set of permissions in priority order
|
||||
* @since 2.6
|
||||
*/
|
||||
SortedSet<? extends Node> getPermissions();
|
||||
|
||||
/**
|
||||
* Similar to {@link #getPermissions()}, except excluding transient permissions
|
||||
* Similar to {@link #getPermissions()}, except without transient permissions
|
||||
*
|
||||
* @return a set of nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getEnduringPermissions();
|
||||
Set<? extends Node> getEnduringPermissions();
|
||||
|
||||
/**
|
||||
* Similar to {@link #getPermissions()}, except excluding non-transient permissions
|
||||
* Gets an immutable set of all transiently held permissions.
|
||||
*
|
||||
* <p> Transient permissions only exist for the duration of the session.
|
||||
*
|
||||
* @return a set of nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getTransientPermissions();
|
||||
Set<? extends Node> getTransientPermissions();
|
||||
|
||||
|
||||
/**
|
||||
* Gets an immutable set of the nodes that this object has and inherits
|
||||
*
|
||||
* @return an immutable set of permissions
|
||||
* @since 2.6
|
||||
* @deprecated in favour of {@link #getAllNodes(Contexts)}
|
||||
@@ -78,6 +89,7 @@ public interface PermissionHolder {
|
||||
* Unlike {@link #getAllNodesFiltered(Contexts)}, this method will not filter individual nodes. The context is only
|
||||
* used to determine which groups should apply.
|
||||
* Nodes are sorted into priority order.
|
||||
*
|
||||
* @param contexts the context for the lookup,
|
||||
* @return a mutable sorted set of permissions
|
||||
* @throws NullPointerException if the context is null
|
||||
@@ -86,9 +98,10 @@ public interface PermissionHolder {
|
||||
SortedSet<LocalizedNode> getAllNodes(Contexts contexts);
|
||||
|
||||
/**
|
||||
* Gets a mutable set of the nodes that is objects has and inherits, filtered by context.
|
||||
* Gets a mutable set of the nodes that this object has and inherits, filtered by context.
|
||||
* Unlike {@link #getAllNodes(Contexts)}, this method WILL filter individual nodes, and only return ones that fully
|
||||
* meet the context provided.
|
||||
*
|
||||
* @param contexts the context for the lookup
|
||||
* @return a mutable set of permissions
|
||||
* @throws NullPointerException if the context is null
|
||||
@@ -96,16 +109,31 @@ public interface PermissionHolder {
|
||||
*/
|
||||
Set<LocalizedNode> getAllNodesFiltered(Contexts contexts);
|
||||
|
||||
/**
|
||||
* Converts the output of {@link #getAllNodesFiltered(Contexts)}, and expands shorthand permissions.
|
||||
* @param contexts the context for the lookup
|
||||
* @param lowerCase if the keys should be made lowercase whilst being exported
|
||||
* @return a mutable map of permissions
|
||||
*/
|
||||
Map<String, Boolean> exportNodes(Contexts contexts, boolean lowerCase);
|
||||
|
||||
/**
|
||||
* Gets an immutable Map of the objects permission nodes
|
||||
*
|
||||
* @return an immutable map of permissions
|
||||
* @deprecated in favour of {@link #getPermissions()}
|
||||
*/
|
||||
@Deprecated
|
||||
Map<String, Boolean> getNodes();
|
||||
|
||||
/**
|
||||
* Removes temporary permissions that have expired
|
||||
*/
|
||||
void auditTemporaryPermissions();
|
||||
|
||||
/**
|
||||
* Checks to see if the object has a certain permission
|
||||
*
|
||||
* @param node the node to check for
|
||||
* @return a Tristate for the holders permission status for the node
|
||||
* @throws NullPointerException if the node is null
|
||||
@@ -115,6 +143,7 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Checks to see if the object has a certain permission
|
||||
*
|
||||
* @param node the node to check for
|
||||
* @return a Tristate for the holders permission status for the node
|
||||
* @throws NullPointerException if the node is null
|
||||
@@ -124,75 +153,82 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Checks to see if the object has a certain permission
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param b If the node is true/false(negated)
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node or server is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b, String server);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server and world
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param world The world
|
||||
* @param world The world
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node, server or world is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b, String server, String world);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server to check on
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server to check on
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node or server is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b, String server, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server and world
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server to check on
|
||||
* @param world The world to check on
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server to check on
|
||||
* @param world The world to check on
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node, server or world is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b, String server, String world, boolean temporary);
|
||||
|
||||
/**
|
||||
* Cheks to see if the object inherits a certain permission
|
||||
*
|
||||
* @param node the node to check for
|
||||
* @return a Tristate for the holders inheritance status for the node
|
||||
* @throws NullPointerException if the node is null
|
||||
@@ -202,78 +238,85 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a certain permission
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param b If the node is true/false(negated)
|
||||
* @return true if the object inherits the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b);
|
||||
|
||||
/**
|
||||
* Checks to see the the object inherits a permission on a certain server
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @return true if the object inherits the permission
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node or server is invalid
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b, String server);
|
||||
|
||||
/**
|
||||
* Checks to see the the object inherits a permission on a certain server and world
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param world The world
|
||||
* @param world The world
|
||||
* @return true if the object inherits the permission
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node server or world is invalid
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b, String server, String world);
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a permission
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the object inherits the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a permission on a certain server
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the object inherits the permission
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node or server is invalid
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b, String server, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a permission on a certain server and world
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param world The world
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param world The world
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the object inherits the permission
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node, server or world if invalid
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b, String server, String world, boolean temporary);
|
||||
|
||||
/**
|
||||
* Sets a permission for the object
|
||||
*
|
||||
* @param node The node to be set
|
||||
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws NullPointerException if the node is null
|
||||
* @since 2.6
|
||||
*/
|
||||
void setPermission(Node node) throws ObjectAlreadyHasException;
|
||||
@@ -289,20 +332,22 @@ public interface PermissionHolder {
|
||||
* want it to persist, and have to worry about removing it when they log out.
|
||||
*
|
||||
* <p> For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}
|
||||
*
|
||||
* @param node The node to be set
|
||||
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws NullPointerException if the node is null
|
||||
* @since 2.6
|
||||
*/
|
||||
void setTransientPermission(Node node) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Sets a permission for the object
|
||||
* @param node The node to be set
|
||||
*
|
||||
* @param node The node to be set
|
||||
* @param value What to set the node to - true/false(negated)
|
||||
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
* @deprecated in favour of {@link #setPermission(Node)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -310,12 +355,13 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Sets a permission for the object on a specific server
|
||||
* @param node The node to set
|
||||
* @param value What to set the node to - true/false(negated)
|
||||
*
|
||||
* @param node The node to set
|
||||
* @param value What to set the node to - true/false(negated)
|
||||
* @param server The server to set the permission on
|
||||
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node or server is invalid
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node or server is invalid
|
||||
* @deprecated in favour of {@link #setPermission(Node)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -323,13 +369,14 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Sets a permission for the object on a specific server and world
|
||||
* @param node The node to set
|
||||
* @param value What to set the node to - true/false(negated)
|
||||
*
|
||||
* @param node The node to set
|
||||
* @param value What to set the node to - true/false(negated)
|
||||
* @param server The server to set the permission on
|
||||
* @param world The world to set the permission on
|
||||
* @param world The world to set the permission on
|
||||
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node, server or world is invalid
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node, server or world is invalid
|
||||
* @deprecated in favour of {@link #setPermission(Node)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -337,12 +384,13 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Sets a temporary permission for the object
|
||||
* @param node The node to set
|
||||
* @param value What to set the node to - true/false(negated)
|
||||
*
|
||||
* @param node The node to set
|
||||
* @param value What to set the node to - true/false(negated)
|
||||
* @param expireAt The time in unixtime when the permission will expire
|
||||
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid or if the expiry time is in the past
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid or if the expiry time is in the past
|
||||
* @deprecated in favour of {@link #setPermission(Node)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -350,13 +398,14 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Sets a temporary permission for the object on a specific server
|
||||
* @param node The node to set
|
||||
* @param value What to set the node to - true/false(negated)
|
||||
* @param server The server to set the permission on
|
||||
*
|
||||
* @param node The node to set
|
||||
* @param value What to set the node to - true/false(negated)
|
||||
* @param server The server to set the permission on
|
||||
* @param expireAt The time in unixtime when the permission will expire
|
||||
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node/server is invalid or if the expiry time is in the past
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node/server is invalid or if the expiry time is in the past
|
||||
* @deprecated in favour of {@link #setPermission(Node)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -364,14 +413,15 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Sets a temporary permission for the object on a specific server and world
|
||||
* @param node The node to set
|
||||
* @param value What to set the node to - true/false(negated)
|
||||
* @param server The server to set the permission on
|
||||
* @param world The world to set the permission on
|
||||
*
|
||||
* @param node The node to set
|
||||
* @param value What to set the node to - true/false(negated)
|
||||
* @param server The server to set the permission on
|
||||
* @param world The world to set the permission on
|
||||
* @param expireAt The time in unixtime when the permission will expire
|
||||
* @throws ObjectAlreadyHasException if the object already has the permission
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node/server/world is invalid, or if the expiry time is in the past
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node/server/world is invalid, or if the expiry time is in the past
|
||||
* @deprecated in favour of {@link #setPermission(Node)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -379,6 +429,7 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Unsets a permission for the object
|
||||
*
|
||||
* @param node The node to be unset
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node is null
|
||||
@@ -388,6 +439,7 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Unsets a transient permission for the object
|
||||
*
|
||||
* @param node The node to be unset
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node is null
|
||||
@@ -397,10 +449,11 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Unsets a permission for the object
|
||||
* @param node The node to be unset
|
||||
*
|
||||
* @param node The node to be unset
|
||||
* @param temporary if the permission being removed is temporary
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
* @deprecated in favour of {@link #unsetPermission(Node)}
|
||||
*/
|
||||
@@ -409,9 +462,10 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Unsets a permission for the object
|
||||
*
|
||||
* @param node The node to be unset
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
* @deprecated in favour of {@link #unsetPermission(Node)}
|
||||
*/
|
||||
@@ -420,10 +474,11 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Unsets a permission for the object on a specific server
|
||||
* @param node The node to be unset
|
||||
*
|
||||
* @param node The node to be unset
|
||||
* @param server The server to unset the node on
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node or server is invalid
|
||||
* @deprecated in favour of {@link #unsetPermission(Node)}
|
||||
*/
|
||||
@@ -432,11 +487,12 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Unsets a permission for the object on a specific server and world
|
||||
* @param node The node to be unset
|
||||
*
|
||||
* @param node The node to be unset
|
||||
* @param server The server to unset the node on
|
||||
* @param world The world to unset the node on
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @param world The world to unset the node on
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node, server or world is invalid
|
||||
* @deprecated in favour of {@link #unsetPermission(Node)}
|
||||
*/
|
||||
@@ -445,11 +501,12 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Unsets a permission for the object on a specific server
|
||||
* @param node The node to be unset
|
||||
* @param server The server to unset the node on
|
||||
*
|
||||
* @param node The node to be unset
|
||||
* @param server The server to unset the node on
|
||||
* @param temporary if the permission being unset is temporary
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node or server is invalid
|
||||
* @deprecated in favour of {@link #unsetPermission(Node)}
|
||||
*/
|
||||
@@ -458,24 +515,129 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Unsets a permission for the object on a specific server and world
|
||||
* @param node The node to be unset
|
||||
* @param server The server to unset the node on
|
||||
* @param world The world to unset the node on
|
||||
*
|
||||
* @param node The node to be unset
|
||||
* @param server The server to unset the node on
|
||||
* @param world The world to unset the node on
|
||||
* @param temporary if the permission being unset is temporary
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws ObjectLacksException if the node wasn't already set
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node, server or world is invalid
|
||||
* @deprecated in favour of {@link #unsetPermission(Node)}
|
||||
*/
|
||||
@Deprecated
|
||||
void unsetPermission(String node, String server, String world, boolean temporary) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Clears all nodes held by the object
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearNodes();
|
||||
|
||||
/**
|
||||
* Clears all nodes held by the object on a specific server
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearNodes(String server);
|
||||
|
||||
/**
|
||||
* Clears all nodes held by the object on a specific server and world
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @param world the world to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearNodes(String server, String world);
|
||||
|
||||
/**
|
||||
* Clears all parent groups
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearParents();
|
||||
|
||||
/**
|
||||
* Clears all parents on a specific server
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearParents(String server);
|
||||
|
||||
/**
|
||||
* Clears all parents on a specific server and world
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @param world the world to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearParents(String server, String world);
|
||||
|
||||
/**
|
||||
* Clears all meta held by the object
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearMeta();
|
||||
|
||||
/**
|
||||
* Clears all meta held by the object on a specific server
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearMeta(String server);
|
||||
|
||||
/**
|
||||
* Clears all meta held by the object on a specific server and world
|
||||
*
|
||||
* @param server the server to filter by, can be null
|
||||
* @param world the world to filter by, can be null
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearMeta(String server, String world);
|
||||
|
||||
/**
|
||||
* Clears all meta for a given key.
|
||||
*
|
||||
* @param key the meta key
|
||||
* @param server the server to filter by, can be null
|
||||
* @param world the world to filter by, can be null
|
||||
* @param temporary whether the query is for temporary nodes or not.
|
||||
*/
|
||||
void clearMetaKeys(String key, String server, String world, boolean temporary);
|
||||
|
||||
/**
|
||||
* Clears all transient permissions the holder has.
|
||||
*/
|
||||
void clearTransientNodes();
|
||||
|
||||
/**
|
||||
* Processes the nodes and returns the non-temporary ones.
|
||||
*
|
||||
* @return a set of permanent nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getPermanentPermissionNodes();
|
||||
|
||||
/**
|
||||
* Processes the nodes and returns the temporary ones.
|
||||
*
|
||||
* @return a set of temporary nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getTemporaryPermissionNodes();
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server and world
|
||||
* @param server The server to get nodes for
|
||||
* @param world The world to get nodes for
|
||||
*
|
||||
* @param server The server to get nodes for
|
||||
* @param world The world to get nodes for
|
||||
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
|
||||
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
|
||||
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
|
||||
* @return a {@link Map} of the permissions
|
||||
* @deprecated in favour of {@link #getPermissions(String, String, Map, boolean, List, boolean)}
|
||||
*/
|
||||
@@ -484,8 +646,9 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server and world
|
||||
* @param server The server to get nodes for
|
||||
* @param world The world to get nodes for
|
||||
*
|
||||
* @param server The server to get nodes for
|
||||
* @param world The world to get nodes for
|
||||
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
|
||||
* @return a {@link Map} of the permissions
|
||||
* @deprecated in favour of {@link #getPermissions(String, String, Map, boolean, List, boolean)}
|
||||
@@ -495,9 +658,10 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for
|
||||
*
|
||||
* @param server The server to get nodes for
|
||||
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
|
||||
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
|
||||
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
|
||||
* @return a {@link Map} of the permissions
|
||||
* @deprecated in favour of {@link #getPermissions(String, String, Map, boolean, List, boolean)}
|
||||
*/
|
||||
@@ -506,7 +670,8 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for
|
||||
*
|
||||
* @param server The server to get nodes for
|
||||
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
|
||||
* @return a {@link Map} of the permissions
|
||||
* @deprecated in favour of {@link #getPermissions(String, String, Map, boolean, List, boolean)}
|
||||
@@ -516,12 +681,13 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Convert the holders nodes into a Map of permissions to be applied on the platform
|
||||
* @param server the server
|
||||
* @param world the world
|
||||
* @param extraContext any extra context to filter by
|
||||
*
|
||||
* @param server the server
|
||||
* @param world the world
|
||||
* @param extraContext any extra context to filter by
|
||||
* @param includeGlobal whether to include global nodes
|
||||
* @param possibleNodes a list of possible permissions for resolving wildcards
|
||||
* @param applyGroups if inherited group permissions should be included
|
||||
* @param applyGroups if inherited group permissions should be included
|
||||
* @return a map of permissions
|
||||
* @since 2.6
|
||||
* @deprecated in favour of {@link #getAllNodesFiltered(Contexts)}
|
||||
@@ -531,37 +697,20 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Processes the nodes and returns the temporary ones.
|
||||
*
|
||||
* @return a map of temporary nodes
|
||||
* @deprecated in favour of {@link #getTemporaryPermissionNodes()}
|
||||
*/
|
||||
@Deprecated
|
||||
Map<Map.Entry<String, Boolean>, Long> getTemporaryNodes();
|
||||
|
||||
/**
|
||||
* Processes the nodes and returns the temporary ones.
|
||||
* @return a set of temporary nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getTemporaryPermissionNodes();
|
||||
|
||||
/**
|
||||
* Processes the nodes and returns the non-temporary ones.
|
||||
*
|
||||
* @return a map of permanent nodes
|
||||
* @deprecated in favour of {@link #getPermanentPermissionNodes()}
|
||||
*/
|
||||
@Deprecated
|
||||
Map<String, Boolean> getPermanentNodes();
|
||||
|
||||
/**
|
||||
* Processes the nodes and returns the non-temporary ones.
|
||||
* @return a set of permanent nodes
|
||||
* @since 2.6
|
||||
*/
|
||||
Set<Node> getPermanentPermissionNodes();
|
||||
|
||||
/**
|
||||
* Removes temporary permissions that have expired
|
||||
*/
|
||||
void auditTemporaryPermissions();
|
||||
|
||||
}
|
||||
@@ -23,7 +23,8 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* Represents the platform type that LuckPerms is running on
|
||||
* The platforms which LuckPerms can run on
|
||||
*
|
||||
* @since 2.7
|
||||
*/
|
||||
public enum PlatformType {
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* 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.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A means of loading and saving data to/from the Storage provider.
|
||||
*
|
||||
* <p>All methods return {@link CompletableFuture}s, which will be populated with the result once the data has been
|
||||
* loaded asynchronously. Care should be taken when using the methods to ensure that the main server thread is not
|
||||
* blocked.
|
||||
*
|
||||
* <p>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();
|
||||
|
||||
/**
|
||||
* Searches for a list of users with a given permission.
|
||||
*
|
||||
* @param permission the permission to search for
|
||||
* @return a list of held permissions, or null if the operation failed
|
||||
* @throws NullPointerException if the permission is null
|
||||
* @since 2.17
|
||||
*/
|
||||
CompletableFuture<List<HeldPermission<UUID>>> getUsersWithPermission(String permission);
|
||||
|
||||
/**
|
||||
* Creates and loads a group into the plugins local storage
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Searches for a list of groups with a given permission.
|
||||
*
|
||||
* @param permission the permission to search for
|
||||
* @return a list of held permissions, or null if the operation failed
|
||||
* @throws NullPointerException if the permission is null
|
||||
* @since 2.17
|
||||
*/
|
||||
CompletableFuture<List<HeldPermission<String>>> getGroupsWithPermission(String permission);
|
||||
|
||||
/**
|
||||
* Creates and loads a track into the plugins local storage
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Gets a username from a UUID
|
||||
*
|
||||
* @param uuid the corresponding uuid
|
||||
* @return a name string, could be null
|
||||
* @throws NullPointerException if either parameters are null
|
||||
* @since 2.17
|
||||
*/
|
||||
CompletableFuture<String> getName(UUID uuid);
|
||||
|
||||
}
|
||||
@@ -28,80 +28,89 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface for internal Track instances
|
||||
* An ordered collection of groups for easy promotions and demotions
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Track {
|
||||
|
||||
/**
|
||||
* Gets the name of this track
|
||||
* @return the name of this track
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Gets an ordered list of the groups on this track
|
||||
* Index 0 is the first/lowest group in (or start of) the track
|
||||
*
|
||||
* <p> Index 0 is the first/lowest group in (or start of) the track
|
||||
*
|
||||
* @return an ordered {@link List} of the groups on this track
|
||||
*/
|
||||
List<String> getGroups();
|
||||
|
||||
/**
|
||||
* Gets the number of groups on this track
|
||||
*
|
||||
* @return the number of groups on this track
|
||||
*/
|
||||
int getSize();
|
||||
|
||||
/**
|
||||
* Gets the next group on the track, after the one provided
|
||||
*
|
||||
* @param current the group before the group being requested
|
||||
* @return the group name, or null if the end of the track has been reached
|
||||
* @throws ObjectLacksException if the track does not contain the group given
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws ObjectLacksException if the track does not contain the group given
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
String getNext(Group current) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Gets the previous group on the track, before the one provided
|
||||
*
|
||||
* @param current the group after the group being requested
|
||||
* @return the group name, or null if the start of the track has been reached
|
||||
* @throws ObjectLacksException if the track does not contain the group given
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws ObjectLacksException if the track does not contain the group given
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
String getPrevious(Group current) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Appends a group to the end of this track
|
||||
*
|
||||
* @param group the group to append
|
||||
* @throws ObjectAlreadyHasException if the group is already on this track somewhere
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
void appendGroup(Group group) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Inserts a group at a certain position on this track
|
||||
* @param group the group to be inserted
|
||||
*
|
||||
* @param group the group to be inserted
|
||||
* @param position the index position (a value of 0 inserts at the start)
|
||||
* @throws ObjectAlreadyHasException if the group is already on this track somewhere
|
||||
* @throws IndexOutOfBoundsException if the position is less than 0 or greater than the size of the track
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
void insertGroup(Group group, int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Removes a group from this track
|
||||
*
|
||||
* @param group the group to remove
|
||||
* @throws ObjectLacksException if the group is not on this track
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws ObjectLacksException if the group is not on this track
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
void removeGroup(Group group) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Removes a group from this track
|
||||
*
|
||||
* @param group the group to remove
|
||||
* @throws ObjectLacksException if the group is not on this track
|
||||
* @throws NullPointerException if the group is null
|
||||
@@ -110,15 +119,17 @@ public interface Track {
|
||||
|
||||
/**
|
||||
* Checks if a group features on this track
|
||||
*
|
||||
* @param group the group to check
|
||||
* @return true if the group is on this track
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
boolean containsGroup(Group group);
|
||||
|
||||
/**
|
||||
* Checks if a group features on this track
|
||||
*
|
||||
* @param group the group to check
|
||||
* @return true if the group is on this track
|
||||
* @throws NullPointerException if the group is null
|
||||
@@ -126,7 +137,7 @@ public interface Track {
|
||||
boolean containsGroup(String group);
|
||||
|
||||
/**
|
||||
* Clear all of the groups within this track
|
||||
* Clear all of the groups from this track
|
||||
*/
|
||||
void clearGroups();
|
||||
|
||||
|
||||
@@ -23,25 +23,51 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* Represents a permission value
|
||||
* Represents a permission setting.
|
||||
*
|
||||
* <p> Consider a value of {@link #FALSE} to be a "negated" setting, and a value of {@link #UNDEFINED} to be a
|
||||
* non-existent value.
|
||||
*/
|
||||
public enum Tristate {
|
||||
|
||||
/**
|
||||
* A value indicating a holder has a permission set.
|
||||
*/
|
||||
TRUE(true),
|
||||
|
||||
/**
|
||||
* A value indicating a holder has a negated value for a permission.
|
||||
*/
|
||||
FALSE(false),
|
||||
|
||||
/**
|
||||
* A value indicating a holder doesn't have a value for a permission set.
|
||||
*/
|
||||
UNDEFINED(false);
|
||||
|
||||
/**
|
||||
* Converts from {@link Boolean} a boolean
|
||||
*
|
||||
* @param b the boolean
|
||||
* @return {@link #TRUE} or {@link #FALSE}, depending on the value of the boolean.
|
||||
*/
|
||||
public static Tristate fromBoolean(boolean b) {
|
||||
return b ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
private final boolean booleanValue;
|
||||
|
||||
Tristate(boolean booleanValue) {
|
||||
this.booleanValue = booleanValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the Tristate as a boolean.
|
||||
* <p> A value of {@link #UNDEFINED} converts to false.
|
||||
*
|
||||
* @return a boolean representation of the Tristate.
|
||||
*/
|
||||
public boolean asBoolean() {
|
||||
return booleanValue;
|
||||
}
|
||||
|
||||
public static Tristate fromBoolean(boolean b) {
|
||||
return b ? TRUE : FALSE;
|
||||
}
|
||||
}
|
||||
@@ -31,50 +31,67 @@ import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Interface for internal User instances
|
||||
* A player holding permission data
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface User extends PermissionHolder {
|
||||
|
||||
/**
|
||||
* Gets the users unique ID
|
||||
*
|
||||
* @return the users Mojang assigned unique id
|
||||
*/
|
||||
UUID getUuid();
|
||||
|
||||
/**
|
||||
* Gets the users username
|
||||
*
|
||||
* @return the Users Username
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Gets the users primary group
|
||||
*
|
||||
* @return the users primary group
|
||||
*/
|
||||
String getPrimaryGroup();
|
||||
|
||||
/**
|
||||
* Sets a users primary group
|
||||
*
|
||||
* @param group the new primary group
|
||||
* @throws ObjectAlreadyHasException if the user already has this set as their primary group
|
||||
* @throws IllegalStateException if the user is not a member of that group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the user is not a member of that group
|
||||
* @throws NullPointerException if the group is null
|
||||
*/
|
||||
void setPrimaryGroup(String group) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Refresh and re-assign the users permissions
|
||||
* Refresh and re-assign the users permissions.
|
||||
*
|
||||
* <p> This request is not buffered, and the refresh call will be ran directly. This should ideally be called on
|
||||
* an asynchronous thread.
|
||||
*/
|
||||
void refreshPermissions();
|
||||
|
||||
/**
|
||||
* Gets the user's {@link UserData} cache, if they have one setup.
|
||||
*
|
||||
* @return an optional, possibly containing the user's cached lookup data.
|
||||
* @since 2.13
|
||||
*/
|
||||
Optional<UserData> getUserDataCache();
|
||||
|
||||
/**
|
||||
* Sets up the users data cache, if the don't have one setup already.
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
void setupDataCache();
|
||||
|
||||
/**
|
||||
* Check to see if the user is a member of a group
|
||||
*
|
||||
* @param group The group to check membership of
|
||||
* @return true if the user is a member of the group
|
||||
* @throws NullPointerException if the group is null
|
||||
@@ -83,186 +100,198 @@ public interface User extends PermissionHolder {
|
||||
|
||||
/**
|
||||
* Check to see if a user is a member of a group on a specific server
|
||||
* @param group The group to check membership of
|
||||
*
|
||||
* @param group The group to check membership of
|
||||
* @param server The server to check on
|
||||
* @return true if the user is a member of the group
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
*/
|
||||
boolean isInGroup(Group group, String server);
|
||||
|
||||
/**
|
||||
* Check to see if a user is a member of a group on a specific server and world
|
||||
* @param group The group to check membership of
|
||||
*
|
||||
* @param group The group to check membership of
|
||||
* @param server The server to check on
|
||||
* @param world The world to check on
|
||||
* @param world The world to check on
|
||||
* @return true if the user is a member of the group
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalArgumentException if the server or world is invalid
|
||||
*/
|
||||
boolean isInGroup(Group group, String server, String world);
|
||||
|
||||
/**
|
||||
* Add a user to a group
|
||||
*
|
||||
* @param group The group to add the user to
|
||||
* @throws ObjectAlreadyHasException if the user is already a member of the group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
void addGroup(Group group) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Add a user to a group on a specific server
|
||||
* @param group The group to add the user to
|
||||
*
|
||||
* @param group The group to add the user to
|
||||
* @param server The server to add the group on
|
||||
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
*/
|
||||
void addGroup(Group group, String server) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Add a user to a group on a specific server and world
|
||||
* @param group The group to add the user to
|
||||
*
|
||||
* @param group The group to add the user to
|
||||
* @param server The server to add the group on
|
||||
* @param world The world to add the group on
|
||||
* @param world The world to add the group on
|
||||
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server or world is invalid
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server or world is invalid
|
||||
*/
|
||||
void addGroup(Group group, String server, String world) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Add a user to a group temporarily on a specific server
|
||||
* @param group The group to add the user to
|
||||
*
|
||||
* @param group The group to add the user to
|
||||
* @param expireAt when the group should expire
|
||||
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past
|
||||
*/
|
||||
void addGroup(Group group, long expireAt) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Add a user to a group temporarily on a specific server
|
||||
* @param group The group to add the user to
|
||||
* @param server The server to add the group on
|
||||
*
|
||||
* @param group The group to add the user to
|
||||
* @param server The server to add the group on
|
||||
* @param expireAt when the group should expire
|
||||
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server is invalid
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server is invalid
|
||||
*/
|
||||
void addGroup(Group group, String server, long expireAt) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Add a user to a group temporarily on a specific server and world
|
||||
* @param group The group to add the user to
|
||||
* @param server The server to add the group on
|
||||
* @param world The world to add the group on
|
||||
*
|
||||
* @param group The group to add the user to
|
||||
* @param server The server to add the group on
|
||||
* @param world The world to add the group on
|
||||
* @param expireAt when the group should expire
|
||||
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server/world is invalid
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server/world is invalid
|
||||
*/
|
||||
void addGroup(Group group, String server, String world, long expireAt) throws ObjectAlreadyHasException;
|
||||
|
||||
/**
|
||||
* Remove the user from a group
|
||||
*
|
||||
* @param group the group to remove the user from
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
void removeGroup(Group group) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Remove the user from a group
|
||||
* @param group the group to remove the user from
|
||||
*
|
||||
* @param group the group to remove the user from
|
||||
* @param temporary if the group being removed is temporary
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
*/
|
||||
void removeGroup(Group group, boolean temporary) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Remove the user from a group on a specific server
|
||||
* @param group The group to remove the user from
|
||||
*
|
||||
* @param group The group to remove the user from
|
||||
* @param server The server to remove the group on
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
*/
|
||||
void removeGroup(Group group, String server) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Remove the user from a group on a specific server and world
|
||||
* @param group The group to remove the user from
|
||||
*
|
||||
* @param group The group to remove the user from
|
||||
* @param server The server to remove the group on
|
||||
* @param world The world to remove the group on
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @param world The world to remove the group on
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the server or world is invalid
|
||||
*/
|
||||
void removeGroup(Group group, String server, String world) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Remove the user from a group on a specific server
|
||||
* @param group The group to remove the user from
|
||||
* @param server The server to remove the group on
|
||||
*
|
||||
* @param group The group to remove the user from
|
||||
* @param server The server to remove the group on
|
||||
* @param temporary if the group being removed is temporary
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group or server is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server is invalid
|
||||
*/
|
||||
void removeGroup(Group group, String server, boolean temporary) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Remove the user from a group on a specific server and world
|
||||
* @param group The group to remove the user from
|
||||
* @param server The server to remove the group on
|
||||
* @param world The world to remove the group on
|
||||
*
|
||||
* @param group The group to remove the user from
|
||||
* @param server The server to remove the group on
|
||||
* @param world The world to remove the group on
|
||||
* @param temporary if the group being removed is temporary
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws ObjectLacksException if the user isn't a member of the group
|
||||
* @throws NullPointerException if the group, server or world is null
|
||||
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
|
||||
* @throws IllegalArgumentException if the expiry time is in the past or the server/world is invalid
|
||||
*/
|
||||
void removeGroup(Group group, String server, String world, boolean temporary) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Clear all of the users permission nodes
|
||||
*/
|
||||
void clearNodes();
|
||||
|
||||
/**
|
||||
* Get a {@link List} of all of the groups the user is a member of, on all servers
|
||||
*
|
||||
* @return a {@link List} of group names
|
||||
*/
|
||||
List<String> getGroupNames();
|
||||
|
||||
/**
|
||||
* Get a {@link List} of the groups the user is a member of on a specific server
|
||||
*
|
||||
* @param server the server to check
|
||||
* @param world the world to check
|
||||
* @param world the world to check
|
||||
* @return a {@link List} of group names
|
||||
* @throws NullPointerException if the server or world is null
|
||||
* @throws NullPointerException if the server or world is null
|
||||
* @throws IllegalArgumentException if the server or world is invalid
|
||||
*/
|
||||
List<String> getLocalGroups(String server, String world);
|
||||
|
||||
/**
|
||||
* Get a {@link List} of the groups the user is a member of on a specific server
|
||||
*
|
||||
* @param server the server to check
|
||||
* @return a {@link List} of group names
|
||||
* @throws NullPointerException if the server is null
|
||||
* @throws NullPointerException if the server is null
|
||||
* @throws IllegalArgumentException if the server is invalid
|
||||
*/
|
||||
List<String> getLocalGroups(String server);
|
||||
|
||||
@@ -27,21 +27,21 @@ import java.util.UUID;
|
||||
/**
|
||||
* A UUID cache for online users, between external Mojang UUIDs, and internal LuckPerms UUIDs.
|
||||
*
|
||||
* <p> This UuidCache is a means of allowing users to have the same internal UUID across a network of offline mode servers
|
||||
* or mixed offline mode and online mode servers. Platforms running in offline mode generate a random UUID for a user when
|
||||
* they first join the server, but this UUID will then not be consistent across the network. LuckPerms will instead check
|
||||
* the datastore cache, to get a UUID for a user that is consistent across an entire network.
|
||||
* <p> This UuidCache is a means of allowing users to have the same internal UUID across a network of offline mode
|
||||
* servers or mixed offline mode and online mode servers. Platforms running in offline mode generate a UUID for a
|
||||
* user when they first join the server, but this UUID will then not be consistent across the network. LuckPerms will
|
||||
* instead check the datastore cache, to get a UUID for a user that is consistent across an entire network.
|
||||
*
|
||||
* <p> If you want to get a user object from the 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.
|
||||
* <p> THIS IS ONLY EFFECTIVE FOR ONLINE PLAYERS. USE THE DATASTORE METHODS FOR OFFLINE PLAYERS.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface UuidCache {
|
||||
|
||||
/**
|
||||
* Gets a users internal "LuckPerms" UUID, from the one given by the server.
|
||||
*
|
||||
* @param external the UUID assigned by the server, through Player#getUniqueId or ProxiedPlayer#getUniqueId
|
||||
* @return the corresponding internal UUID
|
||||
*/
|
||||
@@ -49,6 +49,7 @@ public interface UuidCache {
|
||||
|
||||
/**
|
||||
* Gets a users external, server assigned or Mojang assigned unique id, from the internal one used within LuckPerms.
|
||||
*
|
||||
* @param internal the UUID used within LuckPerms, through User#getUuid
|
||||
* @return the corresponding external UUID
|
||||
*/
|
||||
|
||||
@@ -27,36 +27,44 @@ import java.util.SortedMap;
|
||||
|
||||
/**
|
||||
* Holds cached Meta lookup data for a specific set of contexts
|
||||
*
|
||||
* @since 2.13
|
||||
*/
|
||||
public interface MetaData {
|
||||
|
||||
/**
|
||||
* Gets an immutable copy of the meta this user has
|
||||
*
|
||||
* @return an immutable map of meta
|
||||
*/
|
||||
Map<String, String> getMeta();
|
||||
|
||||
/**
|
||||
* Gets an immutable sorted map of all of the prefixes the user has, whereby the first value is the highest priority prefix.
|
||||
* Gets an immutable sorted map of all of the prefixes the user has, whereby the first value is the highest priority
|
||||
* prefix.
|
||||
*
|
||||
* @return a sorted map of prefixes
|
||||
*/
|
||||
SortedMap<Integer, String> getPrefixes();
|
||||
|
||||
/**
|
||||
* Gets an immutable sorted map of all of the suffixes the user has, whereby the first value is the highest priority suffix.
|
||||
* Gets an immutable sorted map of all of the suffixes the user has, whereby the first value is the highest priority
|
||||
* suffix.
|
||||
*
|
||||
* @return a sorted map of suffixes
|
||||
*/
|
||||
SortedMap<Integer, String> getSuffixes();
|
||||
|
||||
/**
|
||||
* Gets the user's highest priority prefix, or null if the user has no prefixes
|
||||
*
|
||||
* @return a prefix string, or null
|
||||
*/
|
||||
String getPrefix();
|
||||
|
||||
/**
|
||||
* Gets the user's highest priority suffix, or null if the user has no suffixes
|
||||
*
|
||||
* @return a suffix string, or null
|
||||
*/
|
||||
String getSuffix();
|
||||
|
||||
@@ -28,12 +28,14 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Holds cached Permission lookup data for a specific set of contexts
|
||||
*
|
||||
* @since 2.13
|
||||
*/
|
||||
public interface PermissionData {
|
||||
|
||||
/**
|
||||
* Gets a permission value for the given permission node
|
||||
*
|
||||
* @param permission the permission node
|
||||
* @return a tristate result
|
||||
* @throws NullPointerException if permission is null
|
||||
@@ -42,12 +44,14 @@ public interface PermissionData {
|
||||
|
||||
/**
|
||||
* Invalidates the underlying permission calculator cache.
|
||||
* Can be called to allow for an update in defaults.
|
||||
*
|
||||
* <p> Can be called to allow for an update in defaults.
|
||||
*/
|
||||
void invalidateCache();
|
||||
|
||||
/**
|
||||
* Gets an immutable copy of the permission map backing the permission calculator
|
||||
*
|
||||
* @return an immutable set of permissions
|
||||
*/
|
||||
Map<String, Boolean> getImmutableBacking();
|
||||
|
||||
@@ -28,7 +28,8 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* Holds cached permission and meta lookup data for a {@link me.lucko.luckperms.api.User}.
|
||||
* Data is only likely to be available for online users. All calls will account for inheritance, as well as any
|
||||
*
|
||||
* <p>Data is only likely to be available for online users. All calls will account for inheritance, as well as any
|
||||
* default data provided by the platform. This calls are heavily cached and are therefore fast.
|
||||
*
|
||||
* @since 2.13
|
||||
@@ -37,7 +38,9 @@ public interface UserData {
|
||||
|
||||
/**
|
||||
* Gets PermissionData from the cache, given a specified context.
|
||||
* If the data is not cached, it is calculated. Therefore, this call could be costly.
|
||||
*
|
||||
* <p> If the data is not cached, it is calculated. Therefore, this call could be costly.
|
||||
*
|
||||
* @param contexts the contexts to get the permission data in
|
||||
* @return a permission data instance
|
||||
* @throws NullPointerException if contexts is null
|
||||
@@ -46,7 +49,9 @@ public interface UserData {
|
||||
|
||||
/**
|
||||
* Gets MetaData from the cache, given a specified context.
|
||||
* If the data is not cached, it is calculated. Therefore, this call could be costly.
|
||||
*
|
||||
* <p> If the data is not cached, it is calculated. Therefore, this call could be costly.
|
||||
*
|
||||
* @param contexts the contexts to get the permission data in
|
||||
* @return a meta data instance
|
||||
* @throws NullPointerException if contexts is null
|
||||
@@ -55,6 +60,7 @@ public interface UserData {
|
||||
|
||||
/**
|
||||
* Calculates permission data, bypassing the cache.
|
||||
*
|
||||
* @param contexts the contexts to get permission data in
|
||||
* @return a permission data instance
|
||||
* @throws NullPointerException if contexts is null
|
||||
@@ -63,6 +69,7 @@ public interface UserData {
|
||||
|
||||
/**
|
||||
* Calculates meta data, bypassing the cache.
|
||||
*
|
||||
* @param contexts the contexts to get meta data in
|
||||
* @return a meta data instance
|
||||
* @throws NullPointerException if contexts is null
|
||||
@@ -70,16 +77,22 @@ public interface UserData {
|
||||
MetaData calculateMeta(Contexts contexts);
|
||||
|
||||
/**
|
||||
* Calculates permission data and stores it in the cache. If there is already data cached for the given contexts,
|
||||
* and if the resultant output is different, the cached value is updated.
|
||||
* Calculates permission data and stores it in the cache.
|
||||
*
|
||||
* <p> If there is already data cached for the given contexts, and if the resultant output is different,
|
||||
* the cached value is updated.
|
||||
*
|
||||
* @param contexts the contexts to recalculate in.
|
||||
* @throws NullPointerException if contexts is null
|
||||
*/
|
||||
void recalculatePermissions(Contexts contexts);
|
||||
|
||||
/**
|
||||
* Calculates meta data and stores it in the cache. If there is already data cached for the given contexts,
|
||||
* and if the resultant output is different, the cached value is updated.
|
||||
* Calculates meta data and stores it in the cache.
|
||||
*
|
||||
* <p> If there is already data cached for the given contexts, and if the resultant output is different,
|
||||
* the cached value is updated.
|
||||
*
|
||||
* @param contexts the contexts to recalculate in.
|
||||
* @throws NullPointerException if contexts is null
|
||||
*/
|
||||
@@ -97,14 +110,17 @@ public interface UserData {
|
||||
|
||||
/**
|
||||
* Calls {@link #preCalculate(Contexts)} for the given contexts
|
||||
*
|
||||
* @param contexts a set of contexts
|
||||
* @throws NullPointerException if contexts is null
|
||||
*/
|
||||
void preCalculate(Set<Contexts> contexts);
|
||||
|
||||
/**
|
||||
* Ensures that PermissionData and MetaData is cached for a context. If the cache does not contain any data for the
|
||||
* context, it will be calculated and saved.
|
||||
* Ensures that PermissionData and MetaData is cached for a context.
|
||||
*
|
||||
* <p> If the cache does not contain any data for the context, it will be calculated and saved.
|
||||
*
|
||||
* @param contexts the contexts to pre-calculate for
|
||||
* @throws NullPointerException if contexts is null
|
||||
*/
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* A simple implementation of the listener aspects of {@link IContextCalculator}
|
||||
*
|
||||
* @param <T> the subject type
|
||||
*/
|
||||
public abstract class ContextCalculator<T> implements IContextCalculator<T> {
|
||||
@@ -36,8 +37,9 @@ public abstract class ContextCalculator<T> implements IContextCalculator<T> {
|
||||
/**
|
||||
* Pushes an update to all registered {@link ContextListener}s.
|
||||
* Make sure any changes are applied internally before this method is called.
|
||||
*
|
||||
* @param subject the subject that changed
|
||||
* @param before the context state before the change
|
||||
* @param before the context state before the change
|
||||
* @param current the context state after the change (now)
|
||||
* @throws NullPointerException if any parameters are null
|
||||
*/
|
||||
|
||||
@@ -26,14 +26,16 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Listens to context changes
|
||||
*
|
||||
* @param <T> the subject type, Is ALWAYS the player class of the platform.
|
||||
*/
|
||||
public interface ContextListener<T> {
|
||||
|
||||
/**
|
||||
* Called whenever a context changes on the
|
||||
*
|
||||
* @param subject the subject that had context changed
|
||||
* @param before the context state before the change
|
||||
* @param before the context state before the change
|
||||
* @param current the context state after the change (now)
|
||||
*/
|
||||
void onContextChange(T subject, Map.Entry<String, String> before, Map.Entry<String, String> current) throws Exception;
|
||||
|
||||
@@ -22,134 +22,114 @@
|
||||
|
||||
package me.lucko.luckperms.api.context;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Holds contexts.
|
||||
* All contained contexts are immutable, and unlike {@link MutableContextSet}, contexts cannot be added or removed.
|
||||
* Implementations may be either mutable or immutable.
|
||||
*
|
||||
* @since 2.13
|
||||
*/
|
||||
public class ContextSet {
|
||||
public interface ContextSet {
|
||||
|
||||
/**
|
||||
* Make a singleton ContextSet from a context pair
|
||||
* @param key the key
|
||||
* Make a singleton ImmutableContextSet from a context pair
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
* @return a new ContextSet containing one KV pair
|
||||
* @return a new ImmutableContextSet containing one KV pair
|
||||
* @throws NullPointerException if key or value is null
|
||||
*/
|
||||
public static ContextSet singleton(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.add(key, value);
|
||||
return set.immutableCopy();
|
||||
static ImmutableContextSet singleton(String key, String value) {
|
||||
return ImmutableContextSet.singleton(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ContextSet from an existing map
|
||||
* Creates a ImmutableContextSet from an existing map
|
||||
*
|
||||
* @param map the map to copy from
|
||||
* @return a new ContextSet representing the pairs from the map
|
||||
* @return a new ImmutableContextSet representing the pairs from the map
|
||||
* @throws NullPointerException if the map is null
|
||||
*/
|
||||
public static ContextSet fromMap(Map<String, String> map) {
|
||||
if (map == null) {
|
||||
throw new NullPointerException("map");
|
||||
}
|
||||
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.addAll(map);
|
||||
return set.immutableCopy();
|
||||
static ImmutableContextSet fromMap(Map<String, String> map) {
|
||||
return ImmutableContextSet.fromMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ContextSet from an existing iterable of Map Entries
|
||||
* Creates a ImmutableContextSet from an existing iterable of Map Entries
|
||||
*
|
||||
* @param iterable the iterable to copy from
|
||||
* @return a new ContextSet representing the pairs in the iterable
|
||||
* @return a new ImmutableContextSet representing the pairs in the iterable
|
||||
* @throws NullPointerException if the iterable is null
|
||||
*/
|
||||
public static ContextSet fromEntries(Iterable<Map.Entry<String, String>> iterable) {
|
||||
if (iterable == null) {
|
||||
throw new NullPointerException("iterable");
|
||||
}
|
||||
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.addAll(iterable);
|
||||
return set.immutableCopy();
|
||||
static ImmutableContextSet fromEntries(Iterable<? extends Map.Entry<String, String>> iterable) {
|
||||
return ImmutableContextSet.fromEntries(iterable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ContextSet from an existing set.
|
||||
* Creates a ImmutableContextSet from an existing multimap
|
||||
*
|
||||
* @param multimap the multimap to copy from
|
||||
* @return a new ImmutableContextSet representing the pairs in the multimap
|
||||
* @throws NullPointerException if the multimap is null
|
||||
* @since 2.16
|
||||
*/
|
||||
static ImmutableContextSet fromMultimap(Multimap<String, String> multimap) {
|
||||
return ImmutableContextSet.fromMultimap(multimap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ImmutableContextSet from an existing set.
|
||||
* Only really useful for converting between mutable and immutable types.
|
||||
*
|
||||
* @param contextSet the context set to copy from
|
||||
* @return a new ContextSet with the same content and the one provided
|
||||
* @return a new ImmutableContextSet with the same content and the one provided
|
||||
* @throws NullPointerException if contextSet is null
|
||||
*/
|
||||
public static ContextSet fromSet(ContextSet contextSet) {
|
||||
if (contextSet == null) {
|
||||
throw new NullPointerException("contextSet");
|
||||
}
|
||||
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.addAll(contextSet.toSet());
|
||||
return set.immutableCopy();
|
||||
static ImmutableContextSet fromSet(ContextSet contextSet) {
|
||||
return ImmutableContextSet.fromSet(contextSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new empty ContextSet.
|
||||
* @return a new ContextSet
|
||||
* Creates a new empty ImmutableContextSet.
|
||||
*
|
||||
* @return a new ImmutableContextSet
|
||||
*/
|
||||
public static ContextSet empty() {
|
||||
return new ContextSet();
|
||||
}
|
||||
|
||||
final Set<Map.Entry<String, String>> contexts;
|
||||
|
||||
public ContextSet() {
|
||||
this.contexts = new HashSet<>();
|
||||
}
|
||||
|
||||
protected ContextSet(Set<Map.Entry<String, String>> contexts) {
|
||||
this.contexts = contexts;
|
||||
static ImmutableContextSet empty() {
|
||||
return ImmutableContextSet.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this set is in an immutable form
|
||||
*
|
||||
* @return true if the set is immutable
|
||||
*/
|
||||
public boolean isImmutable() {
|
||||
return true;
|
||||
}
|
||||
boolean isImmutable();
|
||||
|
||||
/**
|
||||
* If the set is mutable, this method will return an immutable copy. Otherwise just returns itself.
|
||||
*
|
||||
* @return an immutable ContextSet
|
||||
*/
|
||||
public ContextSet makeImmutable() {
|
||||
return this;
|
||||
}
|
||||
ImmutableContextSet makeImmutable();
|
||||
|
||||
/**
|
||||
* Creates a mutable copy of this set.
|
||||
*
|
||||
* @return a mutable ContextSet
|
||||
* @since 2.16
|
||||
*/
|
||||
MutableContextSet mutableCopy();
|
||||
|
||||
/**
|
||||
* Converts this ContextSet to an immutable {@link Set} of {@link Map.Entry}s.
|
||||
*
|
||||
* @return an immutable set
|
||||
*/
|
||||
public Set<Map.Entry<String, String>> toSet() {
|
||||
synchronized (contexts) {
|
||||
return ImmutableSet.copyOf(contexts);
|
||||
}
|
||||
}
|
||||
Set<Map.Entry<String, String>> toSet();
|
||||
|
||||
/**
|
||||
* Converts this ContextSet to an immutable {@link Map}
|
||||
@@ -159,148 +139,66 @@ public class ContextSet {
|
||||
*
|
||||
* @return an immutable map
|
||||
*/
|
||||
public Map<String, String> toMap() {
|
||||
synchronized (contexts) {
|
||||
return ImmutableMap.copyOf(contexts.stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
|
||||
}
|
||||
}
|
||||
Map<String, String> toMap();
|
||||
|
||||
/**
|
||||
* Converts this ContextSet to an immutable {@link Multimap}
|
||||
*
|
||||
* @return a multimap
|
||||
* @since 2.16
|
||||
*/
|
||||
Multimap<String, String> toMultimap();
|
||||
|
||||
/**
|
||||
* Check if the set contains at least one value for the given key.
|
||||
*
|
||||
* @param key the key to check for
|
||||
* @return true if the set contains a value for the key
|
||||
* @throws NullPointerException if the key is null
|
||||
*/
|
||||
public boolean containsKey(String key) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
for (Map.Entry<String, String> e : contexts) {
|
||||
if (e.getKey().equalsIgnoreCase(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
boolean containsKey(String key);
|
||||
|
||||
/**
|
||||
* Gets a set of all of the values mapped to the given key
|
||||
*
|
||||
* @param key the key to find values for
|
||||
* @return a set of values
|
||||
* @throws NullPointerException if the key is null
|
||||
*/
|
||||
public Set<String> getValues(String key) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
return ImmutableSet.copyOf(contexts.stream()
|
||||
.filter(e -> e.getKey().equalsIgnoreCase(key))
|
||||
.map(Map.Entry::getValue)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
}
|
||||
}
|
||||
Set<String> getValues(String key);
|
||||
|
||||
/**
|
||||
* Check if thr set contains a given key mapped to a given value
|
||||
* @param key the key to look for
|
||||
*
|
||||
* @param key the key to look for
|
||||
* @param value the value to look for (case sensitive)
|
||||
* @return true if the set contains the KV pair
|
||||
* @throws NullPointerException if the key or value is null
|
||||
*/
|
||||
public boolean has(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
for (Map.Entry<String, String> e : contexts) {
|
||||
if (!e.getKey().equalsIgnoreCase(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!e.getValue().equals(value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
boolean has(String key, String value);
|
||||
|
||||
/**
|
||||
* Same as {@link #has(String, String)}, except ignores the case of the value.
|
||||
* @param key the key to look for
|
||||
*
|
||||
* @param key the key to look for
|
||||
* @param value the value to look for
|
||||
* @return true if the set contains the KV pair
|
||||
* @throws NullPointerException if the key or value is null
|
||||
*/
|
||||
public boolean hasIgnoreCase(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
for (Map.Entry<String, String> e : contexts) {
|
||||
if (!e.getKey().equalsIgnoreCase(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!e.getValue().equalsIgnoreCase(value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
boolean hasIgnoreCase(String key, String value);
|
||||
|
||||
/**
|
||||
* Check if the set is empty
|
||||
*
|
||||
* @return true if the set is empty
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
synchronized (contexts) {
|
||||
return contexts.isEmpty();
|
||||
}
|
||||
}
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Gets the number of key-value context pairs in the set
|
||||
*
|
||||
* @return the size of the set
|
||||
*/
|
||||
public int size() {
|
||||
synchronized (contexts) {
|
||||
return contexts.size();
|
||||
}
|
||||
}
|
||||
int size();
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof ContextSet)) return false;
|
||||
final ContextSet other = (ContextSet) o;
|
||||
|
||||
final Object thisContexts = this.contexts;
|
||||
final Object otherContexts = other.contexts;
|
||||
return thisContexts == null ? otherContexts == null : thisContexts.equals(otherContexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 59 + (this.contexts == null ? 43 : this.contexts.hashCode());
|
||||
}
|
||||
}
|
||||
@@ -22,56 +22,30 @@
|
||||
|
||||
package me.lucko.luckperms.api.context;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Calculates whether contexts are applicable to {@link T}
|
||||
*
|
||||
* <p>Somewhat inspired by the system used on Sponge.
|
||||
*
|
||||
* @param <T> the subject type. Is ALWAYS the player class of the platform.
|
||||
*/
|
||||
public interface IContextCalculator<T> {
|
||||
|
||||
/**
|
||||
* Gives the subject all of the applicable contexts they meet
|
||||
* @param subject the subject to add contexts to
|
||||
* @param accumulator a map of contexts to add to
|
||||
* @return the map
|
||||
* @deprecated in favour of {@link #giveApplicableContext(Object, MutableContextSet)}. Older implementations of this interface
|
||||
* will still work, as the replacement method is given as a default, and falls back to using this method.
|
||||
*/
|
||||
@Deprecated
|
||||
default Map<String, String> giveApplicableContext(T subject, Map<String, String> accumulator) {
|
||||
MutableContextSet acc = new MutableContextSet();
|
||||
giveApplicableContext(subject, acc);
|
||||
|
||||
accumulator.putAll(acc.toMap());
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the subject all of the applicable contexts they meet
|
||||
*
|
||||
* <p><b>You MUST implement this method. The default is only provided for backwards compatibility with
|
||||
* {@link #giveApplicableContext(Object, Map)}.</b>
|
||||
*
|
||||
* @param subject the subject to add contexts to
|
||||
* @param subject the subject to add contexts to
|
||||
* @param accumulator a map of contexts to add to
|
||||
* @return the map
|
||||
* @since 2.13
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
default MutableContextSet giveApplicableContext(T subject, MutableContextSet accumulator) {
|
||||
Map<String, String> acc = new HashMap<>();
|
||||
giveApplicableContext(subject, acc);
|
||||
|
||||
accumulator.addAll(acc.entrySet());
|
||||
return accumulator;
|
||||
}
|
||||
MutableContextSet giveApplicableContext(T subject, MutableContextSet accumulator);
|
||||
|
||||
/**
|
||||
* Checks to see if a context is applicable to a subject
|
||||
*
|
||||
* @param subject the subject to check against
|
||||
* @param context the context to check for
|
||||
* @return true if met, or false if not. If this calculator does not calculate the given context, return false.
|
||||
@@ -80,6 +54,7 @@ public interface IContextCalculator<T> {
|
||||
|
||||
/**
|
||||
* Adds a listener to be called whenever a context handled by this calculator changes
|
||||
*
|
||||
* @param listener the listener instance
|
||||
* @throws NullPointerException if listener is null
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* 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.context;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* An immutable implementation of {@link ContextSet}.
|
||||
*
|
||||
* @since 2.16
|
||||
*/
|
||||
public final class ImmutableContextSet implements ContextSet {
|
||||
private static final ImmutableContextSet EMPTY = new ImmutableContextSet(ImmutableMultimap.of());
|
||||
|
||||
/**
|
||||
* Make a singleton ImmutableContextSet from a context pair
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
* @return a new ImmutableContextSet containing one KV pair
|
||||
* @throws NullPointerException if key or value is null
|
||||
*/
|
||||
public static ImmutableContextSet singleton(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
return new ImmutableContextSet(ImmutableMultimap.of(key.toLowerCase(), value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ImmutableContextSet from an existing map
|
||||
*
|
||||
* @param map the map to copy from
|
||||
* @return a new ImmutableContextSet representing the pairs from the map
|
||||
* @throws NullPointerException if the map is null
|
||||
*/
|
||||
public static ImmutableContextSet fromMap(Map<String, String> map) {
|
||||
if (map == null) {
|
||||
throw new NullPointerException("map");
|
||||
}
|
||||
|
||||
ImmutableMultimap.Builder<String, String> b = ImmutableMultimap.builder();
|
||||
for (Map.Entry<String, String> e : map.entrySet()) {
|
||||
b.put(e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
return new ImmutableContextSet(b.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ImmutableContextSet from an existing iterable of Map Entries
|
||||
*
|
||||
* @param iterable the iterable to copy from
|
||||
* @return a new ImmutableContextSet representing the pairs in the iterable
|
||||
* @throws NullPointerException if the iterable is null
|
||||
*/
|
||||
public static ImmutableContextSet fromEntries(Iterable<? extends Map.Entry<String, String>> iterable) {
|
||||
if (iterable == null) {
|
||||
throw new NullPointerException("iterable");
|
||||
}
|
||||
|
||||
return MutableContextSet.fromEntries(iterable).makeImmutable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ImmutableContextSet from an existing multimap
|
||||
*
|
||||
* @param multimap the multimap to copy from
|
||||
* @return a new ImmutableContextSet representing the pairs in the multimap
|
||||
* @throws NullPointerException if the multimap is null
|
||||
*/
|
||||
public static ImmutableContextSet fromMultimap(Multimap<String, String> multimap) {
|
||||
if (multimap == null) {
|
||||
throw new NullPointerException("multimap");
|
||||
}
|
||||
|
||||
return MutableContextSet.fromMultimap(multimap).makeImmutable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ImmutableContextSet from an existing set.
|
||||
* Only really useful for converting between mutable and immutable types.
|
||||
*
|
||||
* @param contextSet the context set to copy from
|
||||
* @return a new ImmutableContextSet with the same content and the one provided
|
||||
* @throws NullPointerException if contextSet is null
|
||||
*/
|
||||
public static ImmutableContextSet fromSet(ContextSet contextSet) {
|
||||
return contextSet.makeImmutable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new empty ContextSet.
|
||||
*
|
||||
* @return a new ContextSet
|
||||
*/
|
||||
public static ImmutableContextSet empty() {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
private final Multimap<String, String> map;
|
||||
|
||||
ImmutableContextSet(Multimap<String, String> contexts) {
|
||||
this.map = ImmutableMultimap.copyOf(contexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImmutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated // This set is already immutable!
|
||||
public ImmutableContextSet makeImmutable() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableContextSet mutableCopy() {
|
||||
return MutableContextSet.fromSet(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Map.Entry<String, String>> toSet() {
|
||||
return ImmutableSet.copyOf(map.entries());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> toMap() {
|
||||
ImmutableMap.Builder<String, String> m = ImmutableMap.builder();
|
||||
for (Map.Entry<String, String> e : map.entries()) {
|
||||
m.put(e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
return m.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Multimap<String, String> toMultimap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getValues(String key) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
|
||||
Collection<String> c = map.get(key);
|
||||
return c != null && !c.isEmpty() ? ImmutableSet.copyOf(c) : ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
return map.containsEntry(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIgnoreCase(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
Collection<String> c = map.get(key);
|
||||
if (c == null || c.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String val : c) {
|
||||
if (val.equalsIgnoreCase(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof ContextSet)) return false;
|
||||
final ContextSet other = (ContextSet) o;
|
||||
|
||||
final Multimap<String, String> thisContexts = this.toMultimap();
|
||||
final Multimap<String, String> otherContexts = other.toMultimap();
|
||||
return thisContexts == null ? otherContexts == null : thisContexts.equals(otherContexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 59 + (this.map == null ? 43 : this.map.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ImmutableContextSet(contexts=" + this.map + ")";
|
||||
}
|
||||
}
|
||||
@@ -22,27 +22,39 @@
|
||||
|
||||
package me.lucko.luckperms.api.context;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Holds contexts
|
||||
* All contained contexts are immutable, but contexts can be added or removed from the set.
|
||||
* A mutable implementation of {@link ContextSet}.
|
||||
*
|
||||
* @since 2.13
|
||||
* @since 2.16
|
||||
*/
|
||||
public class MutableContextSet extends ContextSet {
|
||||
public final class MutableContextSet implements ContextSet {
|
||||
|
||||
/**
|
||||
* Make a singleton MutableContextSet from a context pair
|
||||
* @param key the key
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
* @return a new MutableContextSet containing one KV pair
|
||||
* @throws NullPointerException if key or value is null
|
||||
*/
|
||||
public static MutableContextSet singleton(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.add(key, value);
|
||||
return set;
|
||||
@@ -50,11 +62,16 @@ public class MutableContextSet extends ContextSet {
|
||||
|
||||
/**
|
||||
* Creates a MutableContextSet from an existing map
|
||||
*
|
||||
* @param map the map to copy from
|
||||
* @return a new MutableContextSet representing the pairs from the map
|
||||
* @throws NullPointerException if the map is null
|
||||
*/
|
||||
public static MutableContextSet fromMap(Map<String, String> map) {
|
||||
if (map == null) {
|
||||
throw new NullPointerException("map");
|
||||
}
|
||||
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.addAll(map);
|
||||
return set;
|
||||
@@ -62,24 +79,49 @@ public class MutableContextSet extends ContextSet {
|
||||
|
||||
/**
|
||||
* Creates a MutableContextSet from an existing iterable of Map Entries
|
||||
*
|
||||
* @param iterable the iterable to copy from
|
||||
* @return a new MutableContextSet representing the pairs in the iterable
|
||||
* @throws NullPointerException if the iterable is null
|
||||
*/
|
||||
public static MutableContextSet fromEntries(Iterable<Map.Entry<String, String>> iterable) {
|
||||
public static MutableContextSet fromEntries(Iterable<? extends Map.Entry<String, String>> iterable) {
|
||||
if (iterable == null) {
|
||||
throw new NullPointerException("iterable");
|
||||
}
|
||||
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.addAll(iterable);
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a MutableContextSet from an existing multimap
|
||||
*
|
||||
* @param multimap the multimap to copy from
|
||||
* @return a new MutableContextSet representing the pairs in the multimap
|
||||
* @throws NullPointerException if the multimap is null
|
||||
*/
|
||||
public static MutableContextSet fromMultimap(Multimap<String, String> multimap) {
|
||||
if (multimap == null) {
|
||||
throw new NullPointerException("multimap");
|
||||
}
|
||||
|
||||
return fromEntries(multimap.entries());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new MutableContextSet from an existing set.
|
||||
* Only really useful for converting between mutable and immutable types.
|
||||
*
|
||||
* @param contextSet the context set to copy from
|
||||
* @return a new MutableContextSet with the same content and the one provided
|
||||
* @throws NullPointerException if contextSet is null
|
||||
*/
|
||||
public static MutableContextSet fromSet(ContextSet contextSet) {
|
||||
if (contextSet == null) {
|
||||
throw new NullPointerException("contextSet");
|
||||
}
|
||||
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.addAll(contextSet.toSet());
|
||||
return set;
|
||||
@@ -87,35 +129,125 @@ public class MutableContextSet extends ContextSet {
|
||||
|
||||
/**
|
||||
* Creates a new empty MutableContextSet.
|
||||
*
|
||||
* @return a new MutableContextSet
|
||||
*/
|
||||
public static MutableContextSet empty() {
|
||||
public static MutableContextSet create() {
|
||||
return new MutableContextSet();
|
||||
}
|
||||
|
||||
private final Multimap<String, String> map;
|
||||
|
||||
public MutableContextSet() {
|
||||
this.map = Multimaps.synchronizedMultimap(HashMultimap.create());
|
||||
}
|
||||
|
||||
private MutableContextSet(Multimap<String, String> contexts) {
|
||||
this.map = Multimaps.synchronizedMultimap(HashMultimap.create(contexts));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImmutable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextSet makeImmutable() {
|
||||
return immutableCopy();
|
||||
public ImmutableContextSet makeImmutable() {
|
||||
return new ImmutableContextSet(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable copy of this set.
|
||||
* @return an immutable copy of this set
|
||||
*/
|
||||
public ContextSet immutableCopy() {
|
||||
synchronized (contexts) {
|
||||
return new ContextSet(new HashSet<>(contexts));
|
||||
@Override
|
||||
public MutableContextSet mutableCopy() {
|
||||
return new MutableContextSet(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Map.Entry<String, String>> toSet() {
|
||||
return ImmutableSet.copyOf(map.entries());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> toMap() {
|
||||
ImmutableMap.Builder<String, String> m = ImmutableMap.builder();
|
||||
for (Map.Entry<String, String> e : map.entries()) {
|
||||
m.put(e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
return m.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Multimap<String, String> toMultimap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getValues(String key) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
|
||||
Collection<String> c = map.get(key);
|
||||
return c != null && !c.isEmpty() ? ImmutableSet.copyOf(c) : ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
return map.containsEntry(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIgnoreCase(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
Collection<String> c = map.get(key);
|
||||
if (c == null || c.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String val : c) {
|
||||
if (val.equalsIgnoreCase(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new key value pair to the set
|
||||
* @param key the key to add
|
||||
*
|
||||
* @param key the key to add
|
||||
* @param value the value to add
|
||||
* @throws NullPointerException if the key or value is null
|
||||
*/
|
||||
@@ -127,13 +259,12 @@ public class MutableContextSet extends ContextSet {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
contexts.add(Maps.immutableEntry(key, value));
|
||||
}
|
||||
map.put(key.toLowerCase(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new key value pair to the set
|
||||
*
|
||||
* @param entry the entry to add
|
||||
* @throws NullPointerException if the entry is null
|
||||
*/
|
||||
@@ -142,30 +273,28 @@ public class MutableContextSet extends ContextSet {
|
||||
throw new NullPointerException("context");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
contexts.add(Maps.immutableEntry(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
map.put(entry.getKey().toLowerCase(), entry.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an iterable containing contexts to the set
|
||||
*
|
||||
* @param iterable an iterable of key value context pairs
|
||||
* @throws NullPointerException if iterable is null
|
||||
*/
|
||||
public void addAll(Iterable<Map.Entry<String, String>> iterable) {
|
||||
public void addAll(Iterable<? extends Map.Entry<String, String>> iterable) {
|
||||
if (iterable == null) {
|
||||
throw new NullPointerException("contexts");
|
||||
}
|
||||
|
||||
synchronized (this.contexts) {
|
||||
for (Map.Entry<String, String> e : iterable) {
|
||||
this.contexts.add(Maps.immutableEntry(e.getKey(), e.getValue()));
|
||||
}
|
||||
for (Map.Entry<String, String> e : iterable) {
|
||||
this.map.put(e.getKey().toLowerCase(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the entry set of a map to the set
|
||||
*
|
||||
* @param map the map to add from
|
||||
* @throws NullPointerException if the map is null
|
||||
*/
|
||||
@@ -178,6 +307,7 @@ public class MutableContextSet extends ContextSet {
|
||||
|
||||
/**
|
||||
* Adds of of the values in another ContextSet to this set
|
||||
*
|
||||
* @param contextSet the set to add from
|
||||
* @throws NullPointerException if the contextSet is null
|
||||
*/
|
||||
@@ -186,14 +316,13 @@ public class MutableContextSet extends ContextSet {
|
||||
throw new NullPointerException("contextSet");
|
||||
}
|
||||
|
||||
synchronized (this.contexts) {
|
||||
this.contexts.addAll(contextSet.toSet());
|
||||
}
|
||||
this.map.putAll(contextSet.toMultimap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a key value pair from this set
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @param key the key to remove
|
||||
* @param value the value to remove (case sensitive)
|
||||
* @throws NullPointerException if the key or value is null
|
||||
*/
|
||||
@@ -205,14 +334,13 @@ public class MutableContextSet extends ContextSet {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
contexts.removeIf(e -> e.getKey().equalsIgnoreCase(key) && e.getValue().equals(value));
|
||||
}
|
||||
map.entries().removeIf(entry -> entry.getKey().equalsIgnoreCase(key) && entry.getValue().equals(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #remove(String, String)}, except ignores the case of the value
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @param key the key to remove
|
||||
* @param value the value to remove
|
||||
* @throws NullPointerException if the key or value is null
|
||||
*/
|
||||
@@ -224,13 +352,12 @@ public class MutableContextSet extends ContextSet {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
contexts.removeIf(e -> e.getKey().equalsIgnoreCase(key) && e.getValue().equalsIgnoreCase(value));
|
||||
}
|
||||
map.entries().removeIf(e -> e.getKey().equalsIgnoreCase(key) && e.getValue().equalsIgnoreCase(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all pairs with the given key
|
||||
*
|
||||
* @param key the key to remove
|
||||
* @throws NullPointerException if the key is null
|
||||
*/
|
||||
@@ -239,18 +366,14 @@ public class MutableContextSet extends ContextSet {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
contexts.removeIf(e -> e.getKey().equalsIgnoreCase(key));
|
||||
}
|
||||
map.removeAll(key.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the set
|
||||
*/
|
||||
public void clear() {
|
||||
synchronized (contexts) {
|
||||
contexts.clear();
|
||||
}
|
||||
map.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -259,14 +382,18 @@ public class MutableContextSet extends ContextSet {
|
||||
if (!(o instanceof ContextSet)) return false;
|
||||
final ContextSet other = (ContextSet) o;
|
||||
|
||||
final Object thisContexts = this.contexts;
|
||||
final Object otherContexts = other.contexts;
|
||||
final Multimap<String, String> thisContexts = this.toMultimap();
|
||||
final Multimap<String, String> otherContexts = other.toMultimap();
|
||||
return thisContexts == null ? otherContexts == null : thisContexts.equals(otherContexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 59 + (this.contexts == null ? 43 : this.contexts.hashCode());
|
||||
return 59 + (this.map == null ? 43 : this.map.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MutableContextSet(contexts=" + this.map + ")";
|
||||
}
|
||||
}
|
||||
@@ -27,18 +27,16 @@ 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> {
|
||||
|
||||
/**
|
||||
* Called when the operation completes.
|
||||
* @param t the return value, may be null
|
||||
*/
|
||||
void onComplete(T t);
|
||||
|
||||
static <T> Callback<T> empty() {
|
||||
return t -> {};
|
||||
return t -> {
|
||||
};
|
||||
}
|
||||
|
||||
static <T> Callback<T> of(Runnable runnable) {
|
||||
@@ -55,4 +53,26 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the operation completes.
|
||||
*
|
||||
* @param t the return value, may be null
|
||||
*/
|
||||
void onComplete(T t);
|
||||
|
||||
}
|
||||
@@ -30,8 +30,11 @@ package me.lucko.luckperms.api.data;
|
||||
public interface DatastoreConfiguration extends MySQLConfiguration {
|
||||
|
||||
String getAddress();
|
||||
|
||||
String getDatabase();
|
||||
|
||||
String getUsername();
|
||||
|
||||
String getPassword();
|
||||
|
||||
}
|
||||
@@ -29,7 +29,10 @@ package me.lucko.luckperms.api.data;
|
||||
public interface MySQLConfiguration {
|
||||
|
||||
String getAddress();
|
||||
|
||||
String getDatabase();
|
||||
|
||||
String getUsername();
|
||||
|
||||
String getPassword();
|
||||
}
|
||||
@@ -29,15 +29,14 @@ import me.lucko.luckperms.api.LuckPermsApi;
|
||||
*/
|
||||
public abstract class LPEvent {
|
||||
|
||||
/**
|
||||
* A link to the API instance provided for convenience.
|
||||
*/
|
||||
private LuckPermsApi api = null;
|
||||
|
||||
/**
|
||||
* A friendly name of the event
|
||||
*/
|
||||
private final String eventName;
|
||||
/**
|
||||
* A link to the API instance provided for convenience.
|
||||
*/
|
||||
private LuckPermsApi api = null;
|
||||
|
||||
protected LPEvent(String eventName) {
|
||||
this.eventName = eventName;
|
||||
|
||||
@@ -24,6 +24,7 @@ package me.lucko.luckperms.api.event;
|
||||
|
||||
/**
|
||||
* Represents an event acting upon a target
|
||||
*
|
||||
* @param <T> the target type
|
||||
*/
|
||||
public class TargetedEvent<T> extends LPEvent {
|
||||
|
||||
@@ -27,6 +27,7 @@ import me.lucko.luckperms.api.event.TargetedEvent;
|
||||
|
||||
/**
|
||||
* Called when a permission expires for an object.
|
||||
*
|
||||
* @deprecated in favour of {@link PermissionNodeExpireEvent}
|
||||
*/
|
||||
@Deprecated
|
||||
|
||||
@@ -28,6 +28,7 @@ import me.lucko.luckperms.api.event.AbstractPermissionEvent;
|
||||
|
||||
/**
|
||||
* Called when a temporary permission node expires
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
public class PermissionNodeExpireEvent extends AbstractPermissionEvent {
|
||||
|
||||
@@ -28,6 +28,7 @@ import me.lucko.luckperms.api.event.AbstractPermissionEvent;
|
||||
|
||||
/**
|
||||
* Called when a permission node is set on a holder
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
public class PermissionNodeSetEvent extends AbstractPermissionEvent {
|
||||
|
||||
@@ -28,6 +28,7 @@ import me.lucko.luckperms.api.event.AbstractPermissionEvent;
|
||||
|
||||
/**
|
||||
* Called when a permission node is unset from a holder
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
public class PermissionNodeUnsetEvent extends AbstractPermissionEvent {
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Called whenever a user or group has a permission set.
|
||||
*
|
||||
* @deprecated in favour of {@link PermissionNodeSetEvent}
|
||||
*/
|
||||
@Deprecated
|
||||
|
||||
@@ -27,6 +27,7 @@ import me.lucko.luckperms.api.event.AbstractPermissionRemoveEvent;
|
||||
|
||||
/**
|
||||
* Called whenever a user or group has a permission unset.
|
||||
*
|
||||
* @deprecated in favour of {@link PermissionNodeUnsetEvent}
|
||||
*/
|
||||
@Deprecated
|
||||
|
||||
@@ -27,11 +27,11 @@ import me.lucko.luckperms.api.event.LPEvent;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Called when the user logs into the network for the first time.
|
||||
* Particularly useful for networks with multiple lobbies, who want to welcome a user when they join for the first time.
|
||||
* Called when the user logs into the network for the first time. Particularly useful for networks with multiple
|
||||
* lobbies, who want to welcome a user when they join for the first time.
|
||||
*
|
||||
* <p>This event is fired before the player has actually joined the game on the async login / auth event.
|
||||
* If you want to do something with the user, store the UUID in a set, and then check the set in the PlayerJoinEvent o.e.
|
||||
* <p>This event is fired before the player has actually joined the game on the async login / auth event. If you want to
|
||||
* do something with the user, store the UUID in a set, and then check the set in the PlayerJoinEvent o.e.
|
||||
*/
|
||||
public class UserFirstLoginEvent extends LPEvent {
|
||||
|
||||
|
||||
+2
-2
@@ -26,8 +26,8 @@ import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.api.event.UserEvent;
|
||||
|
||||
/**
|
||||
* Called after a user has their permissions refreshed.
|
||||
* If you cache user permissions within your own plugin, it's a good idea to update said cache whenever this event is called.
|
||||
* Called after a user has their permissions refreshed. If you cache user permissions within your own plugin, it's a
|
||||
* good idea to update said cache whenever this event is called.
|
||||
*/
|
||||
public class UserPermissionRefreshEvent extends UserEvent {
|
||||
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
package me.lucko.luckperms.exceptions;
|
||||
|
||||
/**
|
||||
* Thrown when a permission holding object doesn't / already has a permission or isn't / is already is a member of a group
|
||||
* Thrown when a permission holding object doesn't / already has a permission or isn't / is already is a member of a
|
||||
* group
|
||||
*
|
||||
* @since 2.7
|
||||
*/
|
||||
public abstract class MembershipException extends Exception {
|
||||
|
||||
+8
-24
@@ -1,18 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<version>2.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>luckperms-bukkit-legacy</artifactId>
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<finalName>LuckPerms-bukkit-legacy-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<finalName>LuckPerms-Bukkit-Legacy-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
@@ -47,26 +47,6 @@
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.slf4j</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.slf4j</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.zaxxer.hikari</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.hikari</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.mongodb</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.mongodb</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bson</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.bson</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.h2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.h2</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.google.common</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.guava</shadedPattern>
|
||||
@@ -75,6 +55,10 @@
|
||||
<pattern>com.google.gson</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.gson</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>io.github.mkremins.fanciful</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.fanciful</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<version>2.17-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 -->
|
||||
|
||||
+51
-13
@@ -25,17 +25,26 @@ package me.lucko.luckperms.api.placeholders;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.util.TimeUtil;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.Track;
|
||||
import me.lucko.luckperms.api.User;
|
||||
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>
|
||||
@@ -52,6 +61,10 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
private static final String PLUGIN_NAME = "LuckPerms";
|
||||
private static final String AUTHOR = "Luck";
|
||||
|
||||
private static String formatBoolean(boolean b) {
|
||||
return b ? PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanFalse();
|
||||
}
|
||||
|
||||
private LuckPermsApi api = null;
|
||||
|
||||
@Override
|
||||
@@ -71,7 +84,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 +104,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 +129,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 +139,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 +155,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 +176,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;
|
||||
@@ -175,8 +217,4 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
public String getAuthor() {
|
||||
return AUTHOR;
|
||||
}
|
||||
|
||||
private static String formatBoolean(boolean b) {
|
||||
return b ? PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanFalse();
|
||||
}
|
||||
}
|
||||
+56
-29
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<version>2.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<finalName>LuckPerms-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<finalName>LuckPerms-Bukkit-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
@@ -44,31 +44,10 @@
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>false</minimizeJar>
|
||||
<artifactSet>
|
||||
<excludes>
|
||||
<exclude>org.xerial:*</exclude>
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.slf4j</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.slf4j</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.zaxxer.hikari</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.hikari</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.mongodb</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.mongodb</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bson</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.bson</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.h2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.h2</shadedPattern>
|
||||
<pattern>io.github.mkremins.fanciful</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.fanciful</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
@@ -96,8 +75,8 @@
|
||||
<dependencies>
|
||||
<!-- BukkitAPI -->
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
@@ -122,6 +101,13 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- HikariCP - needed as source -->
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>2.5.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
@@ -129,5 +115,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>
|
||||
@@ -23,41 +23,48 @@
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
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.common.users.User;
|
||||
import me.lucko.luckperms.bukkit.model.LPPermissible;
|
||||
import me.lucko.luckperms.common.calculators.AbstractCalculatorFactory;
|
||||
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.core.model.User;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BukkitCalculatorFactory implements CalculatorFactory {
|
||||
public class BukkitCalculatorFactory extends AbstractCalculatorFactory {
|
||||
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 registerCalculator(new PermissionCalculator(plugin, user.getName(), processors.build()));
|
||||
}
|
||||
}
|
||||
@@ -24,11 +24,11 @@ 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;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -38,24 +38,25 @@ 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()
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
|
||||
);
|
||||
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,6 +23,7 @@
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import me.lucko.luckperms.common.config.AbstractConfiguration;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
|
||||
@@ -23,10 +23,11 @@
|
||||
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.core.model.User;
|
||||
import me.lucko.luckperms.common.utils.AbstractListener;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -35,6 +36,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;
|
||||
|
||||
@@ -46,9 +48,9 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
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 +63,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 +108,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());
|
||||
@@ -115,7 +117,7 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
plugin.getWorldCalculator().getWorldCache().remove(internal);
|
||||
|
||||
// Remove the custom permissible
|
||||
Injector.unInject(player);
|
||||
Injector.unInject(player, true);
|
||||
|
||||
// Handle auto op
|
||||
if (plugin.getConfiguration().isAutoOp()) {
|
||||
@@ -138,9 +140,16 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
.replace("spigot:", "")
|
||||
.replace("minecraft:", "");
|
||||
|
||||
if (s.startsWith("op") || s.startsWith("deop")) {
|
||||
if (s.equals("op") || s.startsWith("op ") || s.equals("deop") || s.startsWith("deop ")) {
|
||||
e.setCancelled(true);
|
||||
e.getPlayer().sendMessage(Message.OP_DISABLED.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginEnable(PluginEnableEvent e) {
|
||||
if (e.getPlugin().getName().equalsIgnoreCase("Vault")) {
|
||||
plugin.tryVaultHook(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,26 +22,24 @@
|
||||
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import me.lucko.luckperms.bukkit.compat.MessageHandler;
|
||||
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;
|
||||
|
||||
import io.github.mkremins.fanciful.FancyMessage;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitSenderFactory extends SenderFactory<CommandSender> {
|
||||
private static BukkitSenderFactory instance = null;
|
||||
private final MessageHandler messageHandler;
|
||||
|
||||
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;
|
||||
messageHandler = new MessageHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,7 +47,7 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> {
|
||||
if (sender instanceof Player) {
|
||||
return sender.getName();
|
||||
}
|
||||
return Constants.getConsoleName();
|
||||
return Constants.CONSOLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,7 +55,7 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> {
|
||||
if (sender instanceof Player) {
|
||||
return ((Player) sender).getUniqueId();
|
||||
}
|
||||
return Constants.getConsoleUUID();
|
||||
return Constants.CONSOLE_UUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,6 +63,11 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> {
|
||||
sender.sendMessage(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendMessage(CommandSender sender, FancyMessage message) {
|
||||
messageHandler.sendJsonMessage(sender, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasPermission(CommandSender sender, String node) {
|
||||
return sender.hasPermission(node);
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.ApiHandler;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
@@ -31,72 +33,176 @@ 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.inject.Injector;
|
||||
import me.lucko.luckperms.bukkit.model.ChildPermissionProvider;
|
||||
import me.lucko.luckperms.bukkit.model.DefaultsProvider;
|
||||
import me.lucko.luckperms.bukkit.model.LPPermissible;
|
||||
import me.lucko.luckperms.bukkit.vault.VaultHook;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.api.ApiHandler;
|
||||
import me.lucko.luckperms.common.api.ApiProvider;
|
||||
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
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.core.model.User;
|
||||
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.dependencies.DependencyManager;
|
||||
import me.lucko.luckperms.common.managers.GroupManager;
|
||||
import me.lucko.luckperms.common.managers.TrackManager;
|
||||
import me.lucko.luckperms.common.managers.UserManager;
|
||||
import me.lucko.luckperms.common.managers.impl.GenericGroupManager;
|
||||
import me.lucko.luckperms.common.managers.impl.GenericTrackManager;
|
||||
import me.lucko.luckperms.common.managers.impl.GenericUserManager;
|
||||
import me.lucko.luckperms.common.messaging.RedisMessaging;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
import me.lucko.luckperms.common.storage.StorageFactory;
|
||||
import me.lucko.luckperms.common.tracks.TrackManager;
|
||||
import me.lucko.luckperms.common.users.UserManager;
|
||||
import me.lucko.luckperms.common.storage.StorageType;
|
||||
import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
|
||||
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.common.tasks.UpdateTask;
|
||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||
import me.lucko.luckperms.common.utils.DebugHandler;
|
||||
import me.lucko.luckperms.common.utils.LocaleManager;
|
||||
import me.lucko.luckperms.common.utils.LogFactory;
|
||||
import me.lucko.luckperms.common.utils.PermissionCache;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
private Set<UUID> ignoringLogs;
|
||||
private Executor syncExecutor;
|
||||
private Executor asyncExecutor;
|
||||
private VaultHook vaultHook = null;
|
||||
|
||||
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 BukkitListener listener;
|
||||
private ApiProvider apiProvider;
|
||||
private Logger log;
|
||||
private Importer importer;
|
||||
private ConsecutiveExecutor consecutiveExecutor;
|
||||
private DefaultsProvider defaultsProvider;
|
||||
private ChildPermissionProvider childPermissionProvider;
|
||||
private LocaleManager localeManager;
|
||||
private CachedStateManager cachedStateManager;
|
||||
private ContextManager<Player> contextManager;
|
||||
private WorldCalculator worldCalculator;
|
||||
private CalculatorFactory calculatorFactory;
|
||||
private BufferedRequest<Void> updateTaskBuffer;
|
||||
private boolean started = false;
|
||||
private DebugHandler debugHandler;
|
||||
private BukkitSenderFactory senderFactory;
|
||||
private PermissionCache permissionCache;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Used whilst the server is still starting
|
||||
asyncExecutor = Executors.newCachedThreadPool();
|
||||
syncExecutor = r -> getServer().getScheduler().runTask(this, r);
|
||||
Executor bukkitAsyncExecutor = r -> getServer().getScheduler().runTaskAsynchronously(this, r);
|
||||
|
||||
log = LogFactory.wrap(getLogger());
|
||||
ignoringLogs = ConcurrentHashMap.newKeySet();
|
||||
debugHandler = new DebugHandler(bukkitAsyncExecutor, getVersion());
|
||||
senderFactory = new BukkitSenderFactory(this);
|
||||
permissionCache = new PermissionCache(bukkitAsyncExecutor);
|
||||
|
||||
getLog().info("Loading configuration...");
|
||||
configuration = new BukkitConfig(this);
|
||||
|
||||
Set<StorageType> storageTypes = StorageFactory.getRequiredTypes(this, StorageType.H2);
|
||||
DependencyManager.loadDependencies(this, storageTypes);
|
||||
|
||||
// setup the Bukkit defaults hook
|
||||
defaultsProvider = new DefaultsProvider();
|
||||
childPermissionProvider = new ChildPermissionProvider();
|
||||
|
||||
// give all plugins a chance to load their defaults, then refresh.
|
||||
getServer().getScheduler().runTaskLater(this, () -> {
|
||||
defaultsProvider.refresh();
|
||||
childPermissionProvider.setup();
|
||||
|
||||
getServer().getScheduler().runTaskAsynchronously(this, () -> {
|
||||
for (Map.Entry<String, Boolean> e : defaultsProvider.getOpDefaults().entrySet()) {
|
||||
permissionCache.offer(e.getKey());
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Boolean> e : defaultsProvider.getNonOpDefaults().entrySet()) {
|
||||
permissionCache.offer(e.getKey());
|
||||
}
|
||||
|
||||
ImmutableMap<Map.Entry<String, Boolean>, ImmutableMap<String, Boolean>> permissions = childPermissionProvider.getPermissions();
|
||||
for (Map.Entry<Map.Entry<String, Boolean>, ImmutableMap<String, Boolean>> e : permissions.entrySet()) {
|
||||
permissionCache.offer(e.getKey().getKey());
|
||||
for (Map.Entry<String, Boolean> e1 : e.getValue().entrySet()) {
|
||||
permissionCache.offer(e1.getKey());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}, 1L);
|
||||
|
||||
// register events
|
||||
PluginManager pm = getServer().getPluginManager();
|
||||
listener = new BukkitListener(this);
|
||||
pm.registerEvents(listener, this);
|
||||
|
||||
// initialise datastore
|
||||
storage = StorageFactory.getInstance(this, StorageType.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,31 +214,23 @@ 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);
|
||||
PluginCommand main = getServer().getPluginCommand("luckperms");
|
||||
main.setExecutor(commandManager);
|
||||
main.setTabCompleter(commandManager);
|
||||
main.setAliases(Arrays.asList("perms", "lp", "permissions", "p", "perm"));
|
||||
|
||||
datastore = StorageFactory.getDatastore(this, "h2");
|
||||
main.setAliases(Arrays.asList("perms", "lp", "permissions", "perm"));
|
||||
|
||||
// load internal managers
|
||||
getLog().info("Loading internal permission managers...");
|
||||
uuidCache = new UuidCache(getConfiguration().isOnlineMode());
|
||||
userManager = new UserManager(this);
|
||||
groupManager = new GroupManager(this);
|
||||
trackManager = new TrackManager();
|
||||
userManager = new GenericUserManager(this);
|
||||
groupManager = new GenericGroupManager(this);
|
||||
trackManager = new GenericTrackManager();
|
||||
importer = new Importer(commandManager);
|
||||
consecutiveExecutor = new ConsecutiveExecutor(commandManager);
|
||||
calculatorFactory = new BukkitCalculatorFactory(this);
|
||||
cachedStateManager = new CachedStateManager(this);
|
||||
|
||||
contextManager = new ContextManager<>();
|
||||
worldCalculator = new WorldCalculator(this);
|
||||
@@ -140,56 +238,62 @@ 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(), 40L, ticks);
|
||||
}
|
||||
|
||||
// run an update instantly.
|
||||
updateTaskBuffer.requestDirectly();
|
||||
|
||||
// register tasks
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, new ExpireTemporaryTask(this), 60L, 60L);
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, new CacheHousekeepingTask(this), 2400L, 2400L);
|
||||
|
||||
// register permissions
|
||||
registerPermissions(getConfiguration().isCommandsAllowOp() ? PermissionDefault.OP : PermissionDefault.FALSE);
|
||||
if (!getConfiguration().isOpsEnabled()) {
|
||||
getServer().getOperators().forEach(o -> o.setOp(false));
|
||||
getServer().getScheduler().runTask(this, () -> getServer().getOperators().forEach(o -> o.setOp(false)));
|
||||
}
|
||||
|
||||
// replace the temporary executor when the Bukkit one starts
|
||||
getServer().getScheduler().runTaskAsynchronously(this, () -> {
|
||||
asyncExecutor = bukkitAsyncExecutor;
|
||||
});
|
||||
|
||||
// Load any online users (in the case of a reload)
|
||||
for (Player player : getServer().getOnlinePlayers()) {
|
||||
doAsync(() -> {
|
||||
listener.onAsyncLogin(player.getUniqueId(), player.getName());
|
||||
User user = getUserManager().get(getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (user != null) {
|
||||
doSync(() -> {
|
||||
try {
|
||||
LPPermissible lpPermissible = new LPPermissible(player, user, this);
|
||||
Injector.inject(player, lpPermissible);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
started = true;
|
||||
@@ -199,8 +303,31 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
@Override
|
||||
public void onDisable() {
|
||||
started = false;
|
||||
|
||||
defaultsProvider.close();
|
||||
permissionCache.setShutdown(true);
|
||||
debugHandler.setShutdown(true);
|
||||
|
||||
for (Player player : getServer().getOnlinePlayers()) {
|
||||
Injector.unInject(player, false);
|
||||
if (getConfiguration().isAutoOp()) {
|
||||
player.setOp(false);
|
||||
}
|
||||
|
||||
final User user = getUserManager().get(getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (user != null) {
|
||||
user.unregisterData();
|
||||
getUserManager().unload(user);
|
||||
}
|
||||
}
|
||||
|
||||
getLog().info("Closing datastore...");
|
||||
datastore.shutdown();
|
||||
storage.shutdown();
|
||||
|
||||
if (redisMessaging != null) {
|
||||
getLog().info("Closing redis...");
|
||||
redisMessaging.shutdown();
|
||||
}
|
||||
|
||||
getLog().info("Unregistering API...");
|
||||
ApiHandler.unregisterProvider();
|
||||
@@ -209,16 +336,77 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
if (vaultHook != null) {
|
||||
vaultHook.unhook(this);
|
||||
}
|
||||
|
||||
// Bukkit will do this again when #onDisable completes, but we do it early to prevent NPEs elsewhere.
|
||||
getServer().getScheduler().cancelTasks(this);
|
||||
HandlerList.unregisterAll(this);
|
||||
|
||||
// Null everything
|
||||
ignoringLogs = null;
|
||||
syncExecutor = null;
|
||||
asyncExecutor = null;
|
||||
vaultHook = null;
|
||||
configuration = null;
|
||||
userManager = null;
|
||||
groupManager = null;
|
||||
trackManager = null;
|
||||
storage = null;
|
||||
redisMessaging = null;
|
||||
uuidCache = null;
|
||||
listener = null;
|
||||
apiProvider = null;
|
||||
log = null;
|
||||
importer = null;
|
||||
defaultsProvider = null;
|
||||
childPermissionProvider = null;
|
||||
localeManager = null;
|
||||
cachedStateManager = null;
|
||||
contextManager = null;
|
||||
worldCalculator = null;
|
||||
calculatorFactory = null;
|
||||
updateTaskBuffer = null;
|
||||
debugHandler = null;
|
||||
senderFactory = null;
|
||||
permissionCache = null;
|
||||
}
|
||||
|
||||
public void tryVaultHook(boolean force) {
|
||||
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 onUserRefresh(User user) {
|
||||
LPPermissible lpp = Injector.getPermissible(uuidCache.getExternalUUID(user.getUuid()));
|
||||
if (lpp != null) {
|
||||
lpp.updateSubscriptions();
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
@@ -236,11 +424,48 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
return PlatformType.BUKKIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerName() {
|
||||
return getServer().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerVersion() {
|
||||
return getServer().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getMainDir() {
|
||||
return getDataFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getResourceStream(String path) {
|
||||
return getResource(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer(User user) {
|
||||
return getServer().getPlayer(uuidCache.getExternalUUID(user.getUuid()));
|
||||
}
|
||||
|
||||
@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 +487,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
|
||||
@@ -284,7 +508,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
c.addAll(getServer().getWorlds().stream()
|
||||
.map(World::getName)
|
||||
.map(s -> {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
MutableContextSet set = MutableContextSet.create();
|
||||
set.add("server", getConfiguration().getServer());
|
||||
set.add("world", s);
|
||||
return set.makeImmutable();
|
||||
@@ -298,7 +522,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
c.addAll(getServer().getWorlds().stream()
|
||||
.map(World::getName)
|
||||
.map(s -> {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
MutableContextSet set = MutableContextSet.create();
|
||||
set.add("server", getConfiguration().getVaultServer());
|
||||
set.add("world", s);
|
||||
return set.makeImmutable();
|
||||
@@ -324,12 +548,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 +563,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);
|
||||
|
||||
@@ -22,12 +22,15 @@
|
||||
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextCalculator;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -71,11 +74,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,10 @@ package me.lucko.luckperms.bukkit.calculators;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -48,4 +50,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,8 @@ 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;
|
||||
@@ -34,14 +35,16 @@ public class AutoOPListener implements ContextListener<Player> {
|
||||
|
||||
@Override
|
||||
public void onContextChange(Player subject, Map.Entry<String, String> before, Map.Entry<String, String> current) throws Exception {
|
||||
LPPermissible permissible = Injector.getPermissible(subject.getUniqueId());
|
||||
if (permissible == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
LPPermissible permissible = Injector.getPermissible(subject.getUniqueId());
|
||||
if (permissible == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Boolean> backing = permissible.getUser().getUserData().getPermissionData(permissible.calculateContexts()).getImmutableBacking();
|
||||
boolean op = Optional.ofNullable(backing.get("luckperms.autoop")).orElse(false);
|
||||
subject.setOp(op);
|
||||
Map<String, Boolean> backing = permissible.getUser().getUserData().getPermissionData(permissible.calculateContexts()).getImmutableBacking();
|
||||
boolean op = Optional.ofNullable(backing.get("luckperms.autoop")).orElse(false);
|
||||
subject.setOp(op);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
}
|
||||
+21
-38
@@ -20,53 +20,36 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands;
|
||||
package me.lucko.luckperms.bukkit.calculators;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.bukkit.model.ChildPermissionProvider;
|
||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Executes commands consecutively
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class ConsecutiveExecutor implements Runnable {
|
||||
private final CommandManager manager;
|
||||
public class ChildProcessor implements PermissionProcessor {
|
||||
private final ChildPermissionProvider provider;
|
||||
private Map<String, Boolean> childPermissions = new ConcurrentHashMap<>();
|
||||
|
||||
private final List<QueuedCommand> commands = new ArrayList<>();
|
||||
|
||||
public void queueCommand(QueuedCommand command) {
|
||||
synchronized (commands) {
|
||||
commands.add(command);
|
||||
}
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
Boolean b = childPermissions.get(permission);
|
||||
return b == null ? Tristate.UNDEFINED : Tristate.fromBoolean(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final List<QueuedCommand> toExecute = new ArrayList<>();
|
||||
synchronized (commands) {
|
||||
toExecute.addAll(commands);
|
||||
commands.clear();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (toExecute.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (QueuedCommand command : toExecute) {
|
||||
manager.onCommand(command.getSender(), "perms", command.getArgs());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public static class QueuedCommand {
|
||||
private final Sender sender;
|
||||
private final List<String> args;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,11 +23,16 @@
|
||||
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 +48,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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.compat;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class BukkitJsonMessageHandler {
|
||||
private static boolean setup = false;
|
||||
private static boolean triedAndFailed = false;
|
||||
|
||||
private static Method GET_HANDLE_METHOD;
|
||||
private static Field PLAYER_CONNECTION_FIELD;
|
||||
private static Method SEND_PACKET_METHOD;
|
||||
private static Constructor<?> PACKET_CHAT_CONSTRUCTOR;
|
||||
private static Method SERIALIZE_METHOD;
|
||||
|
||||
private static void setup(Object player) throws Exception {
|
||||
Class<?> craftPlayerClass = player.getClass();
|
||||
GET_HANDLE_METHOD = craftPlayerClass.getDeclaredMethod("getHandle");
|
||||
|
||||
Object handleObject = GET_HANDLE_METHOD.invoke(player);
|
||||
Class<?> handleClass = handleObject.getClass();
|
||||
|
||||
PLAYER_CONNECTION_FIELD = handleClass.getDeclaredField("playerConnection");
|
||||
|
||||
Object playerConnectionObject = PLAYER_CONNECTION_FIELD.get(handleObject);
|
||||
|
||||
Method[] playerConnectionMethods = playerConnectionObject.getClass().getDeclaredMethods();
|
||||
for (Method m : playerConnectionMethods) {
|
||||
if (m.getName().equals("sendPacket")) {
|
||||
SEND_PACKET_METHOD = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> packetChatClass = Class.forName(getVersionedClassName("PacketPlayOutChat"));
|
||||
Constructor[] packetConstructors = packetChatClass.getDeclaredConstructors();
|
||||
for (Constructor c : packetConstructors) {
|
||||
Class<?>[] parameters = c.getParameterTypes();
|
||||
if (parameters.length == 1 && parameters[0].getName().endsWith("IChatBaseComponent")) {
|
||||
PACKET_CHAT_CONSTRUCTOR = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> baseComponentClass = Class.forName(getVersionedClassName("IChatBaseComponent"));
|
||||
Class<?> chatSerializerClass = baseComponentClass.getClasses()[0];
|
||||
|
||||
SERIALIZE_METHOD = chatSerializerClass.getDeclaredMethod("a", String.class);
|
||||
}
|
||||
|
||||
private static String getVersionedClassName(String className) {
|
||||
Class server = Bukkit.getServer().getClass();
|
||||
if (!server.getSimpleName().equals("CraftServer")) {
|
||||
throw new RuntimeException("Couldn't reflect into server " + server);
|
||||
}
|
||||
|
||||
String version;
|
||||
if (server.getName().equals("org.bukkit.craftbukkit.CraftServer")) {
|
||||
// Non versioned class
|
||||
version = ".";
|
||||
} else {
|
||||
version = server.getName().substring("org.bukkit.craftbukkit".length());
|
||||
version = version.substring(0, version.length() - "CraftServer".length());
|
||||
}
|
||||
|
||||
return "net.minecraft.server" + version + className;
|
||||
}
|
||||
|
||||
private static synchronized boolean trySetup(Object player) {
|
||||
if (setup) return true;
|
||||
if (triedAndFailed) return false;
|
||||
|
||||
try {
|
||||
setup(player);
|
||||
setup = true;
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
triedAndFailed = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean sendJsonMessage(Player player, String json) {
|
||||
if (!trySetup(player)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
Object connection = PLAYER_CONNECTION_FIELD.get(GET_HANDLE_METHOD.invoke(player));
|
||||
SEND_PACKET_METHOD.invoke(connection, PACKET_CHAT_CONSTRUCTOR.newInstance(SERIALIZE_METHOD.invoke(null, json)));
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.compat;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import io.github.mkremins.fanciful.FancyMessage;
|
||||
|
||||
public class MessageHandler {
|
||||
private final BukkitJsonMessageHandler bukkitHandler;
|
||||
private final SpigotJsonMessageHandler spigotHandler;
|
||||
|
||||
public MessageHandler() {
|
||||
bukkitHandler = new BukkitJsonMessageHandler();
|
||||
spigotHandler = isSpigot() ? new SpigotJsonMessageHandler() : null;
|
||||
}
|
||||
|
||||
public void sendJsonMessage(CommandSender sender, FancyMessage message) {
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
String json = message.toJSONString();
|
||||
|
||||
// Try Bukkit.
|
||||
if (bukkitHandler.sendJsonMessage(player, json)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try Spigot.
|
||||
if (spigotHandler != null && spigotHandler.sendJsonMessage(player, json)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to Bukkit
|
||||
sender.sendMessage(message.toOldMessageFormat());
|
||||
}
|
||||
|
||||
private static boolean isSpigot() {
|
||||
try {
|
||||
Class.forName("net.md_5.bungee.chat.ComponentSerializer");
|
||||
return true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.compat;
|
||||
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class SpigotJsonMessageHandler {
|
||||
|
||||
public boolean sendJsonMessage(Player player, String json) {
|
||||
try {
|
||||
player.spigot().sendMessage(ComponentSerializer.parse(json));
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,11 +23,16 @@
|
||||
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;
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -38,21 +43,44 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
@UtilityClass
|
||||
public class Injector {
|
||||
private static final Map<UUID, LPPermissible> INJECTED_PERMISSIBLES = new ConcurrentHashMap<>();
|
||||
|
||||
private static Field HUMAN_ENTITY_FIELD;
|
||||
private static Field PERMISSIBLEBASE_ATTACHMENTS;
|
||||
|
||||
static {
|
||||
try {
|
||||
HUMAN_ENTITY_FIELD = Class.forName(getVersionedClassName("entity.CraftHumanEntity")).getDeclaredField("perm");
|
||||
HUMAN_ENTITY_FIELD.setAccessible(true);
|
||||
|
||||
PERMISSIBLEBASE_ATTACHMENTS = PermissibleBase.class.getDeclaredField("attachments");
|
||||
PERMISSIBLEBASE_ATTACHMENTS.setAccessible(true);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean inject(Player player, LPPermissible permissible) {
|
||||
public static boolean inject(Player player, LPPermissible lpPermissible) {
|
||||
try {
|
||||
HUMAN_ENTITY_FIELD.set(player, permissible);
|
||||
INJECTED_PERMISSIBLES.put(player.getUniqueId(), permissible);
|
||||
PermissibleBase existing = (PermissibleBase) HUMAN_ENTITY_FIELD.get(player);
|
||||
if (existing instanceof LPPermissible) {
|
||||
// uh oh
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
// Move attachments over from the old permissible.
|
||||
List<PermissionAttachment> attachments = (List<PermissionAttachment>) PERMISSIBLEBASE_ATTACHMENTS.get(existing);
|
||||
lpPermissible.addAttachments(attachments);
|
||||
attachments.clear();
|
||||
existing.clearPermissions();
|
||||
|
||||
lpPermissible.recalculatePermissions();
|
||||
lpPermissible.setOldPermissible(existing);
|
||||
|
||||
lpPermissible.updateSubscriptionsAsync();
|
||||
|
||||
HUMAN_ENTITY_FIELD.set(player, lpPermissible);
|
||||
INJECTED_PERMISSIBLES.put(player.getUniqueId(), lpPermissible);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -60,14 +88,31 @@ public class Injector {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean unInject(Player player) {
|
||||
public static boolean unInject(Player player, boolean dummy) {
|
||||
try {
|
||||
Permissible permissible = (Permissible) HUMAN_ENTITY_FIELD.get(player);
|
||||
PermissibleBase permissible = (PermissibleBase) HUMAN_ENTITY_FIELD.get(player);
|
||||
if (permissible instanceof LPPermissible) {
|
||||
/* The player is most likely leaving. Bukkit will attempt to call #clearPermissions, so we cannot set to null.
|
||||
However, there's no need to re-inject a real PermissibleBase, so we just inject a dummy instead.
|
||||
This saves tick time, pointlessly recalculating defaults when the instance will never be used. */
|
||||
HUMAN_ENTITY_FIELD.set(player, new DummyPermissibleBase());
|
||||
|
||||
permissible.clearPermissions();
|
||||
((LPPermissible) permissible).unsubscribeFromAllAsync();
|
||||
|
||||
if (dummy) {
|
||||
HUMAN_ENTITY_FIELD.set(player, new DummyPermissibleBase());
|
||||
} else {
|
||||
LPPermissible lpp = ((LPPermissible) permissible);
|
||||
List<PermissionAttachment> attachments = lpp.getAttachments();
|
||||
|
||||
PermissibleBase newPb = lpp.getOldPermissible();
|
||||
if (newPb == null) {
|
||||
newPb = new PermissibleBase(player);
|
||||
}
|
||||
|
||||
List<PermissionAttachment> newAttachments = (List<PermissionAttachment>) PERMISSIBLEBASE_ATTACHMENTS.get(newPb);
|
||||
newAttachments.addAll(attachments);
|
||||
attachments.clear();
|
||||
|
||||
HUMAN_ENTITY_FIELD.set(player, newPb);
|
||||
}
|
||||
}
|
||||
INJECTED_PERMISSIBLES.remove(player.getUniqueId());
|
||||
return true;
|
||||
|
||||
+107
-95
@@ -20,24 +20,36 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.migration.subcommands;
|
||||
package me.lucko.luckperms.bukkit.migration;
|
||||
|
||||
import de.bananaco.bpermissions.api.Calculable;
|
||||
import de.bananaco.bpermissions.api.CalculableType;
|
||||
import de.bananaco.bpermissions.api.Group;
|
||||
import de.bananaco.bpermissions.api.Permission;
|
||||
import de.bananaco.bpermissions.api.World;
|
||||
import de.bananaco.bpermissions.api.WorldManager;
|
||||
|
||||
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.core.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.core.model.User;
|
||||
import me.lucko.luckperms.common.data.LogEntry;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static me.lucko.luckperms.common.constants.Permission.MIGRATION;
|
||||
|
||||
@@ -81,12 +93,90 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
private static void migrateHolder(LuckPermsPlugin plugin, World world, Calculable c, PermissionHolder holder) {
|
||||
// Migrate the groups permissions in this world
|
||||
for (Permission p : c.getPermissions()) {
|
||||
try {
|
||||
holder.setPermission(p.name(), p.isTrue(), "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + p.name() + " " + p.isTrue() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Include any child permissions
|
||||
for (Map.Entry<String, Boolean> child : p.getChildren().entrySet()) {
|
||||
try {
|
||||
holder.setPermission(child.getKey(), child.getValue(), "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + child.getKey() + " " + child.getValue() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate any inherited groups
|
||||
for (Group parent : c.getGroups()) {
|
||||
try {
|
||||
holder.setPermission("group." + parent.getName(), true, "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("setinherit " + parent.getName() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate existing meta
|
||||
for (Map.Entry<String, String> meta : c.getMeta().entrySet()) {
|
||||
if (meta.getKey().equalsIgnoreCase("prefix") || meta.getKey().equalsIgnoreCase("suffix")) {
|
||||
String chatMeta = MetaUtils.escapeCharacters(meta.getValue());
|
||||
try {
|
||||
holder.setPermission(meta.getKey().toLowerCase() + "." + c.getPriority() + "." + chatMeta, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + meta.getKey().toLowerCase() + "." + c.getPriority() + "." + chatMeta + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
holder.setPermission("meta." + meta.getKey() + "." + meta.getValue(), true, "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set meta." + meta.getKey() + "." + meta.getValue() + " true global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
@@ -109,7 +199,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
log.info("bPermissions Migration: Starting world migration.");
|
||||
for (World world : worldManager.getAllWorlds()) {
|
||||
log.info("bPermissions Migration: Migrating world: " + world.getName());
|
||||
|
||||
|
||||
// Migrate all groups
|
||||
log.info("bPermissions Migration: Starting group migration in world " + world.getName() + ".");
|
||||
int groupCount = 0;
|
||||
@@ -121,19 +211,19 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
// Make a LuckPerms group for the one being migrated.
|
||||
plugin.getDatastore().createAndLoadGroup(groupName).getUnchecked();
|
||||
me.lucko.luckperms.common.groups.Group lpGroup = plugin.getGroupManager().get(groupName);
|
||||
plugin.getStorage().createAndLoadGroup(groupName).join();
|
||||
me.lucko.luckperms.common.core.model.Group lpGroup = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
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 +247,12 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
// Make a LuckPerms user for the one being migrated.
|
||||
plugin.getDatastore().loadUser(uuid, "null").getUnchecked();
|
||||
me.lucko.luckperms.common.users.User lpUser = plugin.getUserManager().get(uuid);
|
||||
plugin.getStorage().loadUser(uuid, "null").join();
|
||||
User lpUser = plugin.getUserManager().get(uuid);
|
||||
|
||||
migrateHolder(plugin, world, user, lpUser);
|
||||
|
||||
plugin.getDatastore().saveUser(lpUser);
|
||||
plugin.getStorage().saveUser(lpUser);
|
||||
plugin.getUserManager().cleanup(lpUser);
|
||||
}
|
||||
|
||||
@@ -172,82 +262,4 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
log.info("bPermissions Migration: Success! Completed without any errors.");
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private static void migrateHolder(LuckPermsPlugin plugin, World world, Calculable c, PermissionHolder holder) {
|
||||
// Migrate the groups permissions in this world
|
||||
for (Permission p : c.getPermissions()) {
|
||||
try {
|
||||
holder.setPermission(p.name(), p.isTrue(), "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(holder).action("set " + p.name() + " " + p.isTrue() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Include any child permissions
|
||||
for (Map.Entry<String, Boolean> child : p.getChildren().entrySet()) {
|
||||
try {
|
||||
holder.setPermission(child.getKey(), child.getValue(), "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(holder).action("set " + child.getKey() + " " + child.getValue() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate any inherited groups
|
||||
for (Group parent : c.getGroups()) {
|
||||
try {
|
||||
holder.setPermission("group." + parent.getName(), true, "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(holder).action("setinherit " + parent.getName() + " global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate existing meta
|
||||
for (Map.Entry<String, String> meta : c.getMeta().entrySet()) {
|
||||
if (meta.getKey().equalsIgnoreCase("prefix") || meta.getKey().equalsIgnoreCase("suffix")) {
|
||||
String chatMeta = MetaUtils.escapeCharacters(meta.getValue());
|
||||
try {
|
||||
holder.setPermission(meta.getKey().toLowerCase() + "." + c.getPriority() + "." + chatMeta, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(holder).action("set " + meta.getKey().toLowerCase() + "." + c.getPriority() + "." + chatMeta + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
holder.setPermission("meta." + meta.getKey() + "." + meta.getValue(), true, "global", world.getName());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(holder).action("set meta." + meta.getKey() + "." + meta.getValue() + " true global " + world.getName())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+61
-50
@@ -20,15 +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.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 +44,22 @@ 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.AbstractMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
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,21 +74,14 @@ 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();
|
||||
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
|
||||
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
|
||||
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(g.getName().toLowerCase());
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -97,7 +101,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission(node, value);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set " + node + " " + value)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -111,7 +115,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission("group." + s.toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("setinherit " + s.toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -121,33 +125,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<>());
|
||||
@@ -174,7 +166,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
UUID uuid;
|
||||
try {
|
||||
uuid = UUID.fromString(user.getUUID());
|
||||
} catch (IllegalArgumentException e){
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -193,7 +185,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,11 +200,11 @@ 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();
|
||||
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(e.getKey());
|
||||
plugin.getStorage().createAndLoadGroup(e.getKey()).join();
|
||||
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(e.getKey());
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -219,17 +217,17 @@ 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);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("setinherit " + groupName + " global " + n.getKey().getKey())
|
||||
.build().submit(plugin);
|
||||
} else {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set " + n.getKey().getValue() + " " + n.getValue() + " global " + n.getKey().getKey())
|
||||
.build().submit(plugin);
|
||||
}
|
||||
@@ -241,29 +239,29 @@ 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();
|
||||
me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(e.getKey());
|
||||
plugin.getStorage().loadUser(e.getKey(), "null").join();
|
||||
me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().get(e.getKey());
|
||||
|
||||
for (Map.Entry<Map.Entry<String, String>, Boolean> n : e.getValue().entrySet()) {
|
||||
// n.key.key = world
|
||||
// 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);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + group + " global " + n.getKey().getKey())
|
||||
.build().submit(plugin);
|
||||
} else {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set " + n.getKey().getValue() + " " + n.getValue() + " global " + n.getKey().getKey())
|
||||
.build().submit(plugin);
|
||||
}
|
||||
@@ -275,7 +273,20 @@ 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);
|
||||
}
|
||||
|
||||
+34
-34
@@ -20,19 +20,25 @@
|
||||
* 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.core.model.Group;
|
||||
import me.lucko.luckperms.common.core.model.User;
|
||||
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;
|
||||
import ru.tehkode.permissions.PermissionManager;
|
||||
@@ -40,21 +46,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 +77,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 {
|
||||
@@ -98,15 +97,15 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
|
||||
for (PermissionGroup group : manager.getGroupList()) {
|
||||
int groupWeight = group.getWeight() * -1;
|
||||
groupCount ++;
|
||||
groupCount++;
|
||||
maxGroupWeight = Math.max(maxGroupWeight, groupWeight);
|
||||
|
||||
final String name = group.getName().toLowerCase();
|
||||
plugin.getDatastore().createAndLoadGroup(name).getUnchecked();
|
||||
Group lpGroup = plugin.getGroupManager().get(name);
|
||||
plugin.getStorage().createAndLoadGroup(name).join();
|
||||
Group lpGroup = plugin.getGroupManager().getIfLoaded(name);
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -124,7 +123,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission(node, value);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("set " + node + " " + value)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -149,7 +148,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission(node, value, "global", world);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("set " + node + " " + value + " global " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -165,7 +164,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission("group." + g.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("setinherit " + g.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -181,7 +180,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission("group." + g.getName().toLowerCase(), true, "global", world);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("setinherit " + g.getName().toLowerCase() + " global " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -201,7 +200,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission("prefix." + groupWeight + "." + prefix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("set prefix." + groupWeight + "." + prefix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -216,7 +215,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpGroup.setPermission("suffix." + groupWeight + "." + suffix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpGroup).action("set suffix." + groupWeight + "." + suffix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -226,7 +225,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveGroup(lpGroup);
|
||||
plugin.getStorage().saveGroup(lpGroup);
|
||||
|
||||
}
|
||||
|
||||
@@ -254,7 +253,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
userCount++;
|
||||
plugin.getDatastore().loadUser(u, "null").getUnchecked();
|
||||
plugin.getStorage().loadUser(u, user.getName()).join();
|
||||
User lpUser = plugin.getUserManager().get(u);
|
||||
|
||||
try {
|
||||
@@ -268,7 +267,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission(node, value);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("set " + node + " " + value)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -293,7 +292,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission(node, value, "global", world);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("set " + node + " " + value + " global " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -309,7 +308,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission("group." + s.toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("addgroup " + s.toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -325,7 +324,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission("group." + s.toLowerCase(), true, "global", world);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("addgroup " + s.toLowerCase() + " global " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -345,7 +344,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission("prefix." + maxGroupWeight + "." + prefix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("set prefix." + maxGroupWeight + "." + prefix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -360,7 +359,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
lpUser.setPermission("suffix." + maxGroupWeight + "." + suffix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(lpUser).action("set suffix." + maxGroupWeight + "." + suffix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -382,12 +381,13 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
if (primary != null) {
|
||||
try {
|
||||
lpUser.setPermission("group." + primary.toLowerCase(), true);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
}
|
||||
lpUser.setPrimaryGroup(primary);
|
||||
}
|
||||
|
||||
plugin.getUserManager().cleanup(lpUser);
|
||||
plugin.getDatastore().saveUser(lpUser);
|
||||
plugin.getStorage().saveUser(lpUser);
|
||||
}
|
||||
|
||||
log.info("PermissionsEx Migration: Migrated " + userCount + " users.");
|
||||
+76
-55
@@ -20,21 +20,33 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.migration.subcommands;
|
||||
package me.lucko.luckperms.bukkit.migration;
|
||||
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.*;
|
||||
import lombok.Cleanup;
|
||||
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.CachedGroup;
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.Group;
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.Permission;
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.PermissionManager;
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.PowerfulPermsPlugin;
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.ResultRunnable;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
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.core.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.core.model.User;
|
||||
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;
|
||||
@@ -43,7 +55,13 @@ import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
@@ -72,25 +90,29 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
Class.forName("com.github.cheesesoftware.PowerfulPermsAPI.ResponseRunnable");
|
||||
legacy = true;
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
|
||||
if (legacy) {
|
||||
try {
|
||||
getPlayerPermissionsMethod = PermissionManager.class.getMethod("getPlayerOwnPermissions", UUID.class, ResultRunnable.class);
|
||||
getPlayerPermissionsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException ignored) {}
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
getPlayerPermissionsMethod = PermissionManager.class.getMethod("getPlayerOwnPermissions", UUID.class);
|
||||
getPlayerPermissionsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException ignored) {}
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
getGroupMethod = CachedGroup.class.getMethod("getGroup");
|
||||
getGroupMethod.setAccessible(true);
|
||||
superLegacy = true;
|
||||
} catch (NoSuchMethodException ignored) {}
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
}
|
||||
|
||||
if (!legacy) {
|
||||
try {
|
||||
@@ -114,29 +136,6 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public MigrationPowerfulPerms() {
|
||||
super("powerfulperms", "Migration from PowerfulPerms", MIGRATION, Predicate.not(5),
|
||||
Arg.list(
|
||||
Arg.create("address", true, "the address of the PP database"),
|
||||
Arg.create("database", true, "the name of the PP database"),
|
||||
Arg.create("username", true, "the username to log into the DB"),
|
||||
Arg.create("password", true, "the password to log into the DB"),
|
||||
Arg.create("db table", true, "the name of the PP table where player data is stored")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) {
|
||||
try {
|
||||
return run(plugin, args);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
private static void getPlayerPermissions(PermissionManager manager, UUID uuid, Callback<List<Permission>> callback) {
|
||||
if (legacy) {
|
||||
try {
|
||||
@@ -173,6 +172,28 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
public MigrationPowerfulPerms() {
|
||||
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"),
|
||||
Arg.create("username", true, "the username to log into the DB"),
|
||||
Arg.create("password", true, "the password to log into the DB"),
|
||||
Arg.create("db table", true, "the name of the PP table where player data is stored")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List<String> args, String label) throws CommandException {
|
||||
try {
|
||||
return run(plugin, args);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
private CommandResult run(LuckPermsPlugin plugin, List<String> args) {
|
||||
final Logger log = plugin.getLog();
|
||||
if (!plugin.isPluginLoaded("PowerfulPerms")) {
|
||||
@@ -246,11 +267,11 @@ 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();
|
||||
final me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
|
||||
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
|
||||
final me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(g.getName().toLowerCase());
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -265,7 +286,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission("group." + parent.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("setinherit " + parent.getName().toLowerCase()) // All versions
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -275,7 +296,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveGroup(group);
|
||||
plugin.getStorage().saveGroup(group);
|
||||
}
|
||||
log.info("PowerfulPerms Migration: Group migration complete.");
|
||||
|
||||
@@ -288,7 +309,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 +320,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);
|
||||
}
|
||||
}
|
||||
@@ -332,7 +353,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -344,7 +365,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -365,7 +386,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -377,7 +398,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -392,7 +413,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -404,7 +425,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -422,7 +443,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);
|
||||
}
|
||||
}
|
||||
@@ -528,7 +549,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value, server, world);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + node + " " + value + " " + server + " " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -540,7 +561,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value, server, world, expireAt);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("settemp " + node + " " + value + " " + expireAt + " " + server + " " + world)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -555,7 +576,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + node + " " + value + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -567,7 +588,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value, server, expireAt);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("settemp " + node + " " + value + " " + expireAt + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -581,7 +602,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("set " + node + " " + value)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -593,7 +614,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
try {
|
||||
holder.setPermission(node, value, expireAt);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(holder).action("settemp " + node + " " + value + " " + expireAt)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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.model.Group;
|
||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.core.model.Track;
|
||||
import me.lucko.luckperms.common.core.model.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.Membership;
|
||||
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().getIfLoaded(g.toLowerCase());
|
||||
|
||||
PermissionEntity entity = internalService.getEntity(g, null, true);
|
||||
migrateEntity(group, entity, null);
|
||||
|
||||
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().getIfLoaded(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, internalService.getGroups(u));
|
||||
|
||||
user.setPrimaryGroup(service.getPlayerPrimaryGroup(u));
|
||||
|
||||
if (!entity.isGroup()) {
|
||||
user.setName(entity.getDisplayName());
|
||||
}
|
||||
|
||||
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, List<Membership> memberships) {
|
||||
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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.isGroup()) {
|
||||
for (Inheritance inheritance : entity.getInheritancesAsChild()) {
|
||||
try {
|
||||
if (!inheritance.getParent().getName().equals(group.getObjectName())) {
|
||||
group.setPermission("group." + inheritance.getParent().getName(), true);
|
||||
}
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// entity.getMemberships() doesn't work (always returns 0 records)
|
||||
for (Membership membership : memberships) {
|
||||
try {
|
||||
group.setPermission("group." + membership.getGroup().getDisplayName(), true);
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (EntityMetadata metadata : entity.getMetadata()) {
|
||||
try {
|
||||
group.setPermission(NodeFactory.makeMetaNode(metadata.getName(), metadata.getStringValue()).build());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -20,12 +20,13 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.migration.subcommands.utils;
|
||||
package me.lucko.luckperms.bukkit.migration.utils;
|
||||
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.ResultRunnable;
|
||||
|
||||
/**
|
||||
* Overrides the default ResultRunnable, callbacks will always run in the same thread. (an async one, hopefully.)
|
||||
*
|
||||
* @param <T> type
|
||||
*/
|
||||
public abstract class LPResultRunnable<T> extends ResultRunnable<T> {
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.model;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.permissions.Permission;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ChildPermissionProvider {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
private ImmutableMap<Map.Entry<String, Boolean>, ImmutableMap<String, Boolean>> permissions = ImmutableMap.of();
|
||||
|
||||
public void setup() {
|
||||
Map<Map.Entry<String, Boolean>, ImmutableMap<String, Boolean>> permissions = new HashMap<>();
|
||||
|
||||
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 = ImmutableMap.copyOf(permissions);
|
||||
}
|
||||
}
|
||||
+50
-24
@@ -20,10 +20,15 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.calculators;
|
||||
package me.lucko.luckperms.bukkit.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.permissions.Permission;
|
||||
@@ -38,26 +43,7 @@ import java.util.Set;
|
||||
|
||||
public class DefaultsProvider {
|
||||
|
||||
private final DummyPermissible opDummy = new DummyPermissible(this::refreshOp);
|
||||
private final DummyPermissible nonOpDummy = new DummyPermissible(this::refreshNonOp);
|
||||
|
||||
private final Map<String, Boolean> op = new HashMap<>();
|
||||
private final Map<String, Boolean> nonOp = new HashMap<>();
|
||||
|
||||
public void refresh() {
|
||||
refreshOp();
|
||||
refreshNonOp();
|
||||
}
|
||||
|
||||
private void refreshOp() {
|
||||
calculateDefaults(op, opDummy, true);
|
||||
}
|
||||
|
||||
private void refreshNonOp() {
|
||||
calculateDefaults(nonOp, nonOpDummy, false);
|
||||
}
|
||||
|
||||
private static void calculateDefaults(Map<String, Boolean> map, DummyPermissible p, boolean op) {
|
||||
private static void unregisterDefaults(Map<String, Boolean> map, DummyPermissible p) {
|
||||
Set<String> perms = map.keySet();
|
||||
|
||||
for (String name : perms) {
|
||||
@@ -66,9 +52,9 @@ public class DefaultsProvider {
|
||||
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(false, p);
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(true, p);
|
||||
}
|
||||
|
||||
map.clear();
|
||||
|
||||
private static void calculateDefaults(Map<String, Boolean> map, DummyPermissible p, boolean op) {
|
||||
Set<Permission> defaults = Bukkit.getServer().getPluginManager().getDefaultPermissions(op);
|
||||
Bukkit.getServer().getPluginManager().subscribeToDefaultPerms(op, p);
|
||||
|
||||
@@ -95,13 +81,53 @@ public class DefaultsProvider {
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
private Map<String, Boolean> opDefaults = ImmutableMap.of();
|
||||
private final DummyPermissible opDummy = new DummyPermissible(this::refreshOp);
|
||||
|
||||
@Getter
|
||||
private Map<String, Boolean> nonOpDefaults = ImmutableMap.of();
|
||||
private final DummyPermissible nonOpDummy = new DummyPermissible(this::refreshNonOp);
|
||||
|
||||
public void refresh() {
|
||||
refreshOp();
|
||||
refreshNonOp();
|
||||
}
|
||||
|
||||
private void refreshOp() {
|
||||
unregisterDefaults(opDefaults, opDummy);
|
||||
|
||||
Map<String, Boolean> builder = new HashMap<>();
|
||||
calculateDefaults(builder, opDummy, true);
|
||||
|
||||
opDefaults = ImmutableMap.copyOf(builder);
|
||||
}
|
||||
|
||||
private void refreshNonOp() {
|
||||
unregisterDefaults(nonOpDefaults, nonOpDummy);
|
||||
|
||||
Map<String, Boolean> builder = new HashMap<>();
|
||||
calculateDefaults(builder, nonOpDummy, false);
|
||||
|
||||
nonOpDefaults = ImmutableMap.copyOf(builder);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
unregisterDefaults(opDefaults, opDummy);
|
||||
unregisterDefaults(nonOpDefaults, nonOpDummy);
|
||||
}
|
||||
|
||||
public Tristate hasDefault(String permission, boolean isOp) {
|
||||
Map<String, Boolean> map = isOp ? op : nonOp;
|
||||
Map<String, Boolean> map = isOp ? opDefaults : nonOpDefaults;
|
||||
|
||||
Boolean b = map.get(permission);
|
||||
return b == null ? Tristate.UNDEFINED : Tristate.fromBoolean(b);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return opDefaults.size() + nonOpDefaults.size();
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private static class DummyPermissible implements Permissible {
|
||||
private final Runnable onRefresh;
|
||||
+61
-21
@@ -20,21 +20,33 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.inject;
|
||||
package me.lucko.luckperms.bukkit.model;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.core.model.User;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.*;
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.permissions.PermissionRemovedExecutor;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -49,25 +61,65 @@ public class LPPermissible extends PermissibleBase {
|
||||
@Getter
|
||||
private final Player parent;
|
||||
|
||||
@Getter
|
||||
private final LPBukkitPlugin plugin;
|
||||
|
||||
@Getter
|
||||
private final SubscriptionManager subscriptions;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private PermissibleBase oldPermissible = null;
|
||||
|
||||
// Attachment stuff.
|
||||
@Getter
|
||||
private final Map<String, PermissionAttachmentInfo> attachmentPermissions = new HashMap<>();
|
||||
private final List<PermissionAttachment> attachments = new LinkedList<>();
|
||||
private final Map<String, PermissionAttachmentInfo> attachmentPermissions = new ConcurrentHashMap<>();
|
||||
@Getter
|
||||
private final List<PermissionAttachment> attachments = Collections.synchronizedList(new LinkedList<>());
|
||||
|
||||
public LPPermissible(@NonNull Player parent, User user, LPBukkitPlugin plugin) {
|
||||
super(parent);
|
||||
this.user = user;
|
||||
this.parent = parent;
|
||||
this.plugin = plugin;
|
||||
this.subscriptions = new SubscriptionManager(this);
|
||||
|
||||
recalculatePermissions();
|
||||
}
|
||||
|
||||
public void updateSubscriptionsAsync() {
|
||||
plugin.doAsync(this::updateSubscriptions);
|
||||
}
|
||||
|
||||
public void updateSubscriptions() {
|
||||
Set<String> ent = new HashSet<>(user.getUserData().getPermissionData(calculateContexts()).getImmutableBacking().keySet());
|
||||
|
||||
if (parent.isOp()) {
|
||||
ent.addAll(plugin.getDefaultsProvider().getOpDefaults().keySet());
|
||||
} else {
|
||||
ent.addAll(plugin.getDefaultsProvider().getNonOpDefaults().keySet());
|
||||
}
|
||||
|
||||
subscriptions.subscribe(ent);
|
||||
}
|
||||
|
||||
public void unsubscribeFromAllAsync() {
|
||||
plugin.doAsync(this::unsubscribeFromAll);
|
||||
}
|
||||
|
||||
public void unsubscribeFromAll() {
|
||||
subscriptions.subscribe(Collections.emptySet());
|
||||
}
|
||||
|
||||
public void addAttachments(List<PermissionAttachment> attachments) {
|
||||
for (PermissionAttachment attachment : attachments) {
|
||||
this.attachments.add(attachment);
|
||||
}
|
||||
}
|
||||
|
||||
public Contexts calculateContexts() {
|
||||
return new Contexts(
|
||||
plugin.getContextManager().giveApplicableContext(parent, new MutableContextSet()),
|
||||
plugin.getContextManager().getApplicableContext(parent),
|
||||
plugin.getConfiguration().isIncludingGlobalPerms(),
|
||||
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
@@ -185,7 +237,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 +307,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.bukkit.model;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SubscriptionManager {
|
||||
|
||||
private final LPPermissible permissible;
|
||||
private Set<String> currentSubscriptions = ImmutableSet.of();
|
||||
|
||||
public synchronized void subscribe(Set<String> perms) {
|
||||
Set<String> newPerms = ImmutableSet.copyOf(perms);
|
||||
|
||||
Map.Entry<Set<String>, Set<String>> changes = compareSets(newPerms, currentSubscriptions);
|
||||
|
||||
Set<String> toAdd = changes.getKey();
|
||||
Set<String> toRemove = changes.getValue();
|
||||
|
||||
permissible.getPlugin().doSync(() -> {
|
||||
for (String s : toAdd) {
|
||||
permissible.getPlugin().getServer().getPluginManager().subscribeToPermission(s, permissible.getParent());
|
||||
}
|
||||
for (String s : toRemove) {
|
||||
permissible.getPlugin().getServer().getPluginManager().unsubscribeFromPermission(s, permissible.getParent());
|
||||
}
|
||||
});
|
||||
|
||||
this.currentSubscriptions = newPerms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two sets
|
||||
* @param local the local set
|
||||
* @param remote the remote set
|
||||
* @return the entries to add to remote, and the entries to remove from remote
|
||||
*/
|
||||
private static Map.Entry<Set<String>, Set<String>> compareSets(Set<String> local, Set<String> remote) {
|
||||
// entries in local but not remote need to be added
|
||||
// entries in remote but not local need to be removed
|
||||
|
||||
Set<String> toAdd = new HashSet<>(local);
|
||||
toAdd.removeAll(remote);
|
||||
|
||||
Set<String> toRemove = new HashSet<>(remote);
|
||||
toRemove.removeAll(local);
|
||||
|
||||
return Maps.immutableEntry(toAdd, toRemove);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,15 +23,20 @@
|
||||
package me.lucko.luckperms.bukkit.vault;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
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.PermissionHolder;
|
||||
import me.lucko.luckperms.common.groups.Group;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.core.NodeBuilder;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
import me.lucko.luckperms.common.core.model.Group;
|
||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.core.model.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;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -55,7 +60,7 @@ import static me.lucko.luckperms.api.MetaUtils.unescapeCharacters;
|
||||
* Normal inheritance rules DO NOT apply.
|
||||
* Permission Nodes = meta.node.value
|
||||
*
|
||||
* Node that special characters used within LuckPerms are escaped:
|
||||
* Note that special characters used within LuckPerms are escaped:
|
||||
* See {@link me.lucko.luckperms.api.MetaUtils#unescapeCharacters(String)}
|
||||
*/
|
||||
public class VaultChatHook extends Chat {
|
||||
@@ -81,21 +86,19 @@ 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);
|
||||
|
||||
perms.getScheduler().execute(() -> {
|
||||
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 -> {
|
||||
try {
|
||||
holder.unsetPermission(n);
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
} 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());
|
||||
}
|
||||
@@ -105,7 +108,8 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
try {
|
||||
holder.setPermission(metaNode.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
}
|
||||
|
||||
perms.save(holder);
|
||||
});
|
||||
@@ -118,8 +122,8 @@ 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));
|
||||
perms.getScheduler().execute(() -> {
|
||||
Node.Builder node = new NodeBuilder((prefix ? "prefix" : "suffix") + ".1000." + escapeCharacters(value));
|
||||
node.setValue(true);
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
node.setServer(perms.getServer());
|
||||
@@ -131,7 +135,8 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
try {
|
||||
holder.setPermission(node.build());
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
}
|
||||
|
||||
perms.save(holder);
|
||||
});
|
||||
@@ -148,7 +153,7 @@ public class VaultChatHook extends Chat {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return unescapeCharacters(user.getUserData().getMetaData(perms.createContext(perms.getServer(), world)).getMeta().getOrDefault(node, defaultValue));
|
||||
return unescapeCharacters(user.getUserData().getMetaData(perms.createContextForWorld(world)).getMeta().getOrDefault(node, defaultValue));
|
||||
}
|
||||
|
||||
private String getUserChatMeta(boolean prefix, User user, String world) {
|
||||
@@ -161,7 +166,7 @@ public class VaultChatHook extends Chat {
|
||||
return "";
|
||||
}
|
||||
|
||||
MetaData data = user.getUserData().getMetaData(perms.createContext(perms.getServer(), world));
|
||||
MetaData data = user.getUserData().getMetaData(perms.createContextForWorld(world));
|
||||
String v = prefix ? data.getPrefix() : data.getSuffix();
|
||||
return v == null ? "" : unescapeCharacters(v);
|
||||
}
|
||||
@@ -215,7 +220,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;
|
||||
}
|
||||
@@ -243,47 +249,47 @@ public class VaultChatHook extends Chat {
|
||||
}
|
||||
|
||||
public String getPlayerPrefix(String world, @NonNull String player) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
return getUserChatMeta(true, user, world);
|
||||
}
|
||||
|
||||
public void setPlayerPrefix(String world, @NonNull String player, @NonNull String prefix) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
setChatMeta(true, user, prefix, world);
|
||||
}
|
||||
|
||||
public String getPlayerSuffix(String world, @NonNull String player) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
return getUserChatMeta(false, user, world);
|
||||
}
|
||||
|
||||
public void setPlayerSuffix(String world, @NonNull String player, @NonNull String suffix) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
setChatMeta(false, user, suffix, world);
|
||||
}
|
||||
|
||||
public String getGroupPrefix(String world, @NonNull String group) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
return getGroupChatMeta(false, g, world);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
return getGroupChatMeta(true, g, world);
|
||||
}
|
||||
|
||||
public void setGroupPrefix(String world, @NonNull String group, @NonNull String prefix) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
setChatMeta(true, g, prefix, world);
|
||||
}
|
||||
|
||||
public String getGroupSuffix(String world, @NonNull String group) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
return getGroupChatMeta(false, g, world);
|
||||
}
|
||||
|
||||
public void setGroupSuffix(String world, @NonNull String group, @NonNull String suffix) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
setChatMeta(false, g, suffix, world);
|
||||
}
|
||||
|
||||
public int getPlayerInfoInteger(String world, @NonNull String player, @NonNull String node, int defaultValue) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
try {
|
||||
return Integer.parseInt(getUserMeta(user, world, node, String.valueOf(defaultValue)));
|
||||
} catch (NumberFormatException e) {
|
||||
@@ -292,12 +298,12 @@ public class VaultChatHook extends Chat {
|
||||
}
|
||||
|
||||
public void setPlayerInfoInteger(String world, @NonNull String player, @NonNull String node, int value) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
setMeta(user, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public int getGroupInfoInteger(String world, @NonNull String group, @NonNull String node, int defaultValue) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
try {
|
||||
return Integer.parseInt(getGroupMeta(g, world, node, String.valueOf(defaultValue)));
|
||||
} catch (NumberFormatException e) {
|
||||
@@ -306,12 +312,12 @@ public class VaultChatHook extends Chat {
|
||||
}
|
||||
|
||||
public void setGroupInfoInteger(String world, @NonNull String group, @NonNull String node, int value) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
setMeta(g, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public double getPlayerInfoDouble(String world, @NonNull String player, @NonNull String node, double defaultValue) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
try {
|
||||
return Double.parseDouble(getUserMeta(user, world, node, String.valueOf(defaultValue)));
|
||||
} catch (NumberFormatException e) {
|
||||
@@ -320,12 +326,12 @@ public class VaultChatHook extends Chat {
|
||||
}
|
||||
|
||||
public void setPlayerInfoDouble(String world, @NonNull String player, @NonNull String node, double value) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
setMeta(user, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public double getGroupInfoDouble(String world, @NonNull String group, @NonNull String node, double defaultValue) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
try {
|
||||
return Double.parseDouble(getGroupMeta(g, world, node, String.valueOf(defaultValue)));
|
||||
} catch (NumberFormatException e) {
|
||||
@@ -334,12 +340,12 @@ public class VaultChatHook extends Chat {
|
||||
}
|
||||
|
||||
public void setGroupInfoDouble(String world, @NonNull String group, @NonNull String node, double value) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
setMeta(g, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public boolean getPlayerInfoBoolean(String world, @NonNull String player, @NonNull String node, boolean defaultValue) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
String s = getUserMeta(user, world, node, String.valueOf(defaultValue));
|
||||
if (!s.equalsIgnoreCase("true") && !s.equalsIgnoreCase("false")) {
|
||||
return defaultValue;
|
||||
@@ -348,12 +354,12 @@ public class VaultChatHook extends Chat {
|
||||
}
|
||||
|
||||
public void setPlayerInfoBoolean(String world, @NonNull String player, @NonNull String node, boolean value) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
setMeta(user, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public boolean getGroupInfoBoolean(String world, @NonNull String group, @NonNull String node, boolean defaultValue) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
String s = getGroupMeta(g, world, node, String.valueOf(defaultValue));
|
||||
if (!s.equalsIgnoreCase("true") && !s.equalsIgnoreCase("false")) {
|
||||
return defaultValue;
|
||||
@@ -362,27 +368,27 @@ public class VaultChatHook extends Chat {
|
||||
}
|
||||
|
||||
public void setGroupInfoBoolean(String world, @NonNull String group, @NonNull String node, boolean value) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
setMeta(g, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public String getPlayerInfoString(String world, @NonNull String player, @NonNull String node, String defaultValue) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
return getUserMeta(user, world, node, defaultValue);
|
||||
}
|
||||
|
||||
public void setPlayerInfoString(String world, @NonNull String player, @NonNull String node, String value) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
setMeta(user, world, node, value);
|
||||
}
|
||||
|
||||
public String getGroupInfoString(String world, @NonNull String group, @NonNull String node, String defaultValue) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
return getGroupMeta(g, world, node, defaultValue);
|
||||
}
|
||||
|
||||
public void setGroupInfoString(String world, @NonNull String group, @NonNull String node, String value) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
setMeta(g, world, node, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,12 +23,18 @@
|
||||
package me.lucko.luckperms.bukkit.vault;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
|
||||
|
||||
import net.milkbowl.vault.chat.Chat;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.ServicesManager;
|
||||
|
||||
/**
|
||||
* Handles hooking with the Vault API
|
||||
*/
|
||||
@Getter
|
||||
public class VaultHook {
|
||||
private VaultChatHook chatHook = null;
|
||||
@@ -37,13 +43,8 @@ public class VaultHook {
|
||||
public void hook(LPBukkitPlugin plugin) {
|
||||
try {
|
||||
if (permissionHook == null) {
|
||||
permissionHook = new VaultPermissionHook();
|
||||
permissionHook = new VaultPermissionHook(plugin);
|
||||
}
|
||||
permissionHook.setPlugin(plugin);
|
||||
permissionHook.setServer(plugin.getConfiguration().getVaultServer());
|
||||
permissionHook.setIncludeGlobal(plugin.getConfiguration().isVaultIncludingGlobal());
|
||||
permissionHook.setIncludeGlobal(plugin.getConfiguration().isVaultIgnoreWorld());
|
||||
permissionHook.setup();
|
||||
|
||||
if (chatHook == null) {
|
||||
chatHook = new VaultChatHook(permissionHook);
|
||||
@@ -62,9 +63,12 @@ public class VaultHook {
|
||||
final ServicesManager sm = plugin.getServer().getServicesManager();
|
||||
if (permissionHook != null) {
|
||||
sm.unregister(Permission.class, permissionHook);
|
||||
permissionHook.getScheduler().cancelTask();
|
||||
permissionHook = null;
|
||||
}
|
||||
if (chatHook != null) {
|
||||
sm.unregister(Chat.class, chatHook);
|
||||
chatHook = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,64 +24,73 @@ package me.lucko.luckperms.bukkit.vault;
|
||||
|
||||
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;
|
||||
import me.lucko.luckperms.common.groups.Group;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.core.model.Group;
|
||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.core.model.User;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* The LuckPerms Vault Permission implementation
|
||||
* Most lookups are cached.
|
||||
*/
|
||||
@Getter
|
||||
public class VaultPermissionHook extends Permission {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private LPBukkitPlugin plugin;
|
||||
|
||||
@Getter
|
||||
private VaultScheduler scheduler;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private final String name = "LuckPerms";
|
||||
|
||||
private String server = "global";
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean includeGlobal = true;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean ignoreWorld = false;
|
||||
private boolean pgo = false;
|
||||
private boolean pgoCheckInherited = false;
|
||||
private boolean pgoCheckExists = true;
|
||||
private boolean pgoCheckMemberOf = true;
|
||||
|
||||
public void setup() {
|
||||
scheduler = new VaultScheduler(plugin);
|
||||
private Function<String, String> WORLD_CORRECTION_FUNCTION = s -> ignoreWorld ? null : s;
|
||||
|
||||
public VaultPermissionHook(LPBukkitPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.scheduler = new VaultScheduler(plugin);
|
||||
|
||||
super.plugin = plugin;
|
||||
|
||||
// Config options
|
||||
this.server = plugin.getConfiguration().getVaultServer();
|
||||
this.includeGlobal = plugin.getConfiguration().isVaultIncludingGlobal();
|
||||
this.ignoreWorld = plugin.getConfiguration().isVaultIgnoreWorld();
|
||||
this.pgo = plugin.getConfiguration().isVaultPrimaryGroupOverrides();
|
||||
this.pgoCheckInherited = plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckInherited();
|
||||
this.pgoCheckExists = plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckExists();
|
||||
this.pgoCheckMemberOf = plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckMemberOf();
|
||||
}
|
||||
|
||||
public void log(String s) {
|
||||
if (plugin.getConfiguration().isDebugPermissionChecks()) {
|
||||
if (plugin.getConfiguration().isVaultDebug()) {
|
||||
plugin.getLog().info("[VAULT] " + s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "LuckPerms";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return plugin.getDatastore().isAcceptingLogins();
|
||||
return plugin.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,57 +100,63 @@ public class VaultPermissionHook extends Permission {
|
||||
|
||||
/**
|
||||
* Generic method to add a permission to a holder
|
||||
* @param world the world to add in
|
||||
* @param holder the holder to add the permission to
|
||||
*
|
||||
* @param world the world to add in
|
||||
* @param holder the holder to add the permission to
|
||||
* @param permission the permission to add
|
||||
*/
|
||||
private void add(String world, PermissionHolder holder, String permission) {
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
holder.setPermission(permission, true, server, world);
|
||||
} else {
|
||||
holder.setPermission(permission, true, server);
|
||||
}
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
private CompletableFuture<Void> add(String world, PermissionHolder holder, String permission) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
if (world != null && !world.equals("") && !world.equalsIgnoreCase("global")) {
|
||||
holder.setPermission(permission, true, server, world);
|
||||
} else {
|
||||
holder.setPermission(permission, true, server);
|
||||
}
|
||||
|
||||
save(holder);
|
||||
save(holder);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
}, scheduler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic method to remove a permission from a holder
|
||||
* @param world the world to remove in
|
||||
* @param holder the holder to remove the permission from
|
||||
*
|
||||
* @param world the world to remove in
|
||||
* @param holder the holder to remove the permission from
|
||||
* @param permission the permission to remove
|
||||
*/
|
||||
private void remove(String world, PermissionHolder holder, String permission) {
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
holder.unsetPermission(permission, server, world);
|
||||
} else {
|
||||
holder.unsetPermission(permission, server);
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
private CompletableFuture<Void> remove(String world, PermissionHolder holder, String permission) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
if (world != null && !world.equals("") && !world.equalsIgnoreCase("global")) {
|
||||
holder.unsetPermission(permission, server, world);
|
||||
} else {
|
||||
holder.unsetPermission(permission, server);
|
||||
}
|
||||
|
||||
save(holder);
|
||||
save(holder);
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
}, scheduler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for saving a user or group
|
||||
* Utility method to asynchronously save a user or group
|
||||
*
|
||||
* @param holder the holder instance
|
||||
*/
|
||||
void save(PermissionHolder holder) {
|
||||
public void save(PermissionHolder holder) {
|
||||
if (holder instanceof User) {
|
||||
|
||||
plugin.getDatastore().saveUser(((User) holder), b -> {
|
||||
((User) holder).getRefreshBuffer().request();
|
||||
});
|
||||
User u = (User) holder;
|
||||
plugin.getStorage().saveUser(u).thenRunAsync(() -> u.getRefreshBuffer().request(), plugin.getAsyncExecutor());
|
||||
}
|
||||
if (holder instanceof Group) {
|
||||
plugin.getDatastore().saveGroup(((Group) holder), b -> plugin.getUpdateTaskBuffer().request());
|
||||
Group g = (Group) holder;
|
||||
plugin.getStorage().saveGroup(g).thenRunAsync(() -> plugin.getUpdateTaskBuffer().request(), plugin.getAsyncExecutor());
|
||||
}
|
||||
}
|
||||
|
||||
Contexts createContext(String server, String world) {
|
||||
public Contexts createContextForWorld(String world) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
if (world != null && !world.equals("")) {
|
||||
context.put("world", world);
|
||||
@@ -152,10 +167,10 @@ public class VaultPermissionHook extends Permission {
|
||||
|
||||
@Override
|
||||
public boolean playerHas(String world, @NonNull String player, @NonNull String permission) {
|
||||
world = ignoreWorld ? null : world; // Correct world value
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Checking if player " + player + " has permission: " + permission + " on world " + world + ", server " + server);
|
||||
|
||||
User user = plugin.getUserManager().get(player);
|
||||
User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
|
||||
if (user.getUserData() == null) {
|
||||
@@ -163,157 +178,235 @@ public class VaultPermissionHook extends Permission {
|
||||
}
|
||||
|
||||
// Effectively fallback to the standard Bukkit #hasPermission check.
|
||||
return user.getUserData().getPermissionData(createContext(server, world)).getPermissionValue(permission).asBoolean();
|
||||
return user.getUserData().getPermissionData(createContextForWorld(world)).getPermissionValue(permission).asBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerAdd(String world, @NonNull String player, @NonNull String permission) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Adding permission to player " + player + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Adding permission to player " + player + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> add(finalWorld, user, permission));
|
||||
add(world, user, permission);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerRemove(String world, @NonNull String player, @NonNull String permission) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Removing permission from player " + player + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Removing permission from player " + player + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> remove(finalWorld, user, permission));
|
||||
remove(world, user, permission);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean groupHas(String world, @NonNull String groupName, @NonNull String permission) {
|
||||
world = ignoreWorld ? null : world; // Correct world value
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Checking if group " + groupName + " has permission: " + permission + " on world " + world + ", server " + server);
|
||||
|
||||
final Group group = plugin.getGroupManager().get(groupName);
|
||||
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
// This is a nasty call. Groups aren't cached. :(
|
||||
Map<String, Boolean> permissions = group.exportNodes(createContext(server, world), true);
|
||||
|
||||
return permissions.containsKey(permission) && permissions.get(permission);
|
||||
Map<String, Boolean> permissions = group.exportNodes(createContextForWorld(world), true);
|
||||
return permissions.containsKey(permission.toLowerCase()) && permissions.get(permission.toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean groupAdd(String world, @NonNull String groupName, @NonNull String permission) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Adding permission to group " + groupName + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Adding permission to group " + groupName + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
|
||||
final Group group = plugin.getGroupManager().get(groupName);
|
||||
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> add(finalWorld, group, permission));
|
||||
add(world, group, permission);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean groupRemove(String world, @NonNull String groupName, @NonNull String permission) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Removing permission from group " + groupName + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Removing permission from group " + groupName + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
|
||||
final Group group = plugin.getGroupManager().get(groupName);
|
||||
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> remove(finalWorld, group, permission));
|
||||
remove(world, group, permission);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerInGroup(String world, @NonNull String player, @NonNull String group) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Checking if player " + player + " is in group: " + group + " on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Checking if player " + player + " is in group: " + group + " on world " + world + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
|
||||
String w = world; // screw effectively final
|
||||
return user.getNodes().stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.filter(n -> n.shouldApplyOnServer(server, isIncludeGlobal(), false))
|
||||
.filter(n -> n.shouldApplyOnWorld(finalWorld, true, false))
|
||||
.filter(n -> n.shouldApplyOnWorld(w, true, false))
|
||||
.map(Node::getGroupName)
|
||||
.filter(s -> s.equalsIgnoreCase(group))
|
||||
.findAny().isPresent();
|
||||
.anyMatch(s -> s.equalsIgnoreCase(group));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerAddGroup(String world, @NonNull String player, @NonNull String groupName) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Adding player " + player + " to group: '" + groupName + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Adding player " + player + " to group: '" + groupName + "' on world " + world + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
|
||||
final Group group = plugin.getGroupManager().get(groupName);
|
||||
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> {
|
||||
String w = world;
|
||||
scheduler.execute(() -> {
|
||||
try {
|
||||
if (finalWorld != null && !finalWorld.equals("")) {
|
||||
user.setInheritGroup(group, server, finalWorld);
|
||||
if (w != null && !w.equals("") && !w.equalsIgnoreCase("global")) {
|
||||
user.setInheritGroup(group, server, w);
|
||||
} else {
|
||||
user.setInheritGroup(group, server);
|
||||
}
|
||||
|
||||
save(user);
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
save(user);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerRemoveGroup(String world, @NonNull String player, @NonNull String groupName) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Removing player " + player + " from group: '" + groupName + "' on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Removing player " + player + " from group: '" + groupName + "' on world " + world + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
|
||||
final Group group = plugin.getGroupManager().get(groupName);
|
||||
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> {
|
||||
String w = world;
|
||||
scheduler.execute(() -> {
|
||||
try {
|
||||
if (finalWorld != null && !finalWorld.equals("")) {
|
||||
user.unsetInheritGroup(group, server, finalWorld);
|
||||
if (w != null && !w.equals("") && !w.equalsIgnoreCase("global")) {
|
||||
user.unsetInheritGroup(group, server, w);
|
||||
} else {
|
||||
user.unsetInheritGroup(group, server);
|
||||
}
|
||||
|
||||
save(user);
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
save(user);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getPlayerGroups(String world, @NonNull String player) {
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Getting groups of player: " + player + ", on world " + finalWorld + ", server " + server);
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Getting groups of player: " + player + ", on world " + world + ", server " + server);
|
||||
|
||||
User user = plugin.getUserManager().get(player);
|
||||
User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return new String[0];
|
||||
|
||||
String w = world; // screw effectively final
|
||||
return user.getNodes().stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.filter(n -> n.shouldApplyOnServer(server, isIncludeGlobal(), false))
|
||||
.filter(n -> n.shouldApplyOnWorld(finalWorld, true, false))
|
||||
.filter(n -> n.shouldApplyOnWorld(w, true, false))
|
||||
.map(Node::getGroupName)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryGroup(String world, @NonNull String player) {
|
||||
world = WORLD_CORRECTION_FUNCTION.apply(world);
|
||||
log("Getting primary group of player: " + player);
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
return (user == null) ? null : user.getPrimaryGroup();
|
||||
final User user = plugin.getUserManager().getByUsername(player);
|
||||
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!pgo) {
|
||||
String g = user.getPrimaryGroup();
|
||||
return plugin.getConfiguration().getGroupNameRewrites().getOrDefault(g, g);
|
||||
}
|
||||
|
||||
if (pgoCheckInherited) {
|
||||
PermissionData data = user.getUserData().getPermissionData(createContextForWorld(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
|
||||
String g = user.getPrimaryGroup();
|
||||
return plugin.getConfiguration().getGroupNameRewrites().getOrDefault(g, g);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,17 +24,26 @@ package me.lucko.luckperms.bukkit.vault;
|
||||
|
||||
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
|
||||
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public class VaultScheduler implements Runnable {
|
||||
/**
|
||||
* Sequential executor for Vault modifications
|
||||
*/
|
||||
public class VaultScheduler implements Runnable, Executor {
|
||||
|
||||
private BukkitTask task = null;
|
||||
private final List<Runnable> tasks = new ArrayList<>();
|
||||
|
||||
public VaultScheduler(LPBukkitPlugin plugin) {
|
||||
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this, 1L, 1L);
|
||||
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this, 1L, 1L);
|
||||
}
|
||||
|
||||
public void scheduleTask(Runnable r) {
|
||||
@Override
|
||||
public void execute(Runnable r) {
|
||||
synchronized (tasks) {
|
||||
tasks.add(r);
|
||||
}
|
||||
@@ -42,12 +51,24 @@ public class VaultScheduler implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<Runnable> toRun = new ArrayList<>();
|
||||
List<Runnable> toRun;
|
||||
synchronized (tasks) {
|
||||
if (tasks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
toRun = new ArrayList<>();
|
||||
toRun.addAll(tasks);
|
||||
tasks.clear();
|
||||
}
|
||||
|
||||
toRun.forEach(Runnable::run);
|
||||
}
|
||||
|
||||
public void cancelTask() {
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
task = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -130,8 +148,8 @@ group-name-rewrite:
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL or MongoDB
|
||||
# Currently supported: mysql, postgresql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL, PostgreSQL or MongoDB
|
||||
storage-method: h2
|
||||
|
||||
# This block enables support for split datastores.
|
||||
@@ -145,16 +163,39 @@ split-storage:
|
||||
log: h2
|
||||
|
||||
data:
|
||||
address: localhost:3306
|
||||
# Uses standard DB engine port by default
|
||||
# MySQL: 3306, PostgreSQL: 5432, MongoDB: 27017
|
||||
# Specify as "host:port" if differs
|
||||
address: localhost
|
||||
|
||||
database: minecraft
|
||||
username: root
|
||||
password: ''
|
||||
pool-size: 10 # The size of the MySQL connection pool.
|
||||
|
||||
# The prefix for all LuckPerms tables. Change this is you want to use different tables for different servers.
|
||||
# This should *not* be set to "lp_" if you have previously ran LuckPerms v2.16.81 or earlier with this database.
|
||||
table_prefix: 'luckperms_'
|
||||
|
||||
# Set to -1 to disable. If this is the only instance accessing the datastore, you can disable syncing.
|
||||
# e.g. if you're using sqlite or flatfile, this can be set to -1 to save resources.
|
||||
sync-minutes: 3
|
||||
|
||||
# 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.
|
||||
#
|
||||
# Port 6379 is used by default; set address to "host:port" if differs
|
||||
redis:
|
||||
enabled: false
|
||||
address: localhost
|
||||
password: ''
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,12 +5,18 @@ 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:
|
||||
description: Manage permissions
|
||||
aliases: [perms, permissions, lp, p, perm]
|
||||
aliases: [perms, permissions, lp, 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
-26
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<version>2.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<finalName>LuckPermsBungee-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<finalName>LuckPerms-Bungee-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
@@ -46,28 +46,8 @@
|
||||
<minimizeJar>false</minimizeJar>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.slf4j</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.slf4j</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.zaxxer.hikari</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.hikari</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.mongodb</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.mongodb</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bson</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.bson</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.h2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.h2</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.sqlite</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.sqlite</shadedPattern>
|
||||
<pattern>io.github.mkremins.fanciful</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.fanciful</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
@@ -114,6 +94,13 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- slf4j library -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.9</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
@@ -121,6 +108,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>
|
||||
@@ -23,8 +23,10 @@
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextCalculator;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
@@ -35,6 +37,10 @@ import java.util.Map;
|
||||
public class BackendServerCalculator extends ContextCalculator<ProxiedPlayer> implements Listener {
|
||||
private static final String WORLD_KEY = "world";
|
||||
|
||||
private static String getServer(ProxiedPlayer player) {
|
||||
return player.getServer() == null ? null : (player.getServer().getInfo() == null ? null : player.getServer().getInfo().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableContextSet giveApplicableContext(ProxiedPlayer subject, MutableContextSet accumulator) {
|
||||
String server = getServer(subject);
|
||||
@@ -60,8 +66,4 @@ public class BackendServerCalculator extends ContextCalculator<ProxiedPlayer> im
|
||||
public void onPlayerServerSwitch(ServerSwitchEvent e) {
|
||||
pushUpdate(e.getPlayer(), Maps.immutableEntry("null", "null"), Maps.immutableEntry(WORLD_KEY, getServer(e.getPlayer())));
|
||||
}
|
||||
|
||||
private static String getServer(ProxiedPlayer player) {
|
||||
return player.getServer() == null ? null : (player.getServer().getInfo() == null ? null : player.getServer().getInfo().getName());
|
||||
}
|
||||
}
|
||||
@@ -23,29 +23,33 @@
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.common.calculators.*;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.common.calculators.AbstractCalculatorFactory;
|
||||
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.core.model.User;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BungeeCalculatorFactory implements CalculatorFactory {
|
||||
public class BungeeCalculatorFactory extends AbstractCalculatorFactory {
|
||||
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 registerCalculator(new PermissionCalculator(plugin, user.getName(), processors.build()));
|
||||
}
|
||||
}
|
||||
@@ -24,10 +24,11 @@ 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;
|
||||
import net.md_5.bungee.api.plugin.TabExecutor;
|
||||
@@ -35,25 +36,26 @@ 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()
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
|
||||
);
|
||||
}
|
||||
|
||||
@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,6 +23,7 @@
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import me.lucko.luckperms.common.config.AbstractConfiguration;
|
||||
|
||||
import net.md_5.bungee.config.Configuration;
|
||||
import net.md_5.bungee.config.ConfigurationProvider;
|
||||
import net.md_5.bungee.config.YamlConfiguration;
|
||||
|
||||
@@ -23,12 +23,13 @@
|
||||
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.users.User;
|
||||
import me.lucko.luckperms.common.core.model.User;
|
||||
import me.lucko.luckperms.common.defaults.Rule;
|
||||
import me.lucko.luckperms.common.utils.AbstractListener;
|
||||
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
@@ -38,6 +39,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 +74,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 +86,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 +98,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();
|
||||
if (uuid == null) {
|
||||
String name = plugin.getStorage().getName(c.getUniqueId()).join();
|
||||
if (name == 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,34 +23,29 @@
|
||||
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;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
|
||||
import io.github.mkremins.fanciful.FancyMessage;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
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) {
|
||||
return sender.getName();
|
||||
}
|
||||
return Constants.getConsoleName();
|
||||
return Constants.CONSOLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,7 +53,7 @@ public class BungeeSenderFactory extends SenderFactory<CommandSender> {
|
||||
if (sender instanceof ProxiedPlayer) {
|
||||
return ((ProxiedPlayer) sender).getUniqueId();
|
||||
}
|
||||
return Constants.getConsoleUUID();
|
||||
return Constants.CONSOLE_UUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,6 +61,15 @@ public class BungeeSenderFactory extends SenderFactory<CommandSender> {
|
||||
sender.sendMessage(new TextComponent(s));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendMessage(CommandSender sender, FancyMessage message) {
|
||||
try {
|
||||
sender.sendMessage(ComponentSerializer.parse(message.toJSONString()));
|
||||
} catch (Exception e) {
|
||||
sendMessage(sender, message.toOldMessageFormat());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasPermission(CommandSender sender, String node) {
|
||||
return sender.hasPermission(node);
|
||||
|
||||
@@ -23,69 +23,126 @@
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.ApiHandler;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.api.ApiHandler;
|
||||
import me.lucko.luckperms.common.api.ApiProvider;
|
||||
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.CommandManager;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
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.core.model.User;
|
||||
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.dependencies.DependencyManager;
|
||||
import me.lucko.luckperms.common.managers.GroupManager;
|
||||
import me.lucko.luckperms.common.managers.TrackManager;
|
||||
import me.lucko.luckperms.common.managers.UserManager;
|
||||
import me.lucko.luckperms.common.managers.impl.GenericGroupManager;
|
||||
import me.lucko.luckperms.common.managers.impl.GenericTrackManager;
|
||||
import me.lucko.luckperms.common.managers.impl.GenericUserManager;
|
||||
import me.lucko.luckperms.common.messaging.RedisMessaging;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
import me.lucko.luckperms.common.storage.StorageFactory;
|
||||
import me.lucko.luckperms.common.tracks.TrackManager;
|
||||
import me.lucko.luckperms.common.users.UserManager;
|
||||
import me.lucko.luckperms.common.storage.StorageType;
|
||||
import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
|
||||
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.common.tasks.UpdateTask;
|
||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||
import me.lucko.luckperms.common.utils.DebugHandler;
|
||||
import me.lucko.luckperms.common.utils.LocaleManager;
|
||||
import me.lucko.luckperms.common.utils.LogFactory;
|
||||
import me.lucko.luckperms.common.utils.PermissionCache;
|
||||
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
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.io.InputStream;
|
||||
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 final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
|
||||
private Executor executor;
|
||||
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;
|
||||
private Importer importer;
|
||||
private ConsecutiveExecutor consecutiveExecutor;
|
||||
private LocaleManager localeManager;
|
||||
private CachedStateManager cachedStateManager;
|
||||
private ContextManager<ProxiedPlayer> contextManager;
|
||||
private CalculatorFactory calculatorFactory;
|
||||
private BufferedRequest<Void> updateTaskBuffer;
|
||||
private DebugHandler debugHandler;
|
||||
private BungeeSenderFactory senderFactory;
|
||||
private PermissionCache permissionCache;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
executor = r -> getProxy().getScheduler().runAsync(this, r);
|
||||
log = LogFactory.wrap(getLogger());
|
||||
debugHandler = new DebugHandler(executor, getVersion());
|
||||
senderFactory = new BungeeSenderFactory(this);
|
||||
permissionCache = new PermissionCache(executor);
|
||||
|
||||
getLog().info("Loading configuration...");
|
||||
configuration = new BungeeConfig(this);
|
||||
|
||||
Set<StorageType> storageTypes = StorageFactory.getRequiredTypes(this, StorageType.H2);
|
||||
DependencyManager.loadDependencies(this, storageTypes);
|
||||
|
||||
// register events
|
||||
getProxy().getPluginManager().registerListener(this, new BungeeListener(this));
|
||||
|
||||
// initialise datastore
|
||||
storage = StorageFactory.getInstance(this, StorageType.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,27 +154,23 @@ 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);
|
||||
groupManager = new GroupManager(this);
|
||||
trackManager = new TrackManager();
|
||||
userManager = new GenericUserManager(this);
|
||||
groupManager = new GenericGroupManager(this);
|
||||
trackManager = new GenericTrackManager();
|
||||
importer = new Importer(commandManager);
|
||||
consecutiveExecutor = new ConsecutiveExecutor(commandManager);
|
||||
calculatorFactory = new BungeeCalculatorFactory(this);
|
||||
cachedStateManager = new CachedStateManager(this);
|
||||
|
||||
contextManager = new ContextManager<>();
|
||||
BackendServerCalculator serverCalculator = new BackendServerCalculator();
|
||||
@@ -125,32 +178,23 @@ 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();
|
||||
getProxy().getScheduler().schedule(this, new CacheHousekeepingTask(this), 2L, 2L, TimeUnit.MINUTES);
|
||||
|
||||
getLog().info("Successfully loaded.");
|
||||
}
|
||||
@@ -158,7 +202,12 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
@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();
|
||||
@@ -174,11 +223,48 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
return PlatformType.BUNGEE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerName() {
|
||||
return getProxy().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerVersion() {
|
||||
return getProxy().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getMainDir() {
|
||||
return getDataFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getResourceStream(String path) {
|
||||
return getResourceAsStream(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxiedPlayer getPlayer(User user) {
|
||||
return getProxy().getPlayer(uuidCache.getExternalUUID(user.getUuid()));
|
||||
}
|
||||
|
||||
@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 +286,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
|
||||
@@ -220,7 +305,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
c.addAll(getProxy().getServers().values().stream()
|
||||
.map(ServerInfo::getName)
|
||||
.map(s -> {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
MutableContextSet set = MutableContextSet.create();
|
||||
set.add("server", getConfiguration().getServer());
|
||||
set.add("world", s);
|
||||
return set.makeImmutable();
|
||||
@@ -271,7 +356,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
|
||||
|
||||
+32
-26
@@ -20,20 +20,26 @@
|
||||
* 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.*;
|
||||
|
||||
import net.alpenblock.bungeeperms.BungeePerms;
|
||||
import net.alpenblock.bungeeperms.Group;
|
||||
import net.alpenblock.bungeeperms.Server;
|
||||
import net.alpenblock.bungeeperms.User;
|
||||
import net.alpenblock.bungeeperms.World;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -43,11 +49,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,14 +66,14 @@ 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();
|
||||
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
|
||||
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
|
||||
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(g.getName().toLowerCase());
|
||||
try {
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("create")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -80,7 +86,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission(perm, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set " + perm + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -96,7 +102,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission(perm, true, e.getKey());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set " + perm + " true " + e.getKey())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -112,7 +118,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission(perm, true, e.getKey(), we.getKey());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set " + perm + " true " + e.getKey() + " " + we.getKey())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -129,7 +135,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission("group." + inherit, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("setinherit " + group)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -148,7 +154,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission("prefix.50." + prefix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set prefix.50." + prefix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -163,7 +169,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
group.setPermission("suffix.50." + suffix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(group).action("set suffix.50." + suffix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -173,7 +179,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveGroup(group);
|
||||
plugin.getStorage().saveGroup(group);
|
||||
}
|
||||
|
||||
log.info("BungeePerms Migration: Migrated " + groupCount + " groups");
|
||||
@@ -187,15 +193,15 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
userCount++;
|
||||
|
||||
// Make a LuckPerms user for the one being migrated.
|
||||
plugin.getDatastore().loadUser(u.getUUID(), "null").getUnchecked();
|
||||
me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(u.getUUID());
|
||||
plugin.getStorage().loadUser(u.getUUID(), "null").join();
|
||||
me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().get(u.getUUID());
|
||||
|
||||
// Migrate global perms
|
||||
for (String perm : u.getPerms()) {
|
||||
try {
|
||||
user.setPermission(perm, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set " + perm + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -211,7 +217,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission(perm, true, e.getKey());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set " + perm + " true " + e.getKey())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -227,7 +233,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission(perm, true, e.getKey(), we.getKey());
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set " + perm + " true " + e.getKey() + " " + we.getKey())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -244,7 +250,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("group." + group, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("addgroup " + group)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -263,7 +269,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("prefix.100." + prefix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set prefix.100." + prefix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -278,7 +284,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
try {
|
||||
user.setPermission("suffix.100." + suffix, true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.actor(Constants.CONSOLE_UUID).actorName(Constants.CONSOLE_NAME)
|
||||
.acted(user).action("set suffix.100." + suffix + " true")
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
@@ -288,7 +294,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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -88,8 +90,8 @@ apply-shorthand: true
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL or MongoDB
|
||||
# Currently supported: mysql, postgresql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL, PostgreSQL or MongoDB
|
||||
storage-method: h2
|
||||
|
||||
# This block enables support for split datastores.
|
||||
@@ -103,16 +105,39 @@ split-storage:
|
||||
log: h2
|
||||
|
||||
data:
|
||||
address: localhost:3306
|
||||
# Uses standard DB engine port by default
|
||||
# MySQL: 3306, PostgreSQL: 5432, MongoDB: 27017
|
||||
# Specify as "host:port" if differs
|
||||
address: localhost
|
||||
|
||||
database: minecraft
|
||||
username: root
|
||||
password: ''
|
||||
pool-size: 10 # The size of the MySQL connection pool.
|
||||
|
||||
# The prefix for all LuckPerms tables. Change this is you want to use different tables for different servers.
|
||||
# This should *not* be set to "lp_" if you have previously ran LuckPerms v2.16.81 or earlier with this database.
|
||||
table_prefix: 'luckperms_'
|
||||
|
||||
# Set to -1 to disable. If this is the only instance accessing the datastore, you can disable syncing.
|
||||
# e.g. if you're using sqlite or flatfile, this can be set to -1 to save resources.
|
||||
sync-minutes: 3
|
||||
|
||||
# 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.
|
||||
#
|
||||
# Port 6379 is used by default; set address to "host:port" if differs
|
||||
redis:
|
||||
enabled: false
|
||||
address: localhost
|
||||
password: ''
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+36
-55
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
<version>2.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -30,42 +30,70 @@
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<artifactId>luckperms-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- fanciful -->
|
||||
<dependency>
|
||||
<groupId>io.github.mkremins</groupId>
|
||||
<artifactId>fanciful</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- MySQL -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.40</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- HikariCP -->
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>2.5.1</version>
|
||||
<scope>compile</scope>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Jedis -->
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>2.8.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- SQLite -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.8.11.2</version>
|
||||
<scope>compile</scope>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- H2 -->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.192</version>
|
||||
<scope>compile</scope>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- PostgreSQL -->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>9.4.1212</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<scope>compile</scope>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- slf4j library -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.9</version>
|
||||
<scope>compile</scope>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- SnakeYAML -->
|
||||
<dependency>
|
||||
@@ -95,53 +123,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>
|
||||
@@ -26,71 +26,232 @@ import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.common.api.ApiProvider;
|
||||
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.commands.BaseCommand;
|
||||
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.core.model.User;
|
||||
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.tracks.TrackManager;
|
||||
import me.lucko.luckperms.common.users.UserManager;
|
||||
import me.lucko.luckperms.common.managers.GroupManager;
|
||||
import me.lucko.luckperms.common.managers.TrackManager;
|
||||
import me.lucko.luckperms.common.managers.UserManager;
|
||||
import me.lucko.luckperms.common.messaging.RedisMessaging;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
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.PermissionCache;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
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();
|
||||
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 cached state manager for the platform.
|
||||
*
|
||||
* @return the cached state manager
|
||||
*/
|
||||
CachedStateManager getCachedStateManager();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* Gets the permission caching instance for the platform.
|
||||
*
|
||||
* @return the permission cache instance
|
||||
*/
|
||||
PermissionCache getPermissionCache();
|
||||
|
||||
/**
|
||||
* 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 name or "brand" of the running platform
|
||||
* @return the server brand
|
||||
*/
|
||||
String getServerName();
|
||||
|
||||
/**
|
||||
* Gets the version of the running platform
|
||||
* @return the server version
|
||||
*/
|
||||
String getServerVersion();
|
||||
|
||||
/**
|
||||
* Gets the plugins main directory
|
||||
*
|
||||
* @return the main plugin directory
|
||||
*/
|
||||
File getMainDir();
|
||||
|
||||
/**
|
||||
* Gets the plugins main data storage directory
|
||||
*
|
||||
* @return the platforms data folder
|
||||
*/
|
||||
File getDataFolder();
|
||||
|
||||
/**
|
||||
* Gets a bundled resource file from the jar
|
||||
*
|
||||
* @param path the path of the file
|
||||
* @return the file as an input stream
|
||||
*/
|
||||
InputStream getResourceStream(String path);
|
||||
|
||||
/**
|
||||
* Returns a colored string indicating the status of a player
|
||||
*
|
||||
* @param uuid The player's uuid
|
||||
* @return a formatted status string
|
||||
*/
|
||||
@@ -99,56 +260,97 @@ 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
|
||||
*/
|
||||
int getPlayerCount();
|
||||
|
||||
/**
|
||||
* Gets the usernames of the users online on the platform
|
||||
*
|
||||
* @return a {@link List} of usernames
|
||||
*/
|
||||
List<String> getPlayerList();
|
||||
|
||||
/**
|
||||
* Gets the UUIDs of the users online on the platform
|
||||
*
|
||||
* @return a {@link Set} of UUIDs
|
||||
*/
|
||||
Set<UUID> getOnlinePlayers();
|
||||
|
||||
/**
|
||||
* Checks if a user is online
|
||||
*
|
||||
* @param external the users external uuid
|
||||
* @return true if the user is online
|
||||
*/
|
||||
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();
|
||||
|
||||
/**
|
||||
* Gets a set of Contexts that should be pre-processed in advance
|
||||
*
|
||||
* @param op if the user being processed is op
|
||||
* @return a set of contexts
|
||||
*/
|
||||
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();
|
||||
|
||||
/**
|
||||
* Gets a loaded plugins instance from the platform
|
||||
*
|
||||
* @param name the name of the plugin
|
||||
* @return a plugin instance
|
||||
*/
|
||||
@@ -156,13 +358,15 @@ public interface LuckPermsPlugin {
|
||||
|
||||
/**
|
||||
* Gets a provided service from the platform.
|
||||
*
|
||||
* @param clazz the class of the service
|
||||
* @return the service instance, if it is provided for
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@@ -170,33 +374,33 @@ public interface LuckPermsPlugin {
|
||||
|
||||
/**
|
||||
* Checks if a plugin is loaded on the platform
|
||||
*
|
||||
* @param name the name of the plugin
|
||||
* @return true if the plugin is loaded
|
||||
*/
|
||||
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
|
||||
* Called at the end of the sync task.
|
||||
*/
|
||||
void doAsync(Runnable r);
|
||||
default void onPostUpdate() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a runnable synchronously
|
||||
* @param r the task to run
|
||||
* Called when a users data is refreshed
|
||||
*
|
||||
* @param user the user
|
||||
*/
|
||||
void doSync(Runnable r);
|
||||
default void onUserRefresh(User user) {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
+32
-39
@@ -20,49 +20,42 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.utils;
|
||||
package me.lucko.luckperms.common.api;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import me.lucko.luckperms.LuckPerms;
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
|
||||
public class AbstractFuture<R> implements LPFuture<R> {
|
||||
private final CountDownLatch latch = new CountDownLatch(1);
|
||||
private R value;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public void complete(R r) {
|
||||
value = r;
|
||||
latch.countDown();
|
||||
}
|
||||
public class ApiHandler {
|
||||
private static Method REGISTER;
|
||||
private static Method UNREGISTER;
|
||||
static {
|
||||
try {
|
||||
REGISTER = LuckPerms.class.getDeclaredMethod("registerProvider", LuckPermsApi.class);
|
||||
REGISTER.setAccessible(true);
|
||||
|
||||
@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();
|
||||
UNREGISTER = LuckPerms.class.getDeclaredMethod("unregisterProvider");
|
||||
UNREGISTER.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerProvider(LuckPermsApi luckPermsApi) {
|
||||
try {
|
||||
REGISTER.invoke(null, luckPermsApi);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void unregisterProvider() {
|
||||
try {
|
||||
UNREGISTER.invoke(null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,23 +22,48 @@
|
||||
|
||||
package me.lucko.luckperms.common.api;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.*;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Datastore;
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.LPConfiguration;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
import me.lucko.luckperms.api.MessagingService;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.NodeFactory;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.Storage;
|
||||
import me.lucko.luckperms.api.Track;
|
||||
import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.api.UuidCache;
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.IContextCalculator;
|
||||
import me.lucko.luckperms.api.event.LPEvent;
|
||||
import me.lucko.luckperms.api.event.LPListener;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.users.UserIdentifier;
|
||||
import me.lucko.luckperms.common.api.delegate.DatastoreDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.GroupDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.LPConfigurationDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.NodeFactoryDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.StorageDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.TrackDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.UserDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.UuidCacheDelegate;
|
||||
import me.lucko.luckperms.common.core.NodeBuilder;
|
||||
import me.lucko.luckperms.common.core.UserIdentifier;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkNode;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkNode;
|
||||
|
||||
/**
|
||||
* Implements the LuckPerms API using the plugin instance
|
||||
@@ -69,7 +94,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public double getApiVersion() {
|
||||
return 2.13;
|
||||
return 2.17;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,17 +119,28 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public LPConfiguration getConfiguration() {
|
||||
return new me.lucko.luckperms.common.api.internal.LPConfigurationLink(plugin.getConfiguration());
|
||||
return new LPConfigurationDelegate(plugin.getConfiguration());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Storage getStorage() {
|
||||
return new StorageDelegate(plugin, plugin.getStorage());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public Datastore getDatastore() {
|
||||
return new me.lucko.luckperms.common.api.internal.DatastoreLink(plugin, plugin.getDatastore());
|
||||
return new DatastoreDelegate(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 UuidCacheDelegate(plugin.getUuidCache());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -114,12 +150,8 @@ 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);
|
||||
final me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().get(uuid);
|
||||
return user == null ? null : new UserDelegate(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,12 +161,8 @@ 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);
|
||||
final me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().getByUsername(name);
|
||||
return user == null ? null : new UserDelegate(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,7 +172,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(UserDelegate::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,18 +182,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());
|
||||
ApiUtils.checkUser(user);
|
||||
plugin.getUserManager().cleanup(((UserDelegate) 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);
|
||||
final me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(name);
|
||||
return group == null ? null : new GroupDelegate(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -175,7 +199,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(GroupDelegate::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -185,12 +209,8 @@ 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);
|
||||
final me.lucko.luckperms.common.core.model.Track track = plugin.getTrackManager().getIfLoaded(name);
|
||||
return track == null ? null : new TrackDelegate(track);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -200,7 +220,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(TrackDelegate::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -208,9 +228,14 @@ public class ApiProvider implements LuckPermsApi {
|
||||
return plugin.getTrackManager().isLoaded(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeFactory getNodeFactory() {
|
||||
return NodeFactoryDelegate.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node.Builder buildNode(@NonNull String permission) throws IllegalArgumentException {
|
||||
return new me.lucko.luckperms.common.core.Node.Builder(checkNode(permission));
|
||||
return new NodeBuilder(checkNode(permission));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -224,4 +249,16 @@ public class ApiProvider implements LuckPermsApi {
|
||||
public void registerContextListener(ContextListener<?> contextListener) {
|
||||
plugin.getContextManager().registerListener(contextListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Contexts> getContextForUser(User user) {
|
||||
ApiUtils.checkUser(user);
|
||||
return Optional.ofNullable(plugin.getContextForUser(((UserDelegate) user).getMaster()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ContextSet getContextForPlayer(Object player) {
|
||||
return plugin.getContextManager().getApplicableContext(player);
|
||||
}
|
||||
}
|
||||
+28
-28
@@ -20,69 +20,69 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.Track;
|
||||
import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.common.api.delegate.GroupDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.TrackDelegate;
|
||||
import me.lucko.luckperms.common.api.delegate.UserDelegate;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
|
||||
@UtilityClass
|
||||
public class Utils {
|
||||
public class ApiUtils {
|
||||
|
||||
public static void checkUser(User user) {
|
||||
if (!(user instanceof UserLink)) {
|
||||
throw new IllegalStateException("User instance cannot be handled by this implementation.");
|
||||
}
|
||||
Preconditions.checkState(user instanceof UserDelegate, "User instance cannot be handled by this implementation.");
|
||||
}
|
||||
|
||||
public static void checkGroup(Group group) {
|
||||
if (!(group instanceof GroupLink)) {
|
||||
throw new IllegalStateException("Group instance cannot be handled by this implementation.");
|
||||
}
|
||||
Preconditions.checkState(group instanceof GroupDelegate, "Group instance cannot be handled by this implementation.");
|
||||
}
|
||||
|
||||
public static void checkTrack(Track track) {
|
||||
if (!(track instanceof TrackLink)) {
|
||||
throw new IllegalStateException("Track instance cannot be handled by this implementation.");
|
||||
}
|
||||
Preconditions.checkState(track instanceof TrackDelegate, "Track instance cannot be handled by this implementation.");
|
||||
}
|
||||
|
||||
public static String checkUsername(String s) {
|
||||
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;
|
||||
}
|
||||
|
||||
+87
-83
@@ -20,33 +20,41 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api.delegate;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.*;
|
||||
|
||||
import me.lucko.luckperms.api.Datastore;
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.Log;
|
||||
import me.lucko.luckperms.api.LogEntry;
|
||||
import me.lucko.luckperms.api.Track;
|
||||
import me.lucko.luckperms.api.User;
|
||||
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.*;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkName;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkTrack;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkUser;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkUsername;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Datastore} and {@link me.lucko.luckperms.common.storage.Datastore}
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class DatastoreLink implements Datastore {
|
||||
@SuppressWarnings("deprecation")
|
||||
public class DatastoreDelegate 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 DatastoreDelegate(@NonNull LuckPermsPlugin plugin, @NonNull Storage master) {
|
||||
this.plugin = plugin;
|
||||
this.master = master;
|
||||
this.async = new Async(master);
|
||||
@@ -54,12 +62,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 +95,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 LogDelegate(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(((UserDelegate) 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(((GroupDelegate) group).getMaster()), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -159,115 +165,115 @@ 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(((GroupDelegate) 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(((TrackDelegate) 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(((TrackDelegate) 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;
|
||||
}
|
||||
return new LogLink(log);
|
||||
return new LogDelegate(log);
|
||||
}
|
||||
|
||||
@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(((UserDelegate) 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(((GroupDelegate) group).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -276,113 +282,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(((GroupDelegate) 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(((TrackDelegate) track).getMaster()).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteTrack(@NonNull Track track) {
|
||||
checkTrack(track);
|
||||
return master.deleteTrack(((TrackLink) track).getMaster()).getUnchecked();
|
||||
return master.force().deleteTrack(((TrackDelegate) 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 LogDelegate(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(((UserDelegate) 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(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -391,44 +395,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(((GroupDelegate) 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(((TrackDelegate) 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(((TrackDelegate) 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));
|
||||
}
|
||||
}
|
||||
|
||||
+30
-22
@@ -20,34 +20,37 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
package me.lucko.luckperms.common.api.delegate;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.*;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkServer;
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkTime;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Group} and {@link me.lucko.luckperms.common.groups.Group}
|
||||
* Provides a link between {@link Group} and {@link me.lucko.luckperms.common.core.model.Group}
|
||||
*/
|
||||
@EqualsAndHashCode(of = {"name"}, callSuper = false)
|
||||
@SuppressWarnings("unused")
|
||||
public class GroupLink extends PermissionHolderLink implements Group {
|
||||
public class GroupDelegate extends PermissionHolderDelegate implements Group {
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final me.lucko.luckperms.common.groups.Group master;
|
||||
private final me.lucko.luckperms.common.core.model.Group master;
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
public GroupLink(@NonNull me.lucko.luckperms.common.groups.Group master) {
|
||||
public GroupDelegate(@NonNull me.lucko.luckperms.common.core.model.Group master) {
|
||||
super(master);
|
||||
this.master = master;
|
||||
this.name = master.getName();
|
||||
@@ -56,91 +59,91 @@ public class GroupLink extends PermissionHolderLink implements Group {
|
||||
@Override
|
||||
public boolean inheritsGroup(@NonNull Group group) {
|
||||
checkGroup(group);
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster());
|
||||
return master.inheritsGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inheritsGroup(@NonNull Group group, @NonNull String server) {
|
||||
checkGroup(group);
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster(), server);
|
||||
return master.inheritsGroup(((GroupDelegate) group).getMaster(), server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inheritsGroup(@NonNull Group group, @NonNull String server, @NonNull String world) {
|
||||
checkGroup(group);
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster(), server, world);
|
||||
return master.inheritsGroup(((GroupDelegate) group).getMaster(), server, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster());
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group, @NonNull String server) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world);
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world, checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world, checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster());
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), temporary);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group, @NonNull String server) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server));
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), temporary);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world, temporary);
|
||||
master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world, temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,6 +161,11 @@ public class GroupLink extends PermissionHolderLink implements Group {
|
||||
return master.getLocalGroups(checkServer(server), world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt getWeight() {
|
||||
return master.getWeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLocalGroups(@NonNull String server) {
|
||||
return master.getLocalGroups(checkServer(server));
|
||||
Loaded 100 of 385 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user