Compare commits

..
32 Commits
Author SHA1 Message Date
Luck 383276f47a Refactor contexts, expose cached data in the API & release 2.13 2016-10-23 16:46:53 +01:00
Luck 33c78e4a17 Use LoadingCache instead of a regular map + more datastore fixes 2016-10-22 20:39:26 +01:00
Luck 55a0de7899 Lower buffer time to 1 second. Should resolve any issues with changes being overridden. (related: #32) 2016-10-22 18:52:51 +01:00
Luck 6b3aab66bf Fix some #saveX methods being waited for, when they can just be ran async 2016-10-22 09:35:11 +01:00
Luck 77e70ef8d3 Fix deadlocks caused by waiting for async operations to complete before the scheduler has started 2016-10-22 09:21:30 +01:00
Luck 9b92143501 prevent logins until the plugin has started 2016-10-22 00:07:30 +01:00
Luck 87f94f6b8f add started value to bukkit plugin 2016-10-22 00:05:33 +01:00
Luck 5d955e77b6 Make the max pool size configurable 2016-10-21 22:22:06 +01:00
Luck 270a276b98 Refactor SQL storage to not hold onto connections for as long 2016-10-21 22:07:14 +01:00
Luck be7d914e39 Finish the buffering refactor - still WIP. Towards #32 2016-10-21 18:34:53 +01:00
Luck 37fc00cce8 Refactoring storage - WIP. Towards #32 2016-10-20 21:55:34 +01:00
Luck 0d515abadb Cleanup some bad code in SQLDatastore. Might help #32 2016-10-19 23:30:30 +01:00
Luck daef01194e Shade MySQL connector into Sponge jar. Resolves #31 2016-10-19 22:23:43 +01:00
Luck 258bf1cc41 small cleanup 2016-10-19 20:57:53 +01:00
Luck ce3d7829d7 Update internal permissions to match the new command layouts 2016-10-19 20:14:16 +01:00
Luck c66a01c1a6 Fix temporary permission expirations never persisting. Fixes #30 2016-10-19 17:37:26 +01:00
Luck d113a92ce5 Cleanup permission calculation 2016-10-18 20:48:59 +01:00
Luck 7b655d12df Add set-primary-group option to the default assignments 2016-10-17 18:23:41 +01:00
Luck a4c872f1e8 Fix per-world permissions not working until a user switches worlds 2016-10-17 17:10:02 +01:00
Luck 0e7d9bf9c1 Bump hikari version 2016-10-16 21:05:25 +01:00
Luck 6252a5bc75 Fix invalid property 2016-10-16 20:53:12 +01:00
Luck e4e80c9c31 Update to SpongeAPI 5.0.0 release 2016-10-16 18:13:55 +01:00
Luck 165c5610c3 Add extra Hikari flag 2016-10-16 17:24:02 +01:00
Luck 13fbc7dd39 Implement default assignment system (#25) 2016-10-16 13:58:57 +01:00
Luck 02a75fc32a Reimplement autoop on Bukkit & other misc fixes 2016-10-15 21:04:04 +01:00
Luck 699c4d107b Swap the javaassist maven plugin with a better method 2016-10-15 08:59:49 +01:00
Luck e4810302e1 Implement meta / Sponge option commands & fix meta caching system. Fully resolves #23 2016-10-14 22:49:32 +01:00
Luck 73f10cad66 Make the recent command changes backwards compatible 2016-10-14 20:42:00 +01:00
Luck f1d670dc46 refactor permission commands 2016-10-14 19:55:22 +01:00
Luck 045539c752 refactor inheritance commands 2016-10-14 19:19:57 +01:00
Luck 782c09b686 Refine bulk group edit primary group check 2016-10-13 21:29:30 +01:00
Luck 6109718c67 Cleanup some remaining TODOs 2016-10-13 21:16:34 +01:00
182 changed files with 5609 additions and 3397 deletions

No files matched your search

+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.12-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,23 +40,19 @@ 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, 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(Map<String, String> context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
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, boolean op) {
public Contexts(ContextSet context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
if (context == null) {
throw new NullPointerException("context");
}
this.context = ImmutableMap.copyOf(context);
this.context = context.makeImmutable();
this.includeGlobal = includeGlobal;
this.includeGlobalWorld = includeGlobalWorld;
this.applyGroups = applyGroups;
@@ -66,16 +61,34 @@ public class Contexts {
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
@@ -110,12 +123,23 @@ 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
@@ -166,7 +190,7 @@ public class Contexts {
public String toString() {
return "Contexts(" +
"context=" + this.getContext() + ", " +
"context=" + this.getContexts() + ", " +
"op=" + this.isOp() + ", " +
"includeGlobal=" + this.isIncludeGlobal() + ", " +
"includeGlobalWorld=" + this.isIncludeGlobalWorld() + ", " +
@@ -190,8 +214,8 @@ public class Contexts {
if (o == this) return true;
if (!(o instanceof Contexts)) return false;
final Contexts other = (Contexts) o;
final Object this$context = this.getContext();
final Object other$context = other.getContext();
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;
@@ -210,7 +234,7 @@ public class Contexts {
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $context = this.getContext();
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);
@@ -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();
}
@@ -0,0 +1,55 @@
/*
* 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.Tristate;
import java.util.Map;
/**
* Holds cached Permission lookup data for a specific set of contexts
* @since 2.13
*/
public interface PermissionData {
/**
* Gets a permission value for the given permission node
* @param permission the permission node
* @return a tristate result
* @throws NullPointerException if permission is null
*/
Tristate getPermissionValue(String permission);
/**
* Invalidates the underlying permission calculator cache.
* Can be called to allow for an update in defaults.
*/
void invalidateCache();
/**
* Gets an immutable copy of the permission map backing the permission calculator
* @return an immutable set of permissions
*/
Map<String, Boolean> getImmutableBacking();
}
@@ -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();
}
@@ -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());
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.12-SNAPSHOT</version>
<version>2.13-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.12-SNAPSHOT</version>
<version>2.13-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.12-SNAPSHOT</version>
<version>2.13-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -28,7 +28,10 @@ import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
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;
@@ -65,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) {
@@ -48,7 +48,7 @@ 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());
@@ -61,7 +61,7 @@ class BukkitListener extends AbstractListener implements Listener {
@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
onLeave(e.getUniqueId());
@@ -28,6 +28,9 @@ 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.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;
@@ -36,7 +39,7 @@ 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.constants.Permission;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.contexts.ServerCalculator;
import me.lucko.luckperms.common.core.UuidCache;
@@ -48,12 +51,12 @@ 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;
@@ -84,6 +87,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private ContextManager<Player> contextManager;
private WorldCalculator worldCalculator;
private CalculatorFactory calculatorFactory;
private BufferedRequest<Void> updateTaskBuffer;
private boolean started = false;
@Override
public void onEnable() {
@@ -135,10 +140,23 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
contextManager.registerCalculator(worldCalculator);
contextManager.registerCalculator(new ServerCalculator<>(getConfiguration().getServer()));
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);
@@ -167,22 +185,20 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// 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();
@@ -205,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();
@@ -220,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();
@@ -235,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.common.constants.Permission.LOG_NOTIFY)))
.filter(me.lucko.luckperms.common.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());
}
@@ -250,32 +276,32 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
@Override
public Set<Contexts> getPreProcessContexts(boolean op) {
Set<Map<String, String>> c = new HashSet<>();
c.add(Collections.emptyMap());
c.add(Collections.singletonMap("server", getConfiguration().getServer()));
Set<ContextSet> c = new HashSet<>();
c.add(ContextSet.empty());
c.add(ContextSet.singleton("server", getConfiguration().getServer()));
// Pre process all worlds
c.addAll(getServer().getWorlds().stream()
.map(World::getName)
.map(s -> {
Map<String, String> map = new HashMap<>();
map.put("server", getConfiguration().getServer());
map.put("world", s);
return map;
MutableContextSet set = new MutableContextSet();
set.add("server", getConfiguration().getServer());
set.add("world", s);
return set.makeImmutable();
})
.collect(Collectors.toList())
);
// Pre process the separate Vault server, if any
if (!getConfiguration().getServer().equals(getConfiguration().getVaultServer())) {
c.add(Collections.singletonMap("server", getConfiguration().getVaultServer()));
c.add(ContextSet.singleton("server", getConfiguration().getVaultServer()));
c.addAll(getServer().getWorlds().stream()
.map(World::getName)
.map(s -> {
Map<String, String> map = new HashMap<>();
map.put("server", getConfiguration().getVaultServer());
map.put("world", s);
return map;
MutableContextSet set = new MutableContextSet();
set.add("server", getConfiguration().getVaultServer());
set.add("world", s);
return set.makeImmutable();
})
.collect(Collectors.toList())
);
@@ -285,8 +311,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// Convert to full Contexts
contexts.addAll(c.stream()
.map(map -> new Contexts(
map,
.map(set -> new Contexts(
set,
getConfiguration().isIncludingGlobalPerms(),
getConfiguration().isIncludingGlobalWorldPerms(),
true,
@@ -338,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.common.constants.Permission p : me.lucko.luckperms.common.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))));
}
}
@@ -26,12 +26,14 @@ import com.google.common.collect.Maps;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
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());
@@ -44,10 +44,8 @@ public class AttachmentProcessor implements PermissionProcessor {
return Tristate.UNDEFINED;
}
if (m.containsKey(permission)) {
return Tristate.fromBoolean(m.get(permission).getValue());
}
return Tristate.UNDEFINED;
PermissionAttachmentInfo pai = m.get(permission);
return pai == null ? Tristate.UNDEFINED : Tristate.fromBoolean(pai.getValue());
}
}
@@ -20,25 +20,28 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.user.subcommands;
package me.lucko.luckperms.bukkit.calculators;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.users.User;
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.List;
import java.util.Map;
import java.util.Optional;
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);
}
public class AutoOPListener implements ContextListener<Player> {
@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;
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;
}
Map<String, Boolean> backing = permissible.getUser().getUserData().getPermissionData(permissible.calculateContexts()).getImmutableBacking();
boolean op = Optional.ofNullable(backing.get("luckperms.autoop")).orElse(false);
subject.setOp(op);
}
}
@@ -41,10 +41,6 @@ public class DefaultsProcessor implements PermissionProcessor {
}
Permission defPerm = Bukkit.getServer().getPluginManager().getPermission(permission);
if (defPerm != null) {
return Tristate.fromBoolean(defPerm.getDefault().getValue(isOp));
} else {
return Tristate.UNDEFINED;
}
return defPerm == null ? Tristate.UNDEFINED : Tristate.fromBoolean(defPerm.getDefault().getValue(isOp));
}
}
@@ -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
@@ -26,6 +26,7 @@ import lombok.Getter;
import lombok.NonNull;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.users.User;
import org.bukkit.Bukkit;
@@ -40,7 +41,7 @@ import java.util.stream.Collectors;
/**
* Modified PermissibleBase for LuckPerms
*/
public class LPPermissible extends PermissibleBase { // TODO autoop stuff
public class LPPermissible extends PermissibleBase {
@Getter
private final User user;
@@ -64,9 +65,9 @@ public class LPPermissible extends PermissibleBase { // TODO autoop stuff
recalculatePermissions();
}
private Contexts calculateContexts() {
public Contexts calculateContexts() {
return new Contexts(
plugin.getContextManager().giveApplicableContext(parent, new HashMap<>()),
plugin.getContextManager().giveApplicableContext(parent, new MutableContextSet()),
plugin.getConfiguration().isIncludingGlobalPerms(),
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
true,
@@ -222,7 +223,7 @@ public class LPPermissible extends PermissibleBase { // TODO autoop stuff
}
if (hasData()) {
user.getUserData().invalidateCache();
user.getUserData().invalidatePermissionCalculators();
}
}
@@ -25,11 +25,11 @@ 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.common.caching.MetaData;
import me.lucko.luckperms.api.caching.MetaData;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import net.milkbowl.vault.chat.Chat;
@@ -39,8 +39,8 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static me.lucko.luckperms.common.utils.ArgumentChecker.escapeCharacters;
import static me.lucko.luckperms.common.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.common.utils.ArgumentChecker.unescapeCharacters
* Permission Nodes = meta.node.value
*
* Node that special characters used within LuckPerms are escaped:
* See {@link ArgumentChecker#escapeCharacters(String)}
* See {@link me.lucko.luckperms.api.MetaUtils#unescapeCharacters(String)}
*/
public class VaultChatHook extends Chat {
private final VaultPermissionHook perms;
@@ -215,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;
}
@@ -27,6 +27,7 @@ import lombok.NonNull;
import lombok.Setter;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Node;
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;
@@ -35,7 +36,6 @@ import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import net.milkbowl.vault.permission.Permission;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -131,12 +131,13 @@ public class VaultPermissionHook extends Permission {
*/
void save(PermissionHolder holder) {
if (holder instanceof User) {
((User) holder).refreshPermissions();
plugin.getDatastore().saveUser(((User) holder));
plugin.getDatastore().saveUser(((User) holder), b -> {
((User) holder).getRefreshBuffer().request();
});
}
if (holder instanceof Group) {
plugin.getDatastore().saveGroup(((Group) holder));
plugin.runUpdateTask();
plugin.getDatastore().saveGroup(((Group) holder), b -> plugin.getUpdateTaskBuffer().request());
}
}
@@ -146,7 +147,7 @@ public class VaultPermissionHook extends Permission {
context.put("world", world);
}
context.put("server", server);
return new Contexts(context, isIncludeGlobal(), true, true, true, true);
return new Contexts(ContextSet.fromMap(context), isIncludeGlobal(), true, true, true, true, false);
}
@Override
@@ -198,7 +199,7 @@ public class VaultPermissionHook extends Permission {
if (group == null) return false;
// This is a nasty call. Groups aren't cached. :(
Map<String, Boolean> permissions = group.exportNodes(createContext(server, world), Collections.emptyList(), true);
Map<String, Boolean> permissions = group.exportNodes(createContext(server, world), true);
return permissions.containsKey(permission) && permissions.get(permission);
}
@@ -258,9 +259,9 @@ public class VaultPermissionHook extends Permission {
scheduler.scheduleTask(() -> {
try {
if (finalWorld != null && !finalWorld.equals("")) {
user.addGroup(group, server, finalWorld);
user.setInheritGroup(group, server, finalWorld);
} else {
user.addGroup(group, server);
user.setInheritGroup(group, server);
}
} catch (ObjectAlreadyHasException ignored) {}
save(user);
@@ -282,9 +283,9 @@ public class VaultPermissionHook extends Permission {
scheduler.scheduleTask(() -> {
try {
if (finalWorld != null && !finalWorld.equals("")) {
user.removeGroup(group, server, finalWorld);
user.unsetInheritGroup(group, server, finalWorld);
} else {
user.removeGroup(group, server);
user.unsetInheritGroup(group, server);
}
} catch (ObjectLacksException ignored) {}
save(user);
+125 -11
View File
@@ -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
@@ -86,12 +115,19 @@ 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
@@ -113,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
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.12-SNAPSHOT</version>
<version>2.13-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -24,6 +24,7 @@ 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;
@@ -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<>();
@@ -23,6 +23,7 @@
package me.lucko.luckperms.bungee;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.api.event.events.UserFirstLoginEvent;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.core.UuidCache;
@@ -38,7 +39,6 @@ import net.md_5.bungee.api.event.PostLoginEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@@ -72,12 +72,13 @@ public class BungeeListener extends AbstractListener implements Listener {
}
Contexts contexts = new Contexts(
plugin.getContextManager().giveApplicableContext(player, new HashMap<>()),
plugin.getContextManager().giveApplicableContext(player, MutableContextSet.empty()),
plugin.getConfiguration().isIncludingGlobalPerms(),
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
true,
plugin.getConfiguration().isApplyingGlobalGroups(),
plugin.getConfiguration().isApplyingGlobalWorldGroups()
plugin.getConfiguration().isApplyingGlobalWorldGroups(),
false
);
e.setHasPermission(user.getUserData().getPermissionData(contexts).getPermissionValue(e.getPermission()).asBoolean());
@@ -95,28 +96,28 @@ 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());
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());
@@ -27,6 +27,8 @@ import me.lucko.luckperms.ApiHandler;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.calculators.CalculatorFactory;
@@ -34,7 +36,6 @@ 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.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.contexts.ServerCalculator;
@@ -47,6 +48,7 @@ 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;
@@ -75,6 +77,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
private LocaleManager localeManager;
private ContextManager<ProxiedPlayer> contextManager;
private CalculatorFactory calculatorFactory;
private BufferedRequest<Void> updateTaskBuffer;
@Override
public void onEnable() {
@@ -122,6 +125,15 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
contextManager.registerCalculator(serverCalculator);
contextManager.registerCalculator(new ServerCalculator<>(getConfiguration().getServer()));
final LPBungeePlugin i = this;
updateTaskBuffer = new BufferedRequest<Void>(6000L, this::doAsync) {
@Override
protected Void perform() {
doAsync(new UpdateTask(i));
return null;
}
};
int mins = getConfiguration().getSyncTime();
if (mins > 0) {
getProxy().getScheduler().schedule(this, new UpdateTask(this), mins, mins, TimeUnit.MINUTES);
@@ -138,11 +150,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
// 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.");
}
@@ -171,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();
@@ -186,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()
@@ -201,28 +214,29 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
@Override
public Set<Contexts> getPreProcessContexts(boolean op) {
Set<Map<String, String>> c = new HashSet<>();
c.add(Collections.emptyMap());
c.add(Collections.singletonMap("server", getConfiguration().getServer()));
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 -> {
Map<String, String> map = new HashMap<>();
map.put("server", getConfiguration().getServer());
map.put("world", s);
return map;
MutableContextSet set = new MutableContextSet();
set.add("server", getConfiguration().getServer());
set.add("world", s);
return set.makeImmutable();
})
.collect(Collectors.toList())
);
return c.stream()
.map(map -> new Contexts(
map,
.map(set -> new Contexts(
set,
getConfiguration().isIncludingGlobalPerms(),
getConfiguration().isIncludingGlobalWorldPerms(),
true,
getConfiguration().isApplyingGlobalGroups(),
getConfiguration().isApplyingGlobalWorldGroups()
getConfiguration().isApplyingGlobalWorldGroups(),
false
))
.collect(Collectors.toSet());
}
@@ -250,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);
@@ -264,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);
}
}
+113 -19
View File
@@ -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 -2
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.12-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 -->
@@ -38,6 +38,7 @@ 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;
@@ -93,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
@@ -107,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
*/
@@ -117,7 +134,11 @@ public interface LuckPermsPlugin {
*/
Sender getConsoleSender();
// TODO javadoc
/**
* Gets a set of Contexts that should be pre-processed in advance
* @param op if the user being processed is op
* @return a set of contexts
*/
Set<Contexts> getPreProcessContexts(boolean op);
/**
@@ -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);
}
@@ -64,12 +64,12 @@ public class ApiProvider implements LuckPermsApi {
@Override
public void runUpdateTask() {
plugin.runUpdateTask();
plugin.getUpdateTaskBuffer().request();
}
@Override
public double getApiVersion() {
return 2.12;
return 2.13;
}
@Override
@@ -22,19 +22,15 @@
package me.lucko.luckperms.common.api.internal;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import me.lucko.luckperms.api.*;
import me.lucko.luckperms.api.data.Callback;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.AbstractFuture;
import 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.common.api.internal.Utils.*;
@@ -210,64 +206,68 @@ public class DatastoreLink implements Datastore {
@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,44 +276,44 @@ public class DatastoreLink implements Datastore {
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
throw new IllegalArgumentException("Cannot delete the default group.");
}
return master.deleteGroup(((GroupLink) group).getMaster());
return master.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();
}
}
@@ -323,193 +323,112 @@ public class DatastoreLink implements Datastore {
@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));
}
}
@@ -25,6 +25,7 @@ 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;
@@ -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
@@ -27,10 +27,12 @@ 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.common.api.internal.Utils.*;
@@ -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
@@ -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());
}
}
}
@@ -1,116 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching;
import com.google.common.collect.ImmutableMap;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;
import java.util.concurrent.ConcurrentHashMap;
@RequiredArgsConstructor
public class MetaData {
private final Contexts contexts;
@Getter
private String prefix = null;
@Getter
private String suffix = null;
private Map<String, String> meta = new ConcurrentHashMap<>();
public void loadMeta(SortedSet<LocalizedNode> nodes) {
invalidateCache();
Map<String, String> contexts = new HashMap<>(this.contexts.getContext());
String server = contexts.remove("server");
String world = contexts.remove("world");
int prefixPriority = Integer.MIN_VALUE;
int suffixPriority = Integer.MIN_VALUE;
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();
if (value.getKey() > prefixPriority) {
this.prefix = value.getValue();
prefixPriority = value.getKey();
}
continue;
}
if (n.isSuffix()) {
Map.Entry<Integer, String> value = n.getSuffix();
if (value.getKey() > suffixPriority) {
this.suffix = value.getValue();
suffixPriority = value.getKey();
}
continue;
}
if (n.isMeta()) {
Map.Entry<String, String> meta = n.getMeta();
this.meta.put(meta.getKey(), meta.getValue());
}
}
}
public void invalidateCache() {
meta.clear();
prefix = null;
suffix = null;
}
public Map<String, String> getMeta() {
return ImmutableMap.copyOf(meta);
}
}
@@ -26,6 +26,7 @@ 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;
@@ -33,18 +34,29 @@ import me.lucko.luckperms.common.users.User;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class PermissionData {
private final Contexts contexts;
/**
* 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 PermissionData(Contexts contexts, User user, CalculatorFactory calculatorFactory) {
this.contexts = contexts;
public PermissionCache(Contexts contexts, User user, CalculatorFactory calculatorFactory) {
permissions = new ConcurrentHashMap<>();
calculator = calculatorFactory.build(contexts, user, permissions);
}
@Override
public void invalidateCache() {
calculator.invalidateCache();
}
@@ -56,34 +68,18 @@ public class PermissionData {
}
public void comparePermissions(Map<String, Boolean> toApply) {
boolean different = false;
if (toApply.size() != permissions.size()) {
different = true;
} else {
for (Map.Entry<String, Boolean> e : permissions.entrySet()) {
if (toApply.containsKey(e.getKey()) && toApply.get(e.getKey()) == e.getValue()) {
continue;
}
different = true;
break;
}
}
if (different) {
if (!permissions.equals(toApply)) {
setPermissions(toApply);
}
}
@Override
public Map<String, Boolean> getImmutableBacking() {
return ImmutableMap.copyOf(permissions);
}
@Override
public Tristate getPermissionValue(@NonNull String permission) {
Tristate t = calculator.getPermissionValue(permission);
if (t != Tristate.UNDEFINED) {
return Tristate.fromBoolean(t.asBoolean());
} else {
return Tristate.UNDEFINED;
}
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);
}
}
@@ -1,107 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.users.User;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@RequiredArgsConstructor
public class UserData {
private final User user;
private final CalculatorFactory calculatorFactory;
private final Map<Contexts, PermissionData> permission = new ConcurrentHashMap<>();
private final Map<Contexts, MetaData> meta = new ConcurrentHashMap<>();
public PermissionData getPermissionData(Contexts contexts) {
return permission.computeIfAbsent(contexts, this::calculatePermissions);
}
public MetaData getMetaData(Contexts contexts) {
return meta.computeIfAbsent(contexts, this::calculateMeta);
}
public PermissionData calculatePermissions(Contexts contexts) {
PermissionData data = new PermissionData(contexts, user, calculatorFactory);
data.setPermissions(user.exportNodes(contexts, Collections.emptyList(), true));
return data;
}
public void recalculatePermissions(Contexts contexts) {
permission.compute(contexts, (c, data) -> {
if (data == null) {
data = new PermissionData(c, user, calculatorFactory);
}
data.comparePermissions(user.exportNodes(c, Collections.emptyList(), true));
return data;
});
}
public void recalculatePermissions() {
permission.keySet().forEach(this::recalculatePermissions);
}
public MetaData calculateMeta(Contexts contexts) {
MetaData data = new MetaData(contexts);
data.loadMeta(user.getAllNodes(null, contexts));
return data;
}
public void recalculateMeta(Contexts contexts) {
meta.compute(contexts, (c, data) -> {
if (data == null) {
data = new MetaData(c);
}
data.loadMeta(user.getAllNodes(null, c));
return data;
});
}
public void recalculateMeta() {
meta.keySet().forEach(this::recalculateMeta);
}
public void preCalculate(Set<Contexts> contexts) {
contexts.forEach(this::preCalculate);
}
public void preCalculate(Contexts contexts) {
getPermissionData(contexts);
getMetaData(contexts);
}
public void invalidateCache() {
permission.clear();
meta.clear();
}
}
@@ -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);
}
}
@@ -22,13 +22,14 @@
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.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() + ")");
@@ -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;
}
}
@@ -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;
}
}
}
}
@@ -22,17 +22,16 @@
package me.lucko.luckperms.common.commands;
import com.google.common.collect.ImmutableMap;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
/**
* Factory class to make a thread-safe sender instance
@@ -100,12 +99,15 @@ public abstract class SenderFactory<T> implements Runnable {
this.console = this.uuid.equals(Constants.getConsoleUUID()) || this.uuid.equals(Constants.getImporterUUID());
if (!this.console) {
if (toCheck == null || toCheck.isEmpty()) {
this.perms = ImmutableMap.copyOf(Arrays.stream(Permission.values())
.collect(Collectors.toMap(p -> p, p -> factory.hasPermission(t, p.getNode()))));
} else {
this.perms = ImmutableMap.copyOf(toCheck.stream().collect(Collectors.toMap(p -> p, p -> factory.hasPermission(t, p.getNode()))));
}
this.perms = ((toCheck == null || toCheck.isEmpty()) ? Arrays.stream(Permission.values()) : toCheck.stream())
.collect(ImmutableCollectors.toImmutableMap(p -> p, p -> {
for (String s : p.getNodes()) {
if (factory.hasPermission(t, s)) {
return true;
}
}
return false;
}));
}
}
@@ -103,7 +103,7 @@ public abstract class SubCommand<T> {
}
}
Util.sendPluginMessage(sender, "&3> &a" + getName() + usage);
Util.sendPluginMessage(sender, "&3> &a" + getName().toLowerCase() + usage);
}
public void sendDetailedUsage(Sender sender) {
@@ -133,15 +133,15 @@ public abstract class SubCommand<T> {
* ----------------------------------------------------------------------------------
*/
protected static List<String> getGroupTabComplete(List<String> args, LuckPermsPlugin plugin) {
public static List<String> getGroupTabComplete(List<String> args, LuckPermsPlugin plugin) {
return getTabComplete(new ArrayList<>(plugin.getGroupManager().getAll().keySet()), args);
}
protected static List<String> getTrackTabComplete(List<String> args, LuckPermsPlugin plugin) {
public static List<String> getTrackTabComplete(List<String> args, LuckPermsPlugin plugin) {
return getTabComplete(new ArrayList<>(plugin.getTrackManager().getAll().keySet()), args);
}
protected static List<String> getBoolTabComplete(List<String> args) {
public static List<String> getBoolTabComplete(List<String> args) {
if (args.size() == 2) {
return Arrays.asList("true", "false");
} else {
@@ -161,33 +161,33 @@ public abstract class SubCommand<T> {
return Collections.emptyList();
}
protected static void save(User user, Sender sender, LuckPermsPlugin plugin) {
if (plugin.getDatastore().saveUser(user)) {
public static void save(User user, Sender sender, LuckPermsPlugin plugin) {
if (plugin.getDatastore().saveUser(user).getUnchecked()) {
Message.USER_SAVE_SUCCESS.send(sender);
} else {
Message.USER_SAVE_ERROR.send(sender);
}
user.refreshPermissions();
user.getRefreshBuffer().request().getUnchecked();
}
protected static void save(Group group, Sender sender, LuckPermsPlugin plugin) {
if (plugin.getDatastore().saveGroup(group)) {
public static void save(Group group, Sender sender, LuckPermsPlugin plugin) {
if (plugin.getDatastore().saveGroup(group).getUnchecked()) {
Message.GROUP_SAVE_SUCCESS.send(sender);
} else {
Message.GROUP_SAVE_ERROR.send(sender);
}
plugin.runUpdateTask();
plugin.getUpdateTaskBuffer().request();
}
protected static void save(Track track, Sender sender, LuckPermsPlugin plugin) {
if (plugin.getDatastore().saveTrack(track)) {
public static void save(Track track, Sender sender, LuckPermsPlugin plugin) {
if (plugin.getDatastore().saveTrack(track).getUnchecked()) {
Message.TRACK_SAVE_SUCCESS.send(sender);
} else {
Message.TRACK_SAVE_ERROR.send(sender);
}
plugin.runUpdateTask();
plugin.getUpdateTaskBuffer().request();
}
}
@@ -20,49 +20,43 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta;
package me.lucko.luckperms.common.commands.generic;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.commands.meta.subcommands.*;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.core.PermissionHolder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class MetaCommands<T extends PermissionHolder> extends SubCommand<T> {
public class SecondaryMainCommand<T extends PermissionHolder> extends SubCommand<T> {
private boolean user;
private final List<SecondarySubCommand> secondaryCommands;
private final List<MetaSubCommand> subCommands = ImmutableList.<MetaSubCommand>builder()
.add(new MetaInfo())
.add(new MetaAddPrefix())
.add(new MetaAddSuffix())
.add(new MetaRemovePrefix())
.add(new MetaRemoveSuffix())
.add(new MetaAddTempPrefix())
.add(new MetaAddTempSuffix())
.add(new MetaRemoveTempPrefix())
.add(new MetaRemoveTempSuffix())
.add(new MetaClear())
.build();
public MetaCommands(boolean user) {
super("meta", "Edit metadata values", null, Predicate.alwaysFalse(), null);
public SecondaryMainCommand(String name, String description, boolean user, List<SecondarySubCommand> secondaryCommands) {
super(name, description, null, Predicate.alwaysFalse(),
!name.equals("Meta") ? ImmutableList.copyOf(secondaryCommands.stream()
.map(s -> Arg.create(s.getName(), false, s.getDescription()))
.collect(Collectors.toList())
) : null
);
this.secondaryCommands = secondaryCommands;
this.user = user;
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, T t, List<String> args, String label) {
if (args.size() == 0) {
sendUsageMeta(sender, user, label);
sendUsageDetailed(sender, user, label);
return CommandResult.INVALID_ARGS;
}
Optional<MetaSubCommand> o = subCommands.stream()
Optional<SecondarySubCommand> o = secondaryCommands.stream()
.filter(s -> s.getName().equalsIgnoreCase(args.get(0)))
.limit(1)
.findAny();
@@ -72,7 +66,7 @@ public class MetaCommands<T extends PermissionHolder> extends SubCommand<T> {
return CommandResult.INVALID_ARGS;
}
final MetaSubCommand sub = o.get();
final SecondarySubCommand sub = o.get();
if (!sub.isAuthorized(sender, user)) {
Message.COMMAND_NO_PERMISSION.send(sender);
return CommandResult.NO_PERMISSION;
@@ -91,9 +85,40 @@ public class MetaCommands<T extends PermissionHolder> extends SubCommand<T> {
return sub.execute(plugin, sender, t, strippedArgs);
}
@Override
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
final List<SecondarySubCommand> subs = secondaryCommands.stream()
.filter(s -> s.isAuthorized(sender, user))
.collect(Collectors.toList());
if (args.size() <= 1) {
if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) {
return subs.stream()
.map(m -> m.getName().toLowerCase())
.collect(Collectors.toList());
}
return subs.stream()
.map(m -> m.getName().toLowerCase())
.filter(s -> s.toLowerCase().startsWith(args.get(0).toLowerCase()))
.collect(Collectors.toList());
}
Optional<SecondarySubCommand> o = subs.stream()
.filter(s -> s.getName().equalsIgnoreCase(args.get(0)))
.limit(1)
.findAny();
if (!o.isPresent()) {
return Collections.emptyList();
}
return o.get().onTabComplete(plugin, sender, args.subList(1, args.size()));
}
@Override
public boolean isAuthorized(Sender sender) {
for (MetaSubCommand subCommand : subCommands) {
for (SecondarySubCommand subCommand : secondaryCommands) {
if (subCommand.isAuthorized(sender, user)) {
return true;
}
@@ -101,19 +126,19 @@ public class MetaCommands<T extends PermissionHolder> extends SubCommand<T> {
return false;
}
private void sendUsageMeta(Sender sender, boolean user, String label) {
List<MetaSubCommand> subs = subCommands.stream()
private void sendUsageDetailed(Sender sender, boolean user, String label) {
List<SecondarySubCommand> subs = secondaryCommands.stream()
.filter(s -> s.isAuthorized(sender, user))
.collect(Collectors.toList());
if (subs.size() > 0) {
if (user) {
Util.sendPluginMessage(sender, "&bMeta Sub Commands: &7(" + String.format("/%s user <user> meta ...)", label));
Util.sendPluginMessage(sender, "&b" + getName() + " Sub Commands: &7(" + String.format("/%s user <user> " + getName().toLowerCase() + " ...)", label));
} else {
Util.sendPluginMessage(sender, "&bMeta Sub Commands: &7(" + String.format("/%s group <group> meta ...)", label));
Util.sendPluginMessage(sender, "&b" + getName() + " Sub Commands: &7(" + String.format("/%s group <group> " + getName().toLowerCase() + " ...)", label));
}
for (MetaSubCommand s : subs) {
for (SecondarySubCommand s : subs) {
s.sendUsage(sender);
}
@@ -20,28 +20,26 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta;
package me.lucko.luckperms.common.commands.generic;
import com.google.common.collect.ImmutableList;
import lombok.AllArgsConstructor;
import lombok.Getter;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.Util;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.users.User;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
@Getter
@AllArgsConstructor
public abstract class MetaSubCommand {
public abstract class SecondarySubCommand {
/**
* The name of the sub command
*/
@@ -67,6 +65,10 @@ public abstract class MetaSubCommand {
public abstract CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args);
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
return Collections.emptyList();
}
public void sendUsage(Sender sender) {
String usage = "";
if (args != null) {
@@ -97,28 +99,17 @@ public abstract class MetaSubCommand {
protected static void save(PermissionHolder holder, Sender sender, LuckPermsPlugin plugin) {
if (holder instanceof User) {
User user = ((User) holder);
if (plugin.getDatastore().saveUser(user)) {
Message.USER_SAVE_SUCCESS.send(sender);
} else {
Message.USER_SAVE_ERROR.send(sender);
}
user.refreshPermissions();
SubCommand.save(user, sender, plugin);
return;
}
if (holder instanceof Group) {
Group group = ((Group) holder);
if (plugin.getDatastore().saveGroup(group)) {
Message.GROUP_SAVE_SUCCESS.send(sender);
} else {
Message.GROUP_SAVE_ERROR.send(sender);
}
plugin.runUpdateTask();
SubCommand.save(group, sender, plugin);
return;
}
throw new IllegalArgumentException();
}
}
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.generic.meta;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.commands.generic.SecondaryMainCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.core.PermissionHolder;
public class CommandMeta<T extends PermissionHolder> extends SecondaryMainCommand<T> {
public CommandMeta(boolean user) {
super("Meta", "Edit metadata values", user, ImmutableList.<SecondarySubCommand>builder()
.add(new MetaInfo())
.add(new MetaSet())
.add(new MetaUnset())
.add(new MetaSetTemp())
.add(new MetaUnsetTemp())
.add(new MetaAddPrefix())
.add(new MetaAddSuffix())
.add(new MetaRemovePrefix())
.add(new MetaRemoveSuffix())
.add(new MetaAddTempPrefix())
.add(new MetaAddTempSuffix())
.add(new MetaRemoveTempPrefix())
.add(new MetaRemoveTempSuffix())
.add(new MetaClear())
.build());
}
}
@@ -20,14 +20,15 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta.subcommands;
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.meta.MetaSubCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
@@ -37,9 +38,9 @@ import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
public class MetaAddPrefix extends MetaSubCommand {
public class MetaAddPrefix extends SecondarySubCommand {
public MetaAddPrefix() {
super("addprefix", "Adds a prefix", Permission.USER_ADDPREFIX, Permission.GROUP_ADDPREFIX, Predicate.notInRange(2, 4),
super("addprefix", "Adds a prefix", Permission.USER_META_ADDPREFIX, Permission.GROUP_META_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"),
@@ -60,7 +61,7 @@ public class MetaAddPrefix extends MetaSubCommand {
return CommandResult.INVALID_ARGS;
}
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
final String node = "prefix." + priority + "." + MetaUtils.escapeCharacters(prefix);
try {
if (args.size() >= 3) {
@@ -20,14 +20,15 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta.subcommands;
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.meta.MetaSubCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
@@ -37,9 +38,9 @@ import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
public class MetaAddSuffix extends MetaSubCommand {
public class MetaAddSuffix extends SecondarySubCommand {
public MetaAddSuffix() {
super("addsuffix", "Adds a suffix", Permission.USER_ADDSUFFIX, Permission.GROUP_ADDSUFFIX, Predicate.notInRange(2, 4),
super("addsuffix", "Adds a suffix", Permission.USER_META_ADDSUFFIX, Permission.GROUP_META_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"),
@@ -60,7 +61,7 @@ public class MetaAddSuffix extends MetaSubCommand {
return CommandResult.INVALID_ARGS;
}
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
final String node = "suffix." + priority + "." + MetaUtils.escapeCharacters(suffix);
try {
if (args.size() >= 3) {
@@ -20,14 +20,15 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta.subcommands;
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.meta.MetaSubCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
@@ -38,9 +39,9 @@ import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
public class MetaAddTempPrefix extends MetaSubCommand {
public class MetaAddTempPrefix extends SecondarySubCommand {
public MetaAddTempPrefix() {
super("addtempprefix", "Adds a prefix temporarily", Permission.USER_ADD_TEMP_PREFIX, Permission.GROUP_ADD_TEMP_PREFIX, Predicate.notInRange(3, 5),
super("addtempprefix", "Adds a prefix temporarily", Permission.USER_META_ADDTEMP_PREFIX, Permission.GROUP_META_ADDTEMP_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"),
@@ -79,7 +80,7 @@ public class MetaAddTempPrefix extends MetaSubCommand {
return CommandResult.INVALID_ARGS;
}
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
final String node = "prefix." + priority + "." + MetaUtils.escapeCharacters(prefix);
try {
if (args.size() >= 4) {
@@ -20,14 +20,15 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta.subcommands;
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.meta.MetaSubCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
@@ -38,9 +39,9 @@ import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
public class MetaAddTempSuffix extends MetaSubCommand {
public class MetaAddTempSuffix extends SecondarySubCommand {
public MetaAddTempSuffix() {
super("addtempsuffix", "Adds a suffix temporarily", Permission.USER_ADD_TEMP_SUFFIX, Permission.GROUP_ADD_TEMP_SUFFIX, Predicate.notInRange(3, 5),
super("addtempsuffix", "Adds a suffix temporarily", Permission.USER_META_ADDTEMP_SUFFIX, Permission.GROUP_META_ADDTEMP_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"),
@@ -79,7 +80,7 @@ public class MetaAddTempSuffix extends MetaSubCommand {
return CommandResult.INVALID_ARGS;
}
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
final String node = "suffix." + priority + "." + MetaUtils.escapeCharacters(suffix);
try {
if (args.size() >= 4) {
@@ -20,14 +20,14 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta.subcommands;
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.meta.MetaSubCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
@@ -37,9 +37,9 @@ import me.lucko.luckperms.common.utils.ArgumentChecker;
import java.util.List;
import java.util.stream.Collectors;
public class MetaClear extends MetaSubCommand {
public class MetaClear extends SecondarySubCommand {
public MetaClear() {
super("clear", "Clears all chat meta", Permission.USER_CLEARMETA, Permission.GROUP_CLEARMETA, Predicate.notInRange(0, 2),
super("clear", "Clears all chat meta", Permission.USER_META_CLEAR, Permission.GROUP_META_CLEAR, Predicate.notInRange(0, 2),
Arg.list(
Arg.create("server", false, "the server name to filter by"),
Arg.create("world", false, "the world name to filter by")
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta.subcommands;
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Node;
@@ -29,16 +29,16 @@ import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.Util;
import me.lucko.luckperms.common.commands.meta.MetaSubCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import java.util.*;
public class MetaInfo extends MetaSubCommand {
public class MetaInfo extends SecondarySubCommand {
public MetaInfo() {
super("info", "Shows all chat meta", Permission.USER_CHATMETA, Permission.GROUP_CHATMETA, Predicate.alwaysFalse(), null);
super("info", "Shows all chat meta", Permission.USER_META_INFO, Permission.GROUP_META_INFO, Predicate.alwaysFalse(), null);
}
@Override
@@ -20,15 +20,16 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta.subcommands;
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.meta.MetaSubCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
@@ -39,9 +40,9 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.ArrayList;
import java.util.List;
public class MetaRemovePrefix extends MetaSubCommand {
public class MetaRemovePrefix extends SecondarySubCommand {
public MetaRemovePrefix() {
super("removeprefix", "Removes a prefix", Permission.USER_REMOVEPREFIX, Permission.GROUP_REMOVEPREFIX, Predicate.notInRange(2, 4),
super("removeprefix", "Removes a prefix", Permission.USER_META_REMOVEPREFIX, Permission.GROUP_META_REMOVEPREFIX, Predicate.notInRange(2, 4),
Arg.list(
Arg.create("priority", true, "the priority to add the prefix at"),
Arg.create("prefix", true, "the prefix string"),
@@ -113,7 +114,7 @@ public class MetaRemovePrefix extends MetaSubCommand {
} else {
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
final String node = "prefix." + priority + "." + MetaUtils.escapeCharacters(prefix);
try {
if (args.size() >= 3) {
@@ -20,15 +20,16 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta.subcommands;
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.meta.MetaSubCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
@@ -39,9 +40,9 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.ArrayList;
import java.util.List;
public class MetaRemoveSuffix extends MetaSubCommand {
public class MetaRemoveSuffix extends SecondarySubCommand {
public MetaRemoveSuffix() {
super("removesuffix", "Removes a suffix", Permission.USER_REMOVESUFFIX, Permission.GROUP_REMOVESUFFIX, Predicate.notInRange(2, 4),
super("removesuffix", "Removes a suffix", Permission.USER_META_REMOVESUFFIX, Permission.GROUP_META_REMOVESUFFIX, Predicate.notInRange(2, 4),
Arg.list(
Arg.create("priority", true, "the priority to add the suffix at"),
Arg.create("suffix", true, "the suffix string"),
@@ -113,7 +114,7 @@ public class MetaRemoveSuffix extends MetaSubCommand {
} else {
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
final String node = "suffix." + priority + "." + MetaUtils.escapeCharacters(suffix);
try {
if (args.size() >= 3) {
@@ -20,15 +20,16 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta.subcommands;
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.meta.MetaSubCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
@@ -39,9 +40,9 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.ArrayList;
import java.util.List;
public class MetaRemoveTempPrefix extends MetaSubCommand {
public class MetaRemoveTempPrefix extends SecondarySubCommand {
public MetaRemoveTempPrefix() {
super("removetempprefix", "Removes a temporary prefix", Permission.USER_REMOVE_TEMP_PREFIX, Permission.GROUP_REMOVE_TEMP_PREFIX, Predicate.notInRange(2, 4),
super("removetempprefix", "Removes a temporary prefix", Permission.USER_META_REMOVETEMP_PREFIX, Permission.GROUP_META_REMOVETEMP_PREFIX, Predicate.notInRange(2, 4),
Arg.list(
Arg.create("priority", true, "the priority to add the prefix at"),
Arg.create("prefix", true, "the prefix string"),
@@ -113,7 +114,7 @@ public class MetaRemoveTempPrefix extends MetaSubCommand {
} else {
final String node = "prefix." + priority + "." + ArgumentChecker.escapeCharacters(prefix);
final String node = "prefix." + priority + "." + MetaUtils.escapeCharacters(prefix);
try {
if (args.size() >= 3) {
@@ -20,15 +20,16 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.meta.subcommands;
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.meta.MetaSubCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
@@ -39,9 +40,9 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.ArrayList;
import java.util.List;
public class MetaRemoveTempSuffix extends MetaSubCommand {
public class MetaRemoveTempSuffix extends SecondarySubCommand {
public MetaRemoveTempSuffix() {
super("removetempsuffix", "Removes a temporary suffix", Permission.USER_REMOVE_TEMP_SUFFIX, Permission.GROUP_REMOVE_TEMP_SUFFIX, Predicate.notInRange(2, 4),
super("removetempsuffix", "Removes a temporary suffix", Permission.USER_META_REMOVETEMP_SUFFIX, Permission.GROUP_META_REMOVETEMP_SUFFIX, Predicate.notInRange(2, 4),
Arg.list(
Arg.create("priority", true, "the priority to add the suffix at"),
Arg.create("suffix", true, "the suffix string"),
@@ -113,7 +114,7 @@ public class MetaRemoveTempSuffix extends MetaSubCommand {
} else {
final String node = "suffix." + priority + "." + ArgumentChecker.escapeCharacters(suffix);
final String node = "suffix." + priority + "." + MetaUtils.escapeCharacters(suffix);
try {
if (args.size() >= 3) {
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.Node;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
public class MetaSet extends SecondarySubCommand {
public MetaSet() {
super("set", "Sets a meta value", Permission.USER_META_SET, Permission.GROUP_META_SET, Predicate.notInRange(2, 4),
Arg.list(
Arg.create("key", true, "the key to set"),
Arg.create("value", true, "the value to set"),
Arg.create("server", false, "the server to add the meta pair on"),
Arg.create("world", false, "the world to add the meta pair on")
)
);
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
String key = MetaUtils.escapeCharacters(args.get(0));
String value = MetaUtils.escapeCharacters(args.get(1));
String node = "meta." + key + "." + value;
String server = null;
String world = null;
if (args.size() >= 3) {
server = args.get(2).toLowerCase();
if (ArgumentChecker.checkServer(server)) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() != 3) {
world = args.get(3).toLowerCase();
}
}
me.lucko.luckperms.api.Node n = new Node.Builder(node).setServer(server).setWorld(world).build();
if (holder.hasPermission(n).asBoolean()) {
Message.ALREADY_HAS_META.send(sender, holder.getFriendlyName());
return CommandResult.STATE_ERROR;
}
holder.clearMetaKeys(key, server, world, false);
try {
holder.setPermission(n);
} catch (ObjectAlreadyHasException ignored) {}
if (server == null) {
Message.SET_META_SUCCESS.send(sender, key, value, holder.getFriendlyName());
LogEntry.build().actor(sender).acted(holder)
.action("meta set " + key + " " + value)
.build().submit(plugin, sender);
} else {
if (world == null) {
Message.SET_META_SERVER_SUCCESS.send(sender, key, value, holder.getFriendlyName(), server);
LogEntry.build().actor(sender).acted(holder)
.action("meta set " + key + " " + value + " " + server)
.build().submit(plugin, sender);
} else {
Message.SET_META_SERVER_WORLD_SUCCESS.send(sender, key, value, holder.getFriendlyName(), server, world);
LogEntry.build().actor(sender).acted(holder)
.action("meta set " + key + " " + value + " " + server + " " + world)
.build().submit(plugin, sender);
}
}
save(holder, sender, plugin);
return CommandResult.SUCCESS;
}
}
@@ -0,0 +1,129 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.Node;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.common.utils.DateUtil;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
public class MetaSetTemp extends SecondarySubCommand {
public MetaSetTemp() {
super("settemp", "Sets a meta value temporarily", Permission.USER_META_SETTEMP, Permission.GROUP_META_SETTEMP, Predicate.notInRange(3, 5),
Arg.list(
Arg.create("key", true, "the key to set"),
Arg.create("value", true, "the value to set"),
Arg.create("duration", true, "the duration until the meta value expires"),
Arg.create("server", false, "the server to add the meta pair on"),
Arg.create("world", false, "the world to add the meta pair on")
)
);
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
long duration;
try {
duration = Long.parseLong(args.get(2));
} catch (NumberFormatException e) {
try {
duration = DateUtil.parseDateDiff(args.get(2), true);
} catch (DateUtil.IllegalDateException e1) {
Message.ILLEGAL_DATE_ERROR.send(sender, args.get(2));
return CommandResult.INVALID_ARGS;
}
}
if (DateUtil.shouldExpire(duration)) {
Message.PAST_DATE_ERROR.send(sender);
return CommandResult.INVALID_ARGS;
}
String key = MetaUtils.escapeCharacters(args.get(0));
String value = MetaUtils.escapeCharacters(args.get(1));
String node = "meta." + key + "." + value;
String server = null;
String world = null;
if (args.size() >= 3) {
server = args.get(2).toLowerCase();
if (ArgumentChecker.checkServer(server)) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() != 3) {
world = args.get(3).toLowerCase();
}
}
me.lucko.luckperms.api.Node n = new Node.Builder(node).setServer(server).setWorld(world).setExpiry(duration).build();
if (holder.hasPermission(n).asBoolean()) {
Message.ALREADY_HAS_META.send(sender, holder.getFriendlyName());
return CommandResult.STATE_ERROR;
}
holder.clearMetaKeys(key, server, world, true);
try {
holder.setPermission(n);
} catch (ObjectAlreadyHasException ignored) {}
if (server == null) {
Message.SET_META_TEMP_SUCCESS.send(sender, key, value, holder.getFriendlyName(), DateUtil.formatDateDiff(duration));
LogEntry.build().actor(sender).acted(holder)
.action("meta settemp " + key + " " + value + " " + duration)
.build().submit(plugin, sender);
} else {
if (world == null) {
Message.SET_META_TEMP_SERVER_SUCCESS.send(sender, key, value, holder.getFriendlyName(), server, DateUtil.formatDateDiff(duration));
LogEntry.build().actor(sender).acted(holder)
.action("meta settemp " + key + " " + value + " " + duration + " " + server)
.build().submit(plugin, sender);
} else {
Message.SET_META_TEMP_SERVER_WORLD_SUCCESS.send(sender, key, value, holder.getFriendlyName(), server, world, DateUtil.formatDateDiff(duration));
LogEntry.build().actor(sender).acted(holder)
.action("meta settemp " + key + " " + value + " " + duration + " " + server + " " + world)
.build().submit(plugin, sender);
}
}
save(holder, sender, plugin);
return CommandResult.SUCCESS;
}
}
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import java.util.List;
import java.util.stream.Collectors;
public class MetaUnset extends SecondarySubCommand {
public MetaUnset() {
super("unset", "Unsets a meta value", Permission.USER_META_UNSET, Permission.GROUP_META_UNSET, Predicate.notInRange(1, 3),
Arg.list(
Arg.create("key", true, "the key to unset"),
Arg.create("server", false, "the server to remove the meta pair on"),
Arg.create("world", false, "the world to remove the meta pair on")
)
);
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
String key = MetaUtils.escapeCharacters(args.get(0));
String server = null;
String world = null;
if (args.size() >= 2) {
server = args.get(1).toLowerCase();
if (ArgumentChecker.checkServer(server)) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() != 2) {
world = args.get(2).toLowerCase();
}
}
holder.clearMetaKeys(key, server, world, false);
if (server == null) {
Message.UNSET_META_SUCCESS.send(sender, key, holder.getFriendlyName());
} else {
if (world == null) {
Message.UNSET_META_SERVER_SUCCESS.send(sender, key, holder.getFriendlyName(), server);
} else {
Message.UNSET_META_SERVER_WORLD_SUCCESS.send(sender, key, holder.getFriendlyName(), server, world);
}
}
LogEntry.build().actor(sender).acted(holder)
.action("meta unset " + args.stream().collect(Collectors.joining(" ")))
.build().submit(plugin, sender);
save(holder, sender, plugin);
return CommandResult.SUCCESS;
}
}
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import java.util.List;
import java.util.stream.Collectors;
public class MetaUnsetTemp extends SecondarySubCommand {
public MetaUnsetTemp() {
super("unsettemp", "Unsets a temporary meta value", Permission.USER_META_UNSETTEMP, Permission.GROUP_META_UNSETTEMP, Predicate.notInRange(1, 3),
Arg.list(
Arg.create("key", true, "the key to unset"),
Arg.create("server", false, "the server to remove the meta pair on"),
Arg.create("world", false, "the world to remove the meta pair on")
)
);
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
String key = MetaUtils.escapeCharacters(args.get(0));
String server = null;
String world = null;
if (args.size() >= 2) {
server = args.get(1).toLowerCase();
if (ArgumentChecker.checkServer(server)) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() != 2) {
world = args.get(2).toLowerCase();
}
}
holder.clearMetaKeys(key, server, world, true);
if (server == null) {
Message.UNSET_META_TEMP_SUCCESS.send(sender, key, holder.getFriendlyName());
} else {
if (world == null) {
Message.UNSET_META_TEMP_SERVER_SUCCESS.send(sender, key, holder.getFriendlyName(), server);
} else {
Message.UNSET_META_TEMP_SERVER_WORLD_SUCCESS.send(sender, key, holder.getFriendlyName(), server, world);
}
}
LogEntry.build().actor(sender).acted(holder)
.action("meta unsettemp " + args.stream().collect(Collectors.joining(" ")))
.build().submit(plugin, sender);
save(holder, sender, plugin);
return CommandResult.SUCCESS;
}
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.generic.parent;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.commands.generic.SecondaryMainCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.core.PermissionHolder;
public class CommandParent<T extends PermissionHolder> extends SecondaryMainCommand<T> {
public CommandParent(boolean user) {
super("Parent", "Edit inheritances", user, ImmutableList.<SecondarySubCommand>builder()
.add(new ParentInfo())
.add(new ParentAdd())
.add(new ParentRemove())
.add(new ParentAddTemp())
.add(new ParentRemoveTemp())
.build());
}
}
@@ -20,33 +20,40 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.user.subcommands;
package me.lucko.luckperms.common.commands.generic.parent;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
public class UserAddGroup extends SubCommand<User> {
public UserAddGroup() {
super("addgroup", "Adds the user to a group", Permission.USER_ADDGROUP, Predicate.notInRange(1, 3),
import static me.lucko.luckperms.common.commands.SubCommand.getGroupTabComplete;
public class ParentAdd extends SecondarySubCommand {
public ParentAdd() {
super("add", "Sets another group for the object to inherit permissions from",
Permission.USER_PARENT_ADD, Permission.GROUP_PARENT_ADD, Predicate.notInRange(1, 3),
Arg.list(
Arg.create("group", true, "the group to add the user to"),
Arg.create("server", false, "the server to add the group on"),
Arg.create("world", false, "the world to add the group on")
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, User user, List<String> args, String label) {
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
String groupName = args.get(0).toLowerCase();
if (ArgumentChecker.checkNode(groupName)) {
@@ -54,7 +61,7 @@ public class UserAddGroup extends SubCommand<User> {
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().loadGroup(groupName)) {
if (!plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}
@@ -74,32 +81,32 @@ public class UserAddGroup extends SubCommand<User> {
}
if (args.size() == 2) {
user.addGroup(group, server);
Message.USER_ADDGROUP_SERVER_SUCCESS.send(sender, user.getName(), group.getDisplayName(), server);
LogEntry.build().actor(sender).acted(user)
.action("addgroup " + group.getName() + " " + server)
holder.setInheritGroup(group, server);
Message.SET_INHERIT_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName(), server);
LogEntry.build().actor(sender).acted(holder)
.action("parent add " + group.getName() + " " + server)
.build().submit(plugin, sender);
} else {
final String world = args.get(2).toLowerCase();
user.addGroup(group, server, world);
Message.USER_ADDGROUP_SERVER_WORLD_SUCCESS.send(sender, user.getName(), group.getDisplayName(), server, world);
LogEntry.build().actor(sender).acted(user)
.action("addgroup " + group.getName() + " " + server + " " + world)
holder.setInheritGroup(group, server, world);
Message.SET_INHERIT_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName(), server, world);
LogEntry.build().actor(sender).acted(holder)
.action("parent add " + group.getName() + " " + server + " " + world)
.build().submit(plugin, sender);
}
} else {
user.addGroup(group);
Message.USER_ADDGROUP_SUCCESS.send(sender, user.getName(), group.getDisplayName());
LogEntry.build().actor(sender).acted(user)
.action("addgroup " + group.getName())
holder.setInheritGroup(group);
Message.SET_INHERIT_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName());
LogEntry.build().actor(sender).acted(holder)
.action("parent add " + group.getName())
.build().submit(plugin, sender);
}
save(user, sender, plugin);
save(holder, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectAlreadyHasException e) {
Message.USER_ALREADY_MEMBER_OF.send(sender, user.getName(), group.getDisplayName());
Message.ALREADY_INHERITS.send(sender, holder.getFriendlyName(), group.getDisplayName());
return CommandResult.STATE_ERROR;
}
}
@@ -20,26 +20,33 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.user.subcommands;
package me.lucko.luckperms.common.commands.generic.parent;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.common.utils.DateUtil;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
public class UserAddTempGroup extends SubCommand<User> {
public UserAddTempGroup() {
super("addtempgroup", "Adds the user to a group temporarily", Permission.USER_ADDTEMPGROUP, Predicate.notInRange(2, 4),
import static me.lucko.luckperms.common.commands.SubCommand.getGroupTabComplete;
public class ParentAddTemp extends SecondarySubCommand {
public ParentAddTemp() {
super("addtemp", "Sets another group for the object to inherit permissions from temporarily",
Permission.USER_PARENT_ADDTEMP, Permission.GROUP_PARENT_ADDTEMP, Predicate.notInRange(2, 4),
Arg.list(
Arg.create("group", true, "the group to add the user to"),
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")
@@ -48,7 +55,7 @@ public class UserAddTempGroup extends SubCommand<User> {
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
String groupName = args.get(0).toLowerCase();
if (ArgumentChecker.checkNode(groupName)) {
@@ -73,7 +80,7 @@ public class UserAddTempGroup extends SubCommand<User> {
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().loadGroup(groupName)) {
if (!plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}
@@ -81,7 +88,7 @@ public class UserAddTempGroup extends SubCommand<User> {
Group group = plugin.getGroupManager().get(groupName);
if (group == null) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.LOADING_ERROR;
return CommandResult.INVALID_ARGS;
}
try {
@@ -93,34 +100,34 @@ public class UserAddTempGroup extends SubCommand<User> {
}
if (args.size() == 3) {
user.addGroup(group, server, duration);
Message.USER_ADDTEMPGROUP_SERVER_SUCCESS.send(sender, user.getName(), group.getDisplayName(), server,
holder.setInheritGroup(group, server, duration);
Message.SET_TEMP_INHERIT_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName(), server,
DateUtil.formatDateDiff(duration));
LogEntry.build().actor(sender).acted(user)
.action("addtempgroup " + group.getName() + " " + duration + " " + server)
LogEntry.build().actor(sender).acted(holder)
.action("parent addtemp " + group.getName() + " " + duration + " " + server)
.build().submit(plugin, sender);
} else {
final String world = args.get(3).toLowerCase();
user.addGroup(group, server, world, duration);
Message.USER_ADDTEMPGROUP_SERVER_WORLD_SUCCESS.send(sender, user.getName(), group.getDisplayName(), server,
holder.setInheritGroup(group, server, world, duration);
Message.SET_TEMP_INHERIT_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName(), server,
world, DateUtil.formatDateDiff(duration));
LogEntry.build().actor(sender).acted(user)
.action("addtempgroup " + group.getName() + " " + duration + " " + server + " " + world)
LogEntry.build().actor(sender).acted(holder)
.action("parent addtemp " + group.getName() + " " + duration + " " + server + " " + world)
.build().submit(plugin, sender);
}
} else {
user.addGroup(group, duration);
Message.USER_ADDTEMPGROUP_SUCCESS.send(sender, user.getName(), group.getDisplayName(), DateUtil.formatDateDiff(duration));
LogEntry.build().actor(sender).acted(user)
.action("addtempgroup " + group.getName() + " " + duration)
holder.setInheritGroup(group, duration);
Message.SET_TEMP_INHERIT_SUCCESS.send(sender, holder.getFriendlyName(), group.getDisplayName(), DateUtil.formatDateDiff(duration));
LogEntry.build().actor(sender).acted(holder)
.action("parent addtemp " + group.getName() + " " + duration)
.build().submit(plugin, sender);
}
save(user, sender, plugin);
save(holder, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectAlreadyHasException e) {
Message.USER_ALREADY_TEMP_MEMBER_OF.send(sender, user.getName(), group.getDisplayName());
Message.ALREADY_TEMP_INHERITS.send(sender, holder.getFriendlyName(), group.getDisplayName());
return CommandResult.STATE_ERROR;
}
}
@@ -20,25 +20,30 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.user.subcommands;
package me.lucko.luckperms.common.commands.generic.parent;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.Util;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.core.PermissionHolder;
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);
public class ParentInfo extends SecondarySubCommand {
public ParentInfo() {
super("info", "Lists the groups that this object inherits from",
Permission.USER_PARENT_INFO, Permission.GROUP_PARENT_INFO, 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)));
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
Message.LISTPARENTS.send(sender, holder.getFriendlyName(), Util.permGroupsToString(holder.getPermissions(false)));
Message.LISTPARENTS_TEMP.send(sender, holder.getFriendlyName(), Util.tempGroupsToString(holder.getPermissions(false)));
return CommandResult.SUCCESS;
}
}
@@ -20,12 +20,17 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.user.subcommands;
package me.lucko.luckperms.common.commands.generic.parent;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.ArgumentChecker;
@@ -33,11 +38,14 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
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),
import static me.lucko.luckperms.common.commands.SubCommand.getGroupTabComplete;
public class ParentRemove extends SecondarySubCommand {
public ParentRemove() {
super("remove", "Removes a previously set inheritance rule", Permission.USER_PARENT_REMOVE, Permission.GROUP_PARENT_REMOVE,
Predicate.notInRange(1, 3),
Arg.list(
Arg.create("group", true, "the group to remove the user from"),
Arg.create("group", true, "the group to remove"),
Arg.create("server", false, "the server to remove the group on"),
Arg.create("world", false, "the world to remove the group on")
)
@@ -45,7 +53,7 @@ public class UserRemoveTempGroup extends SubCommand<User> {
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
String groupName = args.get(0).toLowerCase();
if (ArgumentChecker.checkNode(groupName)) {
@@ -53,6 +61,15 @@ public class UserRemoveTempGroup extends SubCommand<User> {
return CommandResult.INVALID_ARGS;
}
if (holder instanceof User) {
User user = (User) holder;
if ((args.size() == 1 || (args.size() == 2 && args.get(1).equalsIgnoreCase("global")))
&& user.getPrimaryGroup().equalsIgnoreCase(groupName)) {
Message.USER_REMOVEGROUP_ERROR_PRIMARY.send(sender);
return CommandResult.STATE_ERROR;
}
}
try {
if (args.size() >= 2) {
final String server = args.get(1).toLowerCase();
@@ -62,32 +79,32 @@ public class UserRemoveTempGroup extends SubCommand<User> {
}
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)
holder.unsetPermission("group." + groupName, server);
Message.UNSET_INHERIT_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), groupName, server);
LogEntry.build().actor(sender).acted(holder)
.action("parent remove " + 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)
holder.unsetPermission("group." + groupName, server, world);
Message.UNSET_INHERIT_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), groupName, server, world);
LogEntry.build().actor(sender).acted(holder)
.action("parent remove " + 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)
holder.unsetPermission("group." + groupName);
Message.UNSET_INHERIT_SUCCESS.send(sender, holder.getFriendlyName(), groupName);
LogEntry.build().actor(sender).acted(holder)
.action("parent remove " + groupName)
.build().submit(plugin, sender);
}
save(user, sender, plugin);
save(holder, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectLacksException e) {
Message.USER_NOT_TEMP_MEMBER_OF.send(sender, user.getName(), groupName);
Message.DOES_NOT_INHERIT.send(sender, holder.getFriendlyName(), groupName);
return CommandResult.STATE_ERROR;
}
}
@@ -20,24 +20,31 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.user.subcommands;
package me.lucko.luckperms.common.commands.generic.parent;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
public class UserRemoveGroup extends SubCommand<User> {
public UserRemoveGroup() {
super("removegroup", "Removes the user from a group", Permission.USER_REMOVEGROUP, Predicate.notInRange(1, 3),
import static me.lucko.luckperms.common.commands.SubCommand.getGroupTabComplete;
public class ParentRemoveTemp extends SecondarySubCommand {
public ParentRemoveTemp() {
super("removetemp", "Removes a previously set temporary inheritance rule",
Permission.USER_PARENT_REMOVETEMP, Permission.GROUP_PARENT_REMOVETEMP, Predicate.notInRange(1, 3),
Arg.list(
Arg.create("group", true, "the group to remove the user from"),
Arg.create("group", true, "the group to remove"),
Arg.create("server", false, "the server to remove the group on"),
Arg.create("world", false, "the world to remove the group on")
)
@@ -45,7 +52,7 @@ public class UserRemoveGroup extends SubCommand<User> {
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
String groupName = args.get(0).toLowerCase();
if (ArgumentChecker.checkNode(groupName)) {
@@ -53,12 +60,6 @@ public class UserRemoveGroup extends SubCommand<User> {
return CommandResult.INVALID_ARGS;
}
if ((args.size() == 1 || (args.size() == 2 && args.get(1).equalsIgnoreCase("global")))
&& user.getPrimaryGroup().equalsIgnoreCase(groupName)) {
Message.USER_REMOVEGROUP_ERROR_PRIMARY.send(sender);
return CommandResult.STATE_ERROR;
}
try {
if (args.size() >= 2) {
final String server = args.get(1).toLowerCase();
@@ -68,32 +69,32 @@ public class UserRemoveGroup extends SubCommand<User> {
}
if (args.size() == 2) {
user.unsetPermission("group." + groupName, server);
Message.USER_REMOVEGROUP_SERVER_SUCCESS.send(sender, user.getName(), groupName, server);
LogEntry.build().actor(sender).acted(user)
.action("removegroup " + groupName + " " + server)
holder.unsetPermission("group." + groupName, server, true);
Message.UNSET_TEMP_INHERIT_SERVER_SUCCESS.send(sender, holder.getFriendlyName(), groupName, server);
LogEntry.build().actor(sender).acted(holder)
.action("parent removetemp " + groupName + " " + server)
.build().submit(plugin, sender);
} else {
final String world = args.get(2).toLowerCase();
user.unsetPermission("group." + groupName, server, world);
Message.USER_REMOVEGROUP_SERVER_WORLD_SUCCESS.send(sender, user.getName(), groupName, server, world);
LogEntry.build().actor(sender).acted(user)
.action("removegroup " + groupName + " " + server + " " + world)
holder.unsetPermission("group." + groupName, server, world, true);
Message.UNSET_TEMP_INHERIT_SERVER_WORLD_SUCCESS.send(sender, holder.getFriendlyName(), groupName, server, world);
LogEntry.build().actor(sender).acted(holder)
.action("parent removetemp " + groupName + " " + server + " " + world)
.build().submit(plugin, sender);
}
} else {
user.unsetPermission("group." + groupName);
Message.USER_REMOVEGROUP_SUCCESS.send(sender, user.getName(), groupName);
LogEntry.build().actor(sender).acted(user)
.action("removegroup " + groupName)
holder.unsetPermission("group." + groupName, true);
Message.UNSET_TEMP_INHERIT_SUCCESS.send(sender, holder.getFriendlyName(), groupName);
LogEntry.build().actor(sender).acted(holder)
.action("parent removetemp " + groupName)
.build().submit(plugin, sender);
}
save(user, sender, plugin);
save(holder, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectLacksException e) {
Message.USER_NOT_MEMBER_OF.send(sender, user.getName(), groupName);
Message.DOES_NOT_TEMP_INHERIT.send(sender, holder.getFriendlyName(), groupName);
return CommandResult.STATE_ERROR;
}
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.generic.permission;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.commands.generic.SecondaryMainCommand;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.core.PermissionHolder;
public class CommandPermission<T extends PermissionHolder> extends SecondaryMainCommand<T> {
public CommandPermission(boolean user) {
super("Permission", "Edit permissions", user, ImmutableList.<SecondarySubCommand>builder()
.add(new PermissionInfo())
.add(new PermissionSet())
.add(new PermissionUnset())
.add(new PermissionSetTemp())
.add(new PermissionUnsetTemp())
.build());
}
}
@@ -20,26 +20,29 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.group.subcommands;
package me.lucko.luckperms.common.commands.generic.permission;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.Util;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.core.PermissionHolder;
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);
public class PermissionInfo extends SecondarySubCommand {
public PermissionInfo() {
super("info", "Lists the permission nodes the object has", Permission.USER_PERM_INFO, Permission.GROUP_PERM_INFO, 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)));
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
Message.LISTNODES.send(sender, holder.getFriendlyName(), Util.permNodesToString(holder.getPermissions(false)));
Message.LISTNODES_TEMP.send(sender, holder.getFriendlyName(), Util.tempNodesToString(holder.getPermissions(false)));
return CommandResult.SUCCESS;
}
}
@@ -20,22 +20,28 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.group.subcommands;
package me.lucko.luckperms.common.commands.generic.permission;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
public class GroupSetPermission extends SubCommand<Group> {
public GroupSetPermission() {
super("set", "Sets a permission for the group", Permission.GROUP_SETPERMISSION, Predicate.notInRange(2, 4),
import static me.lucko.luckperms.common.commands.SubCommand.getBoolTabComplete;
public class PermissionSet extends SecondarySubCommand {
public PermissionSet() {
super("set", "Sets a permission for the object", Permission.USER_PERM_SET, Permission.GROUP_PERM_SET, 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"),
@@ -46,7 +52,7 @@ public class GroupSetPermission extends SubCommand<Group> {
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
String node = args.get(0).replace("{SPACE}", " ");
String bool = args.get(1).toLowerCase();
@@ -56,7 +62,7 @@ public class GroupSetPermission extends SubCommand<Group> {
}
if (node.toLowerCase().startsWith("group.")) {
Message.GROUP_USE_INHERIT.send(sender);
Message.USE_INHERIT_COMMAND.send(sender);
return CommandResult.INVALID_ARGS;
}
@@ -76,32 +82,32 @@ public class GroupSetPermission extends SubCommand<Group> {
}
if (args.size() == 3) {
group.setPermission(node, b, server);
Message.SETPERMISSION_SERVER_SUCCESS.send(sender, node, bool, group.getDisplayName(), server);
LogEntry.build().actor(sender).acted(group)
.action("set " + node + " " + b + " " + server)
holder.setPermission(node, b, server);
Message.SETPERMISSION_SERVER_SUCCESS.send(sender, node, bool, holder.getFriendlyName(), server);
LogEntry.build().actor(sender).acted(holder)
.action("permission set " + node + " " + b + " " + server)
.build().submit(plugin, sender);
} else {
final String world = args.get(3).toLowerCase();
group.setPermission(node, b, server, world);
Message.SETPERMISSION_SERVER_WORLD_SUCCESS.send(sender, node, bool, group.getDisplayName(), server, world);
LogEntry.build().actor(sender).acted(group)
.action("set " + node + " " + b + " " + server + " " + world)
holder.setPermission(node, b, server, world);
Message.SETPERMISSION_SERVER_WORLD_SUCCESS.send(sender, node, bool, holder.getFriendlyName(), server, world);
LogEntry.build().actor(sender).acted(holder)
.action("permission set " + node + " " + b + " " + server + " " + world)
.build().submit(plugin, sender);
}
} else {
group.setPermission(node, b);
Message.SETPERMISSION_SUCCESS.send(sender, node, bool, group.getDisplayName());
LogEntry.build().actor(sender).acted(group)
.action("set " + node + " " + b)
holder.setPermission(node, b);
Message.SETPERMISSION_SUCCESS.send(sender, node, bool, holder.getFriendlyName());
LogEntry.build().actor(sender).acted(holder)
.action("permission set " + node + " " + b)
.build().submit(plugin, sender);
}
save(group, sender, plugin);
save(holder, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectAlreadyHasException e) {
Message.ALREADY_HASPERMISSION.send(sender, group.getDisplayName());
Message.ALREADY_HASPERMISSION.send(sender, holder.getFriendlyName());
return CommandResult.STATE_ERROR;
}
}
@@ -20,23 +20,29 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.group.subcommands;
package me.lucko.luckperms.common.commands.generic.permission;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.common.utils.DateUtil;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
public class GroupSetTempPermission extends SubCommand<Group> {
public GroupSetTempPermission() {
super("settemp", "Sets a permission for the group temporarily", Permission.GROUP_SET_TEMP_PERMISSION,
import static me.lucko.luckperms.common.commands.SubCommand.getBoolTabComplete;
public class PermissionSetTemp extends SecondarySubCommand {
public PermissionSetTemp() {
super("settemp", "Sets a permission for the object temporarily", Permission.USER_PERM_SETTEMP, Permission.GROUP_PERM_SETTEMP,
Predicate.notInRange(3, 5),
Arg.list(
Arg.create("node", true, "the permission node to set"),
@@ -49,7 +55,7 @@ public class GroupSetTempPermission extends SubCommand<Group> {
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
String node = args.get(0).replace("{SPACE}", " ");
String bool = args.get(1).toLowerCase();
@@ -59,7 +65,7 @@ public class GroupSetTempPermission extends SubCommand<Group> {
}
if (node.toLowerCase().startsWith("group.")) {
Message.GROUP_USE_INHERIT.send(sender);
Message.USE_INHERIT_COMMAND.send(sender);
return CommandResult.INVALID_ARGS;
}
@@ -96,34 +102,34 @@ public class GroupSetTempPermission extends SubCommand<Group> {
}
if (args.size() == 4) {
group.setPermission(node, b, server, duration);
Message.SETPERMISSION_TEMP_SERVER_SUCCESS.send(sender, node, bool, group.getDisplayName(), server,
holder.setPermission(node, b, server, duration);
Message.SETPERMISSION_TEMP_SERVER_SUCCESS.send(sender, node, bool, holder.getFriendlyName(), server,
DateUtil.formatDateDiff(duration));
LogEntry.build().actor(sender).acted(group)
.action("settemp " + node + " " + b + " " + duration + " " + server)
LogEntry.build().actor(sender).acted(holder)
.action("permission settemp " + node + " " + b + " " + duration + " " + server)
.build().submit(plugin, sender);
} else {
final String world = args.get(4).toLowerCase();
group.setPermission(node, b, server, world, duration);
Message.SETPERMISSION_TEMP_SERVER_WORLD_SUCCESS.send(sender, node, bool, group.getDisplayName(), server,
holder.setPermission(node, b, server, world, duration);
Message.SETPERMISSION_TEMP_SERVER_WORLD_SUCCESS.send(sender, node, bool, holder.getFriendlyName(), server,
world, DateUtil.formatDateDiff(duration));
LogEntry.build().actor(sender).acted(group)
.action("settemp " + node + " " + b + " " + duration + " " + server + " " + world)
LogEntry.build().actor(sender).acted(holder)
.action("permission settemp " + node + " " + b + " " + duration + " " + server + " " + world)
.build().submit(plugin, sender);
}
} else {
group.setPermission(node, b, duration);
Message.SETPERMISSION_TEMP_SUCCESS.send(sender, node, bool, group.getDisplayName(), DateUtil.formatDateDiff(duration));
LogEntry.build().actor(sender).acted(group)
.action("settemp " + node + " " + b + " " + duration)
holder.setPermission(node, b, duration);
Message.SETPERMISSION_TEMP_SUCCESS.send(sender, node, bool, holder.getFriendlyName(), DateUtil.formatDateDiff(duration));
LogEntry.build().actor(sender).acted(holder)
.action("permission settemp " + node + " " + b + " " + duration)
.build().submit(plugin, sender);
}
save(group, sender, plugin);
save(holder, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectAlreadyHasException e) {
Message.ALREADY_HAS_TEMP_PERMISSION.send(sender, group.getDisplayName());
Message.ALREADY_HAS_TEMP_PERMISSION.send(sender, holder.getFriendlyName());
return CommandResult.STATE_ERROR;
}
}
@@ -20,22 +20,26 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.group.subcommands;
package me.lucko.luckperms.common.commands.generic.permission;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
public class GroupUnSetPermission extends SubCommand<Group> {
public GroupUnSetPermission() {
super("unset", "Unsets a permission for the group", Permission.GROUP_UNSETPERMISSION, Predicate.notInRange(1, 3),
public class PermissionUnset extends SecondarySubCommand {
public PermissionUnset() {
super("unset", "Unsets a permission for the object", Permission.USER_PERM_UNSET, Permission.GROUP_PERM_UNSET, 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"),
@@ -45,7 +49,7 @@ public class GroupUnSetPermission extends SubCommand<Group> {
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
String node = args.get(0).replace("{SPACE}", " ");
if (ArgumentChecker.checkNode(node)) {
@@ -54,7 +58,7 @@ public class GroupUnSetPermission extends SubCommand<Group> {
}
if (node.toLowerCase().startsWith("group.")) {
Message.GROUP_USE_UNINHERIT.send(sender);
Message.USE_UNINHERIT_COMMAND.send(sender);
return CommandResult.INVALID_ARGS;
}
@@ -67,32 +71,32 @@ public class GroupUnSetPermission extends SubCommand<Group> {
}
if (args.size() == 2) {
group.unsetPermission(node, server);
Message.UNSETPERMISSION_SERVER_SUCCESS.send(sender, node, group.getDisplayName(), server);
LogEntry.build().actor(sender).acted(group)
.action("unset " + node + " " + server)
holder.unsetPermission(node, server);
Message.UNSETPERMISSION_SERVER_SUCCESS.send(sender, node, holder.getFriendlyName(), server);
LogEntry.build().actor(sender).acted(holder)
.action("permission unset " + node + " " + server)
.build().submit(plugin, sender);
} else {
final String world = args.get(2).toLowerCase();
group.unsetPermission(node, server, world);
Message.UNSETPERMISSION_SERVER_WORLD_SUCCESS.send(sender, node, group.getDisplayName(), server, world);
LogEntry.build().actor(sender).acted(group)
.action("unset " + node + " " + server + " " + world)
holder.unsetPermission(node, server, world);
Message.UNSETPERMISSION_SERVER_WORLD_SUCCESS.send(sender, node, holder.getFriendlyName(), server, world);
LogEntry.build().actor(sender).acted(holder)
.action("permission unset " + node + " " + server + " " + world)
.build().submit(plugin, sender);
}
} else {
group.unsetPermission(node);
Message.UNSETPERMISSION_SUCCESS.send(sender, node, group.getDisplayName());
LogEntry.build().actor(sender).acted(group)
.action("unset " + node)
holder.unsetPermission(node);
Message.UNSETPERMISSION_SUCCESS.send(sender, node, holder.getFriendlyName());
LogEntry.build().actor(sender).acted(holder)
.action("permission unset " + node)
.build().submit(plugin, sender);
}
save(group, sender, plugin);
save(holder, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectLacksException e) {
Message.DOES_NOT_HAVEPERMISSION.send(sender, group.getDisplayName());
Message.DOES_NOT_HAVEPERMISSION.send(sender, holder.getFriendlyName());
return CommandResult.STATE_ERROR;
}
}
@@ -20,22 +20,26 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.user.subcommands;
package me.lucko.luckperms.common.commands.generic.permission;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.generic.SecondarySubCommand;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
public class UserUnsetTempPermission extends SubCommand<User> {
public UserUnsetTempPermission() {
super("unsettemp", "Unsets a temporary permission for the user", Permission.USER_UNSET_TEMP_PERMISSION,
public class PermissionUnsetTemp extends SecondarySubCommand {
public PermissionUnsetTemp() {
super("unsettemp", "Unsets a temporary permission for the object", Permission.USER_PERM_UNSETTEMP, Permission.GROUP_PERM_UNSETTEMP,
Predicate.notInRange(1, 3),
Arg.list(
Arg.create("node", true, "the permission node to unset"),
@@ -46,7 +50,7 @@ public class UserUnsetTempPermission extends SubCommand<User> {
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args) {
String node = args.get(0).replace("{SPACE}", " ");
if (ArgumentChecker.checkNode(node)) {
@@ -55,7 +59,7 @@ public class UserUnsetTempPermission extends SubCommand<User> {
}
if (node.toLowerCase().startsWith("group.")) {
Message.USER_USE_REMOVEGROUP.send(sender);
Message.USE_UNINHERIT_COMMAND.send(sender);
return CommandResult.INVALID_ARGS;
}
@@ -68,32 +72,32 @@ public class UserUnsetTempPermission extends SubCommand<User> {
}
if (args.size() == 2) {
user.unsetPermission(node, server, true);
Message.UNSET_TEMP_PERMISSION_SERVER_SUCCESS.send(sender, node, user.getName(), server);
LogEntry.build().actor(sender).acted(user)
.action("unsettemp " + node + " " + server)
holder.unsetPermission(node, server);
Message.UNSET_TEMP_PERMISSION_SERVER_SUCCESS.send(sender, node, holder.getFriendlyName(), server);
LogEntry.build().actor(sender).acted(holder)
.action("permission unsettemp " + node + " " + server)
.build().submit(plugin, sender);
} else {
final String world = args.get(2).toLowerCase();
user.unsetPermission(node, server, world, true);
Message.UNSET_TEMP_PERMISSION_SERVER_WORLD_SUCCESS.send(sender, node, user.getName(), server, world);
LogEntry.build().actor(sender).acted(user)
.action("unsettemp " + node + " " + server + " " + world)
holder.unsetPermission(node, server, world);
Message.UNSET_TEMP_PERMISSION_SERVER_WORLD_SUCCESS.send(sender, node, holder.getFriendlyName(), server, world);
LogEntry.build().actor(sender).acted(holder)
.action("permission unsettemp " + node + " " + server + " " + world)
.build().submit(plugin, sender);
}
} else {
user.unsetPermission(node, true);
Message.UNSET_TEMP_PERMISSION_SUCCESS.send(sender, node, user.getName());
LogEntry.build().actor(sender).acted(user)
.action("unsettemp " + node)
holder.unsetPermission(node, true);
Message.UNSET_TEMP_PERMISSION_SUCCESS.send(sender, node, holder.getFriendlyName());
LogEntry.build().actor(sender).acted(holder)
.action("permission unsettemp " + node)
.build().submit(plugin, sender);
}
save(user, sender, plugin);
save(holder, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectLacksException e) {
Message.DOES_NOT_HAVE_TEMP_PERMISSION.send(sender, user.getName());
Message.DOES_NOT_HAVE_TEMP_PERMISSION.send(sender, holder.getFriendlyName());
return CommandResult.STATE_ERROR;
}
}
@@ -51,19 +51,18 @@ public class CreateGroup extends SingleMainCommand {
return CommandResult.INVALID_ARGS;
}
if (plugin.getDatastore().loadGroup(groupName)) {
if (plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
Message.GROUP_ALREADY_EXISTS.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().createAndLoadGroup(groupName)) {
if (!plugin.getDatastore().createAndLoadGroup(groupName).getUnchecked()) {
Message.CREATE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}
Message.CREATE_SUCCESS.send(sender, groupName);
LogEntry.build().actor(sender).actedName(groupName).type('G').action("create").build().submit(plugin, sender);
plugin.runUpdateTask();
return CommandResult.SUCCESS;
}
}
@@ -55,7 +55,7 @@ public class DeleteGroup extends SingleMainCommand {
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().loadGroup(groupName)) {
if (!plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}
@@ -66,14 +66,14 @@ public class DeleteGroup extends SingleMainCommand {
return CommandResult.LOADING_ERROR;
}
if (!plugin.getDatastore().deleteGroup(group)) {
if (!plugin.getDatastore().deleteGroup(group).getUnchecked()) {
Message.DELETE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}
Message.DELETE_SUCCESS.send(sender, group.getDisplayName());
LogEntry.build().actor(sender).actedName(groupName).type('G').action("delete").build().submit(plugin, sender);
plugin.runUpdateTask();
plugin.getUpdateTaskBuffer().request();
return CommandResult.SUCCESS;
}
@@ -27,8 +27,10 @@ import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.MainCommand;
import me.lucko.luckperms.common.commands.Sender;
import me.lucko.luckperms.common.commands.SubCommand;
import me.lucko.luckperms.common.commands.generic.meta.CommandMeta;
import me.lucko.luckperms.common.commands.generic.parent.CommandParent;
import me.lucko.luckperms.common.commands.generic.permission.CommandPermission;
import me.lucko.luckperms.common.commands.group.subcommands.*;
import me.lucko.luckperms.common.commands.meta.MetaCommands;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.groups.Group;
@@ -39,20 +41,12 @@ public class GroupMainCommand extends MainCommand<Group> {
public GroupMainCommand() {
super("Group", "/%s group <group>", 2, ImmutableList.<SubCommand<Group>>builder()
.add(new GroupInfo())
.add(new GroupListNodes())
.add(new GroupListParents())
.add(new CommandPermission<>(false))
.add(new CommandParent<>(false))
.add(new CommandMeta<>(false))
.add(new GroupHasPerm())
.add(new GroupInheritsPerm())
.add(new GroupSetPermission())
.add(new GroupUnSetPermission())
.add(new GroupSetInherit())
.add(new GroupUnsetInherit())
.add(new GroupSetTempPermission())
.add(new GroupUnsetTempPermission())
.add(new GroupSetTempInherit())
.add(new GroupUnsetTempInherit())
.add(new GroupShowTracks())
.add(new MetaCommands<>(false))
.add(new GroupBulkChange())
.add(new GroupClear())
.add(new GroupRename())
@@ -63,7 +57,7 @@ public class GroupMainCommand extends MainCommand<Group> {
@Override
protected Group getTarget(String target, LuckPermsPlugin plugin, Sender sender) {
if (!plugin.getDatastore().loadGroup(target)) {
if (!plugin.getDatastore().loadGroup(target).getUnchecked()) {
Message.GROUP_NOT_FOUND.send(sender);
return null;
}
@@ -42,7 +42,7 @@ public class ListGroups extends SingleMainCommand {
@Override
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
if (!plugin.getDatastore().loadAllGroups()) {
if (!plugin.getDatastore().loadAllGroups().getUnchecked()) {
Message.GROUPS_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;
}
@@ -47,12 +47,12 @@ public class GroupClone extends SubCommand<Group> {
return CommandResult.INVALID_ARGS;
}
if (plugin.getDatastore().loadGroup(newGroupName)) {
if (plugin.getDatastore().loadGroup(newGroupName).getUnchecked()) {
Message.GROUP_ALREADY_EXISTS.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().createAndLoadGroup(newGroupName)) {
if (!plugin.getDatastore().createAndLoadGroup(newGroupName).getUnchecked()) {
Message.CREATE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}
@@ -47,12 +47,12 @@ public class GroupRename extends SubCommand<Group> {
return CommandResult.INVALID_ARGS;
}
if (plugin.getDatastore().loadGroup(newGroupName)) {
if (plugin.getDatastore().loadGroup(newGroupName).getUnchecked()) {
Message.GROUP_ALREADY_EXISTS.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().createAndLoadGroup(newGroupName)) {
if (!plugin.getDatastore().createAndLoadGroup(newGroupName).getUnchecked()) {
Message.CREATE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}
@@ -63,7 +63,7 @@ public class GroupRename extends SubCommand<Group> {
return CommandResult.LOADING_ERROR;
}
if (!plugin.getDatastore().deleteGroup(group)) {
if (!plugin.getDatastore().deleteGroup(group).getUnchecked()) {
Message.DELETE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}
@@ -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.common.commands.group.subcommands;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
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);
}
}
@@ -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.common.commands.group.subcommands;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.common.utils.DateUtil;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
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);
}
}
@@ -39,7 +39,7 @@ public class GroupShowTracks extends SubCommand<Group> {
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
if (!plugin.getDatastore().loadAllTracks()) {
if (!plugin.getDatastore().loadAllTracks().getUnchecked()) {
Message.TRACKS_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;
}
@@ -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.common.commands.group.subcommands;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
public class GroupUnsetInherit extends SubCommand<Group> {
public GroupUnsetInherit() {
super("unsetinherit", "Removes a previously set inheritance rule", Permission.GROUP_UNSETINHERIT,
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);
Message.GROUP_UNSETINHERIT_SERVER_SUCCESS.send(sender, group.getDisplayName(), groupName, server);
LogEntry.build().actor(sender).acted(group)
.action("unsetinherit " + groupName + " " + server)
.build().submit(plugin, sender);
} else {
final String world = args.get(2).toLowerCase();
group.unsetPermission("group." + groupName, server, world);
Message.GROUP_UNSETINHERIT_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), groupName, server, world);
LogEntry.build().actor(sender).acted(group)
.action("unsetinherit " + groupName + " " + server + " " + world)
.build().submit(plugin, sender);
}
} else {
group.unsetPermission("group." + groupName);
Message.GROUP_UNSETINHERIT_SUCCESS.send(sender, group.getDisplayName(), groupName);
LogEntry.build().actor(sender).acted(group)
.action("unsetinherit " + groupName)
.build().submit(plugin, sender);
}
save(group, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectLacksException e) {
Message.GROUP_DOES_NOT_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);
}
}
@@ -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.common.commands.group.subcommands;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectLacksException;
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);
}
}
@@ -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.common.commands.group.subcommands;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectLacksException;
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;
}
}
}
@@ -52,7 +52,7 @@ public class LogMainCommand extends MainCommand<Log> {
@Override
protected Log getTarget(String target, LuckPermsPlugin plugin, Sender sender) {
Log log = plugin.getDatastore().getLog();
Log log = plugin.getDatastore().getLog().getUnchecked();
if (log == null) {
Message.LOG_LOAD_ERROR.send(sender);
@@ -74,7 +74,7 @@ public class LogRecent extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
UUID uuid = plugin.getDatastore().getUUID(s);
UUID uuid = plugin.getDatastore().getUUID(s).getUnchecked();
if (uuid == null) {
Message.USER_NOT_FOUND.send(sender);
@@ -76,7 +76,7 @@ public class LogUserHistory extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
UUID uuid1 = plugin.getDatastore().getUUID(user);
UUID uuid1 = plugin.getDatastore().getUUID(user).getUnchecked();
if (uuid1 == null) {
Message.USER_NOT_FOUND.send(sender);
@@ -24,6 +24,7 @@ package me.lucko.luckperms.common.commands.migration.subcommands;
import de.bananaco.bpermissions.api.*;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
@@ -32,7 +33,6 @@ import me.lucko.luckperms.common.commands.SubCommand;
import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.core.PermissionHolder;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.lang.reflect.Field;
@@ -121,7 +121,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
}
// Make a LuckPerms group for the one being migrated.
plugin.getDatastore().createAndLoadGroup(groupName);
plugin.getDatastore().createAndLoadGroup(groupName).getUnchecked();
me.lucko.luckperms.common.groups.Group lpGroup = plugin.getGroupManager().get(groupName);
try {
LogEntry.build()
@@ -157,7 +157,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
}
// Make a LuckPerms user for the one being migrated.
plugin.getDatastore().loadUser(uuid, "null");
plugin.getDatastore().loadUser(uuid, "null").getUnchecked();
me.lucko.luckperms.common.users.User lpUser = plugin.getUserManager().get(uuid);
migrateHolder(plugin, world, user, lpUser);
@@ -222,7 +222,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
// Migrate existing meta
for (Map.Entry<String, String> meta : c.getMeta().entrySet()) {
if (meta.getKey().equalsIgnoreCase("prefix") || meta.getKey().equalsIgnoreCase("suffix")) {
String chatMeta = ArgumentChecker.escapeCharacters(meta.getValue());
String chatMeta = MetaUtils.escapeCharacters(meta.getValue());
try {
holder.setPermission(meta.getKey().toLowerCase() + "." + c.getPriority() + "." + chatMeta, true);
LogEntry.build()
@@ -23,6 +23,7 @@
package me.lucko.luckperms.common.commands.migration.subcommands;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.Predicate;
@@ -31,7 +32,6 @@ import me.lucko.luckperms.common.commands.SubCommand;
import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import net.alpenblock.bungeeperms.*;
@@ -63,7 +63,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
groupCount ++;
// Make a LuckPerms group for the one being migrated
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase());
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase()).getUnchecked();
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
try {
LogEntry.build()
@@ -144,7 +144,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
String suffix = g.getSuffix();
if (prefix != null && !prefix.equals("")) {
prefix = ArgumentChecker.escapeCharacters(prefix);
prefix = MetaUtils.escapeCharacters(prefix);
try {
group.setPermission("prefix.50." + prefix, true);
LogEntry.build()
@@ -159,7 +159,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
}
if (suffix != null && !suffix.equals("")) {
suffix = ArgumentChecker.escapeCharacters(suffix);
suffix = MetaUtils.escapeCharacters(suffix);
try {
group.setPermission("suffix.50." + suffix, true);
LogEntry.build()
@@ -187,7 +187,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
userCount++;
// Make a LuckPerms user for the one being migrated.
plugin.getDatastore().loadUser(u.getUUID(), "null");
plugin.getDatastore().loadUser(u.getUUID(), "null").getUnchecked();
me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(u.getUUID());
// Migrate global perms
@@ -259,7 +259,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
String suffix = u.getSuffix();
if (prefix != null && !prefix.equals("")) {
prefix = ArgumentChecker.escapeCharacters(prefix);
prefix = MetaUtils.escapeCharacters(prefix);
try {
user.setPermission("prefix.100." + prefix, true);
LogEntry.build()
@@ -274,7 +274,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
}
if (suffix != null && !suffix.equals("")) {
suffix = ArgumentChecker.escapeCharacters(suffix);
suffix = MetaUtils.escapeCharacters(suffix);
try {
user.setPermission("suffix.100." + suffix, true);
LogEntry.build()
@@ -73,7 +73,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
}
for (Group g : gg.getGroupList()) {
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase());
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase()).getUnchecked();
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
try {
LogEntry.build()
@@ -202,7 +202,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
log.info("GroupManager Migration: Found a total of " + users.size() + " users and " + groups.size() + " groups.");
for (Map.Entry<String, Map<Map.Entry<String, String>, Boolean>> e : groups.entrySet()) {
plugin.getDatastore().createAndLoadGroup(e.getKey());
plugin.getDatastore().createAndLoadGroup(e.getKey()).getUnchecked();
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(e.getKey());
try {
LogEntry.build()
@@ -245,7 +245,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
}
for (Map.Entry<UUID, Map<Map.Entry<String, String>, Boolean>> e : users.entrySet()) {
plugin.getDatastore().loadUser(e.getKey(), "null");
plugin.getDatastore().loadUser(e.getKey(), "null").getUnchecked();
me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(e.getKey());
for (Map.Entry<Map.Entry<String, String>, Boolean> n : e.getValue().entrySet()) {
@@ -23,6 +23,7 @@
package me.lucko.luckperms.common.commands.migration.subcommands;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
@@ -31,7 +32,6 @@ import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import ru.tehkode.permissions.NativeInterface;
import ru.tehkode.permissions.PermissionGroup;
@@ -102,7 +102,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
maxGroupWeight = Math.max(maxGroupWeight, groupWeight);
final String name = group.getName().toLowerCase();
plugin.getDatastore().createAndLoadGroup(name);
plugin.getDatastore().createAndLoadGroup(name).getUnchecked();
Group lpGroup = plugin.getGroupManager().get(name);
try {
LogEntry.build()
@@ -197,7 +197,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
String suffix = group.getOwnSuffix();
if (prefix != null && !prefix.equals("")) {
prefix = ArgumentChecker.escapeCharacters(prefix);
prefix = MetaUtils.escapeCharacters(prefix);
try {
lpGroup.setPermission("prefix." + groupWeight + "." + prefix, true);
LogEntry.build()
@@ -212,7 +212,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
}
if (suffix != null && !suffix.equals("")) {
suffix = ArgumentChecker.escapeCharacters(suffix);
suffix = MetaUtils.escapeCharacters(suffix);
try {
lpGroup.setPermission("suffix." + groupWeight + "." + suffix, true);
LogEntry.build()
@@ -254,7 +254,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
}
userCount++;
plugin.getDatastore().loadUser(u, "null");
plugin.getDatastore().loadUser(u, "null").getUnchecked();
User lpUser = plugin.getUserManager().get(u);
try {
@@ -341,7 +341,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
String suffix = user.getOwnSuffix();
if (prefix != null && !prefix.equals("")) {
prefix = ArgumentChecker.escapeCharacters(prefix);
prefix = MetaUtils.escapeCharacters(prefix);
try {
lpUser.setPermission("prefix." + maxGroupWeight + "." + prefix, true);
LogEntry.build()
@@ -356,7 +356,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
}
if (suffix != null && !suffix.equals("")) {
suffix = ArgumentChecker.escapeCharacters(suffix);
suffix = MetaUtils.escapeCharacters(suffix);
try {
lpUser.setPermission("suffix." + maxGroupWeight + "." + suffix, true);
LogEntry.build()
@@ -246,7 +246,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
log.info("PowerfulPerms Migration: Starting group migration.");
Map<Integer, Group> groups = pm.getGroups(); // All versions
for (Group g : groups.values()) {
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase());
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase()).getUnchecked();
final me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
try {
LogEntry.build()
@@ -288,7 +288,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
progress.put(uuid, new CountDownLatch(2));
// Create a LuckPerms user for the UUID
plugin.getDatastore().loadUser(uuid, "null");
plugin.getDatastore().loadUser(uuid, "null").getUnchecked();
User user = plugin.getUserManager().get(uuid);
// Get a list of Permissions held by the user from the PP API.
@@ -23,6 +23,7 @@
package me.lucko.luckperms.common.commands.migration.subcommands;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.*;
import me.lucko.luckperms.common.constants.Constants;
@@ -31,7 +32,6 @@ import me.lucko.luckperms.common.data.LogEntry;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.tracks.Track;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import org.tyrannyofheaven.bukkit.zPermissions.ZPermissionsService;
@@ -72,7 +72,7 @@ public class MigrationZPermissions extends SubCommand<Object> {
// Migrate all groups
log.info("zPermissions Migration: Starting group migration.");
for (String g : service.getAllGroups()) {
plugin.getDatastore().createAndLoadGroup(g.toLowerCase());
plugin.getDatastore().createAndLoadGroup(g.toLowerCase()).getUnchecked();
Group group = plugin.getGroupManager().get(g.toLowerCase());
try {
LogEntry.build()
@@ -121,7 +121,7 @@ public class MigrationZPermissions extends SubCommand<Object> {
// Migrate all tracks
log.info("zPermissions Migration: Starting track migration.");
for (String t : service.getAllTracks()) {
plugin.getDatastore().createAndLoadTrack(t.toLowerCase());
plugin.getDatastore().createAndLoadTrack(t.toLowerCase()).getUnchecked();
Track track = plugin.getTrackManager().get(t.toLowerCase());
try {
LogEntry.build()
@@ -150,7 +150,7 @@ public class MigrationZPermissions extends SubCommand<Object> {
// Migrate all users.
log.info("zPermissions Migration: Starting user migration.");
for (UUID u : service.getAllPlayersUUID()) {
plugin.getDatastore().loadUser(u, "null");
plugin.getDatastore().loadUser(u, "null").getUnchecked();
User user = plugin.getUserManager().get(u);
for (Map.Entry<String, Boolean> e : service.getPlayerPermissions(null, null, u).entrySet()) {
@@ -213,7 +213,7 @@ public class MigrationZPermissions extends SubCommand<Object> {
String suffix = service.getPlayerSuffix(u);
if (prefix != null && !prefix.equals("")) {
prefix = ArgumentChecker.escapeCharacters(prefix);
prefix = MetaUtils.escapeCharacters(prefix);
try {
user.setPermission("prefix.100." + prefix, true);
LogEntry.build()
@@ -228,7 +228,7 @@ public class MigrationZPermissions extends SubCommand<Object> {
}
if (suffix != null && !suffix.equals("")) {
suffix = ArgumentChecker.escapeCharacters(suffix);
suffix = MetaUtils.escapeCharacters(suffix);
try {
user.setPermission("suffix.100." + suffix, true);
LogEntry.build()
@@ -118,13 +118,13 @@ public class ExportCommand extends SingleMainCommand {
// Export users
log.info("Export: Exporting all users. Finding a list of unique users to export.");
Datastore ds = plugin.getDatastore();
Set<UUID> users = ds.getUniqueUsers();
Set<UUID> users = ds.getUniqueUsers().getUnchecked();
log.info("Export: Found " + users.size() + " unique users to export.");
int userCount = 0;
for (UUID uuid : users) {
userCount++;
plugin.getDatastore().loadUser(uuid, "null");
plugin.getDatastore().loadUser(uuid, "null").getUnchecked();
User user = plugin.getUserManager().get(uuid);
boolean inDefault = false;
Loaded 100 of 182 files, more files were not shown because too many files have changed in this diff. Show more