Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
383276f47a | ||
|
|
33c78e4a17 | ||
|
|
55a0de7899 | ||
|
|
6b3aab66bf | ||
|
|
77e70ef8d3 | ||
|
|
9b92143501 | ||
|
|
87f94f6b8f | ||
|
|
5d955e77b6 | ||
|
|
270a276b98 | ||
|
|
be7d914e39 | ||
|
|
37fc00cce8 | ||
|
|
0d515abadb | ||
|
|
daef01194e | ||
|
|
258bf1cc41 | ||
|
|
ce3d7829d7 | ||
|
|
c66a01c1a6 | ||
|
|
d113a92ce5 | ||
|
|
7b655d12df | ||
|
|
a4c872f1e8 | ||
|
|
0e7d9bf9c1 | ||
|
|
6252a5bc75 | ||
|
|
e4e80c9c31 | ||
|
|
165c5610c3 | ||
|
|
13fbc7dd39 | ||
|
|
02a75fc32a | ||
|
|
699c4d107b | ||
|
|
e4810302e1 | ||
|
|
73f10cad66 | ||
|
|
f1d670dc46 | ||
|
|
045539c752 | ||
|
|
782c09b686 | ||
|
|
6109718c67 | ||
|
|
cd758d7e48 | ||
|
|
fcb0fcadeb | ||
|
|
26fb506560 | ||
|
|
b6c4239322 | ||
|
|
74f9283f18 | ||
|
|
60e6ae6e23 | ||
|
|
83d9229295 | ||
|
|
e079b0f3ed | ||
|
|
d433a5461d | ||
|
|
2c43f6bf21 | ||
|
|
ac57509a29 | ||
|
|
c5ce655cf6 | ||
|
|
9fe05efb4e | ||
|
|
dcf207f5e5 | ||
|
|
11facab71c | ||
|
|
5b4975f34c | ||
|
|
069e535f1a | ||
|
|
1eb053447e | ||
|
|
93c7c06b2d | ||
|
|
b0085bc1e1 | ||
|
|
9133951446 | ||
|
|
7853d4686a | ||
|
|
ed5892eb56 | ||
|
|
687804de2c | ||
|
|
9d166041ab | ||
|
|
924041bff4 | ||
|
|
e9216d3e0f | ||
|
|
db8f1bca66 |
No files matched your search
@@ -14,13 +14,16 @@ LuckPerms is an advanced permissions implementation aiming to be a flexible, per
|
||||
* [Sponge Plugin Page](https://forums.spongepowered.org/t/luckperms-an-advanced-permissions-system/14274 "Sponge Plugin Page")
|
||||
|
||||
## LuckPerms vs Other Plugins
|
||||
### Bukkit
|
||||

|
||||
_Features checked on 23rd Aug 2016. If you find any inaccuracies, please do let me know. I tried to be as fair as possible, and copy all major features from the respective plugin pages._
|
||||
|
||||
### 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
|
||||
See LICENSE.md.
|
||||
LuckPerms is licensed under the permissive MIT license. See LICENSE.md for more info.
|
||||
|
||||
## Thanks to:
|
||||
[](http://www.ej-technologies.com/products/jprofiler/overview.html)
|
||||
|
||||
Thanks to ej-technologies for granting LuckPerms an open source licence to their [java profiling software](http://www.ej-technologies.com/products/jprofiler/overview.html "Java Profiler").
|
||||
Thanks to ej-technologies for granting LuckPerms an open source licence to their [Java Profiling Software](http://www.ej-technologies.com/products/jprofiler/overview.html "Java Profiler").
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.11-SNAPSHOT</version>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -22,9 +22,8 @@
|
||||
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -41,32 +40,61 @@ public class Contexts {
|
||||
* @return a context that will not apply any filters
|
||||
*/
|
||||
public static Contexts allowAll() {
|
||||
return new Contexts(Collections.emptyMap(), true, true, true, true, true);
|
||||
return new Contexts(ContextSet.empty(), true, true, true, true, true, true);
|
||||
}
|
||||
|
||||
public static Contexts of(Map<String, String> context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups) {
|
||||
return new Contexts(context, includeGlobal, includeGlobalWorld, applyGroups, applyGlobalGroups, applyGlobalWorldGroups);
|
||||
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(Map<String, String> context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, 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 = ImmutableMap.copyOf(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) {
|
||||
return new Contexts(context, includeGlobal, includeGlobalWorld, applyGroups, applyGlobalGroups, applyGlobalWorldGroups);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public static Contexts of(Map<String, String> context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
|
||||
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.
|
||||
*/
|
||||
private final Map<String, String> context;
|
||||
private final ContextSet context;
|
||||
|
||||
/**
|
||||
* The mode to parse defaults on Bukkit
|
||||
* @since 2.12
|
||||
*/
|
||||
private final boolean op;
|
||||
|
||||
/**
|
||||
* If global or non server specific nodes should be applied
|
||||
@@ -95,12 +123,31 @@ public class Contexts {
|
||||
|
||||
/**
|
||||
* Gets the contexts that apply for this lookup
|
||||
* @return an immutable map of context key value pairs
|
||||
* @return an immutable set of context key value pairs
|
||||
* @since 2.13
|
||||
*/
|
||||
public Map<String, String> getContext() {
|
||||
public ContextSet getContexts() {
|
||||
return this.context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the contexts that apply for this lookup
|
||||
* @return an immutable map of context key value pairs
|
||||
* @deprecated in favour of {@link #getContexts()}
|
||||
*/
|
||||
@Deprecated
|
||||
public Map<String, String> getContext() {
|
||||
return this.context.toMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if OP defaults should be included
|
||||
* @return true if op defaults should be included
|
||||
*/
|
||||
public boolean isOp() {
|
||||
return this.op;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if global or non server specific nodes should be applied
|
||||
* @return true if global or non server specific nodes should be applied
|
||||
@@ -143,7 +190,8 @@ public class Contexts {
|
||||
|
||||
public String toString() {
|
||||
return "Contexts(" +
|
||||
"context=" + this.getContext() + ", " +
|
||||
"context=" + this.getContexts() + ", " +
|
||||
"op=" + this.isOp() + ", " +
|
||||
"includeGlobal=" + this.isIncludeGlobal() + ", " +
|
||||
"includeGlobalWorld=" + this.isIncludeGlobalWorld() + ", " +
|
||||
"applyGroups=" + this.isApplyGroups() + ", " +
|
||||
@@ -152,4 +200,49 @@ public class Contexts {
|
||||
")";
|
||||
}
|
||||
|
||||
/*
|
||||
* Ugly auto-generated lombok code
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check for equality
|
||||
* @param o the other
|
||||
* @return true if equal
|
||||
* @since 2.12
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof Contexts)) return false;
|
||||
final Contexts other = (Contexts) o;
|
||||
final Object this$context = this.getContexts();
|
||||
final Object other$context = other.getContexts();
|
||||
if (this$context == null ? other$context != null : !this$context.equals(other$context)) return false;
|
||||
if (this.isOp() != other.isOp()) return false;
|
||||
if (this.isIncludeGlobal() != other.isIncludeGlobal()) return false;
|
||||
if (this.isIncludeGlobalWorld() != other.isIncludeGlobalWorld()) return false;
|
||||
if (this.isApplyGroups() != other.isApplyGroups()) return false;
|
||||
if (this.isApplyGlobalGroups() != other.isApplyGlobalGroups()) return false;
|
||||
if (this.isApplyGlobalWorldGroups() != other.isApplyGlobalWorldGroups()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hashcode
|
||||
* @return the hashcode
|
||||
* @since 2.12
|
||||
*/
|
||||
public int hashCode() {
|
||||
final int PRIME = 59;
|
||||
int result = 1;
|
||||
final Object $context = this.getContexts();
|
||||
result = result * PRIME + ($context == null ? 43 : $context.hashCode());
|
||||
result = result * PRIME + (this.isOp() ? 79 : 97);
|
||||
result = result * PRIME + (this.isIncludeGlobal() ? 79 : 97);
|
||||
result = result * PRIME + (this.isIncludeGlobalWorld() ? 79 : 97);
|
||||
result = result * PRIME + (this.isApplyGroups() ? 79 : 97);
|
||||
result = result * PRIME + (this.isApplyGlobalGroups() ? 79 : 97);
|
||||
result = result * PRIME + (this.isApplyGlobalWorldGroups() ? 79 : 97);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -258,7 +258,7 @@ public class MetaUtils {
|
||||
|
||||
int priority = Integer.MIN_VALUE;
|
||||
String meta = null;
|
||||
for (Node n : holder.getAllNodes()) {
|
||||
for (Node n : holder.getAllNodes(Contexts.allowAll())) {
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -22,10 +22,9 @@
|
||||
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Represents an immutable node object
|
||||
@@ -109,15 +108,40 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
* @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
|
||||
*/
|
||||
boolean shouldApplyWithContext(Map<String, String> context, boolean worldAndServer);
|
||||
boolean shouldApplyWithContext(ContextSet context, boolean worldAndServer);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
boolean shouldApplyWithContext(Map<String, String> context);
|
||||
boolean shouldApplyWithContext(ContextSet context);
|
||||
|
||||
/**
|
||||
* If this node should apply in the given context
|
||||
* @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)}
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean shouldApplyWithContext(Map<String, String> context, boolean worldAndServer) {
|
||||
return shouldApplyWithContext(ContextSet.fromMap(context), worldAndServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean shouldApplyWithContext(Map<String, String> context) {
|
||||
return shouldApplyWithContext(ContextSet.fromMap(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link #shouldApplyOnServer(String, boolean, boolean)}, except this method accepts a List
|
||||
@@ -186,8 +210,18 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* @return the extra contexts required for this node to apply
|
||||
* @deprecated in favour of {@link #getContexts()}
|
||||
*/
|
||||
Map<String, String> getExtraContexts();
|
||||
@Deprecated
|
||||
default Map<String, String> getExtraContexts() {
|
||||
return getContexts().toMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the extra contexts required for this node to apply
|
||||
* @since 2.13
|
||||
*/
|
||||
ContextSet getContexts();
|
||||
|
||||
/**
|
||||
* Converts this node into a serialized form
|
||||
@@ -302,7 +336,9 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,12 @@
|
||||
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
import me.lucko.luckperms.api.caching.UserData;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@@ -64,6 +66,13 @@ public interface User extends PermissionHolder {
|
||||
*/
|
||||
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();
|
||||
|
||||
/**
|
||||
* Check to see if the user is a member of a group
|
||||
* @param group The group to check membership of
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.caching;
|
||||
|
||||
import java.util.Map;
|
||||
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.
|
||||
* @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.
|
||||
* @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();
|
||||
|
||||
}
|
||||
+24
-26
@@ -20,38 +20,36 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.internal;
|
||||
package me.lucko.luckperms.api.caching;
|
||||
|
||||
import me.lucko.luckperms.config.AbstractConfiguration;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class StandaloneConfiguration extends AbstractConfiguration<StandaloneBase> {
|
||||
public StandaloneConfiguration(StandaloneBase plugin) {
|
||||
super(plugin, "global", true, "null");
|
||||
}
|
||||
/**
|
||||
* Holds cached Permission lookup data for a specific set of contexts
|
||||
* @since 2.13
|
||||
*/
|
||||
public interface PermissionData {
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
}
|
||||
/**
|
||||
* Gets a permission value for the given permission node
|
||||
* @param permission the permission node
|
||||
* @return a tristate result
|
||||
* @throws NullPointerException if permission is null
|
||||
*/
|
||||
Tristate getPermissionValue(String permission);
|
||||
|
||||
@Override
|
||||
protected String getString(String path, String def) {
|
||||
return def;
|
||||
}
|
||||
/**
|
||||
* Invalidates the underlying permission calculator cache.
|
||||
* Can be called to allow for an update in defaults.
|
||||
*/
|
||||
void invalidateCache();
|
||||
|
||||
@Override
|
||||
protected int getInt(String path, int def) {
|
||||
return def;
|
||||
}
|
||||
/**
|
||||
* Gets an immutable copy of the permission map backing the permission calculator
|
||||
* @return an immutable set of permissions
|
||||
*/
|
||||
Map<String, Boolean> getImmutableBacking();
|
||||
|
||||
@Override
|
||||
protected boolean getBoolean(String path, boolean def) {
|
||||
return def;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, String> getMap(String path, Map<String, String> def) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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.caching;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
|
||||
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
|
||||
* default data provided by the platform. This calls are heavily cached and are therefore fast.
|
||||
*
|
||||
* @since 2.13
|
||||
*/
|
||||
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.
|
||||
* @param contexts the contexts to get the permission data in
|
||||
* @return a permission data instance
|
||||
* @throws NullPointerException if contexts is null
|
||||
*/
|
||||
PermissionData getPermissionData(Contexts contexts);
|
||||
|
||||
/**
|
||||
* Gets MetaData from the cache, given a specified context.
|
||||
* 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
|
||||
*/
|
||||
MetaData getMetaData(Contexts contexts);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
PermissionData calculatePermissions(Contexts contexts);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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.
|
||||
* @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.
|
||||
* @param contexts the contexts to recalculate in.
|
||||
* @throws NullPointerException if contexts is null
|
||||
*/
|
||||
void recalculateMeta(Contexts contexts);
|
||||
|
||||
/**
|
||||
* Calls {@link #recalculatePermissions(Contexts)} for all current loaded contexts
|
||||
*/
|
||||
void recalculatePermissions();
|
||||
|
||||
/**
|
||||
* Calls {@link #recalculateMeta(Contexts)} for all current loaded contexts
|
||||
*/
|
||||
void recalculateMeta();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param contexts the contexts to pre-calculate for
|
||||
* @throws NullPointerException if contexts is null
|
||||
*/
|
||||
void preCalculate(Contexts contexts);
|
||||
|
||||
/**
|
||||
* Invalidates all of the underlying Permission calculators.
|
||||
* Can be called to allow for an update in defaults.
|
||||
*/
|
||||
void invalidatePermissionCalculators();
|
||||
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* A simple implementation of the listener aspects of {@link IContextCalculator<T>}
|
||||
* A simple implementation of the listener aspects of {@link IContextCalculator}
|
||||
* @param <T> the subject type
|
||||
*/
|
||||
public abstract class ContextCalculator<T> implements IContextCalculator<T> {
|
||||
|
||||
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
* 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.ImmutableSet;
|
||||
|
||||
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.
|
||||
*
|
||||
* @since 2.13
|
||||
*/
|
||||
public class ContextSet {
|
||||
|
||||
/**
|
||||
* Make a singleton ContextSet from a context pair
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
* @return a new ContextSet 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ContextSet from an existing map
|
||||
* @param map the map to copy from
|
||||
* @return a new ContextSet 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ContextSet from an existing iterable of Map Entries
|
||||
* @param iterable the iterable to copy from
|
||||
* @return a new ContextSet 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ContextSet 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
|
||||
* @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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new empty ContextSet.
|
||||
* @return a new ContextSet
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this set is in an immutable form
|
||||
* @return true if the set is immutable
|
||||
*/
|
||||
public boolean isImmutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this ContextSet to an immutable {@link Map}
|
||||
*
|
||||
* <b>NOTE: Use of this method may result in data being lost. ContextSets can contain lots of different values for
|
||||
* one key.</b>
|
||||
*
|
||||
* @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)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if thr set contains a given key mapped to a given value
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #has(String, String)}, except ignores the case of the value.
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the set is empty
|
||||
* @return true if the set is empty
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
synchronized (contexts) {
|
||||
return contexts.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();
|
||||
}
|
||||
}
|
||||
|
||||
@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,6 +22,7 @@
|
||||
|
||||
package me.lucko.luckperms.api.context;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -34,11 +35,40 @@ public interface IContextCalculator<T> {
|
||||
|
||||
/**
|
||||
* Gives the subject all of the applicable contexts they meet
|
||||
* @param subject the subject to add contexts tp
|
||||
* @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.
|
||||
*/
|
||||
Map<String, String> giveApplicableContext(T subject, Map<String, String> accumulator);
|
||||
@Deprecated
|
||||
default Map<String, String> giveApplicableContext(T subject, Map<String, String> accumulator) {
|
||||
MutableContextSet acc = new MutableContextSet();
|
||||
giveApplicableContext(subject, acc);
|
||||
|
||||
accumulator.putAll(acc.toMap());
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the subject all of the applicable contexts they meet
|
||||
*
|
||||
* <p><b>You MUST implement this method. The default is only provided for backwards compatibility with
|
||||
* {@link #giveApplicableContext(Object, Map)}.</b>
|
||||
*
|
||||
* @param subject the subject to add contexts to
|
||||
* @param accumulator a map of contexts to add to
|
||||
* @return the map
|
||||
* @since 2.13
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
default MutableContextSet giveApplicableContext(T subject, MutableContextSet accumulator) {
|
||||
Map<String, String> acc = new HashMap<>();
|
||||
giveApplicableContext(subject, acc);
|
||||
|
||||
accumulator.addAll(acc.entrySet());
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a context is applicable to a subject
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* 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.Maps;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Holds contexts
|
||||
* All contained contexts are immutable, but contexts can be added or removed from the set.
|
||||
*
|
||||
* @since 2.13
|
||||
*/
|
||||
public class MutableContextSet extends ContextSet {
|
||||
|
||||
/**
|
||||
* Make a singleton MutableContextSet from a context pair
|
||||
* @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) {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.add(key, value);
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.addAll(map);
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.addAll(iterable);
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.addAll(contextSet.toSet());
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new empty MutableContextSet.
|
||||
* @return a new MutableContextSet
|
||||
*/
|
||||
public static MutableContextSet empty() {
|
||||
return new MutableContextSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImmutable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextSet makeImmutable() {
|
||||
return immutableCopy();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new key value pair to the set
|
||||
* @param key the key to add
|
||||
* @param value the value to add
|
||||
* @throws NullPointerException if the key or value is null
|
||||
*/
|
||||
public void add(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
contexts.add(Maps.immutableEntry(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new key value pair to the set
|
||||
* @param entry the entry to add
|
||||
* @throws NullPointerException if the entry is null
|
||||
*/
|
||||
public void add(Map.Entry<String, String> entry) {
|
||||
if (entry == null) {
|
||||
throw new NullPointerException("context");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
contexts.add(Maps.immutableEntry(entry.getKey(), 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) {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the entry set of a map to the set
|
||||
* @param map the map to add from
|
||||
* @throws NullPointerException if the map is null
|
||||
*/
|
||||
public void addAll(Map<String, String> map) {
|
||||
if (map == null) {
|
||||
throw new NullPointerException("contexts");
|
||||
}
|
||||
addAll(map.entrySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public void addAll(ContextSet contextSet) {
|
||||
if (contextSet == null) {
|
||||
throw new NullPointerException("contextSet");
|
||||
}
|
||||
|
||||
synchronized (this.contexts) {
|
||||
this.contexts.addAll(contextSet.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a key value pair from this set
|
||||
* @param key the key to remove
|
||||
* @param value the value to remove (case sensitive)
|
||||
* @throws NullPointerException if the key or value is null
|
||||
*/
|
||||
public void remove(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
contexts.removeIf(e -> e.getKey().equalsIgnoreCase(key) && e.getValue().equals(value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #remove(String, String)}, except ignores the case of the value
|
||||
* @param key the key to remove
|
||||
* @param value the value to remove
|
||||
* @throws NullPointerException if the key or value is null
|
||||
*/
|
||||
public void removeIgnoreCase(String key, String value) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
contexts.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
|
||||
*/
|
||||
public void removeAll(String key) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
|
||||
synchronized (contexts) {
|
||||
contexts.removeIf(e -> e.getKey().equalsIgnoreCase(key));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the set
|
||||
*/
|
||||
public void clear() {
|
||||
synchronized (contexts) {
|
||||
contexts.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.11-SNAPSHOT</version>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -67,6 +67,14 @@
|
||||
<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>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.google.gson</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.gson</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.11-SNAPSHOT</version>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.11-SNAPSHOT</version>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.vault.cache;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.vault.VaultPermissionHook;
|
||||
import me.lucko.luckperms.users.User;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class VaultUser {
|
||||
private final LPBukkitPlugin plugin;
|
||||
private final VaultPermissionHook vault;
|
||||
|
||||
@Getter
|
||||
private final User user;
|
||||
|
||||
@Getter
|
||||
private final Map<Map<String, String>, ContextCache> contextData = new ConcurrentHashMap<>();
|
||||
|
||||
@Getter
|
||||
private final Map<Map<String, String>, ChatCache> chatData = new ConcurrentHashMap<>();
|
||||
|
||||
public boolean hasPermission(Map<String, String> context, String permission) {
|
||||
ContextCache cd = contextData.computeIfAbsent(context, map -> calculatePermissions(map, false));
|
||||
return cd.getPermissionValue(permission).asBoolean();
|
||||
}
|
||||
|
||||
public ChatCache processChatData(Map<String, String> context) {
|
||||
return chatData.computeIfAbsent(context, map -> calculateChat(map, false));
|
||||
}
|
||||
|
||||
public ContextCache calculatePermissions(Map<String, String> context, boolean apply) {
|
||||
Map<String, Boolean> toApply = user.exportNodes(
|
||||
new Contexts(context, vault.isIncludeGlobal(), true, true, true, true),
|
||||
Collections.emptyList(),
|
||||
true
|
||||
);
|
||||
|
||||
ContextCache existing = contextData.get(context);
|
||||
if (existing == null) {
|
||||
existing = new ContextCache(user, context, plugin, plugin.getDefaultsProvider());
|
||||
if (apply) {
|
||||
contextData.put(context, existing);
|
||||
}
|
||||
}
|
||||
|
||||
boolean different = false;
|
||||
if (toApply.size() != existing.getPermissionCache().size()) {
|
||||
different = true;
|
||||
} else {
|
||||
for (Map.Entry<String, Boolean> e : existing.getPermissionCache().entrySet()) {
|
||||
if (toApply.containsKey(e.getKey()) && toApply.get(e.getKey()) == e.getValue()) {
|
||||
continue;
|
||||
}
|
||||
different = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!different) return existing;
|
||||
|
||||
existing.getPermissionCache().clear();
|
||||
existing.invalidateCache();
|
||||
existing.getPermissionCache().putAll(toApply);
|
||||
return existing;
|
||||
}
|
||||
|
||||
public ChatCache calculateChat(Map<String, String> context, boolean apply) {
|
||||
ChatCache existing = chatData.get(context);
|
||||
if (existing == null) {
|
||||
existing = new ChatCache(context);
|
||||
if (apply) {
|
||||
chatData.put(context, existing);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> contexts = new HashMap<>(context);
|
||||
String server = contexts.get("server");
|
||||
String world = contexts.get("world");
|
||||
contexts.remove("server");
|
||||
contexts.remove("world");
|
||||
|
||||
existing.invalidateCache();
|
||||
|
||||
// Load meta
|
||||
for (Node n : user.getPermissions(true)) {
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.isMeta()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnServer(server, vault.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyWithContext(contexts, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map.Entry<String, String> meta = n.getMeta();
|
||||
existing.getMeta().put(meta.getKey(), meta.getValue());
|
||||
}
|
||||
|
||||
// Load prefixes & suffixes
|
||||
|
||||
int prefixPriority = Integer.MIN_VALUE;
|
||||
int suffixPriority = Integer.MIN_VALUE;
|
||||
|
||||
for (Node n : user.getAllNodes(null, new Contexts(context, vault.isIncludeGlobal(), true, true, true, true))) {
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.isPrefix() && !n.isSuffix()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnServer(server, vault.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, true, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyWithContext(contexts, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n.isPrefix()) {
|
||||
Map.Entry<Integer, String> value = n.getPrefix();
|
||||
if (value.getKey() > prefixPriority) {
|
||||
existing.setPrefix(value.getValue());
|
||||
}
|
||||
} else {
|
||||
Map.Entry<Integer, String> value = n.getSuffix();
|
||||
if (value.getKey() > suffixPriority) {
|
||||
existing.setSuffix(value.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.vault.cache;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.api.vault.VaultPermissionHook;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class VaultUserManager {
|
||||
private final LPBukkitPlugin plugin;
|
||||
private final VaultPermissionHook vault;
|
||||
private final Map<UUID, VaultUser> userCache = new ConcurrentHashMap<>();
|
||||
|
||||
public void setupUser(User user) {
|
||||
VaultUser vaultUser = userCache.computeIfAbsent(user.getUuid(), uuid -> new VaultUser(plugin, vault, user));
|
||||
vaultUser.calculatePermissions(Collections.singletonMap("server", vault.getServer()), true);
|
||||
vaultUser.calculateChat(Collections.singletonMap("server", vault.getServer()), true);
|
||||
for (World world : plugin.getServer().getWorlds()) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
context.put("server", vault.getServer());
|
||||
context.put("world", world.getName());
|
||||
vaultUser.calculatePermissions(context, true);
|
||||
vaultUser.calculateChat(context, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearUser(UUID uuid) {
|
||||
userCache.remove(uuid);
|
||||
}
|
||||
|
||||
public boolean containsUser(UUID uuid) {
|
||||
return userCache.containsKey(uuid);
|
||||
}
|
||||
|
||||
public VaultUser getUser(UUID uuid) {
|
||||
return userCache.get(uuid);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.bukkit.calculators.AttachmentProcessor;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BukkitCalculatorFactory implements CalculatorFactory {
|
||||
private final LPBukkitPlugin plugin;
|
||||
|
||||
@Override
|
||||
public PermissionCalculator build(Contexts contexts, User user, Map<String, Boolean> map) {
|
||||
UUID uuid = plugin.getUuidCache().getExternalUUID(user.getUuid());
|
||||
|
||||
List<PermissionProcessor> processors = new ArrayList<>(5);
|
||||
processors.add(new MapProcessor(map));
|
||||
processors.add(new AttachmentProcessor(() -> {
|
||||
LPPermissible permissible = Injector.getPermissible(uuid);
|
||||
return permissible == null ? null : permissible.getAttachmentPermissions();
|
||||
}));
|
||||
if (plugin.getConfiguration().isApplyingWildcards()) {
|
||||
processors.add(new WildcardProcessor(map));
|
||||
}
|
||||
if (plugin.getConfiguration().isApplyingRegex()) {
|
||||
processors.add(new RegexProcessor(map));
|
||||
}
|
||||
processors.add(new DefaultsProcessor(contexts.isOp(), plugin.getDefaultsProvider()));
|
||||
|
||||
return new PermissionCalculator(plugin, user.getName(), plugin.getConfiguration().isDebugPermissionChecks(), processors);
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -20,14 +20,15 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
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.commands.CommandManager;
|
||||
import me.lucko.luckperms.commands.Util;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
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.constants.Patterns;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
+21
-11
@@ -20,17 +20,18 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import me.lucko.luckperms.config.AbstractConfiguration;
|
||||
import me.lucko.luckperms.common.config.AbstractConfiguration;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class BukkitConfig extends AbstractConfiguration<LPBukkitPlugin> {
|
||||
private YamlConfiguration configuration;
|
||||
@@ -49,13 +50,7 @@ class BukkitConfig extends AbstractConfiguration<LPBukkitPlugin> {
|
||||
getPlugin().saveResource("config.yml", false);
|
||||
}
|
||||
|
||||
configuration = new YamlConfiguration();
|
||||
|
||||
try {
|
||||
configuration.load(configFile);
|
||||
} catch (InvalidConfigurationException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
configuration = YamlConfiguration.loadConfiguration(configFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,6 +68,21 @@ class BukkitConfig extends AbstractConfiguration<LPBukkitPlugin> {
|
||||
return configuration.getBoolean(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getList(String path, List<String> def) {
|
||||
return Optional.ofNullable(configuration.getStringList(path)).orElse(def);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getObjectList(String path, List<String> def) {
|
||||
ConfigurationSection section = configuration.getConfigurationSection(path);
|
||||
if (section == null) {
|
||||
return def;
|
||||
}
|
||||
|
||||
return Optional.ofNullable(section.getKeys(false).stream().collect(Collectors.toList())).orElse(def);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected Map<String, String> getMap(String path, Map<String, String> def) {
|
||||
+38
-67
@@ -20,23 +20,22 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.inject.Injector;
|
||||
import me.lucko.luckperms.inject.LPPermissible;
|
||||
import me.lucko.luckperms.users.BukkitUser;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.AbstractListener;
|
||||
import me.lucko.luckperms.bukkit.inject.Injector;
|
||||
import me.lucko.luckperms.bukkit.inject.LPPermissible;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import me.lucko.luckperms.common.utils.AbstractListener;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
class BukkitListener extends AbstractListener implements Listener {
|
||||
@@ -49,7 +48,8 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent e) {
|
||||
if (!plugin.getDatastore().isAcceptingLogins()) {
|
||||
if (!plugin.isStarted() || !plugin.getDatastore().isAcceptingLogins()) {
|
||||
|
||||
// The datastore is disabled, prevent players from joining the server
|
||||
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.toString());
|
||||
return;
|
||||
@@ -57,38 +57,14 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
|
||||
// Process login
|
||||
onAsyncLogin(e.getUniqueId(), e.getName());
|
||||
|
||||
// Pre-process the user's permissions, so they're ready for PLE.
|
||||
BukkitUser user = (BukkitUser) plugin.getUserManager().get(plugin.getUuidCache().getUUID(e.getUniqueId()));
|
||||
Map<String, Boolean> toApply = user.exportNodes(
|
||||
new Contexts(
|
||||
Collections.singletonMap("server", plugin.getConfiguration().getServer()),
|
||||
plugin.getConfiguration().isIncludingGlobalPerms(),
|
||||
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
plugin.getConfiguration().isApplyingGlobalGroups(),
|
||||
plugin.getConfiguration().isApplyingGlobalWorldGroups()
|
||||
),
|
||||
Collections.emptyList(),
|
||||
true
|
||||
);
|
||||
user.setLoginPreProcess(toApply);
|
||||
|
||||
// Hook with Vault early
|
||||
if (plugin.getVaultHook() != null && plugin.getVaultHook().isHooked()) {
|
||||
plugin.getVaultHook().getPermissionHook().getVaultUserManager().setupUser(user);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerPreLoginMonitor(AsyncPlayerPreLoginEvent e) {
|
||||
if (plugin.getDatastore().isAcceptingLogins() && e.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
|
||||
if (plugin.isStarted() && plugin.getDatastore().isAcceptingLogins() && e.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
|
||||
|
||||
// Login event was cancelled by another plugin
|
||||
final UUID internal = plugin.getUuidCache().getUUID(e.getUniqueId());
|
||||
onLeave(e.getUniqueId());
|
||||
if (plugin.getVaultHook() != null && plugin.getVaultHook().isHooked()) {
|
||||
plugin.getVaultHook().getPermissionHook().getVaultUserManager().clearUser(internal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,61 +74,56 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
|
||||
if (user == null) {
|
||||
// User wasn't loaded for whatever reason.
|
||||
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
BukkitUser u = (BukkitUser) user;
|
||||
try {
|
||||
// Make a new permissible for the user
|
||||
LPPermissible lpPermissible = new LPPermissible(player, plugin, plugin.getDefaultsProvider());
|
||||
|
||||
// Insert the pre-processed permissions into the permissible
|
||||
lpPermissible.getLuckPermsPermissions().putAll(u.getLoginPreProcess());
|
||||
u.setLoginPreProcess(null);
|
||||
LPPermissible lpPermissible = new LPPermissible(player, user, plugin);
|
||||
|
||||
// Inject into the player
|
||||
Injector.inject(player, lpPermissible);
|
||||
u.setLpPermissible(lpPermissible);
|
||||
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
if (player.isOp()) {
|
||||
|
||||
// We assume all users are not op, but those who are need extra calculation.
|
||||
plugin.doAsync(() -> user.getUserData().preCalculate(plugin.getPreProcessContexts(true)));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerLoginMonitor(PlayerLoginEvent e) {
|
||||
if (e.getResult() != PlayerLoginEvent.Result.ALLOWED) {
|
||||
|
||||
// The player got denied on sync login.
|
||||
final UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
onLeave(e.getPlayer().getUniqueId());
|
||||
if (plugin.getVaultHook() != null && plugin.getVaultHook().isHooked()) {
|
||||
plugin.getVaultHook().getPermissionHook().getVaultUserManager().clearUser(internal);
|
||||
}
|
||||
} else {
|
||||
User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||
|
||||
// Call another update to calculate full context. (incl. per world permissions)
|
||||
plugin.doAsync(user::refreshPermissions);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerJoin(PlayerJoinEvent e) {
|
||||
// Refresh permissions again
|
||||
UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
plugin.getWorldCalculator().getWorldCache().put(internal, e.getPlayer().getWorld().getName());
|
||||
plugin.doAsync(() -> refreshPlayer(internal));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
@EventHandler(priority = EventPriority.HIGHEST) // Allow other plugins to see data when this event gets called.
|
||||
public void onPlayerQuit(PlayerQuitEvent e) {
|
||||
final UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
final Player player = e.getPlayer();
|
||||
final UUID internal = plugin.getUuidCache().getUUID(player.getUniqueId());
|
||||
|
||||
// Remove from World cache
|
||||
plugin.getWorldCalculator().getWorldCache().remove(internal);
|
||||
onLeave(e.getPlayer().getUniqueId());
|
||||
if (plugin.getVaultHook() != null && plugin.getVaultHook().isHooked()) {
|
||||
plugin.getVaultHook().getPermissionHook().getVaultUserManager().clearUser(internal);
|
||||
|
||||
// Remove the custom permissible
|
||||
Injector.unInject(player);
|
||||
|
||||
// Handle auto op
|
||||
if (plugin.getConfiguration().isAutoOp()) {
|
||||
player.setOp(false);
|
||||
}
|
||||
|
||||
// Call internal leave handling
|
||||
onLeave(player.getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
+4
-3
@@ -20,10 +20,11 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import me.lucko.luckperms.commands.SenderFactory;
|
||||
import me.lucko.luckperms.constants.Constants;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.SenderFactory;
|
||||
import me.lucko.luckperms.common.constants.Constants;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
+135
-76
@@ -20,36 +20,43 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
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.LuckPermsApi;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.implementation.ApiProvider;
|
||||
import me.lucko.luckperms.api.vault.VaultHook;
|
||||
import me.lucko.luckperms.calculators.DefaultsProvider;
|
||||
import me.lucko.luckperms.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.config.LPConfiguration;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.contexts.ContextManager;
|
||||
import me.lucko.luckperms.contexts.ServerCalculator;
|
||||
import me.lucko.luckperms.contexts.WorldCalculator;
|
||||
import me.lucko.luckperms.core.UuidCache;
|
||||
import me.lucko.luckperms.data.Importer;
|
||||
import me.lucko.luckperms.groups.GroupManager;
|
||||
import me.lucko.luckperms.runnables.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.runnables.UpdateTask;
|
||||
import me.lucko.luckperms.storage.Datastore;
|
||||
import me.lucko.luckperms.storage.StorageFactory;
|
||||
import me.lucko.luckperms.tracks.TrackManager;
|
||||
import me.lucko.luckperms.users.BukkitUserManager;
|
||||
import me.lucko.luckperms.utils.LocaleManager;
|
||||
import me.lucko.luckperms.utils.LogFactory;
|
||||
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.vault.VaultHook;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.api.ApiProvider;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.config.LPConfiguration;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.contexts.ContextManager;
|
||||
import me.lucko.luckperms.common.contexts.ServerCalculator;
|
||||
import me.lucko.luckperms.common.core.UuidCache;
|
||||
import me.lucko.luckperms.common.data.Importer;
|
||||
import me.lucko.luckperms.common.groups.GroupManager;
|
||||
import me.lucko.luckperms.common.runnables.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.common.runnables.UpdateTask;
|
||||
import me.lucko.luckperms.common.storage.Datastore;
|
||||
import me.lucko.luckperms.common.storage.StorageFactory;
|
||||
import me.lucko.luckperms.common.tracks.TrackManager;
|
||||
import me.lucko.luckperms.common.users.UserManager;
|
||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||
import me.lucko.luckperms.common.utils.LocaleManager;
|
||||
import me.lucko.luckperms.common.utils.LogFactory;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
@@ -66,7 +73,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
|
||||
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
|
||||
private LPConfiguration configuration;
|
||||
private BukkitUserManager userManager;
|
||||
private UserManager userManager;
|
||||
private GroupManager groupManager;
|
||||
private TrackManager trackManager;
|
||||
private Datastore datastore;
|
||||
@@ -79,6 +86,9 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
private LocaleManager localeManager;
|
||||
private ContextManager<Player> contextManager;
|
||||
private WorldCalculator worldCalculator;
|
||||
private CalculatorFactory calculatorFactory;
|
||||
private BufferedRequest<Void> updateTaskBuffer;
|
||||
private boolean started = false;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
@@ -117,23 +127,36 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
|
||||
getLog().info("Loading internal permission managers...");
|
||||
uuidCache = new UuidCache(getConfiguration().isOnlineMode());
|
||||
userManager = new BukkitUserManager(this);
|
||||
userManager = new UserManager(this);
|
||||
groupManager = new GroupManager(this);
|
||||
trackManager = new TrackManager();
|
||||
importer = new Importer(commandManager);
|
||||
consecutiveExecutor = new ConsecutiveExecutor(commandManager);
|
||||
calculatorFactory = new BukkitCalculatorFactory(this);
|
||||
|
||||
contextManager = new ContextManager<>();
|
||||
worldCalculator = new WorldCalculator(this);
|
||||
pm.registerEvents(worldCalculator, this);
|
||||
contextManager.registerCalculator(worldCalculator);
|
||||
contextManager.registerCalculator(new ServerCalculator<>(getConfiguration().getServer()));
|
||||
contextManager.registerListener(userManager);
|
||||
|
||||
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, new UpdateTask(this), ticks, ticks);
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, () -> updateTaskBuffer.request(), ticks, ticks);
|
||||
}
|
||||
|
||||
getServer().getScheduler().runTaskTimer(this, BukkitSenderFactory.get(this), 1L, 1L);
|
||||
@@ -157,32 +180,30 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
|
||||
getLog().info("Registering API...");
|
||||
apiProvider = new ApiProvider(this);
|
||||
LuckPerms.registerProvider(apiProvider);
|
||||
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.");
|
||||
try {
|
||||
new UpdateTask(this).run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
updateTaskBuffer.request();
|
||||
|
||||
registerPermissions(getConfiguration().isCommandsAllowOp() ? PermissionDefault.OP : PermissionDefault.FALSE);
|
||||
if (!getConfiguration().isOpsEnabled()) {
|
||||
getServer().getOperators().forEach(o -> o.setOp(false));
|
||||
}
|
||||
|
||||
started = true;
|
||||
getLog().info("Successfully loaded.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
started = false;
|
||||
getLog().info("Closing datastore...");
|
||||
datastore.shutdown();
|
||||
|
||||
getLog().info("Unregistering API...");
|
||||
LuckPerms.unregisterProvider();
|
||||
ApiHandler.unregisterProvider();
|
||||
getServer().getServicesManager().unregisterAll(this);
|
||||
|
||||
if (vaultHook != null) {
|
||||
@@ -200,6 +221,11 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
getServer().getScheduler().runTask(this, r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAsyncRepeating(Runnable r, long interval) {
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, r, interval, interval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return getDescription().getVersion();
|
||||
@@ -215,11 +241,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
return getDataFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message getPlayerStatus(UUID uuid) {
|
||||
return getServer().getPlayer(getUuidCache().getExternalUUID(uuid)) != null ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerCount() {
|
||||
return getServer().getOnlinePlayers().size();
|
||||
@@ -230,11 +251,21 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
return getServer().getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getOnlinePlayers() {
|
||||
return getServer().getOnlinePlayers().stream().map(Player::getUniqueId).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnline(UUID external) {
|
||||
return getServer().getPlayer(external) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Sender> getNotifyListeners() {
|
||||
return getServer().getOnlinePlayers().stream()
|
||||
.map(p -> BukkitSenderFactory.get(this).wrap(p, Collections.singleton(me.lucko.luckperms.constants.Permission.LOG_NOTIFY)))
|
||||
.filter(me.lucko.luckperms.constants.Permission.LOG_NOTIFY::isAuthorized)
|
||||
.map(p -> BukkitSenderFactory.get(this).wrap(p, Collections.singleton(Permission.LOG_NOTIFY)))
|
||||
.filter(Permission.LOG_NOTIFY::isAuthorized)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@@ -244,15 +275,68 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossiblePermissions() {
|
||||
final List<String> perms = new ArrayList<>();
|
||||
public Set<Contexts> getPreProcessContexts(boolean op) {
|
||||
Set<ContextSet> c = new HashSet<>();
|
||||
c.add(ContextSet.empty());
|
||||
c.add(ContextSet.singleton("server", getConfiguration().getServer()));
|
||||
|
||||
getServer().getPluginManager().getPermissions().forEach(p -> {
|
||||
perms.add(p.getName());
|
||||
p.getChildren().keySet().forEach(perms::add);
|
||||
});
|
||||
// Pre process all worlds
|
||||
c.addAll(getServer().getWorlds().stream()
|
||||
.map(World::getName)
|
||||
.map(s -> {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.add("server", getConfiguration().getServer());
|
||||
set.add("world", s);
|
||||
return set.makeImmutable();
|
||||
})
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
|
||||
return perms;
|
||||
// Pre process the separate Vault server, if any
|
||||
if (!getConfiguration().getServer().equals(getConfiguration().getVaultServer())) {
|
||||
c.add(ContextSet.singleton("server", getConfiguration().getVaultServer()));
|
||||
c.addAll(getServer().getWorlds().stream()
|
||||
.map(World::getName)
|
||||
.map(s -> {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.add("server", getConfiguration().getVaultServer());
|
||||
set.add("world", s);
|
||||
return set.makeImmutable();
|
||||
})
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
Set<Contexts> contexts = new HashSet<>();
|
||||
|
||||
// Convert to full Contexts
|
||||
contexts.addAll(c.stream()
|
||||
.map(set -> new Contexts(
|
||||
set,
|
||||
getConfiguration().isIncludingGlobalPerms(),
|
||||
getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
getConfiguration().isApplyingGlobalGroups(),
|
||||
getConfiguration().isApplyingGlobalWorldGroups(),
|
||||
op
|
||||
))
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
|
||||
// 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) {
|
||||
contexts.addAll(c.stream()
|
||||
.map(map -> new Contexts(map, getConfiguration().isVaultIncludingGlobal(), true, true, true, true, op))
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
}
|
||||
|
||||
return contexts;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -280,38 +364,13 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
return getServer().getPluginManager().isPluginEnabled(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runUpdateTask() {
|
||||
getServer().getScheduler().runTaskAsynchronously(this, new UpdateTask(this));
|
||||
}
|
||||
|
||||
private void registerPermissions(PermissionDefault def) {
|
||||
PluginManager pm = getServer().getPluginManager();
|
||||
|
||||
Map<String, List<String>> wildcards = new HashMap<>();
|
||||
List<String> all = new ArrayList<>();
|
||||
for (me.lucko.luckperms.constants.Permission p : me.lucko.luckperms.constants.Permission.values()) {
|
||||
pm.addPermission(new Permission(p.getNode(), def));
|
||||
if (p.getGroup() != null) {
|
||||
if (!wildcards.containsKey(p.getGroup())) {
|
||||
wildcards.put(p.getGroup(), new ArrayList<>());
|
||||
}
|
||||
wildcards.get(p.getGroup()).add(p.getTag());
|
||||
for (Permission p : Permission.values()) {
|
||||
for (String node : p.getNodes()) {
|
||||
pm.addPermission(new org.bukkit.permissions.Permission(node, def));
|
||||
}
|
||||
|
||||
all.add(p.getNode());
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<String>> e : wildcards.entrySet()) {
|
||||
pm.addPermission(new Permission(
|
||||
"luckperms." + e.getKey() + ".*", def,
|
||||
e.getValue().stream()
|
||||
.map(tag -> "luckperms." + e.getKey() + "." + tag)
|
||||
.collect(Collectors.toMap(s -> s, s -> true))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
pm.addPermission(new Permission("luckperms.*", def, all.stream().collect(Collectors.toMap(s -> s, s -> true))));
|
||||
}
|
||||
}
|
||||
+17
-4
@@ -20,18 +20,20 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.contexts;
|
||||
package me.lucko.luckperms.bukkit;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
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;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@@ -47,11 +49,11 @@ public class WorldCalculator extends ContextCalculator<Player> implements Listen
|
||||
private final Map<UUID, String> worldCache = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public Map<String, String> giveApplicableContext(Player subject, Map<String, String> accumulator) {
|
||||
public MutableContextSet giveApplicableContext(Player subject, MutableContextSet accumulator) {
|
||||
String world = getWorld(subject);
|
||||
|
||||
if (world != null) {
|
||||
accumulator.put(WORLD_KEY, world);
|
||||
accumulator.add(Maps.immutableEntry(WORLD_KEY, world));
|
||||
}
|
||||
|
||||
return accumulator;
|
||||
@@ -77,6 +79,17 @@ public class WorldCalculator extends ContextCalculator<Player> implements Listen
|
||||
return plugin.getConfiguration().getWorldRewrites().getOrDefault(world, world);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerJoin(PlayerLoginEvent e) {
|
||||
UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
worldCache.put(internal, e.getPlayer().getWorld().getName());
|
||||
pushUpdate(
|
||||
e.getPlayer(),
|
||||
Maps.immutableEntry(WORLD_KEY, null),
|
||||
Maps.immutableEntry(WORLD_KEY, e.getPlayer().getWorld().getName())
|
||||
);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerChangedWorld(PlayerChangedWorldEvent e) {
|
||||
UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
+9
-5
@@ -20,28 +20,32 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.calculators;
|
||||
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;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class AttachmentProcessor implements PermissionProcessor {
|
||||
|
||||
@Getter
|
||||
private final Map<String, PermissionAttachmentInfo> map;
|
||||
private final Supplier<Map<String, PermissionAttachmentInfo>> map;
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
if (map.containsKey(permission)) {
|
||||
return Tristate.fromBoolean(map.get(permission).getValue());
|
||||
Map<String, PermissionAttachmentInfo> m = map.get();
|
||||
if (m == null) {
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
return Tristate.UNDEFINED;
|
||||
PermissionAttachmentInfo pai = m.get(permission);
|
||||
return pai == null ? Tristate.UNDEFINED : Tristate.fromBoolean(pai.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
+15
-14
@@ -20,27 +20,28 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.contexts;
|
||||
package me.lucko.luckperms.bukkit.calculators;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.api.context.ContextCalculator;
|
||||
import org.spongepowered.api.entity.living.player.Player;
|
||||
import org.spongepowered.api.service.context.Context;
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import me.lucko.luckperms.bukkit.inject.Injector;
|
||||
import me.lucko.luckperms.bukkit.inject.LPPermissible;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class WorldCalculator extends ContextCalculator<Player> {
|
||||
public class AutoOPListener implements ContextListener<Player> {
|
||||
|
||||
@Override
|
||||
public Map<String, String> giveApplicableContext(Player subject, Map<String, String> accumulator) {
|
||||
accumulator.put(Context.WORLD_KEY, subject.getWorld().getName());
|
||||
return accumulator;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContextApplicable(Player subject, Map.Entry<String, String> context) {
|
||||
return context.getKey().equals(Context.WORLD_KEY) && subject.getWorld().getName().equals(context.getValue());
|
||||
Map<String, Boolean> backing = permissible.getUser().getUserData().getPermissionData(permissible.calculateContexts()).getImmutableBacking();
|
||||
boolean op = Optional.ofNullable(backing.get("luckperms.autoop")).orElse(false);
|
||||
subject.setOp(op);
|
||||
}
|
||||
|
||||
}
|
||||
+5
-10
@@ -20,32 +20,27 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.calculators;
|
||||
package me.lucko.luckperms.bukkit.calculators;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.permissions.Permission;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class DefaultsProcessor implements PermissionProcessor {
|
||||
private final Supplier<Boolean> isOp;
|
||||
private final boolean isOp;
|
||||
private final DefaultsProvider defaultsProvider;
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
Tristate t = defaultsProvider.hasDefault(permission, isOp.get());
|
||||
Tristate t = defaultsProvider.hasDefault(permission, isOp);
|
||||
if (t != Tristate.UNDEFINED) {
|
||||
return t;
|
||||
}
|
||||
|
||||
Permission defPerm = Bukkit.getServer().getPluginManager().getPermission(permission);
|
||||
if (defPerm != null) {
|
||||
return Tristate.fromBoolean(defPerm.getDefault().getValue(isOp.get()));
|
||||
} else {
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
return defPerm == null ? Tristate.UNDEFINED : Tristate.fromBoolean(defPerm.getDefault().getValue(isOp));
|
||||
}
|
||||
}
|
||||
+3
-5
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.calculators;
|
||||
package me.lucko.luckperms.bukkit.calculators;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
@@ -97,11 +97,9 @@ public class DefaultsProvider {
|
||||
|
||||
public Tristate hasDefault(String permission, boolean isOp) {
|
||||
Map<String, Boolean> map = isOp ? op : nonOp;
|
||||
if (!map.containsKey(permission)) {
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
return Tristate.fromBoolean(map.get(permission));
|
||||
Boolean b = map.get(permission);
|
||||
return b == null ? Tristate.UNDEFINED : Tristate.fromBoolean(b);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.inject;
|
||||
package me.lucko.luckperms.bukkit.inject;
|
||||
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
import org.bukkit.permissions.Permission;
|
||||
+16
-25
@@ -20,37 +20,39 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.inject;
|
||||
package me.lucko.luckperms.bukkit.inject;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Injects a {@link LPPermissible} into a {@link Player}
|
||||
*/
|
||||
@UtilityClass
|
||||
public class Injector {
|
||||
private static final Map<UUID, LPPermissible> INJECTED_PERMISSIBLES = new ConcurrentHashMap<>();
|
||||
private static Field HUMAN_ENTITY_FIELD;
|
||||
|
||||
static {
|
||||
try {
|
||||
HUMAN_ENTITY_FIELD = Class.forName(getInternalClassName("entity.CraftHumanEntity")).getDeclaredField("perm");
|
||||
HUMAN_ENTITY_FIELD = Class.forName(getVersionedClassName("entity.CraftHumanEntity")).getDeclaredField("perm");
|
||||
HUMAN_ENTITY_FIELD.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean inject(CommandSender sender, PermissibleBase permissible) {
|
||||
public static boolean inject(Player player, LPPermissible permissible) {
|
||||
try {
|
||||
Field f = getPermField(sender);
|
||||
f.set(sender, permissible);
|
||||
HUMAN_ENTITY_FIELD.set(player, permissible);
|
||||
INJECTED_PERMISSIBLES.put(player.getUniqueId(), permissible);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -58,15 +60,16 @@ public class Injector {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean unInject(CommandSender sender) {
|
||||
public static boolean unInject(Player player) {
|
||||
try {
|
||||
Permissible permissible = getPermissible(sender);
|
||||
Permissible permissible = (Permissible) 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. */
|
||||
getPermField(sender).set(sender, new DummyPermissibleBase());
|
||||
HUMAN_ENTITY_FIELD.set(player, new DummyPermissibleBase());
|
||||
}
|
||||
INJECTED_PERMISSIBLES.remove(player.getUniqueId());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -74,23 +77,11 @@ public class Injector {
|
||||
}
|
||||
}
|
||||
|
||||
private static Permissible getPermissible(CommandSender sender) {
|
||||
try {
|
||||
Field f = getPermField(sender);
|
||||
return (Permissible) f.get(sender);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
public static LPPermissible getPermissible(UUID uuid) {
|
||||
return INJECTED_PERMISSIBLES.get(uuid);
|
||||
}
|
||||
|
||||
private static Field getPermField(CommandSender sender) {
|
||||
if (sender instanceof Player) {
|
||||
return HUMAN_ENTITY_FIELD;
|
||||
}
|
||||
throw new RuntimeException("Couldn't get perm field for sender " + sender.getClass().getName());
|
||||
}
|
||||
|
||||
private static String getInternalClassName(String className) {
|
||||
private static String getVersionedClassName(String className) {
|
||||
Class server = Bukkit.getServer().getClass();
|
||||
if (!server.getSimpleName().equals("CraftServer")) {
|
||||
throw new RuntimeException("Couldn't inject into server " + server);
|
||||
+61
-51
@@ -20,20 +20,21 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.inject;
|
||||
package me.lucko.luckperms.bukkit.inject;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.calculators.*;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.*;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -43,42 +44,41 @@ import java.util.stream.Collectors;
|
||||
public class LPPermissible extends PermissibleBase {
|
||||
|
||||
@Getter
|
||||
private final CommandSender parent;
|
||||
|
||||
private final PermissionCalculator calculator;
|
||||
private final User user;
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> luckPermsPermissions = new ConcurrentHashMap<>();
|
||||
private final List<PermissionAttachment> attachments = new LinkedList<>();
|
||||
private final Player parent;
|
||||
|
||||
private final LPBukkitPlugin plugin;
|
||||
|
||||
// Attachment stuff.
|
||||
@Getter
|
||||
private final Map<String, PermissionAttachmentInfo> attachmentPermissions = new HashMap<>();
|
||||
private final List<PermissionAttachment> attachments = new LinkedList<>();
|
||||
|
||||
public LPPermissible(@NonNull CommandSender sender, LuckPermsPlugin plugin, DefaultsProvider defaultsProvider) {
|
||||
super(sender);
|
||||
this.parent = sender;
|
||||
|
||||
List<PermissionProcessor> processors = new ArrayList<>(5);
|
||||
processors.add(new MapProcessor(luckPermsPermissions));
|
||||
processors.add(new AttachmentProcessor(attachmentPermissions));
|
||||
if (plugin.getConfiguration().isApplyingWildcards()) {
|
||||
processors.add(new WildcardProcessor(luckPermsPermissions));
|
||||
}
|
||||
if (plugin.getConfiguration().isApplyingRegex()) {
|
||||
processors.add(new RegexProcessor(luckPermsPermissions));
|
||||
}
|
||||
processors.add(new DefaultsProcessor(parent::isOp, defaultsProvider));
|
||||
|
||||
calculator = new PermissionCalculator(plugin, parent.getName(), plugin.getConfiguration().isDebugPermissionChecks(), processors);
|
||||
public LPPermissible(@NonNull Player parent, User user, LPBukkitPlugin plugin) {
|
||||
super(parent);
|
||||
this.user = user;
|
||||
this.parent = parent;
|
||||
this.plugin = plugin;
|
||||
|
||||
recalculatePermissions();
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
calculator.invalidateCache();
|
||||
public Contexts calculateContexts() {
|
||||
return new Contexts(
|
||||
plugin.getContextManager().giveApplicableContext(parent, new MutableContextSet()),
|
||||
plugin.getConfiguration().isIncludingGlobalPerms(),
|
||||
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
plugin.getConfiguration().isApplyingGlobalGroups(),
|
||||
plugin.getConfiguration().isApplyingGlobalWorldGroups(),
|
||||
parent.isOp()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOp() {
|
||||
return parent.isOp();
|
||||
private boolean hasData() {
|
||||
return user.getUserData() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,7 +88,7 @@ public class LPPermissible extends PermissibleBase {
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(@NonNull String name) {
|
||||
return calculator.getPermissionValue(name) != Tristate.UNDEFINED;
|
||||
return hasData() && user.getUserData().getPermissionData(calculateContexts()).getPermissionValue(name) != Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,9 +98,11 @@ public class LPPermissible extends PermissibleBase {
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NonNull String name) {
|
||||
Tristate ts = calculator.getPermissionValue(name);
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
if (hasData()) {
|
||||
Tristate ts = user.getUserData().getPermissionData(calculateContexts()).getPermissionValue(name);
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
return Permission.DEFAULT_PERMISSION.getValue(isOp());
|
||||
@@ -108,14 +110,32 @@ public class LPPermissible extends PermissibleBase {
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NonNull Permission perm) {
|
||||
Tristate ts = calculator.getPermissionValue(perm.getName());
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
if (hasData()) {
|
||||
Tristate ts = user.getUserData().getPermissionData(calculateContexts()).getPermissionValue(perm.getName());
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
return perm.getDefault().getValue(isOp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
||||
Set<PermissionAttachmentInfo> perms = new HashSet<>();
|
||||
perms.addAll(attachmentPermissions.values());
|
||||
|
||||
if (hasData()) {
|
||||
perms.addAll(
|
||||
user.getUserData().getPermissionData(calculateContexts()).getImmutableBacking().entrySet().stream()
|
||||
.map(e -> new PermissionAttachmentInfo(parent, e.getKey(), null, e.getValue()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(@NonNull Plugin plugin, @NonNull String name, boolean value) {
|
||||
if (!plugin.isEnabled()) {
|
||||
@@ -202,7 +222,9 @@ public class LPPermissible extends PermissibleBase {
|
||||
calculateChildPermissions(attachment.getPermissions(), false, attachment);
|
||||
}
|
||||
|
||||
invalidateCache();
|
||||
if (hasData()) {
|
||||
user.getUserData().invalidatePermissionCalculators();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -234,18 +256,6 @@ public class LPPermissible extends PermissibleBase {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
||||
Set<PermissionAttachmentInfo> perms = new HashSet<>();
|
||||
perms.addAll(attachmentPermissions.values());
|
||||
|
||||
perms.addAll(luckPermsPermissions.entrySet().stream()
|
||||
.map(e -> new PermissionAttachmentInfo(parent, e.getKey(), null, e.getValue()))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
private class RemoveAttachmentRunnable implements Runnable {
|
||||
private PermissionAttachment attachment;
|
||||
|
||||
+51
-47
@@ -20,18 +20,18 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.vault;
|
||||
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.vault.cache.ChatCache;
|
||||
import me.lucko.luckperms.api.vault.cache.VaultUser;
|
||||
import me.lucko.luckperms.core.PermissionHolder;
|
||||
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.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import net.milkbowl.vault.chat.Chat;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -39,8 +39,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.lucko.luckperms.utils.ArgumentChecker.escapeCharacters;
|
||||
import static me.lucko.luckperms.utils.ArgumentChecker.unescapeCharacters;
|
||||
import static me.lucko.luckperms.api.MetaUtils.escapeCharacters;
|
||||
import static me.lucko.luckperms.api.MetaUtils.unescapeCharacters;
|
||||
|
||||
/**
|
||||
* Provides the Vault Chat service through the use of normal permission nodes.
|
||||
@@ -56,7 +56,7 @@ import static me.lucko.luckperms.utils.ArgumentChecker.unescapeCharacters;
|
||||
* Permission Nodes = meta.node.value
|
||||
*
|
||||
* Node that special characters used within LuckPerms are escaped:
|
||||
* See {@link me.lucko.luckperms.utils.ArgumentChecker#escapeCharacters(String)}
|
||||
* See {@link me.lucko.luckperms.api.MetaUtils#unescapeCharacters(String)}
|
||||
*/
|
||||
public class VaultChatHook extends Chat {
|
||||
private final VaultPermissionHook perms;
|
||||
@@ -74,11 +74,14 @@ public class VaultChatHook extends Chat {
|
||||
return perms.isEnabled();
|
||||
}
|
||||
|
||||
private void saveMeta(PermissionHolder holder, String world, String node, String value) {
|
||||
private void setMeta(PermissionHolder holder, String world, String node, String value) {
|
||||
String finalWorld = perms.isIgnoreWorld() ? null : world;
|
||||
if (holder == null) return;
|
||||
if (node.equals("")) return;
|
||||
|
||||
perms.scheduleTask(() -> {
|
||||
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);
|
||||
|
||||
@@ -92,12 +95,12 @@ public class VaultChatHook extends Chat {
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
Node.Builder metaNode = new me.lucko.luckperms.core.Node.Builder("meta." + k + "." + v).setValue(true);
|
||||
Node.Builder metaNode = new me.lucko.luckperms.common.core.Node.Builder("meta." + k + "." + v).setValue(true);
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
metaNode.setServer(perms.getServer());
|
||||
}
|
||||
if (world != null && !world.equals("")) {
|
||||
metaNode.setServer(perms.getServer()).setWorld(world);
|
||||
if (finalWorld != null && !finalWorld.equals("")) {
|
||||
metaNode.setServer(perms.getServer()).setWorld(finalWorld);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -109,18 +112,21 @@ public class VaultChatHook extends Chat {
|
||||
}
|
||||
|
||||
private void setChatMeta(boolean prefix, PermissionHolder holder, String value, String world) {
|
||||
String finalWorld = perms.isIgnoreWorld() ? null : world;
|
||||
if (holder == null) return;
|
||||
if (value.equals("")) return;
|
||||
|
||||
perms.scheduleTask(() -> {
|
||||
Node.Builder node = new me.lucko.luckperms.core.Node.Builder(prefix ? "prefix" : "suffix" + ".1000." + escapeCharacters(value));
|
||||
perms.log("Setting " + (prefix ? "prefix" : "suffix") + " for " + holder.getObjectName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
perms.getScheduler().scheduleTask(() -> {
|
||||
Node.Builder node = new me.lucko.luckperms.common.core.Node.Builder(prefix ? "prefix" : "suffix" + ".1000." + escapeCharacters(value));
|
||||
node.setValue(true);
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
node.setServer(perms.getServer());
|
||||
}
|
||||
|
||||
if (world != null && !world.equals("")) {
|
||||
node.setServer(perms.getServer()).setWorld(world);
|
||||
if (finalWorld != null && !finalWorld.equals("")) {
|
||||
node.setServer(perms.getServer()).setWorld(finalWorld);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -133,46 +139,41 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
private String getUserMeta(User user, String world, String node, String defaultValue) {
|
||||
if (user == null) return defaultValue;
|
||||
world = perms.isIgnoreWorld() ? null : world;
|
||||
node = escapeCharacters(node);
|
||||
|
||||
if (!perms.getVaultUserManager().containsUser(user.getUuid())) {
|
||||
perms.log("Getting meta: '" + node + "' for user " + user.getName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
if (user.getUserData() == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
VaultUser vaultUser = perms.getVaultUserManager().getUser(user.getUuid());
|
||||
Map<String, String> context = new HashMap<>();
|
||||
context.put("server", perms.getServer());
|
||||
if (world != null) {
|
||||
context.put("world", world);
|
||||
}
|
||||
|
||||
ChatCache cd = vaultUser.processChatData(context);
|
||||
return unescapeCharacters(cd.getMeta().getOrDefault(node, defaultValue));
|
||||
return unescapeCharacters(user.getUserData().getMetaData(perms.createContext(perms.getServer(), world)).getMeta().getOrDefault(node, defaultValue));
|
||||
}
|
||||
|
||||
private String getUserChatMeta(boolean prefix, User user, String world) {
|
||||
if (user == null) return "";
|
||||
world = perms.isIgnoreWorld() ? null : world;
|
||||
|
||||
if (!perms.getVaultUserManager().containsUser(user.getUuid())) {
|
||||
perms.log("Getting " + (prefix ? "prefix" : "suffix") + " for user " + user.getName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
if (user.getUserData() == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
VaultUser vaultUser = perms.getVaultUserManager().getUser(user.getUuid());
|
||||
Map<String, String> context = new HashMap<>();
|
||||
context.put("server", perms.getServer());
|
||||
if (world != null) {
|
||||
context.put("world", world);
|
||||
}
|
||||
|
||||
ChatCache cd = vaultUser.processChatData(context);
|
||||
return unescapeCharacters(prefix ? (cd.getPrefix() == null ? "" : cd.getPrefix()) : (cd.getSuffix() == null ? "" : cd.getSuffix()));
|
||||
MetaData data = user.getUserData().getMetaData(perms.createContext(perms.getServer(), world));
|
||||
String v = prefix ? data.getPrefix() : data.getSuffix();
|
||||
return v == null ? "" : unescapeCharacters(v);
|
||||
}
|
||||
|
||||
private String getGroupMeta(Group group, String world, String node, String defaultValue) {
|
||||
world = perms.isIgnoreWorld() ? null : world;
|
||||
if (group == null) return defaultValue;
|
||||
if (node.equals("")) return defaultValue;
|
||||
node = escapeCharacters(node);
|
||||
|
||||
perms.log("Getting meta: '" + node + "' for group " + group.getName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
for (Node n : group.getPermissions(true)) {
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
@@ -200,8 +201,11 @@ public class VaultChatHook extends Chat {
|
||||
}
|
||||
|
||||
private String getGroupChatMeta(boolean prefix, Group group, String world) {
|
||||
world = perms.isIgnoreWorld() ? null : world;
|
||||
if (group == null) return "";
|
||||
|
||||
perms.log("Getting " + (prefix ? "prefix" : "suffix") + " for group " + group + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
int priority = Integer.MIN_VALUE;
|
||||
String meta = null;
|
||||
|
||||
@@ -211,7 +215,7 @@ public class VaultChatHook extends Chat {
|
||||
context.put("world", world);
|
||||
}
|
||||
|
||||
for (Node n : group.getAllNodes(null, new Contexts(context, perms.isIncludeGlobal(), true, true, true, true))) {
|
||||
for (Node n : group.getAllNodes(null, new Contexts(ContextSet.fromMap(context), perms.isIncludeGlobal(), true, true, true, true, false))) {
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
@@ -289,7 +293,7 @@ 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);
|
||||
saveMeta(user, world, node, String.valueOf(value));
|
||||
setMeta(user, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public int getGroupInfoInteger(String world, @NonNull String group, @NonNull String node, int defaultValue) {
|
||||
@@ -303,7 +307,7 @@ 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);
|
||||
saveMeta(g, world, node, String.valueOf(value));
|
||||
setMeta(g, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public double getPlayerInfoDouble(String world, @NonNull String player, @NonNull String node, double defaultValue) {
|
||||
@@ -317,7 +321,7 @@ 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);
|
||||
saveMeta(user, world, node, String.valueOf(value));
|
||||
setMeta(user, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public double getGroupInfoDouble(String world, @NonNull String group, @NonNull String node, double defaultValue) {
|
||||
@@ -331,7 +335,7 @@ 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);
|
||||
saveMeta(g, world, node, String.valueOf(value));
|
||||
setMeta(g, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public boolean getPlayerInfoBoolean(String world, @NonNull String player, @NonNull String node, boolean defaultValue) {
|
||||
@@ -345,7 +349,7 @@ 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);
|
||||
saveMeta(user, world, node, String.valueOf(value));
|
||||
setMeta(user, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public boolean getGroupInfoBoolean(String world, @NonNull String group, @NonNull String node, boolean defaultValue) {
|
||||
@@ -359,7 +363,7 @@ 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);
|
||||
saveMeta(g, world, node, String.valueOf(value));
|
||||
setMeta(g, world, node, String.valueOf(value));
|
||||
}
|
||||
|
||||
public String getPlayerInfoString(String world, @NonNull String player, @NonNull String node, String defaultValue) {
|
||||
@@ -369,7 +373,7 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public void setPlayerInfoString(String world, @NonNull String player, @NonNull String node, String value) {
|
||||
final User user = perms.getPlugin().getUserManager().get(player);
|
||||
saveMeta(user, world, node, value);
|
||||
setMeta(user, world, node, value);
|
||||
}
|
||||
|
||||
public String getGroupInfoString(String world, @NonNull String group, @NonNull String node, String defaultValue) {
|
||||
@@ -379,7 +383,7 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
public void setGroupInfoString(String world, @NonNull String group, @NonNull String node, String value) {
|
||||
final Group g = perms.getPlugin().getGroupManager().get(group);
|
||||
saveMeta(g, world, node, value);
|
||||
setMeta(g, world, node, value);
|
||||
}
|
||||
|
||||
}
|
||||
+3
-2
@@ -20,10 +20,10 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.vault;
|
||||
package me.lucko.luckperms.bukkit.vault;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
|
||||
import net.milkbowl.vault.chat.Chat;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
@@ -42,6 +42,7 @@ public class VaultHook {
|
||||
permissionHook.setPlugin(plugin);
|
||||
permissionHook.setServer(plugin.getConfiguration().getVaultServer());
|
||||
permissionHook.setIncludeGlobal(plugin.getConfiguration().isVaultIncludingGlobal());
|
||||
permissionHook.setIncludeGlobal(plugin.getConfiguration().isVaultIgnoreWorld());
|
||||
permissionHook.setup();
|
||||
|
||||
if (chatHook == null) {
|
||||
+127
-112
@@ -20,38 +20,37 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.vault;
|
||||
package me.lucko.luckperms.bukkit.vault;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.vault.cache.VaultUser;
|
||||
import me.lucko.luckperms.api.vault.cache.VaultUserManager;
|
||||
import me.lucko.luckperms.core.PermissionHolder;
|
||||
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.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The LuckPerms Vault Permission implementation
|
||||
* Most lookups are cached.
|
||||
*/
|
||||
public class VaultPermissionHook extends Permission implements Runnable {
|
||||
private final List<Runnable> tasks = new ArrayList<>();
|
||||
public class VaultPermissionHook extends Permission {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private LPBukkitPlugin plugin;
|
||||
|
||||
@Getter
|
||||
private VaultUserManager vaultUserManager;
|
||||
private VaultScheduler scheduler;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@@ -61,9 +60,12 @@ public class VaultPermissionHook extends Permission implements Runnable {
|
||||
@Setter
|
||||
private boolean includeGlobal = true;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean ignoreWorld = false;
|
||||
|
||||
public void setup() {
|
||||
vaultUserManager = new VaultUserManager(plugin, this);
|
||||
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this, 1L, 1L);
|
||||
scheduler = new VaultScheduler(plugin);
|
||||
}
|
||||
|
||||
public void log(String s) {
|
||||
@@ -72,23 +74,6 @@ public class VaultPermissionHook extends Permission implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
void scheduleTask(Runnable r) {
|
||||
synchronized (tasks) {
|
||||
tasks.add(r);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<Runnable> toRun = new ArrayList<>();
|
||||
synchronized (tasks) {
|
||||
toRun.addAll(tasks);
|
||||
tasks.clear();
|
||||
}
|
||||
|
||||
toRun.forEach(Runnable::run);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "LuckPerms";
|
||||
@@ -104,133 +89,157 @@ public class VaultPermissionHook extends Permission implements Runnable {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean objectHas(String world, Group group, String permission) {
|
||||
if (group == null) return false;
|
||||
/**
|
||||
* 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 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) {}
|
||||
|
||||
save(holder);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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) {}
|
||||
|
||||
save(holder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for saving a user or group
|
||||
* @param holder the holder instance
|
||||
*/
|
||||
void save(PermissionHolder holder) {
|
||||
if (holder instanceof User) {
|
||||
|
||||
plugin.getDatastore().saveUser(((User) holder), b -> {
|
||||
((User) holder).getRefreshBuffer().request();
|
||||
});
|
||||
}
|
||||
if (holder instanceof Group) {
|
||||
plugin.getDatastore().saveGroup(((Group) holder), b -> plugin.getUpdateTaskBuffer().request());
|
||||
}
|
||||
}
|
||||
|
||||
Contexts createContext(String server, String world) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
if (world != null && !world.equals("")) {
|
||||
context.put("world", world);
|
||||
}
|
||||
context.put("server", server);
|
||||
|
||||
Map<String, Boolean> toApply = group.exportNodes(
|
||||
new Contexts(context, includeGlobal, includeGlobal, true, true, true),
|
||||
Collections.emptyList(), true
|
||||
);
|
||||
|
||||
return toApply.containsKey(permission) && toApply.get(permission);
|
||||
}
|
||||
|
||||
private boolean add(String world, PermissionHolder object, String permission) {
|
||||
if (object == null) return false;
|
||||
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
object.setPermission(permission, true, server, world);
|
||||
} else {
|
||||
object.setPermission(permission, true, server);
|
||||
}
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
|
||||
save(object);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean remove(String world, PermissionHolder object, String permission) {
|
||||
if (object == null) return false;
|
||||
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
object.unsetPermission(permission, server, world);
|
||||
} else {
|
||||
object.unsetPermission(permission, server);
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
|
||||
save(object);
|
||||
return true;
|
||||
}
|
||||
|
||||
void save(PermissionHolder t) {
|
||||
if (t instanceof User) {
|
||||
((User) t).refreshPermissions();
|
||||
plugin.getDatastore().saveUser(((User) t));
|
||||
}
|
||||
if (t instanceof Group) {
|
||||
plugin.getDatastore().saveGroup(((Group) t));
|
||||
plugin.runUpdateTask();
|
||||
}
|
||||
return new Contexts(ContextSet.fromMap(context), isIncludeGlobal(), true, true, true, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerHas(String world, @NonNull String player, @NonNull String permission) {
|
||||
world = ignoreWorld ? null : world; // Correct world value
|
||||
log("Checking if player " + player + " has permission: " + permission + " on world " + world + ", server " + server);
|
||||
|
||||
User user = plugin.getUserManager().get(player);
|
||||
if (user == null) return false;
|
||||
|
||||
if (!vaultUserManager.containsUser(user.getUuid())) {
|
||||
if (user.getUserData() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VaultUser vaultUser = vaultUserManager.getUser(user.getUuid());
|
||||
Map<String, String> context = new HashMap<>();
|
||||
context.put("server", server);
|
||||
if (world != null) {
|
||||
context.put("world", world);
|
||||
}
|
||||
|
||||
return vaultUser.hasPermission(context, permission);
|
||||
// Effectively fallback to the standard Bukkit #hasPermission check.
|
||||
return user.getUserData().getPermissionData(createContext(server, world)).getPermissionValue(permission).asBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerAdd(String world, @NonNull String player, @NonNull String permission) {
|
||||
log("Adding permission to player " + player + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Adding permission to player " + player + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
scheduleTask(() -> add(world, user, permission));
|
||||
if (user == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> add(finalWorld, user, permission));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerRemove(String world, @NonNull String player, @NonNull String permission) {
|
||||
log("Removing permission from player " + player + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Removing permission from player " + player + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
scheduleTask(() -> remove(world, user, permission));
|
||||
if (user == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> remove(finalWorld, user, permission));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean groupHas(String world, @NonNull String groupName, @NonNull String permission) {
|
||||
world = ignoreWorld ? null : world; // Correct world value
|
||||
log("Checking if group " + groupName + " has permission: " + permission + " on world " + world + ", server " + server);
|
||||
|
||||
final Group group = plugin.getGroupManager().get(groupName);
|
||||
return objectHas(world, group, permission);
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean groupAdd(String world, @NonNull String groupName, @NonNull String permission) {
|
||||
log("Adding permission to group " + groupName + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Adding permission to group " + groupName + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
|
||||
final Group group = plugin.getGroupManager().get(groupName);
|
||||
scheduleTask(() -> add(world, group, permission));
|
||||
if (group == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> add(finalWorld, group, permission));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean groupRemove(String world, @NonNull String groupName, @NonNull String permission) {
|
||||
log("Removing permission from group " + groupName + ": '" + permission + "' on world " + world + ", server " + server);
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Removing permission from group " + groupName + ": '" + permission + "' on world " + finalWorld + ", server " + server);
|
||||
|
||||
final Group group = plugin.getGroupManager().get(groupName);
|
||||
scheduleTask(() -> remove(world, group, permission));
|
||||
if (group == null) return false;
|
||||
|
||||
scheduler.scheduleTask(() -> remove(finalWorld, group, permission));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerInGroup(String world, @NonNull String player, @NonNull String group) {
|
||||
log("Checking if player " + player + " is in group: " + group + " on world " + world + ", server " + server);
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Checking if player " + player + " is in group: " + group + " on world " + finalWorld + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
if (user == null) return false;
|
||||
|
||||
return user.getNodes().stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.filter(n -> n.shouldApplyOnServer(server, isIncludeGlobal(), false))
|
||||
.filter(n -> n.shouldApplyOnWorld(world, true, false))
|
||||
.filter(n -> n.shouldApplyOnWorld(finalWorld, true, false))
|
||||
.map(Node::getGroupName)
|
||||
.filter(s -> s.equalsIgnoreCase(group))
|
||||
.findAny().isPresent();
|
||||
@@ -238,19 +247,21 @@ public class VaultPermissionHook extends Permission implements Runnable {
|
||||
|
||||
@Override
|
||||
public boolean playerAddGroup(String world, @NonNull String player, @NonNull String groupName) {
|
||||
log("Adding player " + player + " to group: '" + groupName + "' on world " + world + ", server " + server);
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Adding player " + player + " to group: '" + groupName + "' on world " + finalWorld + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
if (user == null) return false;
|
||||
|
||||
final Group group = plugin.getGroupManager().get(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
scheduleTask(() -> {
|
||||
scheduler.scheduleTask(() -> {
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
user.addGroup(group, server, world);
|
||||
if (finalWorld != null && !finalWorld.equals("")) {
|
||||
user.setInheritGroup(group, server, finalWorld);
|
||||
} else {
|
||||
user.addGroup(group, server);
|
||||
user.setInheritGroup(group, server);
|
||||
}
|
||||
} catch (ObjectAlreadyHasException ignored) {}
|
||||
save(user);
|
||||
@@ -260,19 +271,21 @@ public class VaultPermissionHook extends Permission implements Runnable {
|
||||
|
||||
@Override
|
||||
public boolean playerRemoveGroup(String world, @NonNull String player, @NonNull String groupName) {
|
||||
log("Removing player " + player + " from group: '" + groupName + "' on world " + world + ", server " + server);
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Removing player " + player + " from group: '" + groupName + "' on world " + finalWorld + ", server " + server);
|
||||
|
||||
final User user = plugin.getUserManager().get(player);
|
||||
if (user == null) return false;
|
||||
|
||||
final Group group = plugin.getGroupManager().get(groupName);
|
||||
if (group == null) return false;
|
||||
|
||||
scheduleTask(() -> {
|
||||
scheduler.scheduleTask(() -> {
|
||||
try {
|
||||
if (world != null && !world.equals("")) {
|
||||
user.removeGroup(group, server, world);
|
||||
if (finalWorld != null && !finalWorld.equals("")) {
|
||||
user.unsetInheritGroup(group, server, finalWorld);
|
||||
} else {
|
||||
user.removeGroup(group, server);
|
||||
user.unsetInheritGroup(group, server);
|
||||
}
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
save(user);
|
||||
@@ -282,14 +295,16 @@ public class VaultPermissionHook extends Permission implements Runnable {
|
||||
|
||||
@Override
|
||||
public String[] getPlayerGroups(String world, @NonNull String player) {
|
||||
log("Getting groups of player: " + player + ", on world " + world + ", server " + server);
|
||||
String finalWorld = ignoreWorld ? null : world; // Correct world value
|
||||
log("Getting groups of player: " + player + ", on world " + finalWorld + ", server " + server);
|
||||
|
||||
User user = plugin.getUserManager().get(player);
|
||||
if (user == null) return new String[0];
|
||||
|
||||
return user.getNodes().stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.filter(n -> n.shouldApplyOnServer(server, isIncludeGlobal(), false))
|
||||
.filter(n -> n.shouldApplyOnWorld(world, true, false))
|
||||
.filter(n -> n.shouldApplyOnWorld(finalWorld, true, false))
|
||||
.map(Node::getGroupName)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
+23
-15
@@ -20,26 +20,34 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.contexts;
|
||||
package me.lucko.luckperms.bukkit.vault;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.sponge.LuckPermsUserSubject;
|
||||
import me.lucko.luckperms.api.sponge.collections.UserCollection;
|
||||
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class ContextUpdateTask implements Runnable {
|
||||
private final UserCollection userCollection;
|
||||
public class VaultScheduler implements Runnable {
|
||||
private final List<Runnable> tasks = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (LuckPermsUserSubject subject : userCollection.getUsers().values()) {
|
||||
Set<Map<String, String>> contexts = new HashSet<>(subject.getContextData().keySet());
|
||||
contexts.forEach(map -> subject.calculatePermissions(map, true));
|
||||
public VaultScheduler(LPBukkitPlugin plugin) {
|
||||
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this, 1L, 1L);
|
||||
}
|
||||
|
||||
public void scheduleTask(Runnable r) {
|
||||
synchronized (tasks) {
|
||||
tasks.add(r);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<Runnable> toRun = new ArrayList<>();
|
||||
synchronized (tasks) {
|
||||
toRun.addAll(tasks);
|
||||
tasks.clear();
|
||||
}
|
||||
|
||||
toRun.forEach(Runnable::run);
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.users;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.event.events.UserPermissionRefreshEvent;
|
||||
import me.lucko.luckperms.api.implementation.internal.UserLink;
|
||||
import me.lucko.luckperms.inject.LPPermissible;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitUser extends User {
|
||||
private final LPBukkitPlugin plugin;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private LPPermissible lpPermissible = null;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Map<String, Boolean> loginPreProcess = null;
|
||||
|
||||
BukkitUser(UUID uuid, LPBukkitPlugin plugin) {
|
||||
super(uuid, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
BukkitUser(UUID uuid, String username, LPBukkitPlugin plugin) {
|
||||
super(uuid, username, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public boolean isOp() {
|
||||
return lpPermissible != null && lpPermissible.isOp();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public synchronized void refreshPermissions() {
|
||||
if (lpPermissible == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the permissions that should be applied. This is done async, who cares about how long it takes or how often it's done.
|
||||
Map<String, Boolean> toApply = exportNodes(
|
||||
new Contexts(
|
||||
plugin.getContextManager().giveApplicableContext((Player) lpPermissible.getParent(), new HashMap<>()),
|
||||
plugin.getConfiguration().isIncludingGlobalPerms(),
|
||||
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
plugin.getConfiguration().isApplyingGlobalGroups(),
|
||||
plugin.getConfiguration().isApplyingGlobalWorldGroups()
|
||||
),
|
||||
Collections.emptyList(),
|
||||
true
|
||||
);
|
||||
|
||||
try {
|
||||
Map<String, Boolean> existing = lpPermissible.getLuckPermsPermissions();
|
||||
|
||||
boolean different = false;
|
||||
if (toApply.size() != existing.size()) {
|
||||
different = true;
|
||||
} else {
|
||||
for (Map.Entry<String, Boolean> e : existing.entrySet()) {
|
||||
if (toApply.containsKey(e.getKey()) && toApply.get(e.getKey()) == e.getValue()) {
|
||||
continue;
|
||||
}
|
||||
different = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!different) return;
|
||||
|
||||
existing.clear();
|
||||
lpPermissible.invalidateCache();
|
||||
existing.putAll(toApply);
|
||||
|
||||
if (plugin.getConfiguration().isAutoOp()) {
|
||||
boolean op = false;
|
||||
|
||||
for (Map.Entry<String, Boolean> e : toApply.entrySet()) {
|
||||
if (e.getKey().equalsIgnoreCase("luckperms.autoop") && e.getValue()) {
|
||||
op = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean finalOp = op;
|
||||
if (lpPermissible.isOp() != op) {
|
||||
final Permissible parent = lpPermissible.getParent();
|
||||
plugin.doSync(() -> parent.setOp(finalOp));
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getApiProvider().fireEventAsync(new UserPermissionRefreshEvent(new UserLink(this)));
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (plugin.getVaultHook() != null && plugin.getVaultHook().isHooked()) {
|
||||
plugin.getVaultHook().getPermissionHook().getVaultUserManager().setupUser(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.users;
|
||||
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import me.lucko.luckperms.inject.Injector;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BukkitUserManager extends UserManager implements ContextListener<Player> {
|
||||
private final LPBukkitPlugin plugin;
|
||||
|
||||
public BukkitUserManager(LPBukkitPlugin plugin) {
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preUnload(User user) {
|
||||
if (user instanceof BukkitUser) {
|
||||
BukkitUser u = (BukkitUser) user;
|
||||
Player player = plugin.getServer().getPlayer(plugin.getUuidCache().getExternalUUID(u.getUuid()));
|
||||
if (player != null) {
|
||||
if (u.getLpPermissible() != null) {
|
||||
Injector.unInject(player); // TODO is this needed?
|
||||
u.setLpPermissible(null);
|
||||
}
|
||||
|
||||
if (plugin.getConfiguration().isAutoOp()) {
|
||||
player.setOp(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(User user) {
|
||||
if (plugin.getServer().getPlayer(plugin.getUuidCache().getExternalUUID(user.getUuid())) == null) {
|
||||
unload(user);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public User apply(UserIdentifier id) {
|
||||
BukkitUser user = id.getUsername() == null ?
|
||||
new BukkitUser(id.getUuid(), plugin) :
|
||||
new BukkitUser(id.getUuid(), id.getUsername(), plugin);
|
||||
giveDefaultIfNeeded(user, false);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAllUsers() {
|
||||
// Sometimes called async, as we need to get the players on the Bukkit thread.
|
||||
plugin.doSync(() -> {
|
||||
Set<UUID> players = plugin.getServer().getOnlinePlayers().stream()
|
||||
.map(p -> plugin.getUuidCache().getUUID(p.getUniqueId()))
|
||||
.collect(Collectors.toSet());
|
||||
plugin.doAsync(() -> players.forEach(u -> plugin.getDatastore().loadUser(u, "null")));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContextChange(Player subject, Map.Entry<String, String> before, Map.Entry<String, String> current) throws Exception {
|
||||
UUID internal = plugin.getUuidCache().getUUID(subject.getUniqueId());
|
||||
|
||||
User user = get(internal);
|
||||
if (user != null) {
|
||||
plugin.doAsync(user::refreshPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,10 @@
|
||||
# +------------------------------------------------------------------------+ #
|
||||
##############################################################################
|
||||
|
||||
# +------------------------------------------------------------------------+ #
|
||||
# | General | #
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# The name of the server, used for server specific permissions. Set to 'global' to disable.
|
||||
server: global
|
||||
|
||||
@@ -24,21 +28,34 @@ apply-global-world-groups: true
|
||||
|
||||
# If this server is in offline or online mode.
|
||||
# This setting allows a player to have the same UUID across a network of offline mode/mixed servers.
|
||||
|
||||
#
|
||||
# You should generally reflect the setting in server.properties here. Except when...
|
||||
|
||||
#
|
||||
# 1. You have Spigot servers connected to a BungeeCord proxy, with online-mode set to false, but 'bungeecord' set to true in the spigot.yml
|
||||
# AND 'ip-forward' set to true in the BungeeCord config.yml
|
||||
# In this case, set online-mode in LuckPerms to true, despite the server being in offline mode.
|
||||
|
||||
#
|
||||
# 2. You are only running one server instance using LuckPerms, (not a network)
|
||||
# In this case, set online-mode to true no matter what is set in server.properties. (we can just fallback to the servers uuid cache)
|
||||
|
||||
#
|
||||
# 3. If your proxy is running in offline mode, and you are using PaperSpigot (https://ci.destroystokyo.com/job/PaperSpigot/),
|
||||
# you should set "bungee-online-mode" to false in the paper.yml, and set "online-mode" to true in all LuckPerms configs.
|
||||
# This approach is thoroughly recommended for offline mode networks.
|
||||
online-mode: true
|
||||
|
||||
# If the plugin should 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
|
||||
|
||||
|
||||
|
||||
|
||||
# +------------------------------------------------------------------------+ #
|
||||
# | Permission Calculation | #
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# If the plugin should apply wildcard permissions.
|
||||
# If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered permissions matching
|
||||
# the wildcard.
|
||||
@@ -53,11 +70,12 @@ apply-regex: true
|
||||
# If set to true, LuckPerms will detect and expand shorthand node patterns.
|
||||
apply-shorthand: true
|
||||
|
||||
# If the plugin should send log notifications to users whenever permissions are modified.
|
||||
log-notify: true
|
||||
|
||||
# If LuckPerms should print to console every time a plugin checks if a player has a permission
|
||||
debug-permission-checks: false
|
||||
|
||||
|
||||
# +------------------------------------------------------------------------+ #
|
||||
# | OP (Server Operator) Settings | #
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# If the vanilla OP system is enabled. If set to false, all users will be de-opped, and the op/deop commands will be disabled.
|
||||
enable-ops: true
|
||||
@@ -67,12 +85,23 @@ enable-ops: true
|
||||
# Additionally, setting this to true will force the "enable-ops" option above to false. All users will be de-opped unless
|
||||
# they have the permission node, and the op/deop commands will be disabled.
|
||||
#
|
||||
# It is important to note that this setting is only checked when a player first joins the server, and when they switch
|
||||
# worlds. Therefore, simply removing this permission from a user will not automatically de-op them. A player needs to
|
||||
# relog to have the change take effect.
|
||||
#
|
||||
# It is recommended that you use this option instead of assigning a single '*' permission.
|
||||
auto-op: false
|
||||
|
||||
# If opped players should be allowed to use LuckPerms commands. Set to false to only allow users who have the permissions access to the commands
|
||||
commands-allow-op: true
|
||||
|
||||
|
||||
|
||||
|
||||
# +------------------------------------------------------------------------+ #
|
||||
# | Vault | #
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# The name of the server used within Vault operations. If you don't want Vault operations to be server specific, set this
|
||||
# to "global".
|
||||
vault-server: global
|
||||
@@ -80,15 +109,25 @@ vault-server: global
|
||||
# If global permissions should be considered when retrieving meta or player groups
|
||||
vault-include-global: true
|
||||
|
||||
# If Vault operations should ignore any world arguments if supplied.
|
||||
vault-ignore-world: 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:
|
||||
#world_nether: world
|
||||
#world_the_end: world
|
||||
# world_nether: world
|
||||
# world_the_end: world
|
||||
|
||||
# Rewrites group names. The underlying name of the group does not change, just the output in commands / placeholders / Vault.
|
||||
group-name-rewrite:
|
||||
#default: Member
|
||||
# default: Member
|
||||
|
||||
|
||||
|
||||
|
||||
# +------------------------------------------------------------------------+ #
|
||||
# | Storage | #
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, h2, json, yaml, mongodb
|
||||
@@ -110,7 +149,85 @@ data:
|
||||
database: minecraft
|
||||
username: root
|
||||
password: ''
|
||||
pool-size: 10 # The size of the MySQL connection pool.
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
|
||||
# +------------------------------------------------------------------------+ #
|
||||
# | Default Assignments | #
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# This section allows you to define defaults to give users whenever they connect to the server.
|
||||
# The default assignments are highly configurable and conditional.
|
||||
#
|
||||
# There is one default assignment built into LuckPerms, which will add all users to the "default" group if they
|
||||
# are not a member of any other group. This setting cannot be disabled. However, you can use this section to add more of
|
||||
# your own.
|
||||
#
|
||||
# IMPORTANT:
|
||||
# In order to save storage space, LuckPerms does not store users who have no permissions defined, and are only a member
|
||||
# of the default group. Adding default assignments to this section will negate this effect. It is HIGHLY RECCOMENDED
|
||||
# that instead of assigning defaults here, you add permissions to the "default" group, or set the "default" group to inherit
|
||||
# other groups, and then use the group-name-rewrite rule above.
|
||||
#
|
||||
# It is also important to note that these rules are considered every time a player logs into the server, and are applied
|
||||
# directly to the user's data. Simply removing a rule here will not reserse the effect of that rule on any users who have
|
||||
# already had it applied to them.
|
||||
#
|
||||
# The "has" and "lacks" conditions below support standard boolean logic, using the 'and' & 'or' characters used in Java.
|
||||
# e.g. "(some.other.permission | some.permission.other) & some.thing.else" == a user has 'some.other.permission', or
|
||||
# 'some.permission.other', and they also have 'some.thing.else'
|
||||
#
|
||||
# Groups are represented by the permission node: group.<group name>
|
||||
# Per server and per world nodes are represented by: "server-world/permission" or "server/permission"
|
||||
#
|
||||
# Within conditions, permission nodes MUST be escaped using "<" and ">". See the example below.
|
||||
#
|
||||
# Explaination of the examples below: (they're just to demonstrate the features & use cases)
|
||||
#
|
||||
# rule1:
|
||||
# If a user is either in the vip or vip+ group, and they have the "titles.titlecollector" permission set to true, and the
|
||||
# "some.random.permission" set to false... if they're not in the group "prison_titlepack" on the "prison" server, then
|
||||
# give add them to the "prison_titlepack" group on the "prison" server, and remove "some.random.permission".
|
||||
#
|
||||
# rule2:
|
||||
# If the user isn't in any of the following groups on the skyblock server: sb_level1, sb_level2, sb_level3, then add
|
||||
# them to sb_level1 on the skyblock server.
|
||||
#
|
||||
# rule3:
|
||||
# If the user is a member of the default group, remove them from default, add them to member, and set their primary group
|
||||
# to member.
|
||||
#
|
||||
# WARNING: Unlike internal commands, this system does not ensure that a group exists before adding a user to it.
|
||||
# It also does not unsure that a user is a member of a group before making that group their primary group.
|
||||
#
|
||||
# Before you use "give: group.<name>" or "set-primary-group", make sure that the group exists, and that the user is
|
||||
# a member of the group.
|
||||
default-assignments:
|
||||
# rule1:
|
||||
# if:
|
||||
# has-true: (<group.vip> | <group.vip+>) & <titles.tilecollector>
|
||||
# has-false: <some.random.permission>
|
||||
# lacks: <prison/group.prison_titlepack>
|
||||
# give:
|
||||
# - prison/group.prison_titlepack
|
||||
# take:
|
||||
# - some.random.permission
|
||||
# rule2:
|
||||
# if:
|
||||
# lacks: <skyblock/group.sb_level1> & <skyblock/group.sb_level2> & <skyblock/group.sb_level3>
|
||||
# give:
|
||||
# - skyblock/group.sb_level1
|
||||
# rule3:
|
||||
# if:
|
||||
# has-true: <group.default>
|
||||
# take:
|
||||
# - group.default
|
||||
# give:
|
||||
# - group.member
|
||||
# set-primary-group: member
|
||||
@@ -4,7 +4,7 @@ description: A permissions plugin
|
||||
author: Luck
|
||||
website: https://github.com/lucko/LuckPerms
|
||||
|
||||
main: me.lucko.luckperms.LPBukkitPlugin
|
||||
main: me.lucko.luckperms.bukkit.LPBukkitPlugin
|
||||
softdepend: [Vault, PermissionsEx, GroupManager, PowerfulPerms, zPermissions, bPermissions] # For migration
|
||||
|
||||
commands:
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.11-SNAPSHOT</version>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
+4
-3
@@ -20,10 +20,11 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.contexts;
|
||||
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,11 +36,11 @@ public class BackendServerCalculator extends ContextCalculator<ProxiedPlayer> im
|
||||
private static final String WORLD_KEY = "world";
|
||||
|
||||
@Override
|
||||
public Map<String, String> giveApplicableContext(ProxiedPlayer subject, Map<String, String> accumulator) {
|
||||
public MutableContextSet giveApplicableContext(ProxiedPlayer subject, MutableContextSet accumulator) {
|
||||
String server = getServer(subject);
|
||||
|
||||
if (server != null) {
|
||||
accumulator.put(WORLD_KEY, server);
|
||||
accumulator.add(Maps.immutableEntry(WORLD_KEY, server));
|
||||
}
|
||||
|
||||
return accumulator;
|
||||
+14
-23
@@ -20,41 +20,32 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.calculators.*;
|
||||
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 java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class BungeePlayerCache {
|
||||
@AllArgsConstructor
|
||||
public class BungeeCalculatorFactory implements CalculatorFactory {
|
||||
private final LPBungeePlugin plugin;
|
||||
|
||||
private final PermissionCalculator calculator;
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> permissions = new ConcurrentHashMap<>();
|
||||
|
||||
public BungeePlayerCache(LuckPermsPlugin plugin, String name) {
|
||||
@Override
|
||||
public PermissionCalculator build(Contexts contexts, User user, Map<String, Boolean> map) {
|
||||
List<PermissionProcessor> processors = new ArrayList<>(3);
|
||||
processors.add(new MapProcessor(permissions));
|
||||
processors.add(new MapProcessor(map));
|
||||
if (plugin.getConfiguration().isApplyingWildcards()) {
|
||||
processors.add(new WildcardProcessor(permissions));
|
||||
processors.add(new WildcardProcessor(map));
|
||||
}
|
||||
if (plugin.getConfiguration().isApplyingRegex()) {
|
||||
processors.add(new RegexProcessor(permissions));
|
||||
processors.add(new RegexProcessor(map));
|
||||
}
|
||||
|
||||
calculator = new PermissionCalculator(plugin, name, plugin.getConfiguration().isDebugPermissionChecks(), processors);
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
calculator.invalidateCache();
|
||||
}
|
||||
|
||||
public boolean getPermissionValue(String permission) {
|
||||
return calculator.getPermissionValue(permission).asBoolean();
|
||||
return new PermissionCalculator(plugin, user.getName(), plugin.getConfiguration().isDebugPermissionChecks(), processors);
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -20,14 +20,14 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
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.commands.CommandManager;
|
||||
import me.lucko.luckperms.commands.Util;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.common.commands.CommandManager;
|
||||
import me.lucko.luckperms.common.commands.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;
|
||||
+20
-2
@@ -20,9 +20,9 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import me.lucko.luckperms.config.AbstractConfiguration;
|
||||
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;
|
||||
@@ -32,7 +32,10 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class BungeeConfig extends AbstractConfiguration<LPBungeePlugin> {
|
||||
private Configuration configuration;
|
||||
@@ -79,6 +82,21 @@ class BungeeConfig extends AbstractConfiguration<LPBungeePlugin> {
|
||||
return configuration.getBoolean(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getList(String path, List<String> def) {
|
||||
return Optional.ofNullable(configuration.getStringList(path)).orElse(def);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getObjectList(String path, List<String> def) {
|
||||
Configuration section = configuration.getSection(path);
|
||||
if (section == null) {
|
||||
return def;
|
||||
}
|
||||
|
||||
return Optional.ofNullable(section.getKeys().stream().collect(Collectors.toList())).orElse(def);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, String> getMap(String path, Map<String, String> def) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
+44
-18
@@ -20,12 +20,15 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.core.UuidCache;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.AbstractListener;
|
||||
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.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;
|
||||
@@ -58,12 +61,27 @@ public class BungeeListener extends AbstractListener implements Listener {
|
||||
|
||||
final ProxiedPlayer player = ((ProxiedPlayer) e.getSender());
|
||||
|
||||
BungeePlayerCache playerCache = plugin.getPlayerCache().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (playerCache == null) {
|
||||
User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.setHasPermission(playerCache.getPermissionValue(e.getPermission()));
|
||||
if (user.getUserData() == null) {
|
||||
plugin.getLog().warn("Player " + player.getName() + " does not have any user data setup.");
|
||||
return;
|
||||
}
|
||||
|
||||
Contexts contexts = new Contexts(
|
||||
plugin.getContextManager().giveApplicableContext(player, MutableContextSet.empty()),
|
||||
plugin.getConfiguration().isIncludingGlobalPerms(),
|
||||
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
plugin.getConfiguration().isApplyingGlobalGroups(),
|
||||
plugin.getConfiguration().isApplyingGlobalWorldGroups(),
|
||||
false
|
||||
);
|
||||
|
||||
e.setHasPermission(user.getUserData().getPermissionData(contexts).getPermissionValue(e.getPermission()).asBoolean());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -78,22 +96,35 @@ public class BungeeListener extends AbstractListener implements Listener {
|
||||
final PendingConnection c = e.getConnection();
|
||||
|
||||
if (!cache.isOnlineMode()) {
|
||||
UUID uuid = plugin.getDatastore().getUUID(c.getName());
|
||||
UUID uuid = plugin.getDatastore().getUUID(c.getName()).getUnchecked();
|
||||
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().saveUUIDData(c.getName(), c.getUniqueId());
|
||||
plugin.getDatastore().force().saveUUIDData(c.getName(), c.getUniqueId()).getUnchecked();
|
||||
}
|
||||
} else {
|
||||
UUID uuid = plugin.getDatastore().getUUID(c.getName()).getUnchecked();
|
||||
if (uuid == null) {
|
||||
plugin.getApiProvider().fireEventAsync(new UserFirstLoginEvent(c.getUniqueId(), c.getName()));
|
||||
}
|
||||
|
||||
// Online mode, no cache needed. This is just for name -> uuid lookup.
|
||||
plugin.getDatastore().saveUUIDData(c.getName(), c.getUniqueId());
|
||||
plugin.getDatastore().force().saveUUIDData(c.getName(), c.getUniqueId()).getUnchecked();
|
||||
}
|
||||
|
||||
// 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().loadUser(cache.getUUID(c.getUniqueId()), c.getName());
|
||||
plugin.getDatastore().force().loadUser(cache.getUUID(c.getUniqueId()), c.getName()).getUnchecked();
|
||||
User user = plugin.getUserManager().get(cache.getUUID(c.getUniqueId()));
|
||||
if (user == null) {
|
||||
plugin.getLog().warn("Failed to load user: " + c.getName());
|
||||
} else {
|
||||
user.setupData(false); // Pretty nasty calculation call. Sets up the caching system so data is ready when the user joins.
|
||||
}
|
||||
|
||||
final long time = System.currentTimeMillis() - startTime;
|
||||
if (time >= 1000) {
|
||||
plugin.getLog().warn("Processing login for " + c.getName() + " took " + time + "ms.");
|
||||
@@ -105,20 +136,15 @@ public class BungeeListener extends AbstractListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerPostLogin(PostLoginEvent e) {
|
||||
final ProxiedPlayer player = e.getPlayer();
|
||||
final UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
final User user = plugin.getUserManager().get(internal);
|
||||
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||
|
||||
if (user == null) {
|
||||
plugin.getProxy().getScheduler().schedule(plugin, () -> player.sendMessage(WARN_MESSAGE), 3, TimeUnit.SECONDS);
|
||||
} else {
|
||||
plugin.getPlayerCache().put(internal, new BungeePlayerCache(plugin, e.getPlayer().getName()));
|
||||
user.refreshPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerDisconnectEvent e) {
|
||||
plugin.getPlayerCache().remove(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||
onLeave(e.getPlayer().getUniqueId());
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -20,10 +20,11 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import me.lucko.luckperms.commands.SenderFactory;
|
||||
import me.lucko.luckperms.constants.Constants;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.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;
|
||||
+87
-46
@@ -20,32 +20,38 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
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.implementation.ApiProvider;
|
||||
import me.lucko.luckperms.commands.CommandManager;
|
||||
import me.lucko.luckperms.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.config.LPConfiguration;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.contexts.BackendServerCalculator;
|
||||
import me.lucko.luckperms.contexts.ContextManager;
|
||||
import me.lucko.luckperms.contexts.ServerCalculator;
|
||||
import me.lucko.luckperms.core.UuidCache;
|
||||
import me.lucko.luckperms.data.Importer;
|
||||
import me.lucko.luckperms.groups.GroupManager;
|
||||
import me.lucko.luckperms.runnables.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.runnables.UpdateTask;
|
||||
import me.lucko.luckperms.storage.Datastore;
|
||||
import me.lucko.luckperms.storage.StorageFactory;
|
||||
import me.lucko.luckperms.tracks.TrackManager;
|
||||
import me.lucko.luckperms.users.BungeeUserManager;
|
||||
import me.lucko.luckperms.utils.LocaleManager;
|
||||
import me.lucko.luckperms.utils.LogFactory;
|
||||
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.ApiProvider;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.CommandManager;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.config.LPConfiguration;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.contexts.ContextManager;
|
||||
import me.lucko.luckperms.common.contexts.ServerCalculator;
|
||||
import me.lucko.luckperms.common.core.UuidCache;
|
||||
import me.lucko.luckperms.common.data.Importer;
|
||||
import me.lucko.luckperms.common.groups.GroupManager;
|
||||
import me.lucko.luckperms.common.runnables.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.common.runnables.UpdateTask;
|
||||
import me.lucko.luckperms.common.storage.Datastore;
|
||||
import me.lucko.luckperms.common.storage.StorageFactory;
|
||||
import me.lucko.luckperms.common.tracks.TrackManager;
|
||||
import me.lucko.luckperms.common.users.UserManager;
|
||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||
import me.lucko.luckperms.common.utils.LocaleManager;
|
||||
import me.lucko.luckperms.common.utils.LogFactory;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
@@ -57,10 +63,9 @@ import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
private final Map<UUID, BungeePlayerCache> playerCache = new ConcurrentHashMap<>();
|
||||
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
|
||||
private LPConfiguration configuration;
|
||||
private BungeeUserManager userManager;
|
||||
private UserManager userManager;
|
||||
private GroupManager groupManager;
|
||||
private TrackManager trackManager;
|
||||
private Datastore datastore;
|
||||
@@ -71,6 +76,8 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
private ConsecutiveExecutor consecutiveExecutor;
|
||||
private LocaleManager localeManager;
|
||||
private ContextManager<ProxiedPlayer> contextManager;
|
||||
private CalculatorFactory calculatorFactory;
|
||||
private BufferedRequest<Void> updateTaskBuffer;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
@@ -105,18 +112,27 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
|
||||
getLog().info("Loading internal permission managers...");
|
||||
uuidCache = new UuidCache(getConfiguration().isOnlineMode());
|
||||
userManager = new BungeeUserManager(this);
|
||||
userManager = new UserManager(this);
|
||||
groupManager = new GroupManager(this);
|
||||
trackManager = new TrackManager();
|
||||
importer = new Importer(commandManager);
|
||||
consecutiveExecutor = new ConsecutiveExecutor(commandManager);
|
||||
calculatorFactory = new BungeeCalculatorFactory(this);
|
||||
|
||||
contextManager = new ContextManager<>();
|
||||
BackendServerCalculator serverCalculator = new BackendServerCalculator();
|
||||
getProxy().getPluginManager().registerListener(this, serverCalculator);
|
||||
contextManager.registerCalculator(serverCalculator);
|
||||
contextManager.registerCalculator(new ServerCalculator<>(getConfiguration().getServer()));
|
||||
contextManager.registerListener(userManager);
|
||||
|
||||
final LPBungeePlugin i = this;
|
||||
updateTaskBuffer = new BufferedRequest<Void>(6000L, this::doAsync) {
|
||||
@Override
|
||||
protected Void perform() {
|
||||
doAsync(new UpdateTask(i));
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
int mins = getConfiguration().getSyncTime();
|
||||
if (mins > 0) {
|
||||
@@ -130,15 +146,11 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
|
||||
getLog().info("Registering API...");
|
||||
apiProvider = new ApiProvider(this);
|
||||
LuckPerms.registerProvider(apiProvider);
|
||||
ApiHandler.registerProvider(apiProvider);
|
||||
|
||||
// Run update task to refresh any online users
|
||||
getLog().info("Scheduling Update Task to refresh any online users.");
|
||||
try {
|
||||
new UpdateTask(this).run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
updateTaskBuffer.request();
|
||||
|
||||
getLog().info("Successfully loaded.");
|
||||
}
|
||||
@@ -149,7 +161,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
datastore.shutdown();
|
||||
|
||||
getLog().info("Unregistering API...");
|
||||
LuckPerms.unregisterProvider();
|
||||
ApiHandler.unregisterProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -167,11 +179,6 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
return getDataFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message getPlayerStatus(UUID uuid) {
|
||||
return getProxy().getPlayer(getUuidCache().getExternalUUID(uuid)) != null ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerCount() {
|
||||
return getProxy().getOnlineCount();
|
||||
@@ -182,6 +189,16 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
return getProxy().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getOnlinePlayers() {
|
||||
return getProxy().getPlayers().stream().map(ProxiedPlayer::getUniqueId).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnline(UUID external) {
|
||||
return getProxy().getPlayer(external) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Sender> getNotifyListeners() {
|
||||
return getProxy().getPlayers().stream()
|
||||
@@ -196,9 +213,32 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossiblePermissions() {
|
||||
// No such thing on Bungee. Wildcards are processed in the listener instead.
|
||||
return Collections.emptyList();
|
||||
public Set<Contexts> getPreProcessContexts(boolean op) {
|
||||
Set<ContextSet> c = new HashSet<>();
|
||||
c.add(ContextSet.empty());
|
||||
c.add(ContextSet.singleton("server", getConfiguration().getServer()));
|
||||
c.addAll(getProxy().getServers().values().stream()
|
||||
.map(ServerInfo::getName)
|
||||
.map(s -> {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
set.add("server", getConfiguration().getServer());
|
||||
set.add("world", s);
|
||||
return set.makeImmutable();
|
||||
})
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
|
||||
return c.stream()
|
||||
.map(set -> new Contexts(
|
||||
set,
|
||||
getConfiguration().isIncludingGlobalPerms(),
|
||||
getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
getConfiguration().isApplyingGlobalGroups(),
|
||||
getConfiguration().isApplyingGlobalWorldGroups(),
|
||||
false
|
||||
))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -224,11 +264,6 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
.isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runUpdateTask() {
|
||||
doAsync(new UpdateTask(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAsync(Runnable r) {
|
||||
getProxy().getScheduler().runAsync(this, r);
|
||||
@@ -238,4 +273,10 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
public void doSync(Runnable r) {
|
||||
r.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAsyncRepeating(Runnable r, long interval) {
|
||||
long millis = interval * 50L; // convert from ticks to milliseconds
|
||||
getProxy().getScheduler().schedule(this, r, millis, millis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.users;
|
||||
|
||||
import me.lucko.luckperms.BungeePlayerCache;
|
||||
import me.lucko.luckperms.LPBungeePlugin;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.event.events.UserPermissionRefreshEvent;
|
||||
import me.lucko.luckperms.api.implementation.internal.UserLink;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeUser extends User {
|
||||
private final LPBungeePlugin plugin;
|
||||
|
||||
BungeeUser(UUID uuid, LPBungeePlugin plugin) {
|
||||
super(uuid, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
BungeeUser(UUID uuid, String username, LPBungeePlugin plugin) {
|
||||
super(uuid, username, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void refreshPermissions() {
|
||||
ProxiedPlayer player = plugin.getProxy().getPlayer(plugin.getUuidCache().getExternalUUID(getUuid()));
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
BungeePlayerCache playerCache = plugin.getPlayerCache().get(getUuid());
|
||||
if (playerCache == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the permissions that should be applied. This is done async.
|
||||
Map<String, Boolean> toApply = exportNodes(
|
||||
new Contexts(
|
||||
plugin.getContextManager().giveApplicableContext(player, new HashMap<>()),
|
||||
plugin.getConfiguration().isIncludingGlobalPerms(),
|
||||
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
plugin.getConfiguration().isApplyingGlobalGroups(),
|
||||
plugin.getConfiguration().isApplyingGlobalWorldGroups()
|
||||
),
|
||||
Collections.emptyList(),
|
||||
true
|
||||
);
|
||||
|
||||
Map<String, Boolean> existing = playerCache.getPermissions();
|
||||
|
||||
boolean different = false;
|
||||
if (toApply.size() != existing.size()) {
|
||||
different = true;
|
||||
} else {
|
||||
for (Map.Entry<String, Boolean> e : existing.entrySet()) {
|
||||
if (toApply.containsKey(e.getKey()) && toApply.get(e.getKey()) == e.getValue()) {
|
||||
continue;
|
||||
}
|
||||
different = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!different) return;
|
||||
|
||||
existing.clear();
|
||||
playerCache.invalidateCache();
|
||||
existing.putAll(toApply);
|
||||
|
||||
plugin.getApiProvider().fireEventAsync(new UserPermissionRefreshEvent(new UserLink(this)));
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.users;
|
||||
|
||||
import me.lucko.luckperms.LPBungeePlugin;
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeUserManager extends UserManager implements ContextListener<ProxiedPlayer> {
|
||||
private final LPBungeePlugin plugin;
|
||||
|
||||
public BungeeUserManager(LPBungeePlugin plugin) {
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(User user) {
|
||||
if (plugin.getProxy().getPlayer(plugin.getUuidCache().getExternalUUID(user.getUuid())) == null) {
|
||||
unload(user);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public User apply(UserIdentifier id) {
|
||||
BungeeUser user = id.getUsername() == null ?
|
||||
new BungeeUser(id.getUuid(), plugin) :
|
||||
new BungeeUser(id.getUuid(), id.getUsername(), plugin);
|
||||
giveDefaultIfNeeded(user, false);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAllUsers() {
|
||||
plugin.getProxy().getPlayers().stream()
|
||||
.map(p -> plugin.getUuidCache().getUUID(p.getUniqueId()))
|
||||
.forEach(u -> plugin.getDatastore().loadUser(u, "null"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContextChange(ProxiedPlayer subject, Map.Entry<String, String> before, Map.Entry<String, String> current) throws Exception {
|
||||
UUID internal = plugin.getUuidCache().getUUID(subject.getUniqueId());
|
||||
|
||||
User user = get(internal);
|
||||
if (user != null) {
|
||||
plugin.doAsync(user::refreshPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,10 @@
|
||||
# +------------------------------------------------------------------------+ #
|
||||
##############################################################################
|
||||
|
||||
# +------------------------------------------------------------------------+ #
|
||||
# | General | #
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# The name of the server, used for server specific permissions. Set to 'global' to disable.
|
||||
server: bungee
|
||||
|
||||
@@ -24,21 +28,44 @@ apply-global-world-groups: true
|
||||
|
||||
# If this server is in offline or online mode.
|
||||
# This setting allows a player to have the same UUID across a network of offline mode/mixed servers.
|
||||
|
||||
#
|
||||
# You should generally reflect the setting in server.properties here. Except when...
|
||||
|
||||
#
|
||||
# 1. You have Spigot servers connected to a BungeeCord proxy, with online-mode set to false, but 'bungeecord' set to true in the spigot.yml
|
||||
# AND 'ip-forward' set to true in the BungeeCord config.yml
|
||||
# In this case, set online-mode in LuckPerms to true, despite the server being in offline mode.
|
||||
|
||||
#
|
||||
# 2. You are only running one server instance using LuckPerms, (not a network)
|
||||
# In this case, set online-mode to true no matter what is set in server.properties. (we can just fallback to the servers uuid cache)
|
||||
|
||||
#
|
||||
# 3. If your proxy is running in offline mode, and you are using PaperSpigot (https://ci.destroystokyo.com/job/PaperSpigot/),
|
||||
# you should set "bungee-online-mode" to false in the paper.yml, and set "online-mode" to true in all LuckPerms configs.
|
||||
# This approach is thoroughly recommended for offline mode networks.
|
||||
online-mode: true
|
||||
|
||||
# If the plugin should 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:
|
||||
# world_nether: world
|
||||
# world_the_end: world
|
||||
|
||||
# Rewrites group names. The underlying name of the group does not change, just the output in commands / placeholders / Vault.
|
||||
group-name-rewrite:
|
||||
# default: Member
|
||||
|
||||
|
||||
|
||||
|
||||
# +------------------------------------------------------------------------+ #
|
||||
# | Permission Calculation | #
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# If the plugin should apply wildcard permissions.
|
||||
# If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered permissions matching
|
||||
# the wildcard.
|
||||
@@ -53,23 +80,12 @@ apply-regex: true
|
||||
# If set to true, LuckPerms will detect and expand shorthand node patterns.
|
||||
apply-shorthand: true
|
||||
|
||||
# If the plugin should send log notifications to users whenever permissions are modified.
|
||||
log-notify: true
|
||||
|
||||
# If LuckPerms should print to console every time a plugin checks if a player has a permission
|
||||
debug-permission-checks: false
|
||||
|
||||
# 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.
|
||||
# Remember world names on BungeeCord relate to the backend server name a user is connected to.
|
||||
world-rewrite:
|
||||
#hub2: hub
|
||||
#hub3: hub
|
||||
#opfactions: factions
|
||||
|
||||
# Rewrites group names. The underlying name of the group does not change, just the output in commands / placeholders / Vault.
|
||||
group-name-rewrite:
|
||||
#default: Member
|
||||
# +------------------------------------------------------------------------+ #
|
||||
# | Storage | #
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, h2, json, yaml, mongodb
|
||||
@@ -91,7 +107,85 @@ data:
|
||||
database: minecraft
|
||||
username: root
|
||||
password: ''
|
||||
pool-size: 10 # The size of the MySQL connection pool.
|
||||
|
||||
# Set to -1 to disable. If this is the only instance accessing the datastore, you can disable syncing.
|
||||
# e.g. if you're using sqlite or flatfile, this can be set to -1 to save resources.
|
||||
sync-minutes: 3
|
||||
sync-minutes: 3
|
||||
|
||||
|
||||
|
||||
|
||||
# +------------------------------------------------------------------------+ #
|
||||
# | Default Assignments | #
|
||||
# +------------------------------------------------------------------------+ #
|
||||
|
||||
# This section allows you to define defaults to give users whenever they connect to the server.
|
||||
# The default assignments are highly configurable and conditional.
|
||||
#
|
||||
# There is one default assignment built into LuckPerms, which will add all users to the "default" group if they
|
||||
# are not a member of any other group. This setting cannot be disabled. However, you can use this section to add more of
|
||||
# your own.
|
||||
#
|
||||
# IMPORTANT:
|
||||
# In order to save storage space, LuckPerms does not store users who have no permissions defined, and are only a member
|
||||
# of the default group. Adding default assignments to this section will negate this effect. It is HIGHLY RECCOMENDED
|
||||
# that instead of assigning defaults here, you add permissions to the "default" group, or set the "default" group to inherit
|
||||
# other groups, and then use the group-name-rewrite rule above.
|
||||
#
|
||||
# It is also important to note that these rules are considered every time a player logs into the server, and are applied
|
||||
# directly to the user's data. Simply removing a rule here will not reserse the effect of that rule on any users who have
|
||||
# already had it applied to them.
|
||||
#
|
||||
# The "has" and "lacks" conditions below support standard boolean logic, using the 'and' & 'or' characters used in Java.
|
||||
# e.g. "(some.other.permission | some.permission.other) & some.thing.else" == a user has 'some.other.permission', or
|
||||
# 'some.permission.other', and they also have 'some.thing.else'
|
||||
#
|
||||
# Groups are represented by the permission node: group.<group name>
|
||||
# Per server and per world nodes are represented by: "server-world/permission" or "server/permission"
|
||||
#
|
||||
# Within conditions, permission nodes MUST be escaped using "<" and ">". See the example below.
|
||||
#
|
||||
# Explaination of the examples below: (they're just to demonstrate the features & use cases)
|
||||
#
|
||||
# rule1:
|
||||
# If a user is either in the vip or vip+ group, and they have the "titles.titlecollector" permission set to true, and the
|
||||
# "some.random.permission" set to false... if they're not in the group "prison_titlepack" on the "prison" server, then
|
||||
# give add them to the "prison_titlepack" group on the "prison" server, and remove "some.random.permission".
|
||||
#
|
||||
# rule2:
|
||||
# If the user isn't in any of the following groups on the skyblock server: sb_level1, sb_level2, sb_level3, then add
|
||||
# them to sb_level1 on the skyblock server.
|
||||
#
|
||||
# rule3:
|
||||
# If the user is a member of the default group, remove them from default, add them to member, and set their primary group
|
||||
# to member.
|
||||
#
|
||||
# WARNING: Unlike internal commands, this system does not ensure that a group exists before adding a user to it.
|
||||
# It also does not unsure that a user is a member of a group before making that group their primary group.
|
||||
#
|
||||
# Before you use "give: group.<name>" or "set-primary-group", make sure that the group exists, and that the user is
|
||||
# a member of the group.
|
||||
default-assignments:
|
||||
# rule1:
|
||||
# if:
|
||||
# has-true: (<group.vip> | <group.vip+>) & <titles.tilecollector>
|
||||
# has-false: <some.random.permission>
|
||||
# lacks: <prison/group.prison_titlepack>
|
||||
# give:
|
||||
# - prison/group.prison_titlepack
|
||||
# take:
|
||||
# - some.random.permission
|
||||
# rule2:
|
||||
# if:
|
||||
# lacks: <skyblock/group.sb_level1> & <skyblock/group.sb_level2> & <skyblock/group.sb_level3>
|
||||
# give:
|
||||
# - skyblock/group.sb_level1
|
||||
# rule3:
|
||||
# if:
|
||||
# has-true: <group.default>
|
||||
# take:
|
||||
# - group.default
|
||||
# give:
|
||||
# - group.member
|
||||
# set-primary-group: member
|
||||
@@ -2,5 +2,5 @@ name: LuckPerms
|
||||
version: ${release.version}.${git.closest.tag.commit.count}
|
||||
description: A permissions plugin
|
||||
author: Luck
|
||||
main: me.lucko.luckperms.LPBungeePlugin
|
||||
main: me.lucko.luckperms.bungee.LPBungeePlugin
|
||||
softdepends: [PowerfulPerms] # For migration
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.11-SNAPSHOT</version>
|
||||
<version>2.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>2.4.7</version>
|
||||
<version>2.5.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- SQLite -->
|
||||
|
||||
+6
-12
@@ -22,22 +22,16 @@
|
||||
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import me.lucko.luckperms.internal.StandaloneBase;
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
|
||||
public class LPStandaloneApp {
|
||||
private StandaloneBase standaloneBase;
|
||||
public class ApiHandler {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new LPStandaloneApp().start();
|
||||
public static void registerProvider(LuckPermsApi luckPermsApi) {
|
||||
LuckPerms.registerProvider(luckPermsApi);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
standaloneBase = new StandaloneBase(this);
|
||||
LuckPerms.registerProvider(standaloneBase.getApiProvider());
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
standaloneBase.shutdown();
|
||||
public static void unregisterProvider() {
|
||||
LuckPerms.unregisterProvider();
|
||||
}
|
||||
|
||||
}
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupListParents extends SubCommand<Group> {
|
||||
public GroupListParents() {
|
||||
super("listparents", "Lists the groups that this group inherits from", Permission.GROUP_LISTPARENTS, Predicate.alwaysFalse(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
Message.LISTPARENTS.send(sender, group.getDisplayName(), Util.permGroupsToString(group.getPermissions(false)));
|
||||
Message.LISTPARENTS_TEMP.send(sender, group.getDisplayName(), Util.tempGroupsToString(group.getPermissions(false)));
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
-153
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GroupRemovePrefix extends SubCommand<Group> {
|
||||
public GroupRemovePrefix() {
|
||||
super("removeprefix", "Removes a prefix from the group", Permission.GROUP_REMOVEPREFIX, Predicate.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to remove the prefix at"),
|
||||
Arg.create("prefix", true, "the prefix string to remove"),
|
||||
Arg.create("server", false, "the server to remove the prefix on"),
|
||||
Arg.create("world", false, "the world to remove the prefix on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (prefix.equalsIgnoreCase("null")) {
|
||||
String server = null;
|
||||
String world = null;
|
||||
|
||||
if (args.size() >= 3) {
|
||||
server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 3) {
|
||||
world = args.get(3).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
List<Node> toRemove = new ArrayList<>();
|
||||
for (Node node : group.getNodes()) {
|
||||
if (!node.isPrefix()) continue;
|
||||
if (node.getPrefix().getKey() != priority) continue;
|
||||
if (node.isTemporary()) continue;
|
||||
|
||||
if (node.getServer().isPresent()) {
|
||||
if (server == null) continue;
|
||||
if (!node.getServer().get().equalsIgnoreCase(server)) continue;
|
||||
} else {
|
||||
if (server != null) continue;
|
||||
}
|
||||
|
||||
if (node.getWorld().isPresent()) {
|
||||
if (world == null) continue;
|
||||
if (!node.getWorld().get().equalsIgnoreCase(world)) continue;
|
||||
} else {
|
||||
if (world != null) continue;
|
||||
}
|
||||
|
||||
toRemove.add(node);
|
||||
}
|
||||
|
||||
toRemove.forEach(n -> {
|
||||
try {
|
||||
group.unsetPermission(n);
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
Message.BULK_CHANGE_SUCCESS.send(sender, toRemove.size());
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} else {
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server);
|
||||
Message.REMOVEPREFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removeprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world);
|
||||
Message.REMOVEPREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removeprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node);
|
||||
Message.REMOVEPREFIX_SUCCESS.send(sender, group.getDisplayName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removeprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-153
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GroupRemoveSuffix extends SubCommand<Group> {
|
||||
public GroupRemoveSuffix() {
|
||||
super("removesuffix", "Removes a suffix from the group", Permission.GROUP_REMOVESUFFIX, Predicate.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to remove the suffix at"),
|
||||
Arg.create("suffix", true, "the suffix string to remove"),
|
||||
Arg.create("server", false, "the server to remove the suffix on"),
|
||||
Arg.create("world", false, "the world to remove the suffix on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (suffix.equalsIgnoreCase("null")) {
|
||||
String server = null;
|
||||
String world = null;
|
||||
|
||||
if (args.size() >= 3) {
|
||||
server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 3) {
|
||||
world = args.get(3).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
List<Node> toRemove = new ArrayList<>();
|
||||
for (Node node : group.getNodes()) {
|
||||
if (!node.isSuffix()) continue;
|
||||
if (node.getSuffix().getKey() != priority) continue;
|
||||
if (node.isTemporary()) continue;
|
||||
|
||||
if (node.getServer().isPresent()) {
|
||||
if (server == null) continue;
|
||||
if (!node.getServer().get().equalsIgnoreCase(server)) continue;
|
||||
} else {
|
||||
if (server != null) continue;
|
||||
}
|
||||
|
||||
if (node.getWorld().isPresent()) {
|
||||
if (world == null) continue;
|
||||
if (!node.getWorld().get().equalsIgnoreCase(world)) continue;
|
||||
} else {
|
||||
if (world != null) continue;
|
||||
}
|
||||
|
||||
toRemove.add(node);
|
||||
}
|
||||
|
||||
toRemove.forEach(n -> {
|
||||
try {
|
||||
group.unsetPermission(n);
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
Message.BULK_CHANGE_SUCCESS.send(sender, toRemove.size());
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} else {
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server);
|
||||
Message.REMOVESUFFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removesuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world);
|
||||
Message.REMOVESUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removesuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node);
|
||||
Message.REMOVESUFFIX_SUCCESS.send(sender, group.getDisplayName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removesuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-154
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GroupRemoveTempPrefix extends SubCommand<Group> {
|
||||
public GroupRemoveTempPrefix() {
|
||||
super("removetempprefix", "Removes a temporary prefix from the group", Permission.GROUP_REMOVE_TEMP_PREFIX,
|
||||
Predicate.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to remove the prefix at"),
|
||||
Arg.create("prefix", true, "the prefix string to remove"),
|
||||
Arg.create("server", false, "the server to remove the prefix on"),
|
||||
Arg.create("world", false, "the world to remove the prefix on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (prefix.equalsIgnoreCase("null")) {
|
||||
String server = null;
|
||||
String world = null;
|
||||
|
||||
if (args.size() >= 3) {
|
||||
server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 3) {
|
||||
world = args.get(3).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
List<Node> toRemove = new ArrayList<>();
|
||||
for (Node node : group.getNodes()) {
|
||||
if (!node.isPrefix()) continue;
|
||||
if (node.getPrefix().getKey() != priority) continue;
|
||||
if (node.isPermanent()) continue;
|
||||
|
||||
if (node.getServer().isPresent()) {
|
||||
if (server == null) continue;
|
||||
if (!node.getServer().get().equalsIgnoreCase(server)) continue;
|
||||
} else {
|
||||
if (server != null) continue;
|
||||
}
|
||||
|
||||
if (node.getWorld().isPresent()) {
|
||||
if (world == null) continue;
|
||||
if (!node.getWorld().get().equalsIgnoreCase(world)) continue;
|
||||
} else {
|
||||
if (world != null) continue;
|
||||
}
|
||||
|
||||
toRemove.add(node);
|
||||
}
|
||||
|
||||
toRemove.forEach(n -> {
|
||||
try {
|
||||
group.unsetPermission(n);
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
Message.BULK_CHANGE_SUCCESS.send(sender, toRemove.size());
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} else {
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SUCCESS.send(sender, group.getDisplayName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-154
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GroupRemoveTempSuffix extends SubCommand<Group> {
|
||||
public GroupRemoveTempSuffix() {
|
||||
super("removetempsuffix", "Removes a temporary suffix from the group", Permission.GROUP_REMOVE_TEMP_SUFFIX,
|
||||
Predicate.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to remove the suffix at"),
|
||||
Arg.create("suffix", true, "the suffix string to remove"),
|
||||
Arg.create("server", false, "the server to remove the suffix on"),
|
||||
Arg.create("world", false, "the world to remove the suffix on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (suffix.equalsIgnoreCase("null")) {
|
||||
String server = null;
|
||||
String world = null;
|
||||
|
||||
if (args.size() >= 3) {
|
||||
server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() != 3) {
|
||||
world = args.get(3).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
List<Node> toRemove = new ArrayList<>();
|
||||
for (Node node : group.getNodes()) {
|
||||
if (!node.isSuffix()) continue;
|
||||
if (node.getSuffix().getKey() != priority) continue;
|
||||
if (node.isPermanent()) continue;
|
||||
|
||||
if (node.getServer().isPresent()) {
|
||||
if (server == null) continue;
|
||||
if (!node.getServer().get().equalsIgnoreCase(server)) continue;
|
||||
} else {
|
||||
if (server != null) continue;
|
||||
}
|
||||
|
||||
if (node.getWorld().isPresent()) {
|
||||
if (world == null) continue;
|
||||
if (!node.getWorld().get().equalsIgnoreCase(world)) continue;
|
||||
} else {
|
||||
if (world != null) continue;
|
||||
}
|
||||
|
||||
toRemove.add(node);
|
||||
}
|
||||
|
||||
toRemove.forEach(n -> {
|
||||
try {
|
||||
group.unsetPermission(n);
|
||||
} catch (ObjectLacksException ignored) {}
|
||||
});
|
||||
|
||||
Message.BULK_CHANGE_SUCCESS.send(sender, toRemove.size());
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
} else {
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SUCCESS.send(sender, group.getDisplayName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-111
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupSetInherit extends SubCommand<Group> {
|
||||
public GroupSetInherit() {
|
||||
super("setinherit", "Sets another group for the group to inherit permissions from",
|
||||
Permission.GROUP_SETINHERIT, Predicate.notInRange(1, 3),
|
||||
Arg.list(
|
||||
Arg.create("group", true, "the group to inherit from"),
|
||||
Arg.create("server", false, "the server to inherit the group on"),
|
||||
Arg.create("world", false, "the world to inherit the group on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
String groupName = args.get(0).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(groupName)) {
|
||||
sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!plugin.getDatastore().loadGroup(groupName)) {
|
||||
Message.GROUP_DOES_NOT_EXIST.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
Group group1 = plugin.getGroupManager().get(groupName);
|
||||
if (group1 == null) {
|
||||
Message.GROUP_DOES_NOT_EXIST.send(sender);
|
||||
return CommandResult.LOADING_ERROR;
|
||||
}
|
||||
|
||||
try {
|
||||
if (args.size() >= 2) {
|
||||
final String server = args.get(1).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
group.setInheritGroup(group1, server);
|
||||
Message.GROUP_SETINHERIT_SERVER_SUCCESS.send(sender, group.getDisplayName(), group1.getDisplayName(), server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("setinherit " + group1.getName() + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(2).toLowerCase();
|
||||
group.setInheritGroup(group1, server, world);
|
||||
Message.GROUP_SETINHERIT_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), group1.getDisplayName(), server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("setinherit " + group1.getName() + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.setInheritGroup(group1);
|
||||
Message.GROUP_SETINHERIT_SUCCESS.send(sender, group.getDisplayName(), group1.getDisplayName());
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("setinherit " + group1.getName())
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.GROUP_ALREADY_INHERITS.send(sender, group.getDisplayName(), group1.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
return getGroupTabComplete(args, plugin);
|
||||
}
|
||||
}
|
||||
-132
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.utils.DateUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupSetTempInherit extends SubCommand<Group> {
|
||||
public GroupSetTempInherit() {
|
||||
super("settempinherit", "Sets another group for the group to inherit permissions from temporarily",
|
||||
Permission.GROUP_SET_TEMP_INHERIT, Predicate.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("group", true, "the group to inherit from"),
|
||||
Arg.create("duration", true, "the duration of the group membership"),
|
||||
Arg.create("server", false, "the server to add the group on"),
|
||||
Arg.create("world", false, "the world to add the group on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
String groupName = args.get(0).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(groupName)) {
|
||||
sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
long duration;
|
||||
try {
|
||||
duration = Long.parseLong(args.get(1));
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
duration = DateUtil.parseDateDiff(args.get(1), true);
|
||||
} catch (DateUtil.IllegalDateException e1) {
|
||||
Message.ILLEGAL_DATE_ERROR.send(sender, args.get(1));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
if (DateUtil.shouldExpire(duration)) {
|
||||
Message.PAST_DATE_ERROR.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!plugin.getDatastore().loadGroup(groupName)) {
|
||||
Message.GROUP_DOES_NOT_EXIST.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
Group group1 = plugin.getGroupManager().get(groupName);
|
||||
if (group1 == null) {
|
||||
Message.GROUP_DOES_NOT_EXIST.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.setInheritGroup(group1, server, duration);
|
||||
Message.GROUP_SET_TEMP_INHERIT_SERVER_SUCCESS.send(sender, group.getDisplayName(), group1.getDisplayName(), server,
|
||||
DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("settempinherit " + group1.getName() + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.setInheritGroup(group1, server, world, duration);
|
||||
Message.GROUP_SET_TEMP_INHERIT_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), group1.getDisplayName(), server,
|
||||
world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("settempinherit " + group1.getName() + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.setInheritGroup(group1, duration);
|
||||
Message.GROUP_SET_TEMP_INHERIT_SUCCESS.send(sender, group.getDisplayName(), group1.getDisplayName(), DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("settempinherit " + group1.getName() + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.USER_ALREADY_TEMP_MEMBER_OF.send(sender, group.getDisplayName(), group1.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
return getGroupTabComplete(args, plugin);
|
||||
}
|
||||
}
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupUnsetTempInherit extends SubCommand<Group> {
|
||||
public GroupUnsetTempInherit() {
|
||||
super("unsettempinherit", "Removes a previously set temporary inheritance rule",
|
||||
Permission.GROUP_UNSET_TEMP_INHERIT, Predicate.notInRange(1, 3),
|
||||
Arg.list(
|
||||
Arg.create("group", true, "the group to uninherit"),
|
||||
Arg.create("server", false, "the server to remove the group on"),
|
||||
Arg.create("world", false, "the world to remove the group on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
String groupName = args.get(0).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(groupName)) {
|
||||
sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
try {
|
||||
if (args.size() >= 2) {
|
||||
final String server = args.get(1).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
group.unsetPermission("group." + groupName, server, true);
|
||||
Message.GROUP_UNSET_TEMP_INHERIT_SERVER_SUCCESS.send(sender, group.getDisplayName(), groupName, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("unsettempinherit " + groupName + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(2).toLowerCase();
|
||||
group.unsetPermission("group." + groupName, server, world, true);
|
||||
Message.GROUP_UNSET_TEMP_INHERIT_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), groupName, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("unsettempinherit " + groupName + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.unsetPermission("group." + groupName, true);
|
||||
Message.GROUP_UNSET_TEMP_INHERIT_SUCCESS.send(sender, group.getDisplayName(), groupName);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("unsettempinherit " + groupName)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.GROUP_DOES_NOT_TEMP_INHERIT.send(sender, group.getDisplayName(), groupName);
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
return getGroupTabComplete(args, plugin);
|
||||
}
|
||||
}
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupUnsetTempPermission extends SubCommand<Group> {
|
||||
public GroupUnsetTempPermission() {
|
||||
super("unsettemp", "Unsets a temporary permission for the group", Permission.GROUP_UNSET_TEMP_PERMISSION,
|
||||
Predicate.notInRange(1, 3),
|
||||
Arg.list(
|
||||
Arg.create("node", true, "the permission node to unset"),
|
||||
Arg.create("server", false, "the server to remove the permission node on"),
|
||||
Arg.create("world", false, "the world to remove the permission node on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
String node = args.get(0).replace("{SPACE}", " ");
|
||||
|
||||
if (ArgumentChecker.checkNode(node)) {
|
||||
sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.GROUP_USE_UNINHERIT.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
try {
|
||||
if (args.size() >= 2) {
|
||||
final String server = args.get(1).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
group.unsetPermission(node, server);
|
||||
Message.UNSET_TEMP_PERMISSION_SERVER_SUCCESS.send(sender, node, group.getDisplayName(), server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("unsettemp " + node + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(2).toLowerCase();
|
||||
group.unsetPermission(node, server, world);
|
||||
Message.UNSET_TEMP_PERMISSION_SERVER_WORLD_SUCCESS.send(sender, node, group.getDisplayName(), server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("unsettemp " + node + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node, true);
|
||||
Message.UNSET_TEMP_PERMISSION_SUCCESS.send(sender, node, group.getDisplayName());
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("unsettemp " + node)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_TEMP_PERMISSION.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserAddPrefix extends SubCommand<User> {
|
||||
public UserAddPrefix() {
|
||||
super("addprefix", "Adds a prefix to the user", Permission.USER_ADDPREFIX, Predicate.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the prefix at"),
|
||||
Arg.create("prefix", true, "the prefix string"),
|
||||
Arg.create("server", false, "the server to add the prefix on"),
|
||||
Arg.create("world", false, "the world to add the prefix on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
user.setPermission(node, true, server);
|
||||
Message.ADDPREFIX_SERVER_SUCCESS.send(sender, user.getName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
user.setPermission(node, true, server, world);
|
||||
Message.ADDPREFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.setPermission(node, true);
|
||||
Message.ADDPREFIX_SUCCESS.send(sender, user.getName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserAddSuffix extends SubCommand<User> {
|
||||
public UserAddSuffix() {
|
||||
super("addsuffix", "Adds a suffix to the user", Permission.USER_ADDSUFFIX, Predicate.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the suffix at"),
|
||||
Arg.create("suffix", true, "the suffix string"),
|
||||
Arg.create("server", false, "the server to add the suffix on"),
|
||||
Arg.create("world", false, "the world to add the suffix on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
user.setPermission(node, true, server);
|
||||
Message.ADDSUFFIX_SERVER_SUCCESS.send(sender, user.getName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addsuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
user.setPermission(node, true, server, world);
|
||||
Message.ADDSUFFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addsuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.setPermission(node, true);
|
||||
Message.ADDSUFFIX_SUCCESS.send(sender, user.getName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addsuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
-118
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.utils.DateUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserAddTempPrefix extends SubCommand<User> {
|
||||
public UserAddTempPrefix() {
|
||||
super("addtempprefix", "Adds a prefix to the user temporarily", Permission.USER_ADD_TEMP_PREFIX, Predicate.notInRange(3, 5),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the prefix at"),
|
||||
Arg.create("prefix", true, "the prefix string"),
|
||||
Arg.create("duration", true, "the duration until the prefix expires"),
|
||||
Arg.create("server", false, "the server to add the prefix on"),
|
||||
Arg.create("world", false, "the world to add the prefix on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String prefix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
long duration;
|
||||
try {
|
||||
duration = Long.parseLong(args.get(2));
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
duration = DateUtil.parseDateDiff(args.get(2), true);
|
||||
} catch (DateUtil.IllegalDateException e1) {
|
||||
Message.ILLEGAL_DATE_ERROR.send(sender, args.get(2));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
if (DateUtil.shouldExpire(duration)) {
|
||||
Message.PAST_DATE_ERROR.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 4) {
|
||||
final String server = args.get(3).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 4) {
|
||||
user.setPermission(node, true, server, duration);
|
||||
Message.ADD_TEMP_PREFIX_SERVER_SUCCESS.send(sender, user.getName(), prefix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(4).toLowerCase();
|
||||
user.setPermission(node, true, server, world, duration);
|
||||
Message.ADD_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), prefix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_PREFIX_SUCCESS.send(sender, user.getName(), prefix, priority, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
-118
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.utils.DateUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserAddTempSuffix extends SubCommand<User> {
|
||||
public UserAddTempSuffix() {
|
||||
super("addtempsuffix", "Adds a suffix to the user temporarily", Permission.USER_ADD_TEMP_SUFFIX, Predicate.notInRange(3, 5),
|
||||
Arg.list(
|
||||
Arg.create("priority", true, "the priority to add the suffix at"),
|
||||
Arg.create("suffix", true, "the suffix string"),
|
||||
Arg.create("duration", true, "the duration until the suffix expires"),
|
||||
Arg.create("server", false, "the server to add the suffix on"),
|
||||
Arg.create("world", false, "the world to add the suffix on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
final String suffix = args.get(1).replace("{SPACE}", " ");
|
||||
int priority;
|
||||
try {
|
||||
priority = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
Message.META_INVALID_PRIORITY.send(sender, args.get(0));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
long duration;
|
||||
try {
|
||||
duration = Long.parseLong(args.get(2));
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
duration = DateUtil.parseDateDiff(args.get(2), true);
|
||||
} catch (DateUtil.IllegalDateException e1) {
|
||||
Message.ILLEGAL_DATE_ERROR.send(sender, args.get(2));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
if (DateUtil.shouldExpire(duration)) {
|
||||
Message.PAST_DATE_ERROR.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
|
||||
|
||||
try {
|
||||
if (args.size() >= 4) {
|
||||
final String server = args.get(3).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 4) {
|
||||
user.setPermission(node, true, server, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, user.getName(), suffix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(4).toLowerCase();
|
||||
user.setPermission(node, true, server, world, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, user.getName(), suffix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SUCCESS.send(sender, user.getName(), suffix, priority, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.users.User;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class UserChatMeta extends SubCommand<User> {
|
||||
public UserChatMeta() {
|
||||
super("chatmeta", "Lists the user's chat meta", Permission.USER_CHATMETA, Predicate.alwaysFalse(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
SortedSet<Map.Entry<Integer, String>> prefixes = new TreeSet<>(Util.getMetaComparator().reversed());
|
||||
SortedSet<Map.Entry<Integer, String>> suffixes = new TreeSet<>(Util.getMetaComparator().reversed());
|
||||
|
||||
for (Node node : user.getAllNodes(null, Contexts.allowAll())) {
|
||||
if (!node.isSuffix() && !node.isPrefix()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (node.isServerSpecific()) {
|
||||
if (node.isWorldSpecific()) {
|
||||
sb.append("&6W=").append(node.getWorld().get()).append(" ");
|
||||
}
|
||||
sb.append("&6S=").append(node.getServer().get()).append(" ");
|
||||
}
|
||||
|
||||
if (node.isPrefix()) {
|
||||
sb.append(node.getPrefix().getValue());
|
||||
prefixes.add(new SimpleEntry<>(node.getPrefix().getKey(), sb.toString()));
|
||||
}
|
||||
|
||||
if (node.isSuffix()) {
|
||||
sb.append(node.getSuffix().getValue());
|
||||
suffixes.add(new SimpleEntry<>(node.getSuffix().getKey(), sb.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
if (prefixes.isEmpty()) {
|
||||
Message.CHAT_META_PREFIX_NONE.send(sender, user.getName());
|
||||
} else {
|
||||
Message.CHAT_META_PREFIX_HEADER.send(sender, user.getName());
|
||||
for (Map.Entry<Integer, String> e : prefixes) {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (suffixes.isEmpty()) {
|
||||
Message.CHAT_META_SUFFIX_NONE.send(sender, user.getName());
|
||||
} else {
|
||||
Message.CHAT_META_SUFFIX_HEADER.send(sender, user.getName());
|
||||
for (Map.Entry<Integer, String> e : suffixes) {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.users.User;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserListGroups extends SubCommand<User> {
|
||||
public UserListGroups() {
|
||||
super("listgroups", "Lists the groups the user is a member of", Permission.USER_LISTGROUPS, Predicate.alwaysFalse(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
Message.LISTGROUPS.send(sender, user.getName(), Util.permGroupsToString(user.getPermissions(false)));
|
||||
Message.LISTGROUPS_TEMP.send(sender, user.getName(), Util.tempGroupsToString(user.getPermissions(false)));
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.users.User;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserListNodes extends SubCommand<User> {
|
||||
public UserListNodes() {
|
||||
super("listnodes", "Lists the permission nodes the user has", Permission.USER_LISTNODES, Predicate.alwaysFalse(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
Message.LISTNODES.send(sender, user.getName(), Util.permNodesToString(user.getPermissions(false)));
|
||||
Message.LISTNODES_TEMP.send(sender, user.getName(), Util.tempNodesToString(user.getPermissions(false)));
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserRemoveTempGroup extends SubCommand<User> {
|
||||
public UserRemoveTempGroup() {
|
||||
super("removetempgroup", "Removes the user from a temporary group", Permission.USER_REMOVETEMPGROUP, Predicate.notInRange(1, 3),
|
||||
Arg.list(
|
||||
Arg.create("group", true, "the group to remove the user from"),
|
||||
Arg.create("server", false, "the server to remove the group on"),
|
||||
Arg.create("world", false, "the world to remove the group on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
String groupName = args.get(0).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(groupName)) {
|
||||
sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
try {
|
||||
if (args.size() >= 2) {
|
||||
final String server = args.get(1).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
user.unsetPermission("group." + groupName, server, true);
|
||||
Message.USER_REMOVETEMPGROUP_SERVER_SUCCESS.send(sender, user.getName(), groupName, server);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removetempgroup " + groupName + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(2).toLowerCase();
|
||||
user.unsetPermission("group." + groupName, server, world, true);
|
||||
Message.USER_REMOVETEMPGROUP_SERVER_WORLD_SUCCESS.send(sender, user.getName(), groupName, server, world);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removetempgroup " + groupName + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.unsetPermission("group." + groupName, true);
|
||||
Message.USER_REMOVETEMPGROUP_SUCCESS.send(sender, user.getName(), groupName);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("removetempgroup " + groupName)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.USER_NOT_TEMP_MEMBER_OF.send(sender, user.getName(), groupName);
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
return getGroupTabComplete(args, plugin);
|
||||
}
|
||||
}
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserSetPermission extends SubCommand<User> {
|
||||
public UserSetPermission() {
|
||||
super("set", "Sets a permission for the user", Permission.USER_SETPERMISSION, Predicate.notInRange(2, 4),
|
||||
Arg.list(
|
||||
Arg.create("node", true, "the permission node to set"),
|
||||
Arg.create("true|false", true, "the value of the node"),
|
||||
Arg.create("server", false, "the server to add the permission node on"),
|
||||
Arg.create("world", false, "the world to add the permission node on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
String node = args.get(0).replace("{SPACE}", " ");
|
||||
String bool = args.get(1).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(node)) {
|
||||
sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.USER_USE_ADDGROUP.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!bool.equalsIgnoreCase("true") && !bool.equalsIgnoreCase("false")) {
|
||||
sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
boolean b = Boolean.parseBoolean(bool);
|
||||
|
||||
try {
|
||||
if (args.size() >= 3) {
|
||||
final String server = args.get(2).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
user.setPermission(node, b, server);
|
||||
Message.SETPERMISSION_SERVER_SUCCESS.send(sender, node, bool, user.getName(), server);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("set " + node + " " + b + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
user.setPermission(node, b, server, world);
|
||||
Message.SETPERMISSION_SERVER_WORLD_SUCCESS.send(sender, node, bool, user.getName(), server, world);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("set " + node + " " + b + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.setPermission(node, b);
|
||||
Message.SETPERMISSION_SUCCESS.send(sender, node, bool, user.getName());
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("set " + node + " " + b)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HASPERMISSION.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
return getBoolTabComplete(args);
|
||||
}
|
||||
}
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.utils.DateUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserSetTempPermission extends SubCommand<User> {
|
||||
public UserSetTempPermission() {
|
||||
super("settemp", "Sets a permission for the user temporarily", Permission.USER_SET_TEMP_PERMISSION,
|
||||
Predicate.notInRange(3, 5),
|
||||
Arg.list(
|
||||
Arg.create("node", true, "the permission node to set"),
|
||||
Arg.create("true|false", true, "the value of the node"),
|
||||
Arg.create("duration", true, "the duration until the permission node expires"),
|
||||
Arg.create("server", false, "the server to add the permission node on"),
|
||||
Arg.create("world", false, "the world to add the permission node on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
String node = args.get(0).replace("{SPACE}", " ");
|
||||
String bool = args.get(1).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(node)) {
|
||||
sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.USER_USE_ADDGROUP.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!bool.equalsIgnoreCase("true") && !bool.equalsIgnoreCase("false")) {
|
||||
sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
boolean b = Boolean.parseBoolean(bool);
|
||||
|
||||
long duration;
|
||||
try {
|
||||
duration = Long.parseLong(args.get(2));
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
duration = DateUtil.parseDateDiff(args.get(2), true);
|
||||
} catch (DateUtil.IllegalDateException e1) {
|
||||
Message.ILLEGAL_DATE_ERROR.send(sender, args.get(2));
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
if (DateUtil.shouldExpire(duration)) {
|
||||
Message.PAST_DATE_ERROR.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
try {
|
||||
if (args.size() >= 4) {
|
||||
final String server = args.get(3).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 4) {
|
||||
user.setPermission(node, b, server, duration);
|
||||
Message.SETPERMISSION_TEMP_SERVER_SUCCESS.send(sender, node, bool, user.getName(), server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("settemp " + node + " " + b + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(4).toLowerCase();
|
||||
user.setPermission(node, b, server, world, duration);
|
||||
Message.SETPERMISSION_TEMP_SERVER_WORLD_SUCCESS.send(sender, node, bool, user.getName(), server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("settemp " + node + " " + b + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.setPermission(node, b, duration);
|
||||
Message.SETPERMISSION_TEMP_SUCCESS.send(sender, node, bool, user.getName(), DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("settemp " + node + " " + b + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_TEMP_PERMISSION.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
|
||||
return getBoolTabComplete(args);
|
||||
}
|
||||
}
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.user.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserUnSetPermission extends SubCommand<User> {
|
||||
public UserUnSetPermission() {
|
||||
super("unset", "Unsets a permission for the user", Permission.USER_UNSETPERMISSION, Predicate.notInRange(1, 3),
|
||||
Arg.list(
|
||||
Arg.create("node", true, "the permission node to unset"),
|
||||
Arg.create("server", false, "the server to remove the permission node on"),
|
||||
Arg.create("world", false, "the world to remove the permission node on")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
|
||||
String node = args.get(0).replace("{SPACE}", " ");
|
||||
|
||||
if (ArgumentChecker.checkNode(node)) {
|
||||
sendDetailedUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.USER_USE_REMOVEGROUP.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
try {
|
||||
if (args.size() >= 2) {
|
||||
final String server = args.get(1).toLowerCase();
|
||||
if (ArgumentChecker.checkServer(server)) {
|
||||
Message.SERVER_INVALID_ENTRY.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
user.unsetPermission(node, server);
|
||||
Message.UNSETPERMISSION_SERVER_SUCCESS.send(sender, node, user.getName(), server);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("unset " + node + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(2).toLowerCase();
|
||||
user.unsetPermission(node, server, world);
|
||||
Message.UNSETPERMISSION_SERVER_WORLD_SUCCESS.send(sender, node, user.getName(), server, world);
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("unset " + node + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
user.unsetPermission(node);
|
||||
Message.UNSETPERMISSION_SUCCESS.send(sender, node, user.getName());
|
||||
LogEntry.build().actor(sender).acted(user)
|
||||
.action("unset " + node)
|
||||
.build().submit(plugin, sender);
|
||||
}
|
||||
|
||||
save(user, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVEPERMISSION.send(sender, user.getName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
+47
-19
@@ -20,23 +20,26 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
package me.lucko.luckperms.common;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.implementation.ApiProvider;
|
||||
import me.lucko.luckperms.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.config.LPConfiguration;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.contexts.ContextManager;
|
||||
import me.lucko.luckperms.core.UuidCache;
|
||||
import me.lucko.luckperms.data.Importer;
|
||||
import me.lucko.luckperms.groups.GroupManager;
|
||||
import me.lucko.luckperms.storage.Datastore;
|
||||
import me.lucko.luckperms.tracks.TrackManager;
|
||||
import me.lucko.luckperms.users.UserManager;
|
||||
import me.lucko.luckperms.utils.LocaleManager;
|
||||
import me.lucko.luckperms.common.api.ApiProvider;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.common.commands.Sender;
|
||||
import me.lucko.luckperms.common.config.LPConfiguration;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.contexts.ContextManager;
|
||||
import me.lucko.luckperms.common.core.UuidCache;
|
||||
import me.lucko.luckperms.common.data.Importer;
|
||||
import me.lucko.luckperms.common.groups.GroupManager;
|
||||
import me.lucko.luckperms.common.storage.Datastore;
|
||||
import me.lucko.luckperms.common.tracks.TrackManager;
|
||||
import me.lucko.luckperms.common.users.UserManager;
|
||||
import me.lucko.luckperms.common.utils.BufferedRequest;
|
||||
import me.lucko.luckperms.common.utils.LocaleManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
@@ -64,6 +67,7 @@ public interface LuckPermsPlugin {
|
||||
ConsecutiveExecutor getConsecutiveExecutor();
|
||||
LocaleManager getLocaleManager();
|
||||
ContextManager getContextManager();
|
||||
CalculatorFactory getCalculatorFactory();
|
||||
|
||||
/**
|
||||
* @return the version of the plugin
|
||||
@@ -90,7 +94,10 @@ public interface LuckPermsPlugin {
|
||||
* @param uuid The player's uuid
|
||||
* @return a formatted status string
|
||||
*/
|
||||
Message getPlayerStatus(UUID uuid);
|
||||
default Message getPlayerStatus(UUID uuid) {
|
||||
UUID external = getUuidCache().getExternalUUID(uuid);
|
||||
return isOnline(external) ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of users online on the platform
|
||||
@@ -104,6 +111,19 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @return a {@link List} of senders online on the platform
|
||||
*/
|
||||
@@ -115,10 +135,11 @@ public interface LuckPermsPlugin {
|
||||
Sender getConsoleSender();
|
||||
|
||||
/**
|
||||
* Gets all possible permission nodes, used for resolving wildcards
|
||||
* @return a {@link List} of permission nodes
|
||||
* 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
|
||||
*/
|
||||
List<String> getPossiblePermissions();
|
||||
Set<Contexts> getPreProcessContexts(boolean op);
|
||||
|
||||
/**
|
||||
* Gets a set of players ignoring logging output
|
||||
@@ -157,7 +178,7 @@ public interface LuckPermsPlugin {
|
||||
/**
|
||||
* Runs an update task
|
||||
*/
|
||||
void runUpdateTask();
|
||||
BufferedRequest<Void> getUpdateTaskBuffer();
|
||||
|
||||
/**
|
||||
* Execute a runnable asynchronously
|
||||
@@ -171,4 +192,11 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
void doSync(Runnable r);
|
||||
|
||||
/**
|
||||
* Execute a runnable asynchronously on a loop
|
||||
* @param r the task to run
|
||||
* @param interval the time between runs in ticks
|
||||
*/
|
||||
void doAsyncRepeating(Runnable r, long interval);
|
||||
|
||||
}
|
||||
+23
-24
@@ -20,26 +20,25 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.implementation;
|
||||
package me.lucko.luckperms.common.api;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
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.api.implementation.internal.*;
|
||||
import me.lucko.luckperms.users.UserIdentifier;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.users.UserIdentifier;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.lucko.luckperms.api.implementation.internal.Utils.checkNode;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkNode;
|
||||
|
||||
/**
|
||||
* Implements the LuckPerms API using the plugin instance
|
||||
@@ -65,12 +64,12 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public void runUpdateTask() {
|
||||
plugin.runUpdateTask();
|
||||
plugin.getUpdateTaskBuffer().request();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getApiVersion() {
|
||||
return 2.11;
|
||||
return 2.13;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -95,17 +94,17 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public LPConfiguration getConfiguration() {
|
||||
return new LPConfigurationLink(plugin.getConfiguration());
|
||||
return new me.lucko.luckperms.common.api.internal.LPConfigurationLink(plugin.getConfiguration());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Datastore getDatastore() {
|
||||
return new DatastoreLink(plugin, plugin.getDatastore());
|
||||
return new me.lucko.luckperms.common.api.internal.DatastoreLink(plugin, plugin.getDatastore());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UuidCache getUuidCache() {
|
||||
return new UuidCacheLink(plugin.getUuidCache());
|
||||
return new me.lucko.luckperms.common.api.internal.UuidCacheLink(plugin.getUuidCache());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,12 +114,12 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public User getUser(@NonNull UUID uuid) {
|
||||
final me.lucko.luckperms.users.User user = plugin.getUserManager().get(uuid);
|
||||
final me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(uuid);
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new UserLink(user);
|
||||
return new me.lucko.luckperms.common.api.internal.UserLink(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,12 +129,12 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public User getUser(@NonNull String name) {
|
||||
final me.lucko.luckperms.users.User user = plugin.getUserManager().get(name);
|
||||
final me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(name);
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new UserLink(user);
|
||||
return new me.lucko.luckperms.common.api.internal.UserLink(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,7 +144,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Set<User> getUsers() {
|
||||
return plugin.getUserManager().getAll().values().stream().map(UserLink::new).collect(Collectors.toSet());
|
||||
return plugin.getUserManager().getAll().values().stream().map(me.lucko.luckperms.common.api.internal.UserLink::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -155,18 +154,18 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public void cleanupUser(@NonNull User user) {
|
||||
Utils.checkUser(user);
|
||||
plugin.getUserManager().cleanup(((UserLink) user).getMaster());
|
||||
me.lucko.luckperms.common.api.internal.Utils.checkUser(user);
|
||||
plugin.getUserManager().cleanup(((me.lucko.luckperms.common.api.internal.UserLink) user).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group getGroup(@NonNull String name) {
|
||||
final me.lucko.luckperms.groups.Group group = plugin.getGroupManager().get(name);
|
||||
final me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(name);
|
||||
if (group == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new GroupLink(group);
|
||||
return new me.lucko.luckperms.common.api.internal.GroupLink(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -176,7 +175,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Set<Group> getGroups() {
|
||||
return plugin.getGroupManager().getAll().values().stream().map(GroupLink::new).collect(Collectors.toSet());
|
||||
return plugin.getGroupManager().getAll().values().stream().map(me.lucko.luckperms.common.api.internal.GroupLink::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -186,12 +185,12 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Track getTrack(@NonNull String name) {
|
||||
final me.lucko.luckperms.tracks.Track track = plugin.getTrackManager().get(name);
|
||||
final me.lucko.luckperms.common.tracks.Track track = plugin.getTrackManager().get(name);
|
||||
if (track == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new TrackLink(track);
|
||||
return new me.lucko.luckperms.common.api.internal.TrackLink(track);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -201,7 +200,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Set<Track> getTracks() {
|
||||
return plugin.getTrackManager().getAll().values().stream().map(TrackLink::new).collect(Collectors.toSet());
|
||||
return plugin.getTrackManager().getAll().values().stream().map(me.lucko.luckperms.common.api.internal.TrackLink::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -211,7 +210,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Node.Builder buildNode(@NonNull String permission) throws IllegalArgumentException {
|
||||
return new me.lucko.luckperms.core.Node.Builder(checkNode(permission));
|
||||
return new me.lucko.luckperms.common.core.Node.Builder(checkNode(permission));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
+56
-137
@@ -20,37 +20,33 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.implementation.internal;
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.utils.AbstractFuture;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import static me.lucko.luckperms.api.implementation.internal.Utils.*;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.*;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Datastore} and {@link me.lucko.luckperms.storage.Datastore}
|
||||
* Provides a link between {@link Datastore} and {@link me.lucko.luckperms.common.storage.Datastore}
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class DatastoreLink implements Datastore {
|
||||
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final me.lucko.luckperms.storage.Datastore master;
|
||||
private final me.lucko.luckperms.common.storage.Datastore master;
|
||||
private final Async async;
|
||||
private final Sync sync;
|
||||
private final Future future;
|
||||
|
||||
public DatastoreLink(@NonNull LuckPermsPlugin plugin, @NonNull me.lucko.luckperms.storage.Datastore master) {
|
||||
public DatastoreLink(@NonNull LuckPermsPlugin plugin, @NonNull me.lucko.luckperms.common.storage.Datastore master) {
|
||||
this.plugin = plugin;
|
||||
this.master = master;
|
||||
this.async = new Async(master);
|
||||
@@ -93,7 +89,7 @@ public class DatastoreLink implements Datastore {
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Async implements Datastore.Async {
|
||||
private final me.lucko.luckperms.storage.Datastore master;
|
||||
private final me.lucko.luckperms.common.storage.Datastore master;
|
||||
|
||||
@Override
|
||||
public void logAction(@NonNull LogEntry entry, Callback<Boolean> callback) {
|
||||
@@ -206,68 +202,72 @@ public class DatastoreLink implements Datastore {
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Sync implements Datastore.Sync {
|
||||
private final me.lucko.luckperms.storage.Datastore master;
|
||||
private final me.lucko.luckperms.common.storage.Datastore master;
|
||||
|
||||
@Override
|
||||
public boolean logAction(@NonNull LogEntry entry) {
|
||||
return master.logAction(entry);
|
||||
return master.logAction(entry).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Log getLog() {
|
||||
return new LogLink(master.getLog());
|
||||
me.lucko.luckperms.common.data.Log log = master.getLog().getUnchecked();
|
||||
if (log == null) {
|
||||
return null;
|
||||
}
|
||||
return new LogLink(log);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadOrCreateUser(@NonNull UUID uuid, @NonNull String username) {
|
||||
return master.loadUser(uuid, checkUsername(username));
|
||||
return master.loadUser(uuid, checkUsername(username)).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadUser(@NonNull UUID uuid) {
|
||||
return master.loadUser(uuid, "null");
|
||||
return master.loadUser(uuid, "null").getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadUser(@NonNull UUID uuid, @NonNull String username) {
|
||||
return master.loadUser(uuid, checkUsername(username));
|
||||
return master.loadUser(uuid, checkUsername(username)).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveUser(@NonNull User user) {
|
||||
checkUser(user);
|
||||
return master.saveUser(((UserLink) user).getMaster());
|
||||
return master.saveUser(((UserLink) user).getMaster()).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cleanupUsers() {
|
||||
return master.cleanupUsers();
|
||||
return master.cleanupUsers().getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getUniqueUsers() {
|
||||
return master.getUniqueUsers();
|
||||
return master.getUniqueUsers().getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadGroup(@NonNull String name) {
|
||||
return master.createAndLoadGroup(checkName(name));
|
||||
return master.createAndLoadGroup(checkName(name)).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadGroup(@NonNull String name) {
|
||||
return master.loadGroup(checkName(name));
|
||||
return master.loadGroup(checkName(name)).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadAllGroups() {
|
||||
return master.loadAllGroups();
|
||||
return master.loadAllGroups().getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveGroup(@NonNull Group group) {
|
||||
checkGroup(group);
|
||||
return master.saveGroup(((GroupLink) group).getMaster());
|
||||
return master.saveGroup(((GroupLink) group).getMaster()).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -276,240 +276,159 @@ 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.deleteGroup(((GroupLink) group).getMaster()).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadTrack(@NonNull String name) {
|
||||
return master.createAndLoadTrack(checkName(name));
|
||||
return master.createAndLoadTrack(checkName(name)).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadTrack(@NonNull String name) {
|
||||
return master.loadTrack(checkName(name));
|
||||
return master.loadTrack(checkName(name)).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadAllTracks() {
|
||||
return master.loadAllTracks();
|
||||
return master.loadAllTracks().getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveTrack(@NonNull Track track) {
|
||||
checkTrack(track);
|
||||
return master.saveTrack(((TrackLink) track).getMaster());
|
||||
return master.saveTrack(((TrackLink) track).getMaster()).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteTrack(@NonNull Track track) {
|
||||
checkTrack(track);
|
||||
return master.deleteTrack(((TrackLink) track).getMaster());
|
||||
return master.deleteTrack(((TrackLink) track).getMaster()).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveUUIDData(@NonNull String username, @NonNull UUID uuid) {
|
||||
return master.saveUUIDData(checkUsername(username), uuid);
|
||||
return master.saveUUIDData(checkUsername(username), uuid).getUnchecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUUID(@NonNull String username) {
|
||||
return master.getUUID(checkUsername(username));
|
||||
return master.getUUID(checkUsername(username)).getUnchecked();
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Future implements Datastore.Future {
|
||||
private final me.lucko.luckperms.storage.Datastore master;
|
||||
private final me.lucko.luckperms.common.storage.Datastore master;
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> logAction(@NonNull LogEntry entry) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.logAction(entry, lpf);
|
||||
return lpf;
|
||||
return master.logAction(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Log> getLog() {
|
||||
LPFuture<Log> lpf = new LPFuture<>();
|
||||
master.getLog(log -> lpf.onComplete(new LogLink(log)));
|
||||
return lpf;
|
||||
AbstractFuture<Log> fut = new AbstractFuture<>();
|
||||
master.getLog(log -> fut.complete(new LogLink(log)));
|
||||
return fut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadOrCreateUser(@NonNull UUID uuid, @NonNull String username) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.loadUser(uuid, checkUsername(username), lpf);
|
||||
return lpf;
|
||||
return master.loadUser(uuid, checkUsername(username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadUser(@NonNull UUID uuid) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.loadUser(uuid, "null", lpf);
|
||||
return lpf;
|
||||
return master.loadUser(uuid, "null");
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadUser(@NonNull UUID uuid, @NonNull String username) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.loadUser(uuid, checkUsername(username), lpf);
|
||||
return lpf;
|
||||
return master.loadUser(uuid, checkUsername(username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> saveUser(@NonNull User user) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
checkUser(user);
|
||||
master.saveUser(((UserLink) user).getMaster(), lpf);
|
||||
return lpf;
|
||||
return master.saveUser(((UserLink) user).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> cleanupUsers() {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.cleanupUsers(lpf);
|
||||
return lpf;
|
||||
return master.cleanupUsers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Set<UUID>> getUniqueUsers() {
|
||||
LPFuture<Set<UUID>> lpf = new LPFuture<>();
|
||||
master.getUniqueUsers(lpf);
|
||||
return lpf;
|
||||
return master.getUniqueUsers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> createAndLoadGroup(@NonNull String name) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.createAndLoadGroup(checkName(name), lpf);
|
||||
return lpf;
|
||||
return master.createAndLoadGroup(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadGroup(@NonNull String name) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.loadGroup(checkName(name), lpf);
|
||||
return lpf;
|
||||
return master.loadGroup(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadAllGroups() {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.loadAllGroups(lpf);
|
||||
return lpf;
|
||||
return master.loadAllGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> saveGroup(@NonNull Group group) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
checkGroup(group);
|
||||
master.saveGroup(((GroupLink) group).getMaster(), lpf);
|
||||
return lpf;
|
||||
return master.saveGroup(((GroupLink) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> deleteGroup(@NonNull Group group) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
checkGroup(group);
|
||||
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
|
||||
throw new IllegalArgumentException("Cannot delete the default group.");
|
||||
}
|
||||
master.deleteGroup(((GroupLink) group).getMaster(), lpf);
|
||||
return lpf;
|
||||
return master.deleteGroup(((GroupLink) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> createAndLoadTrack(@NonNull String name) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.createAndLoadTrack(checkName(name), lpf);
|
||||
return lpf;
|
||||
return master.createAndLoadTrack(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadTrack(@NonNull String name) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.loadTrack(checkName(name), lpf);
|
||||
return lpf;
|
||||
return master.loadTrack(checkName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> loadAllTracks() {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.loadAllTracks(lpf);
|
||||
return lpf;
|
||||
return master.loadAllTracks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> saveTrack(@NonNull Track track) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
checkTrack(track);
|
||||
master.saveTrack(((TrackLink) track).getMaster(), lpf);
|
||||
return lpf;
|
||||
return master.saveTrack(((TrackLink) track).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> deleteTrack(@NonNull Track track) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
checkTrack(track);
|
||||
master.deleteTrack(((TrackLink) track).getMaster(), lpf);
|
||||
return lpf;
|
||||
return master.deleteTrack(((TrackLink) track).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<Boolean> saveUUIDData(@NonNull String username, @NonNull UUID uuid) {
|
||||
LPFuture<Boolean> lpf = new LPFuture<>();
|
||||
master.saveUUIDData(checkUsername(username), uuid, lpf);
|
||||
return lpf;
|
||||
return master.saveUUIDData(checkUsername(username), uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.concurrent.Future<UUID> getUUID(@NonNull String username) {
|
||||
LPFuture<UUID> lpf = new LPFuture<>();
|
||||
master.getUUID(checkUsername(username), lpf);
|
||||
return lpf;
|
||||
}
|
||||
}
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public static class LPFuture<T> implements Callback<T>, java.util.concurrent.Future<T> {
|
||||
private final CountDownLatch latch = new CountDownLatch(1);
|
||||
private T value;
|
||||
|
||||
@Override
|
||||
public void onComplete(T t) {
|
||||
value = t;
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@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 T get() throws InterruptedException {
|
||||
latch.await();
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
|
||||
if (latch.await(timeout, unit)) {
|
||||
return value;
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
return master.getUUID(checkUsername(username));
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.implementation.internal;
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -32,22 +32,22 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static me.lucko.luckperms.api.implementation.internal.Utils.*;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.*;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Group} and {@link me.lucko.luckperms.groups.Group}
|
||||
* Provides a link between {@link Group} and {@link me.lucko.luckperms.common.groups.Group}
|
||||
*/
|
||||
@EqualsAndHashCode(of = {"name"}, callSuper = false)
|
||||
@SuppressWarnings("unused")
|
||||
public class GroupLink extends PermissionHolderLink implements Group {
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final me.lucko.luckperms.groups.Group master;
|
||||
private final me.lucko.luckperms.common.groups.Group master;
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
public GroupLink(@NonNull me.lucko.luckperms.groups.Group master) {
|
||||
public GroupLink(@NonNull me.lucko.luckperms.common.groups.Group master) {
|
||||
super(master);
|
||||
this.master = master;
|
||||
this.name = master.getName();
|
||||
+3
-3
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.implementation.internal;
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.LPConfiguration;
|
||||
@@ -30,11 +30,11 @@ import me.lucko.luckperms.api.data.MySQLConfiguration;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link LPConfiguration} and {@link me.lucko.luckperms.config.LPConfiguration}
|
||||
* Provides a link between {@link LPConfiguration} and {@link me.lucko.luckperms.common.config.LPConfiguration}
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class LPConfigurationLink implements LPConfiguration {
|
||||
private final me.lucko.luckperms.config.LPConfiguration master;
|
||||
private final me.lucko.luckperms.common.config.LPConfiguration master;
|
||||
|
||||
@Override
|
||||
public String getServer() {
|
||||
+4
-4
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.implementation.internal;
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
@@ -31,14 +31,14 @@ import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.UUID;
|
||||
|
||||
import static me.lucko.luckperms.api.implementation.internal.Utils.checkName;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkName;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Log} and {@link me.lucko.luckperms.data.Log}
|
||||
* Provides a link between {@link Log} and {@link me.lucko.luckperms.common.data.Log}
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class LogLink implements Log {
|
||||
private final me.lucko.luckperms.data.Log master;
|
||||
private final me.lucko.luckperms.common.data.Log master;
|
||||
|
||||
@Override
|
||||
public SortedSet<LogEntry> getContent() {
|
||||
+11
-10
@@ -20,28 +20,29 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.implementation.internal;
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static me.lucko.luckperms.api.implementation.internal.Utils.*;
|
||||
import static me.lucko.luckperms.core.PermissionHolder.exportToLegacy;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.*;
|
||||
import static me.lucko.luckperms.common.core.PermissionHolder.exportToLegacy;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link PermissionHolder} and {@link me.lucko.luckperms.core.PermissionHolder}
|
||||
* Provides a link between {@link PermissionHolder} and {@link me.lucko.luckperms.common.core.PermissionHolder}
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@AllArgsConstructor
|
||||
public class PermissionHolderLink implements PermissionHolder {
|
||||
|
||||
@NonNull
|
||||
private final me.lucko.luckperms.core.PermissionHolder master;
|
||||
private final me.lucko.luckperms.common.core.PermissionHolder master;
|
||||
|
||||
@Override
|
||||
public String getObjectName() {
|
||||
@@ -65,12 +66,12 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
|
||||
@Override
|
||||
public Set<Node> getAllNodes() {
|
||||
return Collections.unmodifiableSet(master.getAllNodes(Collections.emptyList(), Contexts.allowAll()));
|
||||
return Collections.unmodifiableSet(master.getAllNodes(null, Contexts.allowAll()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<LocalizedNode> getAllNodes(@NonNull Contexts contexts) {
|
||||
return master.getAllNodes(Collections.emptyList(), contexts);
|
||||
return master.getAllNodes(null, contexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -247,7 +248,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
if (world != null && !world.equals("")) {
|
||||
context.put("world", world);
|
||||
}
|
||||
return master.exportNodes(new Contexts(context, true, true, true, true, true), Collections.emptyList(), false);
|
||||
return master.exportNodes(new Contexts(ContextSet.fromMap(context), true, true, true, true, true, false), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -259,7 +260,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
if (world != null && !world.equals("")) {
|
||||
context.put("world", world);
|
||||
}
|
||||
return master.exportNodes(new Contexts(context, true, true, true, true, true), Collections.emptyList(), false);
|
||||
return master.exportNodes(new Contexts(ContextSet.fromMap(context), true, true, true, true, true, false), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -283,7 +284,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
if (world != null && !world.equals("")) {
|
||||
extraContext.put("world", world);
|
||||
}
|
||||
return master.exportNodes(new Contexts(extraContext, includeGlobal, includeGlobal, applyGroups, true, true), possibleNodes, false);
|
||||
return master.exportNodes(new Contexts(ContextSet.fromMap(extraContext), includeGlobal, includeGlobal, applyGroups, true, true, false), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
+5
-5
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.implementation.internal;
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -33,22 +33,22 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static me.lucko.luckperms.api.implementation.internal.Utils.checkGroup;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.checkGroup;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link Track} and {@link me.lucko.luckperms.tracks.Track}
|
||||
* Provides a link between {@link Track} and {@link me.lucko.luckperms.common.tracks.Track}
|
||||
*/
|
||||
@EqualsAndHashCode(of = {"name"})
|
||||
@SuppressWarnings("unused")
|
||||
public class TrackLink implements Track {
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final me.lucko.luckperms.tracks.Track master;
|
||||
private final me.lucko.luckperms.common.tracks.Track master;
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
public TrackLink(@NonNull me.lucko.luckperms.tracks.Track master) {
|
||||
public TrackLink(@NonNull me.lucko.luckperms.common.tracks.Track master) {
|
||||
this.master = master;
|
||||
this.name = master.getName();
|
||||
}
|
||||
+28
-21
@@ -20,35 +20,37 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.implementation.internal;
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.api.caching.UserData;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static me.lucko.luckperms.api.implementation.internal.Utils.*;
|
||||
import static me.lucko.luckperms.common.api.internal.Utils.*;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link User} and {@link me.lucko.luckperms.users.User}
|
||||
* Provides a link between {@link User} and {@link me.lucko.luckperms.common.users.User}
|
||||
*/
|
||||
@EqualsAndHashCode(of = {"uuid"}, callSuper = false)
|
||||
@SuppressWarnings("unused")
|
||||
public class UserLink extends PermissionHolderLink implements User {
|
||||
|
||||
@Getter
|
||||
private final me.lucko.luckperms.users.User master;
|
||||
private final me.lucko.luckperms.common.users.User master;
|
||||
|
||||
@Getter
|
||||
private final UUID uuid;
|
||||
|
||||
public UserLink(@NonNull me.lucko.luckperms.users.User master) {
|
||||
public UserLink(@NonNull me.lucko.luckperms.common.users.User master) {
|
||||
super(master);
|
||||
this.master = master;
|
||||
this.uuid = master.getUuid();
|
||||
@@ -79,97 +81,102 @@ public class UserLink extends PermissionHolderLink implements User {
|
||||
|
||||
@Override
|
||||
public void refreshPermissions() {
|
||||
master.refreshPermissions();
|
||||
master.getRefreshBuffer().requestDirectly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UserData> getUserDataCache() {
|
||||
return Optional.ofNullable(master.getUserData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGroup(@NonNull Group group) {
|
||||
checkGroup(group);
|
||||
return master.isInGroup(((GroupLink) group).getMaster());
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGroup(@NonNull Group group, @NonNull String server) {
|
||||
checkGroup(group);
|
||||
return master.isInGroup(((GroupLink) group).getMaster(), server);
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster(), server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGroup(@NonNull Group group, @NonNull String server, @NonNull String world) {
|
||||
checkGroup(group);
|
||||
return master.isInGroup(((GroupLink) group).getMaster(), server, world);
|
||||
return master.inheritsGroup(((GroupLink) group).getMaster(), server, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.addGroup(((GroupLink) group).getMaster());
|
||||
master.setInheritGroup(((GroupLink) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group, @NonNull String server) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.addGroup(((GroupLink) group).getMaster(), checkServer(server));
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.addGroup(((GroupLink) group).getMaster(), checkServer(server), world);
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.addGroup(((GroupLink) group).getMaster(), checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.addGroup(((GroupLink) group).getMaster(), checkServer(server), checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException {
|
||||
checkGroup(group);
|
||||
master.addGroup(((GroupLink) group).getMaster(), checkServer(server), world, checkTime(expireAt));
|
||||
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world, checkTime(expireAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.removeGroup(((GroupLink) group).getMaster());
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.removeGroup(((GroupLink) group).getMaster(), temporary);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group, @NonNull String server) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.removeGroup(((GroupLink) group).getMaster(), checkServer(server));
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.removeGroup(((GroupLink) group).getMaster(), checkServer(server), world);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.removeGroup(((GroupLink) group).getMaster(), checkServer(server), temporary);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
checkGroup(group);
|
||||
master.removeGroup(((GroupLink) group).getMaster(), checkServer(server), world, temporary);
|
||||
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world, temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
+2
-2
@@ -20,13 +20,13 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.implementation.internal;
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.Track;
|
||||
import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
|
||||
@UtilityClass
|
||||
public class Utils {
|
||||
+3
-3
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.implementation.internal;
|
||||
package me.lucko.luckperms.common.api.internal;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.UuidCache;
|
||||
@@ -28,11 +28,11 @@ import me.lucko.luckperms.api.UuidCache;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link UuidCache} and {@link me.lucko.luckperms.core.UuidCache}
|
||||
* Provides a link between {@link UuidCache} and {@link me.lucko.luckperms.common.core.UuidCache}
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class UuidCacheLink implements UuidCache {
|
||||
private final me.lucko.luckperms.core.UuidCache master;
|
||||
private final me.lucko.luckperms.common.core.UuidCache master;
|
||||
|
||||
@Override
|
||||
public UUID getUUID(UUID external) {
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.caching;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.caching.MetaData;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Holds a user's cached meta for a given context
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class MetaCache implements MetaData {
|
||||
private final Contexts contexts;
|
||||
|
||||
private final SortedMap<Integer, String> prefixes = new TreeMap<>(Comparator.reverseOrder());
|
||||
private final SortedMap<Integer, String> suffixes = new TreeMap<>(Comparator.reverseOrder());
|
||||
|
||||
private final Map<String, String> meta = new HashMap<>();
|
||||
|
||||
public void loadMeta(SortedSet<LocalizedNode> nodes) {
|
||||
invalidateCache();
|
||||
|
||||
MutableContextSet contexts = MutableContextSet.fromSet(this.contexts.getContexts());
|
||||
String server = contexts.getValues("server").stream().findAny().orElse(null);
|
||||
String world = contexts.getValues("world").stream().findAny().orElse(null);
|
||||
contexts.removeAll("server");
|
||||
contexts.removeAll("world");
|
||||
|
||||
for (LocalizedNode ln : nodes) {
|
||||
Node n = ln.getNode();
|
||||
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.isMeta() && !n.isPrefix() && n.isSuffix()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnServer(server, this.contexts.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, this.contexts.isIncludeGlobalWorld(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyWithContext(contexts, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n.isPrefix()) {
|
||||
Map.Entry<Integer, String> value = n.getPrefix();
|
||||
synchronized (this.prefixes) {
|
||||
if (!this.prefixes.containsKey(value.getKey())) {
|
||||
this.prefixes.put(value.getKey(), value.getValue());
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n.isSuffix()) {
|
||||
Map.Entry<Integer, String> value = n.getSuffix();
|
||||
synchronized (this.suffixes) {
|
||||
if (!this.suffixes.containsKey(value.getKey())) {
|
||||
this.suffixes.put(value.getKey(), value.getValue());
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n.isMeta()) {
|
||||
Map.Entry<String, String> meta = n.getMeta();
|
||||
synchronized (this.meta) {
|
||||
if (!this.meta.containsKey(meta.getKey())) {
|
||||
this.meta.put(meta.getKey(), meta.getValue());
|
||||
}
|
||||
}
|
||||
this.meta.put(meta.getKey(), meta.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void invalidateCache() {
|
||||
synchronized (meta) {
|
||||
meta.clear();
|
||||
}
|
||||
synchronized (prefixes) {
|
||||
prefixes.clear();
|
||||
}
|
||||
synchronized (suffixes) {
|
||||
suffixes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMeta() {
|
||||
synchronized (meta) {
|
||||
return ImmutableMap.copyOf(meta);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedMap<Integer, String> getPrefixes() {
|
||||
synchronized (prefixes) {
|
||||
return ImmutableSortedMap.copyOfSorted(prefixes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedMap<Integer, String> getSuffixes() {
|
||||
synchronized (suffixes) {
|
||||
return ImmutableSortedMap.copyOfSorted(suffixes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefix() {
|
||||
synchronized (prefixes) {
|
||||
if (prefixes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return prefixes.get(prefixes.firstKey());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuffix() {
|
||||
synchronized (suffixes) {
|
||||
if (suffixes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return suffixes.get(suffixes.firstKey());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.caching;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.caching.PermissionData;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.calculators.PermissionCalculator;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Holds a user's cached permissions for a given context
|
||||
*/
|
||||
public class PermissionCache implements PermissionData {
|
||||
|
||||
/**
|
||||
* The raw set of permission strings.
|
||||
*/
|
||||
private final Map<String, Boolean> permissions;
|
||||
|
||||
/**
|
||||
* The calculator instance responsible for resolving the raw permission strings in the permission map.
|
||||
* This calculator will attempt to resolve all regex/wildcard permissions, as well as account for
|
||||
* defaults & attachment permissions (if applicable.)
|
||||
*/
|
||||
private final PermissionCalculator calculator;
|
||||
|
||||
public PermissionCache(Contexts contexts, User user, CalculatorFactory calculatorFactory) {
|
||||
permissions = new ConcurrentHashMap<>();
|
||||
calculator = calculatorFactory.build(contexts, user, permissions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCache() {
|
||||
calculator.invalidateCache();
|
||||
}
|
||||
|
||||
public void setPermissions(Map<String, Boolean> permissions) {
|
||||
this.permissions.clear();
|
||||
this.permissions.putAll(permissions);
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
public void comparePermissions(Map<String, Boolean> toApply) {
|
||||
if (!permissions.equals(toApply)) {
|
||||
setPermissions(toApply);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getImmutableBacking() {
|
||||
return ImmutableMap.copyOf(permissions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tristate getPermissionValue(@NonNull String permission) {
|
||||
return calculator.getPermissionValue(permission);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.caching;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.caching.MetaData;
|
||||
import me.lucko.luckperms.api.caching.PermissionData;
|
||||
import me.lucko.luckperms.api.caching.UserData;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Holds an easily accessible cache of a user's data in a number of contexts
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class UserCache implements UserData {
|
||||
|
||||
/**
|
||||
* The user whom this data instance is representing
|
||||
*/
|
||||
private final User user;
|
||||
|
||||
/**
|
||||
* A provider of {@link me.lucko.luckperms.common.calculators.PermissionCalculator}s for the instance
|
||||
*/
|
||||
private final CalculatorFactory calculatorFactory;
|
||||
|
||||
private final LoadingCache<Contexts, PermissionCache> permission = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<Contexts, PermissionCache>() {
|
||||
@Override
|
||||
public PermissionCache load(Contexts contexts) {
|
||||
return calculatePermissions(contexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<PermissionCache> reload(Contexts contexts, PermissionCache oldData) {
|
||||
oldData.comparePermissions(user.exportNodes(contexts, true));
|
||||
return Futures.immediateFuture(oldData);
|
||||
}
|
||||
});
|
||||
|
||||
private final LoadingCache<Contexts, MetaCache> meta = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<Contexts, MetaCache>() {
|
||||
@Override
|
||||
public MetaCache load(Contexts contexts) {
|
||||
return calculateMeta(contexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<MetaCache> reload(Contexts contexts, MetaCache oldData) {
|
||||
oldData.loadMeta(user.getAllNodes(null, contexts));
|
||||
return Futures.immediateFuture(oldData);
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public PermissionData getPermissionData(@NonNull Contexts contexts) {
|
||||
return permission.getUnchecked(contexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetaData getMetaData(@NonNull Contexts contexts) {
|
||||
return meta.getUnchecked(contexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionCache calculatePermissions(@NonNull Contexts contexts) {
|
||||
PermissionCache data = new PermissionCache(contexts, user, calculatorFactory);
|
||||
data.setPermissions(user.exportNodes(contexts, true));
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetaCache calculateMeta(@NonNull Contexts contexts) {
|
||||
MetaCache data = new MetaCache(contexts);
|
||||
data.loadMeta(user.getAllNodes(null, contexts));
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculatePermissions(@NonNull Contexts contexts) {
|
||||
permission.refresh(contexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculateMeta(@NonNull Contexts contexts) {
|
||||
meta.refresh(contexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculatePermissions() {
|
||||
Set<Contexts> keys = ImmutableSet.copyOf(permission.asMap().keySet());
|
||||
keys.forEach(permission::refresh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculateMeta() {
|
||||
Set<Contexts> keys = ImmutableSet.copyOf(meta.asMap().keySet());
|
||||
keys.forEach(meta::refresh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preCalculate(@NonNull Set<Contexts> contexts) {
|
||||
contexts.forEach(this::preCalculate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preCalculate(@NonNull Contexts contexts) {
|
||||
permission.getUnchecked(contexts);
|
||||
meta.getUnchecked(contexts);
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
permission.invalidateAll();
|
||||
meta.invalidateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidatePermissionCalculators() {
|
||||
permission.asMap().values().forEach(PermissionData::invalidateCache);
|
||||
}
|
||||
|
||||
}
|
||||
+8
-22
@@ -20,32 +20,18 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.vault.cache;
|
||||
package me.lucko.luckperms.common.calculators;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.common.users.User;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class ChatCache {
|
||||
private final Map<String, String> context;
|
||||
/**
|
||||
* Creates a calculator instance given a set of contexts
|
||||
*/
|
||||
public interface CalculatorFactory {
|
||||
|
||||
@Setter
|
||||
private String prefix = null;
|
||||
|
||||
@Setter
|
||||
private String suffix = null;
|
||||
|
||||
private Map<String, String> meta = new ConcurrentHashMap<>();
|
||||
|
||||
public void invalidateCache() {
|
||||
prefix = null;
|
||||
suffix = null;
|
||||
meta.clear();
|
||||
}
|
||||
PermissionCalculator build(Contexts contexts, User user, Map<String, Boolean> map);
|
||||
|
||||
}
|
||||
+3
-6
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.calculators;
|
||||
package me.lucko.luckperms.common.calculators;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
@@ -36,10 +36,7 @@ public class MapProcessor implements PermissionProcessor {
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
if (map.containsKey(permission)) {
|
||||
return Tristate.fromBoolean(map.get(permission));
|
||||
}
|
||||
|
||||
return Tristate.UNDEFINED;
|
||||
Boolean b = map.get(permission);
|
||||
return b == null ? Tristate.UNDEFINED : Tristate.fromBoolean(b);
|
||||
}
|
||||
}
|
||||
+15
-7
@@ -20,15 +20,16 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.calculators;
|
||||
package me.lucko.luckperms.common.calculators;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Calculates and caches permissions
|
||||
@@ -39,15 +40,22 @@ public class PermissionCalculator {
|
||||
private final String objectName;
|
||||
private final boolean debug;
|
||||
private final List<PermissionProcessor> processors;
|
||||
private final Map<String, Tristate> cache = new ConcurrentHashMap<>();
|
||||
|
||||
private final LoadingCache<String, Tristate> cache = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<String, Tristate>() {
|
||||
@Override
|
||||
public Tristate load(String s) {
|
||||
return lookupPermissionValue(s);
|
||||
}
|
||||
});
|
||||
|
||||
public void invalidateCache() {
|
||||
cache.clear();
|
||||
cache.invalidateAll();
|
||||
}
|
||||
|
||||
public Tristate getPermissionValue(String permission) {
|
||||
permission = permission.toLowerCase();
|
||||
Tristate t = cache.computeIfAbsent(permission, this::lookupPermissionValue);
|
||||
Tristate t = cache.getUnchecked(permission);
|
||||
|
||||
if (debug) {
|
||||
plugin.getLog().info("Checking if " + objectName + " has permission: " + permission + " - (" + t.toString() + ")");
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.calculators;
|
||||
package me.lucko.luckperms.common.calculators;
|
||||
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
|
||||
+2
-2
@@ -20,12 +20,12 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.calculators;
|
||||
package me.lucko.luckperms.common.calculators;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.common.constants.Patterns;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
+12
-24
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.calculators;
|
||||
package me.lucko.luckperms.common.calculators;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
@@ -38,43 +38,31 @@ public class WildcardProcessor implements PermissionProcessor {
|
||||
public Tristate hasPermission(String permission) {
|
||||
String node = permission;
|
||||
|
||||
while (node.contains(".")) {
|
||||
while (true) {
|
||||
int endIndex = node.lastIndexOf('.');
|
||||
if (endIndex == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
node = node.substring(0, endIndex);
|
||||
if (!isEmpty(node)) {
|
||||
if (map.containsKey(node + ".*")) {
|
||||
return Tristate.fromBoolean(map.get(node + ".*"));
|
||||
if (!node.isEmpty()) {
|
||||
Boolean b = map.get(node + ".*");
|
||||
if (b != null) {
|
||||
return Tristate.fromBoolean(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (map.containsKey("'*'")) {
|
||||
return Tristate.fromBoolean(map.get("'*'"));
|
||||
Boolean b = map.get("'*'");
|
||||
if (b != null) {
|
||||
return Tristate.fromBoolean(b);
|
||||
}
|
||||
|
||||
if (map.containsKey("*")) {
|
||||
return Tristate.fromBoolean(map.get("*"));
|
||||
b = map.get("*");
|
||||
if (b != null) {
|
||||
return Tristate.fromBoolean(b);
|
||||
}
|
||||
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
private static boolean isEmpty(String s) {
|
||||
if (s.equals("")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char[] chars = s.toCharArray();
|
||||
for (char c : chars) {
|
||||
if (c != '.') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands;
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.AccessLevel;
|
||||
+108
-16
@@ -20,26 +20,26 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands;
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.commands.group.CreateGroup;
|
||||
import me.lucko.luckperms.commands.group.DeleteGroup;
|
||||
import me.lucko.luckperms.commands.group.GroupMainCommand;
|
||||
import me.lucko.luckperms.commands.group.ListGroups;
|
||||
import me.lucko.luckperms.commands.log.LogMainCommand;
|
||||
import me.lucko.luckperms.commands.migration.MigrationMainCommand;
|
||||
import me.lucko.luckperms.commands.misc.*;
|
||||
import me.lucko.luckperms.commands.track.CreateTrack;
|
||||
import me.lucko.luckperms.commands.track.DeleteTrack;
|
||||
import me.lucko.luckperms.commands.track.ListTracks;
|
||||
import me.lucko.luckperms.commands.track.TrackMainCommand;
|
||||
import me.lucko.luckperms.commands.user.UserMainCommand;
|
||||
import me.lucko.luckperms.commands.usersbulkedit.UsersBulkEditMainCommand;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.commands.group.CreateGroup;
|
||||
import me.lucko.luckperms.common.commands.group.DeleteGroup;
|
||||
import me.lucko.luckperms.common.commands.group.GroupMainCommand;
|
||||
import me.lucko.luckperms.common.commands.group.ListGroups;
|
||||
import me.lucko.luckperms.common.commands.log.LogMainCommand;
|
||||
import me.lucko.luckperms.common.commands.migration.MigrationMainCommand;
|
||||
import me.lucko.luckperms.common.commands.misc.*;
|
||||
import me.lucko.luckperms.common.commands.track.CreateTrack;
|
||||
import me.lucko.luckperms.common.commands.track.DeleteTrack;
|
||||
import me.lucko.luckperms.common.commands.track.ListTracks;
|
||||
import me.lucko.luckperms.common.commands.track.TrackMainCommand;
|
||||
import me.lucko.luckperms.common.commands.user.UserMainCommand;
|
||||
import me.lucko.luckperms.common.commands.usersbulkedit.UsersBulkEditMainCommand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -133,8 +133,11 @@ public class CommandManager {
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
List<String> arguments = new ArrayList<>(args);
|
||||
handleRewrites(arguments);
|
||||
|
||||
try {
|
||||
return main.execute(plugin, sender, new ArrayList<>(args.subList(1, args.size())), label);
|
||||
return main.execute(plugin, sender, arguments.subList(1, arguments.size()), label);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
@@ -184,4 +187,93 @@ public class CommandManager {
|
||||
.filter(c -> c.isAuthorized(sender))
|
||||
.forEach(c -> Util.sendPluginMessage(sender, "&3> &a" + String.format(c.getUsage(), label)));
|
||||
}
|
||||
|
||||
private static void handleRewrites(List<String> args) {
|
||||
if (args.size() >= 3) {
|
||||
if (!args.get(0).equalsIgnoreCase("user") && !args.get(0).equalsIgnoreCase("group")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String s = args.get(2).toLowerCase();
|
||||
switch (s) {
|
||||
// Provide aliases
|
||||
case "p":
|
||||
case "perm":
|
||||
case "perms":
|
||||
args.remove(2);
|
||||
args.add(2, "permission");
|
||||
break;
|
||||
case "m":
|
||||
args.remove(2);
|
||||
args.add(2, "meta");
|
||||
break;
|
||||
case "i":
|
||||
case "inherit":
|
||||
case "inheritances":
|
||||
case "group":
|
||||
case "rank":
|
||||
args.remove(2);
|
||||
args.add(2, "parent");
|
||||
break;
|
||||
|
||||
// Provide backwards compatibility
|
||||
case "listnodes":
|
||||
args.remove(2);
|
||||
args.add(2, "permission");
|
||||
args.add(3, "info");
|
||||
break;
|
||||
case "set":
|
||||
case "unset":
|
||||
case "settemp":
|
||||
case "unsettemp":
|
||||
args.add(2, "permission");
|
||||
break;
|
||||
case "listgroups":
|
||||
args.remove(2);
|
||||
args.add(2, "parent");
|
||||
args.add(3, "info");
|
||||
break;
|
||||
case "addgroup":
|
||||
case "setinherit":
|
||||
args.remove(2);
|
||||
args.add(2, "parent");
|
||||
args.add(3, "add");
|
||||
break;
|
||||
case "removegroup":
|
||||
case "unsetinherit":
|
||||
args.remove(2);
|
||||
args.add(2, "parent");
|
||||
args.add(3, "remove");
|
||||
break;
|
||||
case "addtempgroup":
|
||||
case "settempinherit":
|
||||
args.remove(2);
|
||||
args.add(2, "parent");
|
||||
args.add(3, "addtemp");
|
||||
break;
|
||||
case "removetempgroup":
|
||||
case "unsettempinherit":
|
||||
args.remove(2);
|
||||
args.add(2, "parent");
|
||||
args.add(3, "removetemp");
|
||||
break;
|
||||
case "chatmeta":
|
||||
args.remove(2);
|
||||
args.add(2, "meta");
|
||||
args.add(3, "info");
|
||||
break;
|
||||
case "addprefix":
|
||||
case "addsuffix":
|
||||
case "removeprefix":
|
||||
case "removesuffix":
|
||||
case "addtempprefix":
|
||||
case "addtempsuffix":
|
||||
case "removetempprefix":
|
||||
case "removetempsuffix":
|
||||
args.add(2, "meta");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands;
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands;
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
+3
-3
@@ -20,13 +20,13 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands;
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.common.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands;
|
||||
package me.lucko.luckperms.common.commands;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
Loaded 100 of 291 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user