Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3424b0542a | ||
|
|
fec90b8958 | ||
|
|
4da7fe4ff9 | ||
|
|
c53623dd67 | ||
|
|
6540ffa4dd | ||
|
|
5ee6db02ff | ||
|
|
d8221f466a | ||
|
|
462bea2a09 | ||
|
|
f452a97278 | ||
|
|
eb9d2be587 | ||
|
|
df1e747861 | ||
|
|
f48595b1ff | ||
|
|
12cd4e19cb | ||
|
|
a195e94522 | ||
|
|
02abb39dc2 | ||
|
|
f7a0b1ef78 | ||
|
|
7678f25879 | ||
|
|
fa9324bda8 | ||
|
|
1e72f9d8fe | ||
|
|
50fd954599 | ||
|
|
b1e34b55f8 | ||
|
|
cff1b8a411 | ||
|
|
6ffa6720be | ||
|
|
f52a106165 | ||
|
|
bf247b71e1 | ||
|
|
66818e4c82 | ||
|
|
23d53d39b4 | ||
|
|
30ea5a5b69 | ||
|
|
e7a210dc06 | ||
|
|
497de9824a | ||
|
|
be74b50762 | ||
|
|
f2e06b56e7 | ||
|
|
f6aa20c300 | ||
|
|
5e16134f6f | ||
|
|
6165fcbb21 | ||
|
|
831e882db0 | ||
|
|
feb8bf4bd3 | ||
|
|
ce3ee866ca | ||
|
|
d29dd35689 | ||
|
|
3a0a89853f | ||
|
|
e7ca79d251 | ||
|
|
22426bab33 | ||
|
|
116094ea96 | ||
|
|
9df39a9545 | ||
|
|
b8f44df723 | ||
|
|
74f275eb69 | ||
|
|
1142cbcb2c | ||
|
|
37749e5829 | ||
|
|
f9025c7a51 | ||
|
|
c7bfc38477 | ||
|
|
7ca394d7b9 | ||
|
|
31884ea59d | ||
|
|
e79b7c7023 | ||
|
|
1fdb4e8ade | ||
|
|
53db8c5928 | ||
|
|
07514000a4 | ||
|
|
f28721e55a | ||
|
|
fc230291d3 | ||
|
|
89ff4cfa40 | ||
|
|
d786b6abb2 | ||
|
|
fb0e694155 | ||
|
|
cd6cac1fb6 |
No files matched your search
@@ -1,5 +1,6 @@
|
||||

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

|
||||
_Features checked on 23rd Aug 2016. If you find any inaccuracies, please do let me know. I tried to be as fair as possible, and copy all major features from the respective plugin pages._
|
||||
|
||||
## License
|
||||
See LICENSE.md.
|
||||
|
||||
## Thanks to:
|
||||
[](http://www.ej-technologies.com/products/jprofiler/overview.html)
|
||||
|
||||
Thanks to ej-technologies for granting LuckPerms an open source licence to their [java profiling software](http://www.ej-technologies.com/products/jprofiler/overview.html "Java Profiler").
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.8-SNAPSHOT</version>
|
||||
<version>2.10-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -62,6 +62,24 @@ public interface LPConfiguration {
|
||||
*/
|
||||
boolean getIncludeGlobalPerms();
|
||||
|
||||
/**
|
||||
* @return if the users on this server will have their global world permissions applied
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getIncludeGlobalWorldPerms();
|
||||
|
||||
/**
|
||||
* @return true if the platform is applying global groups
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getApplyGlobalGroups();
|
||||
|
||||
/**
|
||||
* @return true if the platform is applying global world groups
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getApplyGlobalWorldGroups();
|
||||
|
||||
/**
|
||||
* @return the online mode setting in the config
|
||||
*/
|
||||
@@ -88,6 +106,12 @@ public interface LPConfiguration {
|
||||
*/
|
||||
boolean getLogNotify();
|
||||
|
||||
/**
|
||||
* @return true if permission checks are being recorded / debugged
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getDebugPermissionChecks();
|
||||
|
||||
/**
|
||||
* @return true if the vanilla op system is enabled
|
||||
* @since 2.8
|
||||
@@ -100,6 +124,12 @@ public interface LPConfiguration {
|
||||
*/
|
||||
boolean getCommandsAllowOp();
|
||||
|
||||
/**
|
||||
* @return true if auto op is enabled
|
||||
* @since 2.9
|
||||
*/
|
||||
boolean getAutoOp();
|
||||
|
||||
/**
|
||||
* @return the name of the server used within Vault operations
|
||||
* @since 2.7
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import me.lucko.luckperms.api.context.IContextCalculator;
|
||||
import me.lucko.luckperms.api.event.LPListener;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -187,7 +189,7 @@ public interface LuckPermsApi {
|
||||
Track getTrack(String name);
|
||||
|
||||
/**
|
||||
* Gets a wrapped tracj object from the track storage. This method does not return null, unlike {@link #getTrack}
|
||||
* Gets a wrapped track object from the track storage. This method does not return null, unlike {@link #getTrack}
|
||||
* @param name the name of the track to get
|
||||
* @return an optional {@link Track} object
|
||||
* @throws NullPointerException if the name is null
|
||||
@@ -218,4 +220,18 @@ public interface LuckPermsApi {
|
||||
*/
|
||||
Node.Builder buildNode(String permission) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Register a custom context calculator to the server
|
||||
* @param contextCalculator the context calculator to register. The type MUST be the player class of the platform.
|
||||
* @throws ClassCastException if the type is not the player class of the platform.
|
||||
*/
|
||||
void registerContextCalculator(IContextCalculator<?> contextCalculator);
|
||||
|
||||
/**
|
||||
* Registers a custom context listener to the server,
|
||||
* @param contextListener the context listener to register. The type MUST be the player class of the platform.
|
||||
* @throws ClassCastException if the type is not the player class of the platform.
|
||||
*/
|
||||
void registerContextListener(ContextListener<?> contextListener);
|
||||
|
||||
}
|
||||
@@ -105,7 +105,15 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
boolean shouldApplyOnWorld(String world, boolean includeGlobal, boolean applyRegex);
|
||||
|
||||
/**
|
||||
* If this node should apply given the specific 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
|
||||
*/
|
||||
boolean shouldApplyWithContext(Map<String, String> 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
|
||||
*/
|
||||
|
||||
@@ -30,7 +30,12 @@ public enum PlatformType {
|
||||
|
||||
BUKKIT("Bukkit"),
|
||||
BUNGEE("Bungee"),
|
||||
SPONGE("Sponge");
|
||||
SPONGE("Sponge"),
|
||||
|
||||
/**
|
||||
* @since 2.9
|
||||
*/
|
||||
STANDALONE("Standalone");
|
||||
|
||||
private final String friendlyName;
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* A simple implementation of the listener aspects of {@link IContextCalculator<T>}
|
||||
* @param <T> the subject type
|
||||
*/
|
||||
public abstract class ContextCalculator<T> implements IContextCalculator<T> {
|
||||
private final List<ContextListener<T>> listeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
/**
|
||||
* Pushes an update to all registered {@link ContextListener}s.
|
||||
* Make sure any changes are applied internally before this method is called.
|
||||
* @param subject the subject that changed
|
||||
* @param before the context state before the change
|
||||
* @param current the context state after the change (now)
|
||||
* @throws NullPointerException if any parameters are null
|
||||
*/
|
||||
protected void pushUpdate(T subject, Map.Entry<String, String> before, Map.Entry<String, String> current) {
|
||||
if (subject == null) {
|
||||
throw new NullPointerException("subject");
|
||||
}
|
||||
if (before == null) {
|
||||
throw new NullPointerException("before");
|
||||
}
|
||||
if (current == null) {
|
||||
throw new NullPointerException("current");
|
||||
}
|
||||
|
||||
for (ContextListener<T> listener : listeners) {
|
||||
try {
|
||||
listener.onContextChange(subject, before, current);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception whilst passing context change to listener: " + listener);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(ContextListener<T> listener) {
|
||||
if (listener == null) {
|
||||
throw new NullPointerException("listener");
|
||||
}
|
||||
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.context;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Listens to context changes
|
||||
* @param <T> the subject type, Is ALWAYS the player class of the platform.
|
||||
*/
|
||||
public interface ContextListener<T> {
|
||||
|
||||
/**
|
||||
* Called whenever a context changes on the
|
||||
* @param subject the subject that had context changed
|
||||
* @param before the context state before the change
|
||||
* @param current the context state after the change (now)
|
||||
*/
|
||||
void onContextChange(T subject, Map.Entry<String, String> before, Map.Entry<String, String> current) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 java.util.Map;
|
||||
|
||||
/**
|
||||
* Calculates whether contexts are applicable to {@link T}
|
||||
*
|
||||
* <p>Somewhat inspired by the system used on Sponge.
|
||||
* @param <T> the subject type. Is ALWAYS the player class of the platform.
|
||||
*/
|
||||
public interface IContextCalculator<T> {
|
||||
|
||||
/**
|
||||
* Gives the subject all of the applicable contexts they meet
|
||||
* @param subject the subject to add contexts tp
|
||||
* @param accumulator a map of contexts to add to
|
||||
* @return the map
|
||||
*/
|
||||
Map<String, String> giveApplicableContext(T subject, Map<String, String> accumulator);
|
||||
|
||||
/**
|
||||
* Checks to see if a context is applicable to a subject
|
||||
* @param subject the subject to check against
|
||||
* @param context the context to check for
|
||||
* @return true if met, or false if not. If this calculator does not calculate the given context, return false.
|
||||
*/
|
||||
boolean isContextApplicable(T subject, Map.Entry<String, String> context);
|
||||
|
||||
/**
|
||||
* Adds a listener to be called whenever a context handled by this calculator changes
|
||||
* @param listener the listener instance
|
||||
* @throws NullPointerException if listener is null
|
||||
*/
|
||||
void addListener(ContextListener<T> listener);
|
||||
|
||||
}
|
||||
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.exceptions;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.10-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>luckperms-bukkit-legacy</artifactId>
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<finalName>LuckPerms-bukkit-legacy-${release.version}.${git.closest.tag.commit.count}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>false</minimizeJar>
|
||||
<artifactSet>
|
||||
<excludes>
|
||||
<exclude>org.xerial:*</exclude>
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.slf4j</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.slf4j</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.zaxxer.hikari</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.hikari</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.mongodb</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.mongodb</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bson</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.bson</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.h2</pattern>
|
||||
<shadedPattern>me.lucko.luckperms.lib.h2</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>pl.project13.maven</groupId>
|
||||
<artifactId>git-commit-id-plugin</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>revision</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<injectAllReactorProjects>true</injectAllReactorProjects>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<!-- LuckPerms Bukkit -->
|
||||
<dependency>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<artifactId>luckperms-bukkit</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Shade gson and guava, as they are not included in earlier Bukkit releases -->
|
||||
<!-- gson -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.7</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- guava -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>19.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.8-SNAPSHOT</version>
|
||||
<version>2.10-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
<dependency>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<artifactId>luckperms-api</artifactId>
|
||||
<version>2.5</version>
|
||||
<scope>compile</scope>
|
||||
<version>2.8</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- BukkitAPI -->
|
||||
<dependency>
|
||||
|
||||
+13
-78
@@ -25,15 +25,11 @@ package me.lucko.luckperms.api.placeholders;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.util.TimeUtil;
|
||||
import me.lucko.luckperms.api.LuckPermsApi;
|
||||
import me.lucko.luckperms.api.Track;
|
||||
import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/*
|
||||
* PlaceholderAPI Expansion for LuckPerms, implemented using the LuckPerms API.
|
||||
@@ -75,7 +71,7 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return "2.5";
|
||||
return "2.8";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,7 +80,7 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
return "";
|
||||
}
|
||||
|
||||
Optional<User> u = api.getUserSafe(player.getUniqueId());
|
||||
Optional<User> u = api.getUserSafe(api.getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (!u.isPresent()) {
|
||||
return "";
|
||||
}
|
||||
@@ -127,17 +123,11 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
if (identifier.startsWith("expiry_time_") && identifier.length() > "expiry_time_".length()) {
|
||||
String node = identifier.substring("expiry_time_".length());
|
||||
|
||||
|
||||
long currentTime = System.currentTimeMillis() / 1000L;
|
||||
Map<Map.Entry<String, Boolean>, Long> temps = user.getTemporaryNodes();
|
||||
|
||||
for (Map.Entry<Map.Entry<String, Boolean>, Long> e : temps.entrySet()) {
|
||||
if (!e.getKey().getKey().equalsIgnoreCase(node)) {
|
||||
continue;
|
||||
for (Node n : user.getTemporaryPermissionNodes()) {
|
||||
if (n.getPermission().equalsIgnoreCase(node)) {
|
||||
return TimeUtil.getTime((int) (n.getExpiryUnixTime() - currentTime));
|
||||
}
|
||||
|
||||
return TimeUtil.getTime((int) (e.getValue() - currentTime));
|
||||
}
|
||||
|
||||
return "";
|
||||
@@ -145,42 +135,27 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
if (identifier.startsWith("group_expiry_time_") && identifier.length() > "group_expiry_time_".length()) {
|
||||
String node = "group." + identifier.substring("group_expiry_time_".length());
|
||||
|
||||
long currentTime = System.currentTimeMillis() / 1000L;
|
||||
Map<Map.Entry<String, Boolean>, Long> temps = user.getTemporaryNodes();
|
||||
|
||||
for (Map.Entry<Map.Entry<String, Boolean>, Long> e : temps.entrySet()) {
|
||||
if (!e.getKey().getKey().equalsIgnoreCase(node)) {
|
||||
continue;
|
||||
for (Node n : user.getTemporaryPermissionNodes()) {
|
||||
if (n.getPermission().equalsIgnoreCase(node)) {
|
||||
return TimeUtil.getTime((int) (n.getExpiryUnixTime() - currentTime));
|
||||
}
|
||||
|
||||
return TimeUtil.getTime((int) (e.getValue() - currentTime));
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
if (identifier.equalsIgnoreCase("prefix")) {
|
||||
return getChatMeta(PREFIX_PATTERN, user);
|
||||
return MetaUtils.getPrefix(user, null, null, true);
|
||||
}
|
||||
|
||||
if (identifier.equalsIgnoreCase("suffix")) {
|
||||
return getChatMeta(SUFFIX_PATTERN, user);
|
||||
return MetaUtils.getSuffix(user, null, null, true);
|
||||
}
|
||||
|
||||
if (identifier.startsWith("meta_") && identifier.length() > "meta_".length()) {
|
||||
String node = "meta." + escapeCharacters(identifier.substring("meta_".length())) + ".";
|
||||
Map<String, Boolean> nodes = user.getNodes();
|
||||
|
||||
for (Map.Entry<String, Boolean> e : nodes.entrySet()) {
|
||||
if (!e.getValue()) continue;
|
||||
if (!e.getKey().toLowerCase().startsWith(node)) continue;
|
||||
|
||||
String meta = e.getKey().substring(node.length());
|
||||
return unescapeCharacters(meta);
|
||||
}
|
||||
|
||||
return "";
|
||||
String node = identifier.substring("meta_".length());
|
||||
return MetaUtils.getMeta(user, null, null, node, "", true);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -204,44 +179,4 @@ public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||
private static String formatBoolean(boolean b) {
|
||||
return b ? PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanFalse();
|
||||
}
|
||||
|
||||
private static String escapeCharacters(String s) {
|
||||
s = s.replace(".", "{SEP}");
|
||||
s = s.replace("/", "{FSEP}");
|
||||
s = s.replace("$", "{DSEP}");
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private static String unescapeCharacters(String s) {
|
||||
s = s.replace("{SEP}", ".");
|
||||
s = s.replace("{FSEP}", "/");
|
||||
s = s.replace("{DSEP}", "$");
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private static final Pattern PREFIX_PATTERN = Pattern.compile("(?i)prefix\\.\\d+\\..*");
|
||||
private static final Pattern SUFFIX_PATTERN = Pattern.compile("(?i)suffix\\.\\d+\\..*");
|
||||
private static final Pattern DOT_PATTERN = Pattern.compile("\\.");
|
||||
|
||||
private static String getChatMeta(Pattern pattern, User user) {
|
||||
int priority = 0;
|
||||
String meta = null;
|
||||
for (Map.Entry<String, Boolean> e : user.getLocalPermissions(null, null).entrySet()) {
|
||||
if (!e.getValue()) continue;
|
||||
|
||||
if (pattern.matcher(e.getKey()).matches()) {
|
||||
String[] parts = DOT_PATTERN.split(e.getKey(), 3);
|
||||
int p = Integer.parseInt(parts[1]);
|
||||
|
||||
if (meta == null || p > priority) {
|
||||
meta = parts[2];
|
||||
priority = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return meta == null ? "" : unescapeCharacters(meta);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.8-SNAPSHOT</version>
|
||||
<version>2.10-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -22,8 +22,12 @@
|
||||
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.commands.CommandManager;
|
||||
import me.lucko.luckperms.commands.Util;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -39,13 +43,18 @@ class BukkitCommand extends CommandManager implements CommandExecutor, TabExecut
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
onCommand(BukkitSenderFactory.get().wrap(sender), label, Arrays.asList(args), Callback.empty());
|
||||
onCommand(
|
||||
BukkitSenderFactory.get(getPlugin()).wrap(sender),
|
||||
label,
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))),
|
||||
Callback.empty()
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
|
||||
return onTabComplete(BukkitSenderFactory.get().wrap(sender), Arrays.asList(args));
|
||||
return onTabComplete(BukkitSenderFactory.get(getPlugin()).wrap(sender), Arrays.asList(args));
|
||||
}
|
||||
}
|
||||
@@ -22,14 +22,17 @@
|
||||
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import me.lucko.luckperms.core.LPConfiguration;
|
||||
import me.lucko.luckperms.config.AbstractConfiguration;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class BukkitConfig extends LPConfiguration<LPBukkitPlugin> {
|
||||
class BukkitConfig extends AbstractConfiguration<LPBukkitPlugin> {
|
||||
private YamlConfiguration configuration;
|
||||
|
||||
BukkitConfig(LPBukkitPlugin plugin) {
|
||||
@@ -55,11 +58,6 @@ class BukkitConfig extends LPConfiguration<LPBukkitPlugin> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void set(String path, Object value) {
|
||||
configuration.set(path, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getString(String path, String def) {
|
||||
return configuration.getString(path, def);
|
||||
@@ -74,4 +72,20 @@ class BukkitConfig extends LPConfiguration<LPBukkitPlugin> {
|
||||
protected boolean getBoolean(String path, boolean def) {
|
||||
return configuration.getBoolean(path, def);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected Map<String, String> getMap(String path, Map<String, String> def) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
ConfigurationSection section = configuration.getConfigurationSection(path);
|
||||
if (section == null) {
|
||||
return def;
|
||||
}
|
||||
|
||||
for (String key : section.getKeys(false)) {
|
||||
map.put(key, section.getString(key));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -23,17 +23,18 @@
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.inject.Injector;
|
||||
import me.lucko.luckperms.inject.LPPermissible;
|
||||
import me.lucko.luckperms.users.BukkitUser;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.utils.AbstractListener;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
class BukkitListener extends AbstractListener implements Listener {
|
||||
private final LPBukkitPlugin plugin;
|
||||
@@ -43,7 +44,7 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent e) {
|
||||
if (!plugin.getDatastore().isAcceptingLogins()) {
|
||||
// The datastore is disabled, prevent players from joining the server
|
||||
@@ -54,7 +55,7 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
onAsyncLogin(e.getUniqueId(), e.getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerLogin(PlayerLoginEvent e) {
|
||||
final Player player = e.getPlayer();
|
||||
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
@@ -67,48 +68,35 @@ class BukkitListener extends AbstractListener implements Listener {
|
||||
if (user instanceof BukkitUser) {
|
||||
BukkitUser u = (BukkitUser) user;
|
||||
|
||||
PermissionAttachment attachment = player.addAttachment(plugin);
|
||||
Map<String, Boolean> newPermMap = new ConcurrentHashMap<>();
|
||||
try {
|
||||
/* Replace the standard LinkedHashMap in the attachment with a ConcurrentHashMap.
|
||||
This means that we can iterate over and change the permissions within our attachment asynchronously,
|
||||
without worrying about thread safety. The Bukkit side of things should still operate normally. Internal
|
||||
permission stuff should work the same. This is by far the most easy and efficient way to do things, without
|
||||
having to do tons of reflection. */
|
||||
BukkitUser.getPermissionsField().set(attachment, newPermMap);
|
||||
LPPermissible lpPermissible = new LPPermissible(player, plugin, plugin.getDefaultsProvider());
|
||||
Injector.inject(player, lpPermissible);
|
||||
u.setLpPermissible(lpPermissible);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
u.setAttachment(new BukkitUser.PermissionAttachmentHolder(attachment, newPermMap));
|
||||
}
|
||||
|
||||
plugin.doAsync(user::refreshPermissions);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerJoin(PlayerJoinEvent e) {
|
||||
// Refresh permissions again
|
||||
plugin.getUserManager().getWorldCache().put(e.getPlayer().getUniqueId(), e.getPlayer().getWorld().getName());
|
||||
plugin.doAsync(() -> refreshPlayer(e.getPlayer().getUniqueId()));
|
||||
UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
plugin.getWorldCalculator().getWorldCache().put(internal, e.getPlayer().getWorld().getName());
|
||||
plugin.doAsync(() -> refreshPlayer(internal));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerChangedWorld(PlayerChangedWorldEvent e) {
|
||||
plugin.getUserManager().getWorldCache().put(e.getPlayer().getUniqueId(), e.getPlayer().getWorld().getName());
|
||||
plugin.doAsync(() -> refreshPlayer(e.getPlayer().getUniqueId()));
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerQuit(PlayerQuitEvent e) {
|
||||
plugin.getUserManager().getWorldCache().remove(e.getPlayer().getUniqueId());
|
||||
plugin.getWorldCalculator().getWorldCache().remove(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||
onLeave(e.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerCommand(PlayerCommandPreprocessEvent e) {
|
||||
if (plugin.getConfiguration().getEnableOps()) {
|
||||
if (plugin.getConfiguration().isOpsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import me.lucko.luckperms.commands.SenderFactory;
|
||||
import me.lucko.luckperms.constants.Constants;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -31,12 +29,16 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class BukkitSenderFactory extends SenderFactory<CommandSender> {
|
||||
private static BukkitSenderFactory instance = null;
|
||||
public static BukkitSenderFactory get() {
|
||||
if (instance == null){
|
||||
instance = new BukkitSenderFactory();
|
||||
|
||||
private BukkitSenderFactory(LuckPermsPlugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
public static synchronized BukkitSenderFactory get(LuckPermsPlugin plugin) {
|
||||
if (instance == null) {
|
||||
instance = new BukkitSenderFactory(plugin);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -30,17 +30,22 @@ import me.lucko.luckperms.api.implementation.ApiProvider;
|
||||
import me.lucko.luckperms.api.vault.VaultHook;
|
||||
import me.lucko.luckperms.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.config.LPConfiguration;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.core.LPConfiguration;
|
||||
import me.lucko.luckperms.contexts.ContextManager;
|
||||
import me.lucko.luckperms.contexts.ServerCalculator;
|
||||
import me.lucko.luckperms.contexts.WorldCalculator;
|
||||
import me.lucko.luckperms.core.UuidCache;
|
||||
import me.lucko.luckperms.data.Importer;
|
||||
import me.lucko.luckperms.groups.GroupManager;
|
||||
import me.lucko.luckperms.inject.DefaultsProvider;
|
||||
import me.lucko.luckperms.runnables.ExpireTemporaryTask;
|
||||
import me.lucko.luckperms.runnables.UpdateTask;
|
||||
import me.lucko.luckperms.storage.Datastore;
|
||||
import me.lucko.luckperms.storage.StorageFactory;
|
||||
import me.lucko.luckperms.tracks.TrackManager;
|
||||
import me.lucko.luckperms.users.BukkitUserManager;
|
||||
import me.lucko.luckperms.utils.LocaleManager;
|
||||
import me.lucko.luckperms.utils.LogFactory;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -68,6 +73,10 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
private Logger log;
|
||||
private Importer importer;
|
||||
private ConsecutiveExecutor consecutiveExecutor;
|
||||
private DefaultsProvider defaultsProvider;
|
||||
private LocaleManager localeManager;
|
||||
private ContextManager<Player> contextManager;
|
||||
private WorldCalculator worldCalculator;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
@@ -76,6 +85,20 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
getLog().info("Loading configuration...");
|
||||
configuration = new BukkitConfig(this);
|
||||
|
||||
localeManager = new LocaleManager();
|
||||
File locale = new File(getDataFolder(), "lang.yml");
|
||||
if (locale.exists()) {
|
||||
getLog().info("Found locale file. Attempting to load from it.");
|
||||
try {
|
||||
localeManager.loadFromFile(locale);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
defaultsProvider = new DefaultsProvider();
|
||||
getServer().getScheduler().runTaskLater(this, () -> defaultsProvider.refresh(), 1L);
|
||||
|
||||
// register events
|
||||
PluginManager pm = getServer().getPluginManager();
|
||||
pm.registerEvents(new BukkitListener(this), this);
|
||||
@@ -91,20 +114,27 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
datastore = StorageFactory.getDatastore(this, "h2");
|
||||
|
||||
getLog().info("Loading internal permission managers...");
|
||||
uuidCache = new UuidCache(getConfiguration().getOnlineMode());
|
||||
uuidCache = new UuidCache(getConfiguration().isOnlineMode());
|
||||
userManager = new BukkitUserManager(this);
|
||||
groupManager = new GroupManager(this);
|
||||
trackManager = new TrackManager();
|
||||
importer = new Importer(commandManager);
|
||||
consecutiveExecutor = new ConsecutiveExecutor(commandManager);
|
||||
|
||||
contextManager = new ContextManager<>();
|
||||
worldCalculator = new WorldCalculator(this);
|
||||
pm.registerEvents(worldCalculator, this);
|
||||
contextManager.registerCalculator(worldCalculator);
|
||||
contextManager.registerCalculator(new ServerCalculator<>(getConfiguration().getServer()));
|
||||
contextManager.registerListener(userManager);
|
||||
|
||||
int mins = getConfiguration().getSyncTime();
|
||||
if (mins > 0) {
|
||||
long ticks = mins * 60 * 20;
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, new UpdateTask(this), ticks, ticks);
|
||||
}
|
||||
|
||||
getServer().getScheduler().runTaskTimer(this, BukkitSenderFactory.get(), 1L, 1L);
|
||||
getServer().getScheduler().runTaskTimer(this, BukkitSenderFactory.get(this), 1L, 1L);
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, new ExpireTemporaryTask(this), 60L, 60L);
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, consecutiveExecutor, 20L, 20L);
|
||||
|
||||
@@ -135,8 +165,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
registerPermissions(getConfiguration().getCommandsAllowOp() ? PermissionDefault.OP : PermissionDefault.FALSE);
|
||||
if (!getConfiguration().getEnableOps()) {
|
||||
registerPermissions(getConfiguration().isCommandsAllowOp() ? PermissionDefault.OP : PermissionDefault.FALSE);
|
||||
if (!getConfiguration().isOpsEnabled()) {
|
||||
getServer().getOperators().forEach(o -> o.setOp(false));
|
||||
}
|
||||
|
||||
@@ -194,13 +224,16 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Sender> getSenders() {
|
||||
return getServer().getOnlinePlayers().stream().map(p -> BukkitSenderFactory.get().wrap(p)).collect(Collectors.toList());
|
||||
public List<Sender> getNotifyListeners() {
|
||||
return getServer().getOnlinePlayers().stream()
|
||||
.map(p -> BukkitSenderFactory.get(this).wrap(p, Collections.singleton(me.lucko.luckperms.constants.Permission.LOG_NOTIFY)))
|
||||
.filter(me.lucko.luckperms.constants.Permission.LOG_NOTIFY::isAuthorized)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sender getConsoleSender() {
|
||||
return BukkitSenderFactory.get().wrap(getServer().getConsoleSender());
|
||||
return BukkitSenderFactory.get(this).wrap(getServer().getConsoleSender());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -267,11 +300,11 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
"luckperms." + e.getKey() + ".*", def,
|
||||
e.getValue().stream()
|
||||
.map(tag -> "luckperms." + e.getKey() + "." + tag)
|
||||
.collect(Collectors.toMap(s -> s, s -> false))
|
||||
.collect(Collectors.toMap(s -> s, s -> true))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
pm.addPermission(new Permission("luckperms.*", def, all.stream().collect(Collectors.toMap(s -> s, s -> false))));
|
||||
pm.addPermission(new Permission("luckperms.*", def, all.stream().collect(Collectors.toMap(s -> s, s -> true))));
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.contexts.Contexts;
|
||||
import me.lucko.luckperms.core.PermissionHolder;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
@@ -89,7 +90,7 @@ public class VaultChatHook extends Chat {
|
||||
}
|
||||
}
|
||||
|
||||
Node.Builder metaNode = new me.lucko.luckperms.utils.Node.Builder("meta." + node + "." + value).setValue(true);
|
||||
Node.Builder metaNode = new me.lucko.luckperms.core.Node.Builder("meta." + node + "." + value).setValue(true);
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
metaNode.setServer(perms.getServer());
|
||||
}
|
||||
@@ -118,10 +119,8 @@ public class VaultChatHook extends Chat {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
if (!n.shouldApplyOnServer(perms.getServer(), perms.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
if (!n.shouldApplyOnServer(perms.getServer(), perms.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, perms.isIncludeGlobal(), false)) {
|
||||
@@ -141,7 +140,7 @@ public class VaultChatHook extends Chat {
|
||||
if (holder == null) return;
|
||||
if (value.equals("")) return;
|
||||
|
||||
Node.Builder node = new me.lucko.luckperms.utils.Node.Builder(prefix ? "prefix" : "suffix" + ".1000." + escapeCharacters(value));
|
||||
Node.Builder node = new me.lucko.luckperms.core.Node.Builder(prefix ? "prefix" : "suffix" + ".1000." + escapeCharacters(value));
|
||||
node.setValue(true);
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
node.setServer(perms.getServer());
|
||||
@@ -164,22 +163,20 @@ public class VaultChatHook extends Chat {
|
||||
int priority = Integer.MIN_VALUE;
|
||||
String meta = null;
|
||||
|
||||
for (Node n : holder.getAllNodes(null)) {
|
||||
for (Node n : holder.getAllNodes(null, Contexts.allowAll())) {
|
||||
if (!n.getValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
if (!n.shouldApplyOnServer(perms.getServer(), perms.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, perms.isIncludeGlobal(), false)) {
|
||||
if (prefix ? !n.isPrefix() : !n.isSuffix()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prefix ? !n.isPrefix() : !n.isSuffix()) {
|
||||
if (!n.shouldApplyOnServer(perms.getServer(), perms.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!n.shouldApplyOnWorld(world, perms.isIncludeGlobal(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class VaultHook {
|
||||
}
|
||||
permissionHook.setPlugin(plugin);
|
||||
permissionHook.setServer(plugin.getConfiguration().getVaultServer());
|
||||
permissionHook.setIncludeGlobal(plugin.getConfiguration().getVaultIncludeGlobal());
|
||||
permissionHook.setIncludeGlobal(plugin.getConfiguration().isVaultIncludingGlobal());
|
||||
|
||||
if (chatHook == null) {
|
||||
chatHook = new VaultChatHook(permissionHook);
|
||||
|
||||
@@ -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.contexts;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.context.ContextCalculator;
|
||||
import 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 java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class WorldCalculator extends ContextCalculator<Player> implements Listener {
|
||||
private static final String WORLD_KEY = "world";
|
||||
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
@Getter
|
||||
private final Map<UUID, String> worldCache = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public Map<String, String> giveApplicableContext(Player subject, Map<String, String> accumulator) {
|
||||
String world = getWorld(subject);
|
||||
|
||||
if (world != null) {
|
||||
accumulator.put(WORLD_KEY, world);
|
||||
}
|
||||
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContextApplicable(Player subject, Map.Entry<String, String> context) {
|
||||
if (!context.getKey().equals(WORLD_KEY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String world = getWorld(subject);
|
||||
return world != null && world.equals(context.getValue());
|
||||
}
|
||||
|
||||
private String getWorld(Player player) {
|
||||
UUID internal = plugin.getUuidCache().getUUID(player.getUniqueId());
|
||||
if (!worldCache.containsKey(internal)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String world = worldCache.get(internal);
|
||||
return plugin.getConfiguration().getWorldRewrites().getOrDefault(world, world);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerChangedWorld(PlayerChangedWorldEvent e) {
|
||||
UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
worldCache.put(internal, e.getPlayer().getWorld().getName());
|
||||
pushUpdate(
|
||||
e.getPlayer(),
|
||||
Maps.immutableEntry(WORLD_KEY, e.getFrom().getName()),
|
||||
Maps.immutableEntry(WORLD_KEY, e.getPlayer().getWorld().getName())
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.inject;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class DefaultsProvider {
|
||||
|
||||
private final DummyPermissible opDummy = new DummyPermissible(this::refreshOp);
|
||||
private final DummyPermissible nonOpDummy = new DummyPermissible(this::refreshNonOp);
|
||||
|
||||
private final Map<String, Boolean> op = new HashMap<>();
|
||||
private final Map<String, Boolean> nonOp = new HashMap<>();
|
||||
|
||||
public void refresh() {
|
||||
refreshOp();
|
||||
refreshNonOp();
|
||||
}
|
||||
|
||||
private void refreshOp() {
|
||||
calculateDefaults(op, opDummy, true);
|
||||
}
|
||||
|
||||
private void refreshNonOp() {
|
||||
calculateDefaults(nonOp, nonOpDummy, false);
|
||||
}
|
||||
|
||||
private static void calculateDefaults(Map<String, Boolean> map, DummyPermissible p, boolean op) {
|
||||
Set<String> perms = map.keySet();
|
||||
|
||||
for (String name : perms) {
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromPermission(name, p);
|
||||
}
|
||||
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(false, p);
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(true, p);
|
||||
|
||||
map.clear();
|
||||
|
||||
Set<Permission> defaults = Bukkit.getServer().getPluginManager().getDefaultPermissions(op);
|
||||
Bukkit.getServer().getPluginManager().subscribeToDefaultPerms(op, p);
|
||||
|
||||
for (Permission perm : defaults) {
|
||||
String name = perm.getName().toLowerCase();
|
||||
map.put(name, true);
|
||||
Bukkit.getServer().getPluginManager().subscribeToPermission(name, p);
|
||||
calculateChildPermissions(map, p, perm.getChildren(), false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void calculateChildPermissions(Map<String, Boolean> map, DummyPermissible p, Map<String, Boolean> children, boolean invert) {
|
||||
for (Map.Entry<String, Boolean> e : children.entrySet()) {
|
||||
Permission perm = Bukkit.getServer().getPluginManager().getPermission(e.getKey());
|
||||
boolean value = e.getValue() ^ invert;
|
||||
String lName = e.getKey().toLowerCase();
|
||||
|
||||
map.put(lName, value);
|
||||
Bukkit.getServer().getPluginManager().subscribeToPermission(e.getKey(), p);
|
||||
|
||||
if (perm != null) {
|
||||
calculateChildPermissions(map, p, perm.getChildren(), !value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private static class DummyPermissible implements Permissible {
|
||||
private final Runnable onRefresh;
|
||||
|
||||
@Override
|
||||
public void recalculatePermissions() {
|
||||
onRefresh.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(String name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(Permission perm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Permission perm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(Plugin plugin) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(Plugin plugin, int ticks) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttachment(PermissionAttachment attachment) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOp() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOp(boolean value) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.inject;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Injects a {@link LPPermissible} into a {@link Player}
|
||||
*/
|
||||
@UtilityClass
|
||||
public class Injector {
|
||||
private static Field HUMAN_ENTITY_FIELD;
|
||||
|
||||
static {
|
||||
try {
|
||||
HUMAN_ENTITY_FIELD = Class.forName(getInternalClassName("entity.CraftHumanEntity")).getDeclaredField("perm");
|
||||
HUMAN_ENTITY_FIELD.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean inject(CommandSender sender, PermissibleBase permissible) {
|
||||
try {
|
||||
Field f = getPermField(sender);
|
||||
f.set(sender, permissible);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean unInject(CommandSender sender) {
|
||||
try {
|
||||
Permissible permissible = getPermissible(sender);
|
||||
if (permissible instanceof LPPermissible) {
|
||||
getPermField(sender).set(sender, new PermissibleBase(sender));
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static Permissible getPermissible(CommandSender sender) {
|
||||
try {
|
||||
Field f = getPermField(sender);
|
||||
return (Permissible) f.get(sender);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Field getPermField(CommandSender sender) {
|
||||
if (sender instanceof Player) {
|
||||
return HUMAN_ENTITY_FIELD;
|
||||
}
|
||||
throw new RuntimeException("Couldn't get perm field for sender " + sender.getClass().getName());
|
||||
}
|
||||
|
||||
private static String getInternalClassName(String className) {
|
||||
Class server = Bukkit.getServer().getClass();
|
||||
if (!server.getSimpleName().equals("CraftServer")) {
|
||||
throw new RuntimeException("Couldn't inject into server " + server);
|
||||
}
|
||||
|
||||
String version;
|
||||
if (server.getName().equals("org.bukkit.craftbukkit.CraftServer")) {
|
||||
// Non versioned class
|
||||
version = ".";
|
||||
} else {
|
||||
version = server.getName().substring("org.bukkit.craftbukkit".length());
|
||||
version = version.substring(0, version.length() - "CraftServer".length());
|
||||
}
|
||||
|
||||
return "org.bukkit.craftbukkit" + version + className;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.inject;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.calculators.PermissionCalculator;
|
||||
import me.lucko.luckperms.calculators.PermissionProcessor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.*;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Modified PermissibleBase for LuckPerms
|
||||
*/
|
||||
public class LPPermissible extends PermissibleBase {
|
||||
|
||||
@Getter
|
||||
private final CommandSender parent;
|
||||
|
||||
private final PermissionCalculator calculator;
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> luckPermsPermissions = new ConcurrentHashMap<>();
|
||||
private final List<PermissionAttachment> attachments = new LinkedList<>();
|
||||
private final Map<String, PermissionAttachmentInfo> attachmentPermissions = new HashMap<>();
|
||||
|
||||
public LPPermissible(@NonNull CommandSender sender, LuckPermsPlugin plugin, DefaultsProvider defaultsProvider) {
|
||||
super(sender);
|
||||
this.parent = sender;
|
||||
|
||||
List<PermissionProcessor> processors = new ArrayList<>(5);
|
||||
processors.add(new PermissionCalculator.MapProcessor(luckPermsPermissions));
|
||||
processors.add(new AttachmentProcessor(attachmentPermissions));
|
||||
if (plugin.getConfiguration().isApplyingWildcards()) {
|
||||
processors.add(new PermissionCalculator.WildcardProcessor(luckPermsPermissions));
|
||||
}
|
||||
if (plugin.getConfiguration().isApplyingRegex()) {
|
||||
processors.add(new PermissionCalculator.RegexProcessor(luckPermsPermissions));
|
||||
}
|
||||
processors.add(new BukkitDefaultsProcessor(parent::isOp, defaultsProvider));
|
||||
|
||||
calculator = new PermissionCalculator(plugin, parent.getName(), plugin.getConfiguration().isDebugPermissionChecks(), processors);
|
||||
|
||||
recalculatePermissions();
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
calculator.invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOp() {
|
||||
return parent.isOp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOp(boolean value) {
|
||||
parent.setOp(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(@NonNull String name) {
|
||||
return calculator.getPermissionValue(name) != Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(@NonNull Permission perm) {
|
||||
return isPermissionSet(perm.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NonNull String name) {
|
||||
Tristate ts = calculator.getPermissionValue(name);
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
}
|
||||
|
||||
return Permission.DEFAULT_PERMISSION.getValue(isOp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NonNull Permission perm) {
|
||||
Tristate ts = calculator.getPermissionValue(perm.getName());
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
}
|
||||
|
||||
return perm.getDefault().getValue(isOp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(@NonNull Plugin plugin, @NonNull String name, boolean value) {
|
||||
if (!plugin.isEnabled()) {
|
||||
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is not enabled");
|
||||
}
|
||||
|
||||
PermissionAttachment result = addAttachment(plugin);
|
||||
result.setPermission(name, value);
|
||||
|
||||
recalculatePermissions();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(@NonNull Plugin plugin) {
|
||||
if (!plugin.isEnabled()) {
|
||||
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is not enabled");
|
||||
}
|
||||
|
||||
PermissionAttachment result = new PermissionAttachment(plugin, parent);
|
||||
|
||||
attachments.add(result);
|
||||
recalculatePermissions();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(@NonNull Plugin plugin, @NonNull String name, boolean value, int ticks) {
|
||||
if (!plugin.isEnabled()) {
|
||||
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is not enabled");
|
||||
}
|
||||
|
||||
PermissionAttachment result = addAttachment(plugin, ticks);
|
||||
if (result != null) {
|
||||
result.setPermission(name, value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(@NonNull Plugin plugin, int ticks) {
|
||||
if (!plugin.isEnabled()) {
|
||||
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is not enabled");
|
||||
}
|
||||
|
||||
PermissionAttachment result = addAttachment(plugin);
|
||||
if (Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new RemoveAttachmentRunnable(result), ticks) == -1) {
|
||||
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add PermissionAttachment to " + parent + " for plugin " + plugin.getDescription().getFullName() + ": Scheduler returned -1");
|
||||
result.remove();
|
||||
return null;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttachment(@NonNull PermissionAttachment attachment) {
|
||||
if (attachments.contains(attachment)) {
|
||||
attachments.remove(attachment);
|
||||
PermissionRemovedExecutor ex = attachment.getRemovalCallback();
|
||||
|
||||
if (ex != null) {
|
||||
ex.attachmentRemoved(attachment);
|
||||
}
|
||||
|
||||
recalculatePermissions();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Given attachment is not part of Permissible object " + parent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculatePermissions() {
|
||||
if (attachmentPermissions == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
attachmentPermissions.clear();
|
||||
|
||||
for (PermissionAttachment attachment : attachments) {
|
||||
calculateChildPermissions(attachment.getPermissions(), false, attachment);
|
||||
}
|
||||
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void clearPermissions() {
|
||||
Set<String> perms = attachmentPermissions.keySet();
|
||||
|
||||
for (String name : perms) {
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromPermission(name, parent);
|
||||
}
|
||||
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(false, parent);
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(true, parent);
|
||||
|
||||
attachmentPermissions.clear();
|
||||
}
|
||||
|
||||
private void calculateChildPermissions(Map<String, Boolean> children, boolean invert, PermissionAttachment attachment) {
|
||||
for (Map.Entry<String, Boolean> e : children.entrySet()) {
|
||||
Permission perm = Bukkit.getServer().getPluginManager().getPermission(e.getKey());
|
||||
boolean value = e.getValue() ^ invert;
|
||||
String name = e.getKey().toLowerCase();
|
||||
|
||||
attachmentPermissions.put(name, new PermissionAttachmentInfo(parent, name, attachment, value));
|
||||
Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent);
|
||||
|
||||
if (perm != null) {
|
||||
calculateChildPermissions(perm.getChildren(), !value, attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
||||
Set<PermissionAttachmentInfo> perms = new HashSet<>();
|
||||
perms.addAll(attachmentPermissions.values());
|
||||
|
||||
perms.addAll(luckPermsPermissions.entrySet().stream()
|
||||
.map(e -> new PermissionAttachmentInfo(parent, e.getKey(), null, e.getValue()))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
private class RemoveAttachmentRunnable implements Runnable {
|
||||
private PermissionAttachment attachment;
|
||||
|
||||
private RemoveAttachmentRunnable(PermissionAttachment attachment) {
|
||||
this.attachment = attachment;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
attachment.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private static class AttachmentProcessor implements PermissionProcessor {
|
||||
|
||||
@Getter
|
||||
private final Map<String, PermissionAttachmentInfo> map;
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
if (map.containsKey(permission)) {
|
||||
return Tristate.fromBoolean(map.get(permission).getValue());
|
||||
}
|
||||
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private static class BukkitDefaultsProcessor implements PermissionProcessor {
|
||||
private final Supplier<Boolean> isOp;
|
||||
private final DefaultsProvider defaultsProvider;
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
Tristate t = defaultsProvider.hasDefault(permission, isOp.get());
|
||||
if (t != Tristate.UNDEFINED) {
|
||||
return t;
|
||||
}
|
||||
|
||||
Permission defPerm = Bukkit.getServer().getPluginManager().getPermission(permission);
|
||||
if (defPerm != null) {
|
||||
return Tristate.fromBoolean(defPerm.getDefault().getValue(isOp.get()));
|
||||
} else {
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,39 +22,27 @@
|
||||
|
||||
package me.lucko.luckperms.users;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.api.event.events.UserPermissionRefreshEvent;
|
||||
import me.lucko.luckperms.api.implementation.internal.UserLink;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
import me.lucko.luckperms.contexts.Contexts;
|
||||
import me.lucko.luckperms.inject.LPPermissible;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitUser extends User {
|
||||
private static Field permissionsField = null;
|
||||
public static Field getPermissionsField() {
|
||||
if (permissionsField == null) {
|
||||
try {
|
||||
permissionsField = PermissionAttachment.class.getDeclaredField("permissions");
|
||||
permissionsField.setAccessible(true);
|
||||
} catch (SecurityException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return permissionsField;
|
||||
}
|
||||
|
||||
|
||||
private final LPBukkitPlugin plugin;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private PermissionAttachmentHolder attachment = null;
|
||||
private LPPermissible lpPermissible = null;
|
||||
|
||||
BukkitUser(UUID uuid, LPBukkitPlugin plugin) {
|
||||
super(uuid, plugin);
|
||||
@@ -68,24 +56,26 @@ public class BukkitUser extends User {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void refreshPermissions() {
|
||||
if (attachment == null) {
|
||||
public synchronized void refreshPermissions() {
|
||||
if (lpPermissible == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the permissions that should be applied. This is done async, who cares about how long it takes or how often it's done.
|
||||
Map<String, Boolean> toApply = exportNodes(
|
||||
getPlugin().getConfiguration().getServer(),
|
||||
plugin.getUserManager().getWorldCache().get(getUuid()),
|
||||
null,
|
||||
plugin.getConfiguration().getIncludeGlobalPerms(),
|
||||
true,
|
||||
plugin.getPossiblePermissions()
|
||||
new Contexts(
|
||||
plugin.getContextManager().giveApplicableContext((Player) lpPermissible.getParent(), new HashMap<>()),
|
||||
plugin.getConfiguration().isIncludingGlobalPerms(),
|
||||
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
plugin.getConfiguration().isApplyingGlobalGroups(),
|
||||
plugin.getConfiguration().isApplyingGlobalWorldGroups()
|
||||
),
|
||||
Collections.emptyList()
|
||||
);
|
||||
|
||||
try {
|
||||
// The map in the LP PermissionAttachment is a ConcurrentHashMap. We can modify and iterate over its contents async.
|
||||
Map<String, Boolean> existing = attachment.getPermissions();
|
||||
Map<String, Boolean> existing = lpPermissible.getLuckPermsPermissions();
|
||||
|
||||
boolean different = false;
|
||||
if (toApply.size() != existing.size()) {
|
||||
@@ -103,26 +93,30 @@ public class BukkitUser extends User {
|
||||
if (!different) return;
|
||||
|
||||
existing.clear();
|
||||
lpPermissible.invalidateCache();
|
||||
existing.putAll(toApply);
|
||||
|
||||
/* Must be called sync, as #recalculatePermissions is an unmodified Bukkit API call that is absolutely not thread safe.
|
||||
Shouldn't be too taxing on the server. This only gets called when permissions have actually changed,
|
||||
which is like once per user per login, assuming their permissions don't get modified. */
|
||||
plugin.doSync(() -> {
|
||||
attachment.getAttachment().getPermissible().recalculatePermissions();
|
||||
plugin.getApiProvider().fireEventAsync(new UserPermissionRefreshEvent(new UserLink(this)));
|
||||
});
|
||||
if (plugin.getConfiguration().isAutoOp()) {
|
||||
boolean op = false;
|
||||
|
||||
for (Map.Entry<String, Boolean> e : toApply.entrySet()) {
|
||||
if (e.getKey().equalsIgnoreCase("luckperms.autoop") && e.getValue()) {
|
||||
op = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean finalOp = op;
|
||||
if (lpPermissible.isOp() != op) {
|
||||
final Permissible parent = lpPermissible.getParent();
|
||||
plugin.doSync(() -> parent.setOp(finalOp));
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getApiProvider().fireEventAsync(new UserPermissionRefreshEvent(new UserLink(this)));
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@AllArgsConstructor
|
||||
public static class PermissionAttachmentHolder {
|
||||
private final PermissionAttachment attachment;
|
||||
private final Map<String, Boolean> permissions;
|
||||
}
|
||||
}
|
||||
@@ -22,22 +22,19 @@
|
||||
|
||||
package me.lucko.luckperms.users;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import me.lucko.luckperms.inject.Injector;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BukkitUserManager extends UserManager {
|
||||
public class BukkitUserManager extends UserManager implements ContextListener<Player> {
|
||||
private final LPBukkitPlugin plugin;
|
||||
|
||||
@Getter
|
||||
private final Map<UUID, String> worldCache = new ConcurrentHashMap<>();
|
||||
|
||||
public BukkitUserManager(LPBukkitPlugin plugin) {
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
@@ -47,14 +44,16 @@ public class BukkitUserManager extends UserManager {
|
||||
public void preUnload(User user) {
|
||||
if (user instanceof BukkitUser) {
|
||||
BukkitUser u = (BukkitUser) user;
|
||||
|
||||
if (u.getAttachment() != null) {
|
||||
Player player = plugin.getServer().getPlayer(plugin.getUuidCache().getExternalUUID(u.getUuid()));
|
||||
|
||||
if (player != null) {
|
||||
player.removeAttachment(u.getAttachment().getAttachment());
|
||||
Player player = plugin.getServer().getPlayer(plugin.getUuidCache().getExternalUUID(u.getUuid()));
|
||||
if (player != null) {
|
||||
if (u.getLpPermissible() != null) {
|
||||
Injector.unInject(player);
|
||||
u.setLpPermissible(null);
|
||||
}
|
||||
|
||||
if (plugin.getConfiguration().isAutoOp()) {
|
||||
player.setOp(false);
|
||||
}
|
||||
u.setAttachment(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,4 +85,14 @@ public class BukkitUserManager extends UserManager {
|
||||
plugin.doAsync(() -> players.forEach(u -> plugin.getDatastore().loadUser(u, "null")));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContextChange(Player subject, Map.Entry<String, String> before, Map.Entry<String, String> current) throws Exception {
|
||||
UUID internal = plugin.getUuidCache().getUUID(subject.getUniqueId());
|
||||
|
||||
User user = get(internal);
|
||||
if (user != null) {
|
||||
plugin.doAsync(user::refreshPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,20 @@
|
||||
# The name of the server, used for server specific permissions. Set to 'global' to disable.
|
||||
server: global
|
||||
|
||||
# If users on this server should have their global permissions/groups applied.
|
||||
# If users on this server should have their global permissions applied.
|
||||
# If set to false, only server specific permissions will apply for users on this server
|
||||
include-global: true
|
||||
|
||||
# If users on this server should have their global world permissions applied.
|
||||
# If set to false, only world specific permissions will apply for users on this server
|
||||
include-global-world: true
|
||||
|
||||
# If users on this server should have global (non-server specific) groups applied
|
||||
apply-global-groups: true
|
||||
|
||||
# If users on this server should have global (non-world specific) groups applied
|
||||
apply-global-world-groups: true
|
||||
|
||||
# If this server is in offline or online mode.
|
||||
# This setting allows a player to have the same UUID across a network of offline mode/mixed servers.
|
||||
|
||||
@@ -30,13 +41,12 @@ online-mode: true
|
||||
|
||||
# If the plugin should apply wildcard permissions.
|
||||
# If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered permissions matching
|
||||
# the wildcard. This will only work for plugins that define all of their permissions to the server.
|
||||
# the wildcard.
|
||||
apply-wildcards: true
|
||||
|
||||
# If the plugin should parse regex permissions.
|
||||
# If set to true, LuckPerms will detect regex permissions, marked with "r=" at the start of the node, and resolve &
|
||||
# apply all registered permissions matching the regex. This will only work for plugins that define all of their
|
||||
# permissions to the server.
|
||||
# apply all registered permissions matching the regex.
|
||||
apply-regex: true
|
||||
|
||||
# If the plugin should complete and apply shorthand permissions.
|
||||
@@ -46,10 +56,21 @@ apply-shorthand: true
|
||||
# If the plugin should send log notifications to users whenever permissions are modified.
|
||||
log-notify: true
|
||||
|
||||
# If LuckPerms should print to console every time a plugin checks if a player has a permission
|
||||
debug-permission-checks: false
|
||||
|
||||
# If the vanilla OP system is enabled. If set to false, all users will be de-opped, and the op/deop commands will be disabled.
|
||||
enable-ops: true
|
||||
|
||||
# If opped players should be allowed to use LuckPerms commands. Set to false to only allow users with the permission access
|
||||
# If set to true, any user with the permission "luckperms.autoop" will automatically be granted server operator status.
|
||||
# This permission can be inherited, or set on specific servers/worlds, temporarily, etc.
|
||||
# Additionally, setting this to true will force the "enable-ops" option above to false. All users will be de-opped unless
|
||||
# they have the permission node, and the op/deop commands will be disabled.
|
||||
#
|
||||
# It is recommended that you use this option instead of assigning a single '*' permission.
|
||||
auto-op: false
|
||||
|
||||
# If opped players should be allowed to use LuckPerms commands. Set to false to only allow users who have the permissions access to the commands
|
||||
commands-allow-op: true
|
||||
|
||||
# The name of the server used within Vault operations. If you don't want Vault operations to be server specific, set this
|
||||
@@ -59,14 +80,22 @@ vault-server: global
|
||||
# If global permissions should be considered when retrieving meta or player groups
|
||||
vault-include-global: true
|
||||
|
||||
# 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
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL or MongoDB
|
||||
storage-method: h2
|
||||
|
||||
# This block enables support for split datastores.
|
||||
# Only touch this if you're sure that you know what you're doing.
|
||||
# I (the author) do not endorse nor recommend the use of this feature.
|
||||
split-storage:
|
||||
enabled: false
|
||||
methods:
|
||||
@@ -84,4 +113,4 @@ data:
|
||||
|
||||
# Set to -1 to disable. If this is the only instance accessing the datastore, you can disable syncing.
|
||||
# e.g. if you're using sqlite or flatfile, this can be set to -1 to save resources.
|
||||
sync-minutes: 3
|
||||
sync-minutes: 3
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.8-SNAPSHOT</version>
|
||||
<version>2.10-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -22,8 +22,12 @@
|
||||
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.commands.CommandManager;
|
||||
import me.lucko.luckperms.commands.Util;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
import net.md_5.bungee.api.plugin.TabExecutor;
|
||||
@@ -40,11 +44,16 @@ class BungeeCommand extends Command implements TabExecutor {
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
manager.onCommand(BungeeSenderFactory.get().wrap(sender), "bperms", Arrays.asList(args), Callback.empty());
|
||||
manager.onCommand(
|
||||
BungeeSenderFactory.get(manager.getPlugin()).wrap(sender),
|
||||
"bperms",
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))),
|
||||
Callback.empty()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args) {
|
||||
return manager.onTabComplete(BungeeSenderFactory.get().wrap(sender), Arrays.asList(args));
|
||||
return manager.onTabComplete(BungeeSenderFactory.get(manager.getPlugin()).wrap(sender), Arrays.asList(args));
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import me.lucko.luckperms.core.LPConfiguration;
|
||||
import me.lucko.luckperms.config.AbstractConfiguration;
|
||||
import net.md_5.bungee.config.Configuration;
|
||||
import net.md_5.bungee.config.ConfigurationProvider;
|
||||
import net.md_5.bungee.config.YamlConfiguration;
|
||||
@@ -31,8 +31,10 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class BungeeConfig extends LPConfiguration<LPBungeePlugin> {
|
||||
class BungeeConfig extends AbstractConfiguration<LPBungeePlugin> {
|
||||
private Configuration configuration;
|
||||
|
||||
BungeeConfig(LPBungeePlugin plugin) {
|
||||
@@ -62,11 +64,6 @@ class BungeeConfig extends LPConfiguration<LPBungeePlugin> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void set(String path, Object value) {
|
||||
configuration.set(path, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getString(String path, String def) {
|
||||
return configuration.getString(path, def);
|
||||
@@ -81,4 +78,19 @@ class BungeeConfig extends LPConfiguration<LPBungeePlugin> {
|
||||
protected boolean getBoolean(String path, boolean def) {
|
||||
return configuration.getBoolean(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, String> getMap(String path, Map<String, String> def) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
Configuration section = configuration.getSection(path);
|
||||
if (section == null) {
|
||||
return def;
|
||||
}
|
||||
|
||||
for (String key : section.getKeys()) {
|
||||
map.put(key, section.getString(key));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -29,12 +29,13 @@ import me.lucko.luckperms.utils.AbstractListener;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.*;
|
||||
import net.md_5.bungee.api.event.LoginEvent;
|
||||
import net.md_5.bungee.api.event.PermissionCheckEvent;
|
||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -51,22 +52,18 @@ public class BungeeListener extends AbstractListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerPermissionCheck(PermissionCheckEvent e) {
|
||||
if (!(e.getSender() instanceof ProxiedPlayer)) {
|
||||
e.setHasPermission(true);
|
||||
return;
|
||||
}
|
||||
|
||||
final ProxiedPlayer player = ((ProxiedPlayer) e.getSender());
|
||||
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (user == null) return;
|
||||
|
||||
|
||||
final String server = player.getServer() == null ? null : (player.getServer().getInfo() == null ? null : player.getServer().getInfo().getName());
|
||||
Map<String, Boolean> local = user.getLocalPermissions(plugin.getConfiguration().getServer(), server, null, Collections.singletonList(e.getPermission()));
|
||||
for (Map.Entry<String, Boolean> en : local.entrySet()) {
|
||||
if (en.getKey().equalsIgnoreCase(e.getPermission())) {
|
||||
e.setHasPermission(en.getValue());
|
||||
return;
|
||||
}
|
||||
BungeePlayerCache playerCache = plugin.getPlayerCache().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (playerCache == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.setHasPermission(playerCache.getPermissionValue(e.getPermission()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -108,22 +105,20 @@ public class BungeeListener extends AbstractListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerPostLogin(PostLoginEvent e) {
|
||||
final ProxiedPlayer player = e.getPlayer();
|
||||
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||
final UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||
final User user = plugin.getUserManager().get(internal);
|
||||
|
||||
if (user == null) {
|
||||
plugin.getProxy().getScheduler().schedule(plugin, () -> player.sendMessage(WARN_MESSAGE), 3, TimeUnit.SECONDS);
|
||||
} else {
|
||||
plugin.getPlayerCache().put(internal, new BungeePlayerCache(plugin, e.getPlayer().getName()));
|
||||
user.refreshPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerDisconnectEvent e) {
|
||||
plugin.getPlayerCache().remove(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||
onLeave(e.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerServerSwitch(ServerSwitchEvent e) {
|
||||
refreshPlayer(e.getPlayer().getUniqueId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.calculators.PermissionCalculator;
|
||||
import me.lucko.luckperms.calculators.PermissionProcessor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class BungeePlayerCache {
|
||||
|
||||
private final PermissionCalculator calculator;
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> permissions = new ConcurrentHashMap<>();
|
||||
|
||||
public BungeePlayerCache(LuckPermsPlugin plugin, String name) {
|
||||
List<PermissionProcessor> processors = new ArrayList<>(3);
|
||||
processors.add(new PermissionCalculator.MapProcessor(permissions));
|
||||
if (plugin.getConfiguration().isApplyingWildcards()) {
|
||||
processors.add(new PermissionCalculator.WildcardProcessor(permissions));
|
||||
}
|
||||
if (plugin.getConfiguration().isApplyingRegex()) {
|
||||
processors.add(new PermissionCalculator.RegexProcessor(permissions));
|
||||
}
|
||||
|
||||
calculator = new PermissionCalculator(plugin, name, plugin.getConfiguration().isDebugPermissionChecks(), processors);
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
calculator.invalidateCache();
|
||||
}
|
||||
|
||||
public boolean getPermissionValue(String permission) {
|
||||
return calculator.getPermissionValue(permission).asBoolean();
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
package me.lucko.luckperms;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import me.lucko.luckperms.commands.SenderFactory;
|
||||
import me.lucko.luckperms.constants.Constants;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
@@ -32,12 +30,16 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class BungeeSenderFactory extends SenderFactory<CommandSender> {
|
||||
private static BungeeSenderFactory instance = null;
|
||||
public static BungeeSenderFactory get() {
|
||||
if (instance == null){
|
||||
instance = new BungeeSenderFactory();
|
||||
|
||||
private BungeeSenderFactory(LuckPermsPlugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
public static synchronized BungeeSenderFactory get(LuckPermsPlugin plugin) {
|
||||
if (instance == null) {
|
||||
instance = new BungeeSenderFactory(plugin);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,12 @@ import me.lucko.luckperms.api.implementation.ApiProvider;
|
||||
import me.lucko.luckperms.commands.CommandManager;
|
||||
import me.lucko.luckperms.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.config.LPConfiguration;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.core.LPConfiguration;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.contexts.BackendServerCalculator;
|
||||
import me.lucko.luckperms.contexts.ContextManager;
|
||||
import me.lucko.luckperms.contexts.ServerCalculator;
|
||||
import me.lucko.luckperms.core.UuidCache;
|
||||
import me.lucko.luckperms.data.Importer;
|
||||
import me.lucko.luckperms.groups.GroupManager;
|
||||
@@ -40,25 +44,23 @@ import me.lucko.luckperms.storage.Datastore;
|
||||
import me.lucko.luckperms.storage.StorageFactory;
|
||||
import me.lucko.luckperms.tracks.TrackManager;
|
||||
import me.lucko.luckperms.users.BungeeUserManager;
|
||||
import me.lucko.luckperms.users.UserManager;
|
||||
import me.lucko.luckperms.utils.LocaleManager;
|
||||
import me.lucko.luckperms.utils.LogFactory;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
private final Map<UUID, BungeePlayerCache> playerCache = new ConcurrentHashMap<>();
|
||||
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
|
||||
private LPConfiguration configuration;
|
||||
private UserManager userManager;
|
||||
private BungeeUserManager userManager;
|
||||
private GroupManager groupManager;
|
||||
private TrackManager trackManager;
|
||||
private Datastore datastore;
|
||||
@@ -67,6 +69,8 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
private Logger log;
|
||||
private Importer importer;
|
||||
private ConsecutiveExecutor consecutiveExecutor;
|
||||
private LocaleManager localeManager;
|
||||
private ContextManager<ProxiedPlayer> contextManager;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
@@ -75,6 +79,17 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
getLog().info("Loading configuration...");
|
||||
configuration = new BungeeConfig(this);
|
||||
|
||||
localeManager = new LocaleManager();
|
||||
File locale = new File(getDataFolder(), "lang.yml");
|
||||
if (locale.exists()) {
|
||||
getLog().info("Found locale file. Attempting to load from it.");
|
||||
try {
|
||||
localeManager.loadFromFile(locale);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// register events
|
||||
getProxy().getPluginManager().registerListener(this, new BungeeListener(this));
|
||||
|
||||
@@ -89,20 +104,27 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
datastore = StorageFactory.getDatastore(this, "h2");
|
||||
|
||||
getLog().info("Loading internal permission managers...");
|
||||
uuidCache = new UuidCache(getConfiguration().getOnlineMode());
|
||||
uuidCache = new UuidCache(getConfiguration().isOnlineMode());
|
||||
userManager = new BungeeUserManager(this);
|
||||
groupManager = new GroupManager(this);
|
||||
trackManager = new TrackManager();
|
||||
importer = new Importer(commandManager);
|
||||
consecutiveExecutor = new ConsecutiveExecutor(commandManager);
|
||||
|
||||
contextManager = new ContextManager<>();
|
||||
BackendServerCalculator serverCalculator = new BackendServerCalculator();
|
||||
getProxy().getPluginManager().registerListener(this, serverCalculator);
|
||||
contextManager.registerCalculator(serverCalculator);
|
||||
contextManager.registerCalculator(new ServerCalculator<>(getConfiguration().getServer()));
|
||||
contextManager.registerListener(userManager);
|
||||
|
||||
int mins = getConfiguration().getSyncTime();
|
||||
if (mins > 0) {
|
||||
getProxy().getScheduler().schedule(this, new UpdateTask(this), mins, mins, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
// 20 times per second (once per "tick")
|
||||
getProxy().getScheduler().schedule(this, BungeeSenderFactory.get(), 50L, 50L, TimeUnit.MILLISECONDS);
|
||||
getProxy().getScheduler().schedule(this, BungeeSenderFactory.get(this), 50L, 50L, TimeUnit.MILLISECONDS);
|
||||
getProxy().getScheduler().schedule(this, new ExpireTemporaryTask(this), 3L, 3L, TimeUnit.SECONDS);
|
||||
getProxy().getScheduler().schedule(this, consecutiveExecutor, 1L, 1L, TimeUnit.SECONDS);
|
||||
|
||||
@@ -161,13 +183,16 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Sender> getSenders() {
|
||||
return getProxy().getPlayers().stream().map(p -> BungeeSenderFactory.get().wrap(p)).collect(Collectors.toList());
|
||||
public List<Sender> getNotifyListeners() {
|
||||
return getProxy().getPlayers().stream()
|
||||
.map(p -> BungeeSenderFactory.get(this).wrap(p, Collections.singleton(Permission.LOG_NOTIFY)))
|
||||
.filter(Permission.LOG_NOTIFY::isAuthorized)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sender getConsoleSender() {
|
||||
return BungeeSenderFactory.get().wrap(getProxy().getConsole());
|
||||
return BungeeSenderFactory.get(this).wrap(getProxy().getConsole());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.contexts;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import me.lucko.luckperms.api.context.ContextCalculator;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class BackendServerCalculator extends ContextCalculator<ProxiedPlayer> implements Listener {
|
||||
private static final String WORLD_KEY = "world";
|
||||
|
||||
@Override
|
||||
public Map<String, String> giveApplicableContext(ProxiedPlayer subject, Map<String, String> accumulator) {
|
||||
String server = getServer(subject);
|
||||
|
||||
if (server != null) {
|
||||
accumulator.put(WORLD_KEY, server);
|
||||
}
|
||||
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContextApplicable(ProxiedPlayer subject, Map.Entry<String, String> context) {
|
||||
if (!context.getKey().equals(WORLD_KEY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String server = getServer(subject);
|
||||
return server != null && server.equals(context.getValue());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerServerSwitch(ServerSwitchEvent e) {
|
||||
pushUpdate(e.getPlayer(), Maps.immutableEntry("null", "null"), Maps.immutableEntry(WORLD_KEY, getServer(e.getPlayer())));
|
||||
}
|
||||
|
||||
private static String getServer(ProxiedPlayer player) {
|
||||
return player.getServer() == null ? null : (player.getServer().getInfo() == null ? null : player.getServer().getInfo().getName());
|
||||
}
|
||||
}
|
||||
@@ -22,21 +22,77 @@
|
||||
|
||||
package me.lucko.luckperms.users;
|
||||
|
||||
import me.lucko.luckperms.BungeePlayerCache;
|
||||
import me.lucko.luckperms.LPBungeePlugin;
|
||||
import me.lucko.luckperms.api.event.events.UserPermissionRefreshEvent;
|
||||
import me.lucko.luckperms.api.implementation.internal.UserLink;
|
||||
import me.lucko.luckperms.contexts.Contexts;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeUser extends User {
|
||||
private final LPBungeePlugin plugin;
|
||||
|
||||
BungeeUser(UUID uuid, LPBungeePlugin plugin) {
|
||||
super(uuid, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
BungeeUser(UUID uuid, String username, LPBungeePlugin plugin) {
|
||||
super(uuid, username, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshPermissions() {
|
||||
// Do nothing. Permissions are applied when needed in a listener.
|
||||
public synchronized void refreshPermissions() {
|
||||
ProxiedPlayer player = plugin.getProxy().getPlayer(plugin.getUuidCache().getExternalUUID(getUuid()));
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
BungeePlayerCache playerCache = plugin.getPlayerCache().get(getUuid());
|
||||
if (playerCache == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the permissions that should be applied. This is done async.
|
||||
Map<String, Boolean> toApply = exportNodes(
|
||||
new Contexts(
|
||||
plugin.getContextManager().giveApplicableContext(player, new HashMap<>()),
|
||||
plugin.getConfiguration().isIncludingGlobalPerms(),
|
||||
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
|
||||
true,
|
||||
plugin.getConfiguration().isApplyingGlobalGroups(),
|
||||
plugin.getConfiguration().isApplyingGlobalWorldGroups()
|
||||
),
|
||||
Collections.emptyList()
|
||||
);
|
||||
|
||||
Map<String, Boolean> existing = playerCache.getPermissions();
|
||||
|
||||
boolean different = false;
|
||||
if (toApply.size() != existing.size()) {
|
||||
different = true;
|
||||
} else {
|
||||
for (Map.Entry<String, Boolean> e : existing.entrySet()) {
|
||||
if (toApply.containsKey(e.getKey()) && toApply.get(e.getKey()) == e.getValue()) {
|
||||
continue;
|
||||
}
|
||||
different = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!different) return;
|
||||
|
||||
existing.clear();
|
||||
playerCache.invalidateCache();
|
||||
existing.putAll(toApply);
|
||||
|
||||
plugin.getApiProvider().fireEventAsync(new UserPermissionRefreshEvent(new UserLink(this)));
|
||||
}
|
||||
}
|
||||
@@ -23,10 +23,13 @@
|
||||
package me.lucko.luckperms.users;
|
||||
|
||||
import me.lucko.luckperms.LPBungeePlugin;
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeUserManager extends UserManager {
|
||||
public class BungeeUserManager extends UserManager implements ContextListener<ProxiedPlayer> {
|
||||
private final LPBungeePlugin plugin;
|
||||
|
||||
public BungeeUserManager(LPBungeePlugin plugin) {
|
||||
@@ -57,4 +60,14 @@ public class BungeeUserManager extends UserManager {
|
||||
.map(p -> plugin.getUuidCache().getUUID(p.getUniqueId()))
|
||||
.forEach(u -> plugin.getDatastore().loadUser(u, "null"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContextChange(ProxiedPlayer subject, Map.Entry<String, String> before, Map.Entry<String, String> current) throws Exception {
|
||||
UUID internal = plugin.getUuidCache().getUUID(subject.getUniqueId());
|
||||
|
||||
User user = get(internal);
|
||||
if (user != null) {
|
||||
plugin.doAsync(user::refreshPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,20 @@
|
||||
# The name of the server, used for server specific permissions. Set to 'global' to disable.
|
||||
server: bungee
|
||||
|
||||
# If users on this server should have their global permissions/groups applied.
|
||||
# If users on this server should have their global permissions applied.
|
||||
# If set to false, only server specific permissions will apply for users on this server
|
||||
include-global: false
|
||||
|
||||
# If users on this server should have their global world permissions applied.
|
||||
# If set to false, only world specific permissions will apply for users on this server
|
||||
include-global-world: true
|
||||
|
||||
# If users on this server should have global (non-server specific) groups applied
|
||||
apply-global-groups: true
|
||||
|
||||
# If users on this server should have global (non-world specific) groups applied
|
||||
apply-global-world-groups: true
|
||||
|
||||
# If this server is in offline or online mode.
|
||||
# This setting allows a player to have the same UUID across a network of offline mode/mixed servers.
|
||||
|
||||
@@ -30,13 +41,12 @@ online-mode: true
|
||||
|
||||
# If the plugin should apply wildcard permissions.
|
||||
# If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered permissions matching
|
||||
# the wildcard. This will only work for plugins that define all of their permissions to the server.
|
||||
# the wildcard.
|
||||
apply-wildcards: true
|
||||
|
||||
# If the plugin should parse regex permissions.
|
||||
# If set to true, LuckPerms will detect regex permissions, marked with "r=" at the start of the node, and resolve &
|
||||
# apply all registered permissions matching the regex. This will only work for plugins that define all of their
|
||||
# permissions to the server.
|
||||
# apply all registered permissions matching the regex.
|
||||
apply-regex: true
|
||||
|
||||
# If the plugin should complete and apply shorthand permissions.
|
||||
@@ -46,14 +56,27 @@ 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
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, h2, json, yaml, mongodb
|
||||
# Fill out connection info below if you're using MySQL or MongoDB
|
||||
storage-method: h2
|
||||
|
||||
# This block enables support for split datastores.
|
||||
# Only touch this if you're sure that you know what you're doing.
|
||||
# I (the author) do not endorse nor recommend the use of this feature.
|
||||
split-storage:
|
||||
enabled: false
|
||||
methods:
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.8-SNAPSHOT</version>
|
||||
<version>2.10-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -27,14 +27,16 @@ import me.lucko.luckperms.api.PlatformType;
|
||||
import me.lucko.luckperms.api.implementation.ApiProvider;
|
||||
import me.lucko.luckperms.commands.ConsecutiveExecutor;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.config.LPConfiguration;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.core.LPConfiguration;
|
||||
import me.lucko.luckperms.contexts.ContextManager;
|
||||
import me.lucko.luckperms.core.UuidCache;
|
||||
import me.lucko.luckperms.data.Importer;
|
||||
import me.lucko.luckperms.groups.GroupManager;
|
||||
import me.lucko.luckperms.storage.Datastore;
|
||||
import me.lucko.luckperms.tracks.TrackManager;
|
||||
import me.lucko.luckperms.users.UserManager;
|
||||
import me.lucko.luckperms.utils.LocaleManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
@@ -60,6 +62,8 @@ public interface LuckPermsPlugin {
|
||||
ApiProvider getApiProvider();
|
||||
Importer getImporter();
|
||||
ConsecutiveExecutor getConsecutiveExecutor();
|
||||
LocaleManager getLocaleManager();
|
||||
ContextManager getContextManager();
|
||||
|
||||
/**
|
||||
* @return the version of the plugin
|
||||
@@ -103,7 +107,7 @@ public interface LuckPermsPlugin {
|
||||
/**
|
||||
* @return a {@link List} of senders online on the platform
|
||||
*/
|
||||
List<Sender> getSenders();
|
||||
List<Sender> getNotifyListeners();
|
||||
|
||||
/**
|
||||
* @return the console sender of the instance
|
||||
|
||||
@@ -27,6 +27,8 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.*;
|
||||
import me.lucko.luckperms.api.context.ContextListener;
|
||||
import me.lucko.luckperms.api.context.IContextCalculator;
|
||||
import me.lucko.luckperms.api.event.LPEvent;
|
||||
import me.lucko.luckperms.api.event.LPListener;
|
||||
import me.lucko.luckperms.api.implementation.internal.*;
|
||||
@@ -67,7 +69,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public double getApiVersion() {
|
||||
return 2.8;
|
||||
return 2.10;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -208,6 +210,18 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public Node.Builder buildNode(@NonNull String permission) throws IllegalArgumentException {
|
||||
return new me.lucko.luckperms.utils.Node.Builder(checkNode(permission));
|
||||
return new me.lucko.luckperms.core.Node.Builder(checkNode(permission));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void registerContextCalculator(IContextCalculator<?> contextCalculator) {
|
||||
plugin.getContextManager().registerCalculator(contextCalculator);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void registerContextListener(ContextListener<?> contextListener) {
|
||||
plugin.getContextManager().registerListener(contextListener);
|
||||
}
|
||||
}
|
||||
+37
-13
@@ -30,11 +30,11 @@ import me.lucko.luckperms.api.data.MySQLConfiguration;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides a link between {@link LPConfiguration} and {@link me.lucko.luckperms.core.LPConfiguration}
|
||||
* Provides a link between {@link LPConfiguration} and {@link me.lucko.luckperms.config.LPConfiguration}
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class LPConfigurationLink implements LPConfiguration {
|
||||
private final me.lucko.luckperms.core.LPConfiguration master;
|
||||
private final me.lucko.luckperms.config.LPConfiguration master;
|
||||
|
||||
@Override
|
||||
public String getServer() {
|
||||
@@ -58,42 +58,67 @@ public class LPConfigurationLink implements LPConfiguration {
|
||||
|
||||
@Override
|
||||
public boolean getIncludeGlobalPerms() {
|
||||
return master.getIncludeGlobalPerms();
|
||||
return master.isIncludingGlobalPerms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getIncludeGlobalWorldPerms() {
|
||||
return master.isIncludingGlobalWorldPerms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getApplyGlobalGroups() {
|
||||
return master.isApplyingGlobalGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getApplyGlobalWorldGroups() {
|
||||
return master.isApplyingGlobalWorldGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getOnlineMode() {
|
||||
return master.getOnlineMode();
|
||||
return master.isOnlineMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getApplyWildcards() {
|
||||
return master.getApplyWildcards();
|
||||
return master.isApplyingWildcards();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getApplyRegex() {
|
||||
return master.getApplyRegex();
|
||||
return master.isApplyingRegex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getApplyShorthand() {
|
||||
return master.getApplyShorthand();
|
||||
return master.isApplyingShorthand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getLogNotify() {
|
||||
return master.getLogNotify();
|
||||
return master.isLogNotify();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDebugPermissionChecks() {
|
||||
return master.isDebugPermissionChecks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getEnableOps() {
|
||||
return master.getEnableOps();
|
||||
return master.isOpsEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCommandsAllowOp() {
|
||||
return master.getCommandsAllowOp();
|
||||
return master.isCommandsAllowOp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAutoOp() {
|
||||
return master.isAutoOp();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,7 +128,7 @@ public class LPConfigurationLink implements LPConfiguration {
|
||||
|
||||
@Override
|
||||
public boolean getVaultIncludeGlobal() {
|
||||
return master.getVaultIncludeGlobal();
|
||||
return master.isVaultIncludingGlobal();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@@ -124,10 +149,9 @@ public class LPConfigurationLink implements LPConfiguration {
|
||||
|
||||
@Override
|
||||
public boolean getSplitStorage() {
|
||||
return master.getSplitStorage();
|
||||
return master.isSplitStorage();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Map<String, String> getSplitStorageOptions() {
|
||||
return master.getSplitStorageOptions();
|
||||
|
||||
+12
-2
@@ -27,6 +27,7 @@ import lombok.NonNull;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.PermissionHolder;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.contexts.Contexts;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
@@ -67,7 +68,7 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
|
||||
@Override
|
||||
public Set<Node> getAllNodes() {
|
||||
return Collections.unmodifiableSet(master.getAllNodes(null));
|
||||
return Collections.unmodifiableSet(master.getAllNodes(Collections.emptyList(), Contexts.allowAll()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -252,7 +253,16 @@ public class PermissionHolderLink implements PermissionHolder {
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getPermissions(String server, String world, Map<String, String> extraContext, boolean includeGlobal, List<String> possibleNodes, boolean applyGroups) {
|
||||
return master.exportNodes(server, world, extraContext, includeGlobal, applyGroups, possibleNodes);
|
||||
if (extraContext == null) {
|
||||
extraContext = new HashMap<>();
|
||||
}
|
||||
if (server != null && !server.equals("")) {
|
||||
extraContext.put("server", server);
|
||||
}
|
||||
if (world != null && !world.equals("")) {
|
||||
extraContext.put("world", world);
|
||||
}
|
||||
return master.exportNodes(new Contexts(extraContext, includeGlobal, includeGlobal, applyGroups, true, true), possibleNodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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.calculators;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Calculates and caches permissions
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class PermissionCalculator {
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final String objectName;
|
||||
private final boolean debug;
|
||||
private final List<PermissionProcessor> processors;
|
||||
private final Map<String, Tristate> cache = new ConcurrentHashMap<>();
|
||||
|
||||
public void invalidateCache() {
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
public Tristate getPermissionValue(String permission) {
|
||||
if (debug) {
|
||||
plugin.getLog().info("Checking if " + objectName + " has permission: " + permission);
|
||||
}
|
||||
|
||||
permission = permission.toLowerCase();
|
||||
return cache.computeIfAbsent(permission, this::lookupPermissionValue);
|
||||
}
|
||||
|
||||
private Tristate lookupPermissionValue(String permission) {
|
||||
for (PermissionProcessor processor : processors) {
|
||||
Tristate v = processor.hasPermission(permission);
|
||||
if (v == Tristate.UNDEFINED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public static class MapProcessor implements PermissionProcessor {
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> map;
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
if (map.containsKey(permission)) {
|
||||
return Tristate.fromBoolean(map.get(permission));
|
||||
}
|
||||
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public static class RegexProcessor implements PermissionProcessor {
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> map;
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
for (Map.Entry<String, Boolean> e : map.entrySet()) {
|
||||
if (e.getKey().toLowerCase().startsWith("r=")) {
|
||||
Pattern p = Patterns.compile(e.getKey().substring(2));
|
||||
if (p == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p.matcher(permission).matches()) {
|
||||
return Tristate.fromBoolean(e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public static class WildcardProcessor implements PermissionProcessor {
|
||||
|
||||
@Getter
|
||||
private final Map<String, Boolean> map;
|
||||
|
||||
@Override
|
||||
public Tristate hasPermission(String permission) {
|
||||
String node = permission;
|
||||
|
||||
while (node.contains(".")) {
|
||||
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 (map.containsKey("'*'")) {
|
||||
return Tristate.fromBoolean(map.get("'*'"));
|
||||
}
|
||||
|
||||
if (map.containsKey("*")) {
|
||||
return Tristate.fromBoolean(map.get("*"));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.calculators;
|
||||
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
|
||||
public interface PermissionProcessor {
|
||||
|
||||
Tristate hasPermission(String permission);
|
||||
|
||||
}
|
||||
@@ -39,7 +39,6 @@ import me.lucko.luckperms.commands.track.DeleteTrack;
|
||||
import me.lucko.luckperms.commands.track.ListTracks;
|
||||
import me.lucko.luckperms.commands.track.TrackMainCommand;
|
||||
import me.lucko.luckperms.commands.user.UserMainCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -49,6 +48,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class CommandManager {
|
||||
@Getter
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
@Getter
|
||||
@@ -61,6 +61,7 @@ public class CommandManager {
|
||||
.add(new InfoCommand())
|
||||
.add(new DebugCommand())
|
||||
.add(new ImportCommand())
|
||||
.add(new ExportCommand())
|
||||
.add(new QueueCommand())
|
||||
.add(new MigrationMainCommand())
|
||||
.add(new CreateGroup())
|
||||
@@ -176,8 +177,7 @@ public class CommandManager {
|
||||
}
|
||||
|
||||
private void sendCommandUsage(Sender sender, String label) {
|
||||
Message.INFO_BRIEF.send(sender, plugin.getVersion());
|
||||
|
||||
Util.sendPluginMessage(sender, "&6Running &bLuckPerms v" + plugin.getVersion() + "&6.");
|
||||
mainCommands.stream()
|
||||
.filter(c -> c.isAuthorized(sender))
|
||||
.forEach(c -> Util.sendPluginMessage(sender, "&e-> &d" + String.format(c.getUsage(), label)));
|
||||
|
||||
@@ -98,7 +98,7 @@ public abstract class MainCommand<T> {
|
||||
}
|
||||
|
||||
if (sub.getIsArgumentInvalid().test(strippedArgs.size())) {
|
||||
sub.sendUsage(sender, label);
|
||||
sub.sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
@@ -146,10 +146,10 @@ public abstract class MainCommand<T> {
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (subs.size() > 0) {
|
||||
Util.sendPluginMessage(sender, "&e" + getName() + " Sub Commands:");
|
||||
Util.sendPluginMessage(sender, "&e" + getName() + " Sub Commands: &7(" + String.format(getUsage(), label) + " ...)");
|
||||
|
||||
for (SubCommand s : subs) {
|
||||
s.sendUsage(sender, label);
|
||||
s.sendUsage(sender);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
package me.lucko.luckperms.commands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -31,6 +32,7 @@ import java.util.UUID;
|
||||
*/
|
||||
public interface Sender {
|
||||
|
||||
LuckPermsPlugin getPlatform();
|
||||
String getName();
|
||||
UUID getUuid();
|
||||
void sendMessage(String s);
|
||||
|
||||
@@ -24,6 +24,8 @@ package me.lucko.luckperms.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.constants.Constants;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
|
||||
@@ -36,7 +38,9 @@ import java.util.stream.Collectors;
|
||||
* Factory class to make a thread-safe sender instance
|
||||
* @param <T> the command sender type
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public abstract class SenderFactory<T> implements Runnable {
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final Map<T, List<String>> messages = new HashMap<>();
|
||||
private final AtomicBoolean shouldSend = new AtomicBoolean(false);
|
||||
private final SenderFactory<T> factory = this;
|
||||
@@ -47,7 +51,11 @@ public abstract class SenderFactory<T> implements Runnable {
|
||||
protected abstract boolean hasPermission(T t, String node);
|
||||
|
||||
public final Sender wrap(T t) {
|
||||
return new SenderImp(t);
|
||||
return new SenderImp(plugin, t, null);
|
||||
}
|
||||
|
||||
public final Sender wrap(T t, Set<Permission> toCheck) {
|
||||
return new SenderImp(plugin, t, toCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,15 +89,23 @@ public abstract class SenderFactory<T> implements Runnable {
|
||||
|
||||
private final boolean console;
|
||||
|
||||
private SenderImp(T t) {
|
||||
@Getter
|
||||
private final LuckPermsPlugin platform;
|
||||
|
||||
private SenderImp(LuckPermsPlugin platform, T t, Set<Permission> toCheck) {
|
||||
this.platform = platform;
|
||||
this.tRef = new WeakReference<>(t);
|
||||
this.name = factory.getName(t);
|
||||
this.uuid = factory.getUuid(t);
|
||||
this.console = this.uuid.equals(Constants.getConsoleUUID()) || this.uuid.equals(Constants.getImporterUUID());
|
||||
|
||||
if (!this.console) {
|
||||
this.perms = ImmutableMap.copyOf(Arrays.stream(Permission.values())
|
||||
.collect(Collectors.toMap(p -> p, p -> factory.hasPermission(t, p.getNode()))));
|
||||
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()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
package me.lucko.luckperms.commands;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
@@ -42,7 +41,6 @@ import java.util.stream.Collectors;
|
||||
* Abstract SubCommand class
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public abstract class SubCommand<T> {
|
||||
|
||||
/**
|
||||
@@ -70,6 +68,14 @@ public abstract class SubCommand<T> {
|
||||
*/
|
||||
private final Predicate<? super Integer> isArgumentInvalid;
|
||||
|
||||
public SubCommand(String name, String description, String usage, Permission permission, Predicate<? super Integer> isArgumentInvalid) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.permission = permission;
|
||||
this.isArgumentInvalid = isArgumentInvalid;
|
||||
this.usage = usage.replace("<", "&8<&7").replace(">", "&8>&7").replace("[", "&8[&7").replace("]", "&8]&7");
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this sub command is ran
|
||||
* @param plugin a link to the main plugin instance
|
||||
@@ -95,10 +101,9 @@ public abstract class SubCommand<T> {
|
||||
/**
|
||||
* Send the command usage to a sender
|
||||
* @param sender the sender to send the usage to
|
||||
* @param label the command label used
|
||||
*/
|
||||
public void sendUsage(Sender sender, String label) {
|
||||
Util.sendPluginMessage(sender, "&e-> &d" + String.format(getUsage(), label));
|
||||
public void sendUsage(Sender sender) {
|
||||
Util.sendPluginMessage(sender, "&e-> &6" + getName() + (usage.isEmpty() ? "" : "&e - &7" + getUsage()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,22 @@ public class Util {
|
||||
sender.sendMessage(color(Message.PREFIX + message));
|
||||
}
|
||||
|
||||
public static List<String> stripQuotes(List<String> input) {
|
||||
input = new ArrayList<>(input);
|
||||
ListIterator<String> iterator = input.listIterator();
|
||||
while (iterator.hasNext()) {
|
||||
String value = iterator.next();
|
||||
if (!(value.length() >= 3)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value.charAt(0) == '"' && value.charAt(value.length() - 1) == '"') {
|
||||
iterator.set(value.substring(1, value.length() - 1));
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
public static String color(String s) {
|
||||
return translateAlternateColorCodes('&', s);
|
||||
}
|
||||
@@ -165,6 +181,64 @@ public class Util {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String permGroupsToString(SortedSet<Node> nodes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Node node : nodes) {
|
||||
if (!node.isGroupNode()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (node.isTemporary()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sb.append("&a-> &b").append(node.getGroupName());
|
||||
if (node.isServerSpecific()) {
|
||||
sb.append(" &7(&f").append(node.getServer().get()).append("&7)");
|
||||
}
|
||||
if (node.isWorldSpecific()) {
|
||||
sb.append(" &7(&f").append(node.getWorld().get()).append("&7)");
|
||||
}
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
if (sb.length() == 0) {
|
||||
return "&6None";
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String tempGroupsToString(SortedSet<Node> nodes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (Node node : nodes) {
|
||||
if (!node.isGroupNode()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!node.isTemporary()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sb.append("&a-> &b").append(node.getGroupName());
|
||||
if (node.isServerSpecific()) {
|
||||
sb.append(" &7(&f").append(node.getServer().get()).append("&7)");
|
||||
}
|
||||
if (node.isWorldSpecific()) {
|
||||
sb.append(" &7(&f").append(node.getWorld().get()).append("&7)");
|
||||
}
|
||||
|
||||
sb.append("&6 - expires in ").append(DateUtil.formatDateDiff(node.getExpiryUnixTime())).append("\n");
|
||||
}
|
||||
|
||||
if (sb.length() == 0) {
|
||||
return "&6None";
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static UUID parseUuid(String s) {
|
||||
try {
|
||||
return UUID.fromString(s);
|
||||
|
||||
@@ -71,7 +71,7 @@ public class DeleteGroup extends SingleMainCommand {
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
Message.DELETE_SUCCESS.send(sender, groupName);
|
||||
Message.DELETE_SUCCESS.send(sender, group.getDisplayName());
|
||||
LogEntry.build().actor(sender).actedName(groupName).type('G').action("delete").build().submit(plugin, sender);
|
||||
plugin.runUpdateTask();
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
@@ -39,6 +39,7 @@ public class GroupMainCommand extends MainCommand<Group> {
|
||||
super("Group", "/%s group <group>", 2, ImmutableList.<SubCommand<Group>>builder()
|
||||
.add(new GroupInfo())
|
||||
.add(new GroupListNodes())
|
||||
.add(new GroupListParents())
|
||||
.add(new GroupHasPerm())
|
||||
.add(new GroupInheritsPerm())
|
||||
.add(new GroupSetPermission())
|
||||
@@ -59,6 +60,7 @@ public class GroupMainCommand extends MainCommand<Group> {
|
||||
.add(new GroupAddTempSuffix())
|
||||
.add(new GroupRemoveTempPrefix())
|
||||
.add(new GroupRemoveTempSuffix())
|
||||
.add(new GroupBulkChange())
|
||||
.add(new GroupClear())
|
||||
.add(new GroupRename())
|
||||
.build()
|
||||
|
||||
@@ -29,9 +29,11 @@ import me.lucko.luckperms.commands.SingleMainCommand;
|
||||
import me.lucko.luckperms.commands.Util;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ListGroups extends SingleMainCommand {
|
||||
public ListGroups() {
|
||||
@@ -45,7 +47,13 @@ public class ListGroups extends SingleMainCommand {
|
||||
return CommandResult.LOADING_ERROR;
|
||||
}
|
||||
|
||||
Message.GROUPS_LIST.send(sender, Util.listToCommaSep(new ArrayList<>(plugin.getGroupManager().getAll().keySet())));
|
||||
Message.GROUPS_LIST.send(
|
||||
sender,
|
||||
Util.listToCommaSep(new ArrayList<>(plugin.getGroupManager().getAll().values().stream()
|
||||
.map(Group::getDisplayName)
|
||||
.collect(Collectors.toList()))
|
||||
)
|
||||
);
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -38,7 +38,7 @@ import java.util.List;
|
||||
|
||||
public class GroupAddPrefix extends SubCommand<Group> {
|
||||
public GroupAddPrefix() {
|
||||
super("addprefix", "Adds a prefix to the group", "/%s group <group> addprefix <priority> <prefix> [server] [world]",
|
||||
super("addprefix", "Adds a prefix to the group", "<priority> <prefix> [server] [world]",
|
||||
Permission.GROUP_ADDPREFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@@ -65,14 +65,14 @@ public class GroupAddPrefix extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.setPermission(node, true, server);
|
||||
Message.ADDPREFIX_SERVER_SUCCESS.send(sender, group.getName(), prefix, priority, server);
|
||||
Message.ADDPREFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.setPermission(node, true, server, world);
|
||||
Message.ADDPREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), prefix, priority, server, world);
|
||||
Message.ADDPREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -80,7 +80,7 @@ public class GroupAddPrefix extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.setPermission(node, true);
|
||||
Message.ADDPREFIX_SUCCESS.send(sender, group.getName(), prefix, priority);
|
||||
Message.ADDPREFIX_SUCCESS.send(sender, group.getDisplayName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
@@ -89,7 +89,7 @@ public class GroupAddPrefix extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, group.getName());
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -38,7 +38,7 @@ import java.util.List;
|
||||
|
||||
public class GroupAddSuffix extends SubCommand<Group> {
|
||||
public GroupAddSuffix() {
|
||||
super("addsuffix", "Adds a suffix to the group", "/%s group <group> addsuffix <priority> <suffix> [server] [world]",
|
||||
super("addsuffix", "Adds a suffix to the group", "<priority> <suffix> [server] [world]",
|
||||
Permission.GROUP_ADDSUFFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@@ -65,14 +65,14 @@ public class GroupAddSuffix extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.setPermission(node, true, server);
|
||||
Message.ADDSUFFIX_SERVER_SUCCESS.send(sender, group.getName(), suffix, priority, server);
|
||||
Message.ADDSUFFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addsuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.setPermission(node, true, server, world);
|
||||
Message.ADDSUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), suffix, priority, server, world);
|
||||
Message.ADDSUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addsuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -80,7 +80,7 @@ public class GroupAddSuffix extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.setPermission(node, true);
|
||||
Message.ADDSUFFIX_SUCCESS.send(sender, group.getName(), suffix, priority);
|
||||
Message.ADDSUFFIX_SUCCESS.send(sender, group.getDisplayName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addsuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
@@ -89,7 +89,7 @@ public class GroupAddSuffix extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, group.getName());
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -39,7 +39,7 @@ import java.util.List;
|
||||
|
||||
public class GroupAddTempPrefix extends SubCommand<Group> {
|
||||
public GroupAddTempPrefix() {
|
||||
super("addtempprefix", "Adds a prefix to the group temporarily", "/%s group <group> addtempprefix <priority> <prefix> <duration> [server] [world]",
|
||||
super("addtempprefix", "Adds a prefix to the group temporarily", "<priority> <prefix> <duration> [server] [world]",
|
||||
Permission.GROUP_ADD_TEMP_PREFIX, Predicate.notInRange(3, 5));
|
||||
}
|
||||
|
||||
@@ -83,14 +83,14 @@ public class GroupAddTempPrefix extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 4) {
|
||||
group.setPermission(node, true, server, duration);
|
||||
Message.ADD_TEMP_PREFIX_SERVER_SUCCESS.send(sender, group.getName(), prefix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
Message.ADD_TEMP_PREFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(4).toLowerCase();
|
||||
group.setPermission(node, true, server, world, duration);
|
||||
Message.ADD_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), prefix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
Message.ADD_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -98,7 +98,7 @@ public class GroupAddTempPrefix extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_PREFIX_SUCCESS.send(sender, group.getName(), prefix, priority, DateUtil.formatDateDiff(duration));
|
||||
Message.ADD_TEMP_PREFIX_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempprefix " + priority + " " + args.get(1) + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -107,7 +107,7 @@ public class GroupAddTempPrefix extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, group.getName());
|
||||
Message.ALREADY_HAS_PREFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -39,7 +39,7 @@ import java.util.List;
|
||||
|
||||
public class GroupAddTempSuffix extends SubCommand<Group> {
|
||||
public GroupAddTempSuffix() {
|
||||
super("addtempsuffix", "Adds a suffix to the group temporarily", "/%s group <group> addtempsuffix <priority> <suffix> <duration> [server] [world]",
|
||||
super("addtempsuffix", "Adds a suffix to the group temporarily", "<priority> <suffix> <duration> [server] [world]",
|
||||
Permission.GROUP_ADD_TEMP_SUFFIX, Predicate.notInRange(3, 5));
|
||||
}
|
||||
|
||||
@@ -83,14 +83,14 @@ public class GroupAddTempSuffix extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 4) {
|
||||
group.setPermission(node, true, server, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, group.getName(), suffix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(4).toLowerCase();
|
||||
group.setPermission(node, true, server, world, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), suffix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
Message.ADD_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server, world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -98,7 +98,7 @@ public class GroupAddTempSuffix extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.setPermission(node, true, duration);
|
||||
Message.ADD_TEMP_SUFFIX_SUCCESS.send(sender, group.getName(), suffix, priority, DateUtil.formatDateDiff(duration));
|
||||
Message.ADD_TEMP_SUFFIX_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("addtempsuffix " + priority + " " + args.get(1) + " " + duration)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -107,7 +107,7 @@ public class GroupAddTempSuffix extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, group.getName());
|
||||
Message.ALREADY_HAS_SUFFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class GroupBulkChange extends SubCommand<Group> {
|
||||
public GroupBulkChange() {
|
||||
super("bulkchange", "Applies a bulk permission change to the groups permissions", "<server|world> <from> <to>",
|
||||
Permission.GROUP_BULKCHANGE, Predicate.not(3));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
String type = args.get(0).toLowerCase();
|
||||
String from = args.get(1);
|
||||
String to = args.get(2);
|
||||
if (to.equals("null")) {
|
||||
to = null;
|
||||
}
|
||||
|
||||
Set<Node> toAdd = new HashSet<>();
|
||||
|
||||
if (!type.equals("world") && !type.equals("server")) {
|
||||
Message.BULK_CHANGE_TYPE_ERROR.send(sender);
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
Iterator<Node> iterator = group.getNodes().iterator();
|
||||
if (type.equals("world")) {
|
||||
while (iterator.hasNext()) {
|
||||
Node element = iterator.next();
|
||||
String world = element.getWorld().orElse("null");
|
||||
if (!world.equals(from)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
iterator.remove();
|
||||
toAdd.add(me.lucko.luckperms.core.Node.builderFromExisting(element).setWorld(to).build());
|
||||
}
|
||||
} else {
|
||||
while (iterator.hasNext()) {
|
||||
Node element = iterator.next();
|
||||
String server = element.getServer().orElse("global");
|
||||
if (!server.equals(from)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
iterator.remove();
|
||||
toAdd.add(me.lucko.luckperms.core.Node.builderFromExisting(element).setServer(to).build());
|
||||
}
|
||||
}
|
||||
|
||||
group.getNodes().addAll(toAdd);
|
||||
save(group, sender, plugin);
|
||||
Message.BULK_CHANGE_SUCCESS.send(sender, toAdd.size());
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -27,14 +27,14 @@ import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.contexts.Contexts;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class GroupChatMeta extends SubCommand<Group> {
|
||||
public GroupChatMeta() {
|
||||
super("chatmeta", "Displays a groups chat meta", "/%s group <group> chatmeta", Permission.GROUP_CHATMETA,
|
||||
Predicate.alwaysFalse());
|
||||
super("chatmeta", "Displays a groups chat meta", "", Permission.GROUP_CHATMETA, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -42,7 +42,7 @@ public class GroupChatMeta extends SubCommand<Group> {
|
||||
SortedSet<Map.Entry<Integer, String>> prefixes = new TreeSet<>(Util.getMetaComparator().reversed());
|
||||
SortedSet<Map.Entry<Integer, String>> suffixes = new TreeSet<>(Util.getMetaComparator().reversed());
|
||||
|
||||
for (Node node : group.getAllNodes(null)) {
|
||||
for (Node node : group.getAllNodes(null, Contexts.allowAll())) {
|
||||
if (!node.isSuffix() && !node.isPrefix()) {
|
||||
continue;
|
||||
}
|
||||
@@ -67,18 +67,18 @@ public class GroupChatMeta extends SubCommand<Group> {
|
||||
}
|
||||
|
||||
if (prefixes.isEmpty()) {
|
||||
Message.CHAT_META_PREFIX_NONE.send(sender, group.getName());
|
||||
Message.CHAT_META_PREFIX_NONE.send(sender, group.getDisplayName());
|
||||
} else {
|
||||
Message.CHAT_META_PREFIX_HEADER.send(sender, group.getName());
|
||||
Message.CHAT_META_PREFIX_HEADER.send(sender, group.getDisplayName());
|
||||
for (Map.Entry<Integer, String> e : prefixes) {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (suffixes.isEmpty()) {
|
||||
Message.CHAT_META_SUFFIX_NONE.send(sender, group.getName());
|
||||
Message.CHAT_META_SUFFIX_NONE.send(sender, group.getDisplayName());
|
||||
} else {
|
||||
Message.CHAT_META_SUFFIX_HEADER.send(sender, group.getName());
|
||||
Message.CHAT_META_SUFFIX_HEADER.send(sender, group.getDisplayName());
|
||||
for (Map.Entry<Integer, String> e : suffixes) {
|
||||
Message.CHAT_META_ENTRY.send(sender, e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
@@ -36,14 +36,13 @@ import java.util.List;
|
||||
|
||||
public class GroupClear extends SubCommand<Group> {
|
||||
public GroupClear() {
|
||||
super("clear", "Clears a groups permissions", "/%s group <group> clear", Permission.GROUP_CLEAR,
|
||||
Predicate.alwaysFalse());
|
||||
super("clear", "Clears a groups permissions", "", Permission.GROUP_CLEAR, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
group.clearNodes();
|
||||
Message.CLEAR_SUCCESS.send(sender, group.getName());
|
||||
Message.CLEAR_SUCCESS.send(sender, group.getDisplayName());
|
||||
LogEntry.build().actor(sender).acted(group).action("clear").build().submit(plugin, sender);
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
+2
-3
@@ -33,9 +33,8 @@ import java.util.List;
|
||||
|
||||
public class GroupHasPerm extends SubCommand<Group> {
|
||||
public GroupHasPerm() {
|
||||
super("haspermission", "Checks to see if a group has a certain permission node",
|
||||
"/%s group <group> haspermission <node> [server] [world]", Permission.GROUP_HASPERMISSION,
|
||||
Predicate.notInRange(1, 3));
|
||||
super("haspermission", "Checks to see if a group has a certain permission node", "<node> [server] [world]",
|
||||
Permission.GROUP_HASPERMISSION, Predicate.notInRange(1, 3));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -35,14 +35,13 @@ import java.util.List;
|
||||
|
||||
public class GroupInfo extends SubCommand<Group> {
|
||||
public GroupInfo() {
|
||||
super("info", "Gives info about the group", "/%s group <group> info", Permission.GROUP_INFO,
|
||||
Predicate.alwaysFalse());
|
||||
super("info", "Gives info about the group", "", Permission.GROUP_INFO, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
Message.GROUP_INFO.send(sender,
|
||||
group.getName(),
|
||||
group.getDisplayName(),
|
||||
group.getPermanentNodes().size(),
|
||||
group.getTemporaryNodes().size(),
|
||||
label,
|
||||
|
||||
+2
-3
@@ -33,9 +33,8 @@ import java.util.List;
|
||||
|
||||
public class GroupInheritsPerm extends SubCommand<Group> {
|
||||
public GroupInheritsPerm() {
|
||||
super("inheritspermission", "Checks to see if a group inherits a certain permission node",
|
||||
"/%s group <group> inheritspermission <node> [server] [world]", Permission.GROUP_INHERITSPERMISSION,
|
||||
Predicate.notInRange(1, 3));
|
||||
super("inheritspermission", "Checks to see if a group inherits a certain permission node", "<node> [server] [world]",
|
||||
Permission.GROUP_INHERITSPERMISSION, Predicate.notInRange(1, 3));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-4
@@ -32,14 +32,13 @@ import java.util.List;
|
||||
|
||||
public class GroupListNodes extends SubCommand<Group> {
|
||||
public GroupListNodes() {
|
||||
super("listnodes", "Lists the permission nodes the group has", "/%s group <group> listnodes",
|
||||
Permission.GROUP_LISTNODES, Predicate.alwaysFalse());
|
||||
super("listnodes", "Lists the permission nodes the group has", "", Permission.GROUP_LISTNODES, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
Message.LISTNODES.send(sender, group.getName(), Util.permNodesToString(group.getPermissions(false)));
|
||||
Message.LISTNODES_TEMP.send(sender, group.getName(), Util.tempNodesToString(group.getPermissions(false)));
|
||||
Message.LISTNODES.send(sender, group.getDisplayName(), Util.permNodesToString(group.getPermissions(false)));
|
||||
Message.LISTNODES_TEMP.send(sender, group.getDisplayName(), Util.tempNodesToString(group.getPermissions(false)));
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.group.subcommands;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.*;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupListParents extends SubCommand<Group> {
|
||||
public GroupListParents() {
|
||||
super("listparents", "Lists the groups that this group inherits from", "", Permission.GROUP_LISTPARENTS, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
|
||||
Message.LISTPARENTS.send(sender, group.getDisplayName(), Util.permGroupsToString(group.getPermissions(false)));
|
||||
Message.LISTPARENTS_TEMP.send(sender, group.getDisplayName(), Util.tempGroupsToString(group.getPermissions(false)));
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -38,7 +38,7 @@ import java.util.List;
|
||||
|
||||
public class GroupRemovePrefix extends SubCommand<Group> {
|
||||
public GroupRemovePrefix() {
|
||||
super("removeprefix", "Removes a prefix from a group", "/%s group <group> removeprefix <priority> <prefix> [server] [world]",
|
||||
super("removeprefix", "Removes a prefix from a group", "<priority> <prefix> [server] [world]",
|
||||
Permission.GROUP_REMOVEPREFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@@ -65,14 +65,14 @@ public class GroupRemovePrefix extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server);
|
||||
Message.REMOVEPREFIX_SERVER_SUCCESS.send(sender, group.getName(), prefix, priority, server);
|
||||
Message.REMOVEPREFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removeprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world);
|
||||
Message.REMOVEPREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), prefix, priority, server, world);
|
||||
Message.REMOVEPREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removeprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -80,7 +80,7 @@ public class GroupRemovePrefix extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node);
|
||||
Message.REMOVEPREFIX_SUCCESS.send(sender, group.getName(), prefix, priority);
|
||||
Message.REMOVEPREFIX_SUCCESS.send(sender, group.getDisplayName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removeprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
@@ -89,7 +89,7 @@ public class GroupRemovePrefix extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, group.getName());
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -38,7 +38,7 @@ import java.util.List;
|
||||
|
||||
public class GroupRemoveSuffix extends SubCommand<Group> {
|
||||
public GroupRemoveSuffix() {
|
||||
super("removesuffix", "Removes a suffix from a group", "/%s group <group> removesuffix <priority> <suffix> [server] [world]",
|
||||
super("removesuffix", "Removes a suffix from a group", "<priority> <suffix> [server] [world]",
|
||||
Permission.GROUP_REMOVESUFFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@@ -65,14 +65,14 @@ public class GroupRemoveSuffix extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server);
|
||||
Message.REMOVESUFFIX_SERVER_SUCCESS.send(sender, group.getName(), suffix, priority, server);
|
||||
Message.REMOVESUFFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removesuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world);
|
||||
Message.REMOVESUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), suffix, priority, server, world);
|
||||
Message.REMOVESUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removesuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -80,7 +80,7 @@ public class GroupRemoveSuffix extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node);
|
||||
Message.REMOVESUFFIX_SUCCESS.send(sender, group.getName(), suffix, priority);
|
||||
Message.REMOVESUFFIX_SUCCESS.send(sender, group.getDisplayName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removesuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
@@ -89,7 +89,7 @@ public class GroupRemoveSuffix extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, group.getName());
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -38,7 +38,7 @@ import java.util.List;
|
||||
|
||||
public class GroupRemoveTempPrefix extends SubCommand<Group> {
|
||||
public GroupRemoveTempPrefix() {
|
||||
super("removetempprefix", "Removes a temporary prefix from a group", "/%s group <group> removetempprefix <priority> <prefix> [server] [world]",
|
||||
super("removetempprefix", "Removes a temporary prefix from a group", "<priority> <prefix> [server] [world]",
|
||||
Permission.GROUP_REMOVE_TEMP_PREFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@@ -65,14 +65,14 @@ public class GroupRemoveTempPrefix extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_SUCCESS.send(sender, group.getName(), prefix, priority, server);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempprefix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), prefix, priority, server, world);
|
||||
Message.REMOVE_TEMP_PREFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), prefix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempprefix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -80,7 +80,7 @@ public class GroupRemoveTempPrefix extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node, true);
|
||||
Message.REMOVE_TEMP_PREFIX_SUCCESS.send(sender, group.getName(), prefix, priority);
|
||||
Message.REMOVE_TEMP_PREFIX_SUCCESS.send(sender, group.getDisplayName(), prefix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempprefix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
@@ -89,7 +89,7 @@ public class GroupRemoveTempPrefix extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, group.getName());
|
||||
Message.DOES_NOT_HAVE_PREFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -38,7 +38,7 @@ import java.util.List;
|
||||
|
||||
public class GroupRemoveTempSuffix extends SubCommand<Group> {
|
||||
public GroupRemoveTempSuffix() {
|
||||
super("removetempsuffix", "Removes a temporary suffix from a group", "/%s group <group> removetempsuffix <priority> <suffix> [server] [world]",
|
||||
super("removetempsuffix", "Removes a temporary suffix from a group", "<priority> <suffix> [server] [world]",
|
||||
Permission.GROUP_REMOVE_TEMP_SUFFIX, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@@ -65,14 +65,14 @@ public class GroupRemoveTempSuffix extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.unsetPermission(node, server, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, group.getName(), suffix, priority, server);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1) + " " + server)
|
||||
.build().submit(plugin, sender);
|
||||
} else {
|
||||
final String world = args.get(3).toLowerCase();
|
||||
group.unsetPermission(node, server, world, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getName(), suffix, priority, server, world);
|
||||
Message.REMOVE_TEMP_SUFFIX_SERVER_WORLD_SUCCESS.send(sender, group.getDisplayName(), suffix, priority, server, world);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1) + " " + server + " " + world)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -80,7 +80,7 @@ public class GroupRemoveTempSuffix extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node, true);
|
||||
Message.REMOVE_TEMP_SUFFIX_SUCCESS.send(sender, group.getName(), suffix, priority);
|
||||
Message.REMOVE_TEMP_SUFFIX_SUCCESS.send(sender, group.getDisplayName(), suffix, priority);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("removetempsuffix " + priority + " " + args.get(1))
|
||||
.build().submit(plugin, sender);
|
||||
@@ -89,7 +89,7 @@ public class GroupRemoveTempSuffix extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, group.getName());
|
||||
Message.DOES_NOT_HAVE_SUFFIX.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,8 +37,7 @@ import java.util.List;
|
||||
|
||||
public class GroupRename extends SubCommand<Group> {
|
||||
public GroupRename() {
|
||||
super("rename", "Rename this group", "/%s group <group> rename <new name>",
|
||||
Permission.TRACK_APPEND, Predicate.not(1));
|
||||
super("rename", "Rename this group", "<new name>", Permission.TRACK_APPEND, Predicate.not(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+7
-8
@@ -38,9 +38,8 @@ import java.util.List;
|
||||
|
||||
public class GroupSetInherit extends SubCommand<Group> {
|
||||
public GroupSetInherit() {
|
||||
super("setinherit", "Sets another group for this group to inherit permissions from",
|
||||
"/%s group <group> setinherit <group> [server] [world]", Permission.GROUP_SETINHERIT,
|
||||
Predicate.notInRange(1, 3));
|
||||
super("setinherit", "Sets another group for this group to inherit permissions from", "<group> [server] [world]",
|
||||
Permission.GROUP_SETINHERIT, Predicate.notInRange(1, 3));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +47,7 @@ public class GroupSetInherit extends SubCommand<Group> {
|
||||
String groupName = args.get(0).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(groupName)) {
|
||||
sendUsage(sender, label);
|
||||
sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
@@ -73,14 +72,14 @@ public class GroupSetInherit extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 2) {
|
||||
group.setInheritGroup(group1, server);
|
||||
Message.GROUP_SETINHERIT_SERVER_SUCCESS.send(sender, group.getName(), group1.getName(), 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.getName(), group1.getName(), 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);
|
||||
@@ -88,7 +87,7 @@ public class GroupSetInherit extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.setInheritGroup(group1);
|
||||
Message.GROUP_SETINHERIT_SUCCESS.send(sender, group.getName(), group1.getName());
|
||||
Message.GROUP_SETINHERIT_SUCCESS.send(sender, group.getDisplayName(), group1.getDisplayName());
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("setinherit " + group1.getName())
|
||||
.build().submit(plugin, sender);
|
||||
@@ -97,7 +96,7 @@ public class GroupSetInherit extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.GROUP_ALREADY_INHERITS.send(sender, group.getName(), group1.getName());
|
||||
Message.GROUP_ALREADY_INHERITS.send(sender, group.getDisplayName(), group1.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-10
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
@@ -39,8 +38,8 @@ import java.util.List;
|
||||
|
||||
public class GroupSetPermission extends SubCommand<Group> {
|
||||
public GroupSetPermission() {
|
||||
super("set", "Sets a permission for a group", "/%s group <group> set <node> <true|false> [server] [world]",
|
||||
Permission.GROUP_SETPERMISSION, Predicate.notInRange(2, 4));
|
||||
super("set", "Sets a permission for a group", "<node> <true|false> [server] [world]", Permission.GROUP_SETPERMISSION,
|
||||
Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,17 +48,17 @@ public class GroupSetPermission extends SubCommand<Group> {
|
||||
String bool = args.get(1).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(node)) {
|
||||
sendUsage(sender, label);
|
||||
sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.GROUP_USE_INHERIT.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!bool.equalsIgnoreCase("true") && !bool.equalsIgnoreCase("false")) {
|
||||
sendUsage(sender, label);
|
||||
sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
@@ -75,14 +74,14 @@ public class GroupSetPermission extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.setPermission(node, b, server);
|
||||
Message.SETPERMISSION_SERVER_SUCCESS.send(sender, node, bool, group.getName(), server);
|
||||
Message.SETPERMISSION_SERVER_SUCCESS.send(sender, node, bool, group.getDisplayName(), server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("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.getName(), 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)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -90,7 +89,7 @@ public class GroupSetPermission extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.setPermission(node, b);
|
||||
Message.SETPERMISSION_SUCCESS.send(sender, node, bool, group.getName());
|
||||
Message.SETPERMISSION_SUCCESS.send(sender, node, bool, group.getDisplayName());
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("set " + node + " " + b)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -99,7 +98,7 @@ public class GroupSetPermission extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HASPERMISSION.send(sender, group.getName());
|
||||
Message.ALREADY_HASPERMISSION.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-7
@@ -40,8 +40,7 @@ import java.util.List;
|
||||
public class GroupSetTempInherit extends SubCommand<Group> {
|
||||
public GroupSetTempInherit() {
|
||||
super("settempinherit", "Sets another group for this group to inherit permissions from temporarily",
|
||||
"/%s group <group> settempinherit <group> <duration> [server] [world]",
|
||||
Permission.GROUP_SET_TEMP_INHERIT, Predicate.notInRange(2, 4));
|
||||
"<group> <duration> [server] [world]", Permission.GROUP_SET_TEMP_INHERIT, Predicate.notInRange(2, 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,7 +48,7 @@ public class GroupSetTempInherit extends SubCommand<Group> {
|
||||
String groupName = args.get(0).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(groupName)) {
|
||||
sendUsage(sender, label);
|
||||
sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
@@ -91,7 +90,7 @@ public class GroupSetTempInherit extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 3) {
|
||||
group.setInheritGroup(group1, server, duration);
|
||||
Message.GROUP_SET_TEMP_INHERIT_SERVER_SUCCESS.send(sender, group.getName(), group1.getName(), server,
|
||||
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)
|
||||
@@ -99,7 +98,7 @@ public class GroupSetTempInherit extends SubCommand<Group> {
|
||||
} 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.getName(), group1.getName(), server,
|
||||
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)
|
||||
@@ -108,7 +107,7 @@ public class GroupSetTempInherit extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.setInheritGroup(group1, duration);
|
||||
Message.GROUP_SET_TEMP_INHERIT_SUCCESS.send(sender, group.getName(), group1.getName(), DateUtil.formatDateDiff(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);
|
||||
@@ -117,7 +116,7 @@ public class GroupSetTempInherit extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.USER_ALREADY_TEMP_MEMBER_OF.send(sender, group.getName(), group1.getName());
|
||||
Message.USER_ALREADY_TEMP_MEMBER_OF.send(sender, group.getDisplayName(), group1.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-10
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
@@ -40,8 +39,7 @@ import java.util.List;
|
||||
|
||||
public class GroupSetTempPermission extends SubCommand<Group> {
|
||||
public GroupSetTempPermission() {
|
||||
super("settemp", "Sets a temporary permission for a group",
|
||||
"/%s group <group> settemp <node> <true|false> <duration> [server] [world]",
|
||||
super("settemp", "Sets a temporary permission for a group", "<node> <true|false> <duration> [server] [world]",
|
||||
Permission.GROUP_SET_TEMP_PERMISSION, Predicate.notInRange(3, 5));
|
||||
}
|
||||
|
||||
@@ -51,17 +49,17 @@ public class GroupSetTempPermission extends SubCommand<Group> {
|
||||
String bool = args.get(1).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(node)) {
|
||||
sendUsage(sender, label);
|
||||
sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.GROUP_USE_INHERIT.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!bool.equalsIgnoreCase("true") && !bool.equalsIgnoreCase("false")) {
|
||||
sendUsage(sender, label);
|
||||
sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
@@ -94,7 +92,7 @@ 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.getName(), server,
|
||||
Message.SETPERMISSION_TEMP_SERVER_SUCCESS.send(sender, node, bool, group.getDisplayName(), server,
|
||||
DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("settemp " + node + " " + b + " " + duration + " " + server)
|
||||
@@ -102,7 +100,7 @@ public class GroupSetTempPermission extends SubCommand<Group> {
|
||||
} 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.getName(), server,
|
||||
Message.SETPERMISSION_TEMP_SERVER_WORLD_SUCCESS.send(sender, node, bool, group.getDisplayName(), server,
|
||||
world, DateUtil.formatDateDiff(duration));
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("settemp " + node + " " + b + " " + duration + " " + server + " " + world)
|
||||
@@ -111,7 +109,7 @@ public class GroupSetTempPermission extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.setPermission(node, b, duration);
|
||||
Message.SETPERMISSION_TEMP_SUCCESS.send(sender, node, bool, group.getName(), DateUtil.formatDateDiff(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)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -120,7 +118,7 @@ public class GroupSetTempPermission extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectAlreadyHasException e) {
|
||||
Message.ALREADY_HAS_TEMP_PERMISSION.send(sender, group.getName());
|
||||
Message.ALREADY_HAS_TEMP_PERMISSION.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -34,8 +34,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class GroupShowTracks extends SubCommand<Group> {
|
||||
public GroupShowTracks() {
|
||||
super("showtracks", "Lists the tracks that this group features on", "/%s group <group> showtracks",
|
||||
Permission.GROUP_SHOWTRACKS, Predicate.alwaysFalse());
|
||||
super("showtracks", "Lists the tracks that this group features on", "", Permission.GROUP_SHOWTRACKS, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+8
-9
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
@@ -39,8 +38,8 @@ import java.util.List;
|
||||
|
||||
public class GroupUnSetPermission extends SubCommand<Group> {
|
||||
public GroupUnSetPermission() {
|
||||
super("unset", "Unsets a permission for a group", "/%s group <group> unset <node> [server] [world]",
|
||||
Permission.GROUP_UNSETPERMISSION, Predicate.notInRange(1, 3));
|
||||
super("unset", "Unsets a permission for a group", "<node> [server] [world]", Permission.GROUP_UNSETPERMISSION,
|
||||
Predicate.notInRange(1, 3));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,11 +47,11 @@ public class GroupUnSetPermission extends SubCommand<Group> {
|
||||
String node = args.get(0).replace("{SPACE}", " ");
|
||||
|
||||
if (ArgumentChecker.checkNode(node)) {
|
||||
sendUsage(sender, label);
|
||||
sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.GROUP_USE_UNINHERIT.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
@@ -67,14 +66,14 @@ public class GroupUnSetPermission extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 2) {
|
||||
group.unsetPermission(node, server);
|
||||
Message.UNSETPERMISSION_SERVER_SUCCESS.send(sender, node, group.getName(), server);
|
||||
Message.UNSETPERMISSION_SERVER_SUCCESS.send(sender, node, group.getDisplayName(), server);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("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.getName(), 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)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -82,7 +81,7 @@ public class GroupUnSetPermission extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node);
|
||||
Message.UNSETPERMISSION_SUCCESS.send(sender, node, group.getName());
|
||||
Message.UNSETPERMISSION_SUCCESS.send(sender, node, group.getDisplayName());
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("unset " + node)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -91,7 +90,7 @@ public class GroupUnSetPermission extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVEPERMISSION.send(sender, group.getName());
|
||||
Message.DOES_NOT_HAVEPERMISSION.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-7
@@ -39,8 +39,7 @@ import java.util.List;
|
||||
public class GroupUnsetInherit extends SubCommand<Group> {
|
||||
public GroupUnsetInherit() {
|
||||
super("unsetinherit", "Unsets another group for this group to inherit permissions from",
|
||||
"/%s group <group> unsetinherit <group> [server] [world]", Permission.GROUP_UNSETINHERIT,
|
||||
Predicate.notInRange(1, 3));
|
||||
"<group> [server] [world]", Permission.GROUP_UNSETINHERIT, Predicate.notInRange(1, 3));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +47,7 @@ public class GroupUnsetInherit extends SubCommand<Group> {
|
||||
String groupName = args.get(0).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(groupName)) {
|
||||
sendUsage(sender, label);
|
||||
sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
@@ -62,14 +61,14 @@ public class GroupUnsetInherit extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 2) {
|
||||
group.unsetPermission("group." + groupName, server);
|
||||
Message.GROUP_UNSETINHERIT_SERVER_SUCCESS.send(sender, group.getName(), 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.getName(), 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);
|
||||
@@ -77,7 +76,7 @@ public class GroupUnsetInherit extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.unsetPermission("group." + groupName);
|
||||
Message.GROUP_UNSETINHERIT_SUCCESS.send(sender, group.getName(), groupName);
|
||||
Message.GROUP_UNSETINHERIT_SUCCESS.send(sender, group.getDisplayName(), groupName);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("unsetinherit " + groupName)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -86,7 +85,7 @@ public class GroupUnsetInherit extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.GROUP_DOES_NOT_INHERIT.send(sender, group.getName(), groupName);
|
||||
Message.GROUP_DOES_NOT_INHERIT.send(sender, group.getDisplayName(), groupName);
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-7
@@ -39,8 +39,7 @@ import java.util.List;
|
||||
public class GroupUnsetTempInherit extends SubCommand<Group> {
|
||||
public GroupUnsetTempInherit() {
|
||||
super("unsettempinherit", "Unsets another group for this group to inherit permissions from",
|
||||
"/%s group <group> unsettempinherit <group> [server] [world]", Permission.GROUP_UNSET_TEMP_INHERIT,
|
||||
Predicate.notInRange(1, 3));
|
||||
"<group> [server] [world]", Permission.GROUP_UNSET_TEMP_INHERIT, Predicate.notInRange(1, 3));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +47,7 @@ public class GroupUnsetTempInherit extends SubCommand<Group> {
|
||||
String groupName = args.get(0).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(groupName)) {
|
||||
sendUsage(sender, label);
|
||||
sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
@@ -62,14 +61,14 @@ public class GroupUnsetTempInherit extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 2) {
|
||||
group.unsetPermission("group." + groupName, server, true);
|
||||
Message.GROUP_UNSET_TEMP_INHERIT_SERVER_SUCCESS.send(sender, group.getName(), groupName, server);
|
||||
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.getName(), groupName, server, world);
|
||||
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);
|
||||
@@ -77,7 +76,7 @@ public class GroupUnsetTempInherit extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.unsetPermission("group." + groupName, true);
|
||||
Message.GROUP_UNSET_TEMP_INHERIT_SUCCESS.send(sender, group.getName(), groupName);
|
||||
Message.GROUP_UNSET_TEMP_INHERIT_SUCCESS.send(sender, group.getDisplayName(), groupName);
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("unsettempinherit " + groupName)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -86,7 +85,7 @@ public class GroupUnsetTempInherit extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.GROUP_DOES_NOT_TEMP_INHERIT.send(sender, group.getName(), groupName);
|
||||
Message.GROUP_DOES_NOT_TEMP_INHERIT.send(sender, group.getDisplayName(), groupName);
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-10
@@ -28,7 +28,6 @@ import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Patterns;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
@@ -39,9 +38,8 @@ import java.util.List;
|
||||
|
||||
public class GroupUnsetTempPermission extends SubCommand<Group> {
|
||||
public GroupUnsetTempPermission() {
|
||||
super("unsettemp", "Unsets a temporary permission for a group",
|
||||
"/%s group <group> unsettemp <node> [server] [world]", Permission.GROUP_UNSET_TEMP_PERMISSION,
|
||||
Predicate.notInRange(1, 3));
|
||||
super("unsettemp", "Unsets a temporary permission for a group", "<node> [server] [world]",
|
||||
Permission.GROUP_UNSET_TEMP_PERMISSION, Predicate.notInRange(1, 3));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,11 +47,11 @@ public class GroupUnsetTempPermission extends SubCommand<Group> {
|
||||
String node = args.get(0).replace("{SPACE}", " ");
|
||||
|
||||
if (ArgumentChecker.checkNode(node)) {
|
||||
sendUsage(sender, label);
|
||||
sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
|
||||
if (node.toLowerCase().startsWith("group.")) {
|
||||
Message.GROUP_USE_UNINHERIT.send(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
@@ -68,14 +66,14 @@ public class GroupUnsetTempPermission extends SubCommand<Group> {
|
||||
|
||||
if (args.size() == 2) {
|
||||
group.unsetPermission(node, server);
|
||||
Message.UNSET_TEMP_PERMISSION_SERVER_SUCCESS.send(sender, node, group.getName(), 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.getName(), 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);
|
||||
@@ -83,7 +81,7 @@ public class GroupUnsetTempPermission extends SubCommand<Group> {
|
||||
|
||||
} else {
|
||||
group.unsetPermission(node, true);
|
||||
Message.UNSET_TEMP_PERMISSION_SUCCESS.send(sender, node, group.getName());
|
||||
Message.UNSET_TEMP_PERMISSION_SUCCESS.send(sender, node, group.getDisplayName());
|
||||
LogEntry.build().actor(sender).acted(group)
|
||||
.action("unsettemp " + node)
|
||||
.build().submit(plugin, sender);
|
||||
@@ -92,7 +90,7 @@ public class GroupUnsetTempPermission extends SubCommand<Group> {
|
||||
save(group, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (ObjectLacksException e) {
|
||||
Message.DOES_NOT_HAVE_TEMP_PERMISSION.send(sender, group.getName());
|
||||
Message.DOES_NOT_HAVE_TEMP_PERMISSION.send(sender, group.getDisplayName());
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ import java.util.List;
|
||||
|
||||
public class LogExport extends SubCommand<Log> {
|
||||
public LogExport() {
|
||||
super("export", "Export the log to a file", "/%s log export <file>", Permission.LOG_EXPORT, Predicate.not(1));
|
||||
super("export", "Export the log to a file", "<file>", Permission.LOG_EXPORT, Predicate.not(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ import java.util.SortedMap;
|
||||
|
||||
public class LogGroupHistory extends SubCommand<Log> {
|
||||
public LogGroupHistory() {
|
||||
super("grouphistory", "View an objects history", "/%s log grouphistory <group> [page]", Permission.LOG_GROUP_HISTORY,
|
||||
super("grouphistory", "View an objects history", "<group> [page]", Permission.LOG_GROUP_HISTORY,
|
||||
Predicate.notInRange(1, 2));
|
||||
}
|
||||
|
||||
|
||||
@@ -37,8 +37,7 @@ import java.util.UUID;
|
||||
|
||||
public class LogNotify extends SubCommand<Log> {
|
||||
public LogNotify() {
|
||||
super("notify", "Toggle notifications", "/%s log notify [on|off]", Permission.LOG_NOTIFY,
|
||||
Predicate.notInRange(0, 1));
|
||||
super("notify", "Toggle notifications", "[on|off]", Permission.LOG_NOTIFY, Predicate.notInRange(0, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -38,8 +38,7 @@ import java.util.UUID;
|
||||
|
||||
public class LogRecent extends SubCommand<Log> {
|
||||
public LogRecent() {
|
||||
super("recent", "View recent actions", "/%s log recent [user] [page]", Permission.LOG_RECENT,
|
||||
Predicate.notInRange(0, 2));
|
||||
super("recent", "View recent actions", "[user] [page]", Permission.LOG_RECENT, Predicate.notInRange(0, 2));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,8 +40,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class LogSearch extends SubCommand<Log> {
|
||||
public LogSearch() {
|
||||
super("search", "Search the log for an entry", "/%s log search <query> [page]", Permission.LOG_SEARCH,
|
||||
Predicate.is(0));
|
||||
super("search", "Search the log for an entry", "<query> [page]", Permission.LOG_SEARCH, Predicate.is(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-2
@@ -40,8 +40,7 @@ import java.util.SortedMap;
|
||||
|
||||
public class LogTrackHistory extends SubCommand<Log> {
|
||||
public LogTrackHistory() {
|
||||
super("trackhistory", "View an objects history", "/%s log trackhistory <track> [page]", Permission.LOG_TRACK_HISTORY,
|
||||
Predicate.notInRange(1, 2));
|
||||
super("trackhistory", "View an objects history", "<track> [page]", Permission.LOG_TRACK_HISTORY, Predicate.notInRange(1, 2));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-2
@@ -38,8 +38,7 @@ import java.util.UUID;
|
||||
|
||||
public class LogUserHistory extends SubCommand<Log> {
|
||||
public LogUserHistory() {
|
||||
super("userhistory", "View an objects history", "/%s log userhistory <user> [page]", Permission.LOG_USER_HISTORY,
|
||||
Predicate.notInRange(1, 2));
|
||||
super("userhistory", "View an objects history", "<user> [page]", Permission.LOG_USER_HISTORY, Predicate.notInRange(1, 2));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+23
-1
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.migration.subcommands;
|
||||
|
||||
import de.bananaco.bpermissions.api.*;
|
||||
@@ -60,7 +82,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
public MigrationBPermissions() {
|
||||
super("bpermissions", "Migration from bPermissions", "/%s migration bpermissions", MIGRATION, Predicate.alwaysFalse());
|
||||
super("bpermissions", "Migration from bPermissions", "", MIGRATION, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-2
@@ -43,8 +43,7 @@ import java.util.Map;
|
||||
*/
|
||||
public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
public MigrationBungeePerms() {
|
||||
super("bungeeperms", "Migration from BungeePerms", "/%s migration bungeeperms",
|
||||
Permission.MIGRATION, Predicate.alwaysFalse());
|
||||
super("bungeeperms", "Migration from BungeePerms", "", Permission.MIGRATION, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -45,8 +45,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class MigrationGroupManager extends SubCommand<Object> {
|
||||
public MigrationGroupManager() {
|
||||
super("groupmanager", "Migration from GroupManager", "/%s migration groupmanager [world names]",
|
||||
Permission.MIGRATION, Predicate.is(0));
|
||||
super("groupmanager", "Migration from GroupManager", "[world names...]", Permission.MIGRATION, Predicate.is(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,6 +122,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getDatastore().saveGroup(group);
|
||||
}
|
||||
|
||||
Map<UUID, Map<Map.Entry<String, String>, Boolean>> users = new HashMap<>();
|
||||
|
||||
+5
-6
@@ -50,8 +50,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
public MigrationPermissionsEx() {
|
||||
super("permissionsex", "Migration from PermissionsEx", "/%s migration permissionsex [world names]",
|
||||
Permission.MIGRATION, Predicate.alwaysFalse());
|
||||
super("permissionsex", "Migration from PermissionsEx", "[world names...]", Permission.MIGRATION, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@@ -118,7 +117,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
for (String node : group.getOwnPermissions(null)) {
|
||||
boolean value = true;
|
||||
if (node.startsWith("!")) {
|
||||
if (node.startsWith("-")) {
|
||||
node = node.substring(1);
|
||||
value = false;
|
||||
}
|
||||
@@ -143,7 +142,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
for (String world : worlds) {
|
||||
for (String node : group.getOwnPermissions(world)) {
|
||||
boolean value = true;
|
||||
if (node.startsWith("!")) {
|
||||
if (node.startsWith("-")) {
|
||||
node = node.substring(1);
|
||||
value = false;
|
||||
}
|
||||
@@ -262,7 +261,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
try {
|
||||
for (String node : user.getOwnPermissions(null)) {
|
||||
boolean value = true;
|
||||
if (node.startsWith("!")) {
|
||||
if (node.startsWith("-")) {
|
||||
node = node.substring(1);
|
||||
value = false;
|
||||
}
|
||||
@@ -287,7 +286,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
for (String world : worlds) {
|
||||
for (String node : user.getOwnPermissions(world)) {
|
||||
boolean value = true;
|
||||
if (node.startsWith("!")) {
|
||||
if (node.startsWith("-")) {
|
||||
node = node.substring(1);
|
||||
value = false;
|
||||
}
|
||||
|
||||
+256
-182
@@ -23,14 +23,17 @@
|
||||
package me.lucko.luckperms.commands.migration.subcommands;
|
||||
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.*;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import lombok.Cleanup;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.data.Callback;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Predicate;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SubCommand;
|
||||
import me.lucko.luckperms.commands.migration.subcommands.utils.LPResultRunnable;
|
||||
import me.lucko.luckperms.constants.Constants;
|
||||
import me.lucko.luckperms.core.PermissionHolder;
|
||||
import me.lucko.luckperms.data.LogEntry;
|
||||
@@ -45,46 +48,79 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static me.lucko.luckperms.constants.Permission.MIGRATION;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
/* <sadness>
|
||||
The PowerfulPerms API is a complete joke. Seriously, it would probably be easier reflecting into the actual plugin.
|
||||
Methods move about randomly every version...
|
||||
|
||||
What kind of API requires reflection to function with multiple versions...
|
||||
Doesn't that just defeat the whole god damn point of having an API in the first place?
|
||||
Whatever happened to the concept of depreciation and responsible API creation?
|
||||
I tried to keep reflection to a minimum, but in some places there's no other option.
|
||||
This class is a complete fucking mess for that reason. I sad now :(
|
||||
</sadness> */
|
||||
Whatever happened to depreciation?
|
||||
</sadness> */
|
||||
|
||||
private static Method getPlayerPermissionsMethod = null;
|
||||
private static Method getPlayerGroupsMethod = null;
|
||||
private static Method getGroupMethod = null;
|
||||
|
||||
// lol
|
||||
private static boolean superLegacy = false;
|
||||
private static boolean legacy = false;
|
||||
|
||||
static {
|
||||
try {
|
||||
getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerOwnGroups", UUID.class, ResultRunnable.class);
|
||||
getPlayerGroupsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
Class.forName("com.github.cheesesoftware.PowerfulPermsAPI.ResponseRunnable");
|
||||
legacy = true;
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
|
||||
if (legacy) {
|
||||
try {
|
||||
getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerGroups", UUID.class, ResultRunnable.class);
|
||||
getPlayerGroupsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
getPlayerPermissionsMethod = PermissionManager.class.getMethod("getPlayerOwnPermissions", UUID.class, ResultRunnable.class);
|
||||
getPlayerPermissionsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException ignored) {}
|
||||
} else {
|
||||
try {
|
||||
getPlayerPermissionsMethod = PermissionManager.class.getMethod("getPlayerOwnPermissions", UUID.class);
|
||||
getPlayerPermissionsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException ignored) {}
|
||||
}
|
||||
|
||||
try {
|
||||
getGroupMethod = CachedGroup.class.getMethod("getGroup");
|
||||
getGroupMethod.setAccessible(true);
|
||||
legacy = true;
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
superLegacy = true;
|
||||
} catch (NoSuchMethodException ignored) {}
|
||||
|
||||
if (!legacy) {
|
||||
try {
|
||||
getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerOwnGroups", UUID.class);
|
||||
getPlayerGroupsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerOwnGroups", UUID.class, ResultRunnable.class);
|
||||
getPlayerGroupsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
try {
|
||||
getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerGroups", UUID.class, ResultRunnable.class);
|
||||
getPlayerGroupsMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public MigrationPowerfulPerms() {
|
||||
super("powerfulperms", "Migration from PowerfulPerms",
|
||||
"/%s migration powerfulperms <address> <database> <username> <password> <db table>", MIGRATION, Predicate.not(5));
|
||||
super("powerfulperms", "Migration from PowerfulPerms", "<address> <database> <username> <password> <db table>",
|
||||
MIGRATION, Predicate.not(5));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,6 +133,42 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
private static void getPlayerPermissions(PermissionManager manager, UUID uuid, Callback<List<Permission>> callback) {
|
||||
if (legacy) {
|
||||
try {
|
||||
getPlayerPermissionsMethod.invoke(manager, uuid, new LPResultRunnable<List<Permission>>() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onComplete(getResult());
|
||||
}
|
||||
});
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
ListenableFuture<List<Permission>> lf = (ListenableFuture<List<Permission>>) getPlayerPermissionsMethod.invoke(manager, uuid);
|
||||
try {
|
||||
if (lf.isDone()) {
|
||||
callback.onComplete(lf.get());
|
||||
} else {
|
||||
lf.addListener(() -> {
|
||||
try {
|
||||
callback.onComplete(lf.get());
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, Runnable::run);
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CommandResult run(LuckPermsPlugin plugin, List<String> args) {
|
||||
final Logger log = plugin.getLog();
|
||||
if (!plugin.isPluginLoaded("PowerfulPerms")) {
|
||||
@@ -168,7 +240,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
|
||||
// Groups first.
|
||||
log.info("PowerfulPerms Migration: Starting group migration.");
|
||||
Map<Integer, Group> groups = pm.getGroups();
|
||||
Map<Integer, Group> groups = pm.getGroups(); // All versions
|
||||
for (Group g : groups.values()) {
|
||||
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase());
|
||||
final me.lucko.luckperms.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
|
||||
@@ -181,16 +253,16 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
for (Permission p : g.getOwnPermissions()) {
|
||||
for (Permission p : g.getOwnPermissions()) { // All versions
|
||||
applyPerm(group, p, plugin);
|
||||
}
|
||||
|
||||
for (Group parent : g.getParents()) {
|
||||
for (Group parent : g.getParents()) { // All versions
|
||||
try {
|
||||
group.setPermission("group." + parent.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(group).action("setinherit " + parent.getName().toLowerCase())
|
||||
.acted(group).action("setinherit " + parent.getName().toLowerCase()) // All versions
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
@@ -216,156 +288,176 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
User user = plugin.getUserManager().get(uuid);
|
||||
|
||||
// Get a list of Permissions held by the user from the PP API.
|
||||
pm.getPlayerOwnPermissions(uuid, new LPResultRunnable<List<Permission>>() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<Permission> perms = this.getResult();
|
||||
perms.forEach(p -> applyPerm(user, p, plugin));
|
||||
getPlayerPermissions(pm, uuid, perms -> { // Changes each version
|
||||
perms.forEach(p -> applyPerm(user, p, plugin));
|
||||
|
||||
// Update the progress so the user can be saved and unloaded.
|
||||
synchronized (progress) {
|
||||
progress.get(uuid).countDown();
|
||||
if (progress.get(uuid).getCount() == 0) {
|
||||
plugin.getDatastore().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
// Update the progress so the user can be saved and unloaded.
|
||||
synchronized (progress) {
|
||||
progress.get(uuid).countDown();
|
||||
if (progress.get(uuid).getCount() == 0) {
|
||||
plugin.getDatastore().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// Migrate the user's groups to LuckPerms from PP.
|
||||
try {
|
||||
getPlayerGroupsMethod.invoke(pm, uuid, new LPResultRunnable<LinkedHashMap<String, List<CachedGroup>>>() {
|
||||
@Override
|
||||
public void run() {
|
||||
Map<String, List<CachedGroup>> groups = getResult();
|
||||
|
||||
for (Map.Entry<String, List<CachedGroup>> e : groups.entrySet()) {
|
||||
final String server;
|
||||
if (e.getKey() != null && (e.getKey().equals("") || e.getKey().equalsIgnoreCase("all"))) {
|
||||
server = null;
|
||||
} else {
|
||||
server = e.getKey();
|
||||
}
|
||||
|
||||
// This is horrible. So many random API changes through versions, no depreciation.
|
||||
if (legacy) {
|
||||
e.getValue().stream()
|
||||
.filter(cg -> !cg.isNegated())
|
||||
.map(cg -> {
|
||||
try {
|
||||
return (Group) getGroupMethod.invoke(cg);
|
||||
} catch (IllegalAccessException | InvocationTargetException e1) {
|
||||
e1.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.forEach(g -> {
|
||||
if (g != null) {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
e.getValue().stream()
|
||||
.filter(g -> !g.hasExpired() && !g.isNegated())
|
||||
.forEach(g -> {
|
||||
final Group group = pm.getGroup(g.getGroupId());
|
||||
if (g.willExpire()) {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Update the progress so the user can be saved and unloaded.
|
||||
synchronized (progress) {
|
||||
progress.get(uuid).countDown();
|
||||
if (progress.get(uuid).getCount() == 0) {
|
||||
plugin.getDatastore().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
}
|
||||
Callback<Map<String, List<CachedGroup>>> callback = groups1 -> {
|
||||
for (Map.Entry<String, List<CachedGroup>> e : groups1.entrySet()) {
|
||||
final String server;
|
||||
if (e.getKey() != null && (e.getKey().equals("") || e.getKey().equalsIgnoreCase("all"))) {
|
||||
server = null;
|
||||
} else {
|
||||
server = e.getKey();
|
||||
}
|
||||
});
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
log.info("PowerfulPerms Migration: Error");
|
||||
e.printStackTrace();
|
||||
|
||||
if (superLegacy) {
|
||||
e.getValue().stream()
|
||||
.filter(cg -> !cg.isNegated())
|
||||
.map(cg -> {
|
||||
try {
|
||||
return (Group) getGroupMethod.invoke(cg);
|
||||
} catch (IllegalAccessException | InvocationTargetException e1) {
|
||||
e1.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.forEach(g -> {
|
||||
if (g != null) {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + g.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + g.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
e.getValue().stream()
|
||||
.filter(g -> !g.hasExpired() && !g.isNegated())
|
||||
.forEach(g -> {
|
||||
final Group group = pm.getGroup(g.getGroupId());
|
||||
if (g.willExpire()) {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server, g.getExpirationDate().getTime() / 1000L);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (server == null) {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase())
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
user.setPermission("group." + group.getName().toLowerCase(), true, server);
|
||||
LogEntry.build()
|
||||
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
|
||||
.acted(user).action("addgroup " + group.getName().toLowerCase() + " " + server)
|
||||
.build().submit(plugin);
|
||||
} catch (Exception ex) {
|
||||
if (!(ex instanceof ObjectAlreadyHasException)) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Update the progress so the user can be saved and unloaded.
|
||||
synchronized (progress) {
|
||||
progress.get(uuid).countDown();
|
||||
if (progress.get(uuid).getCount() == 0) {
|
||||
plugin.getDatastore().saveUser(user);
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!legacy) {
|
||||
try {
|
||||
ListenableFuture<LinkedHashMap<String, List<CachedGroup>>> future = (ListenableFuture<LinkedHashMap<String, List<CachedGroup>>>) getPlayerGroupsMethod.invoke(pm, uuid);
|
||||
try {
|
||||
if (future.isDone()) {
|
||||
callback.onComplete(future.get());
|
||||
} else {
|
||||
future.addListener(() -> {
|
||||
try {
|
||||
callback.onComplete(future.get());
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, Runnable::run);
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
log.info("PowerfulPerms Migration: Error");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
getPlayerGroupsMethod.invoke(pm, uuid, new LPResultRunnable<LinkedHashMap<String, List<CachedGroup>>>() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onComplete(getResult());
|
||||
}
|
||||
});
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
log.info("PowerfulPerms Migration: Error");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,7 +509,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
long expireAt = 0L;
|
||||
if (!legacy) {
|
||||
if (!superLegacy) {
|
||||
if (p.willExpire()) {
|
||||
expireAt = p.getExpirationDate().getTime() / 1000L;
|
||||
}
|
||||
@@ -508,22 +600,4 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default ResultRunnable, callbacks will always run in the same thread. (an async one, hopefully.)
|
||||
* @param <T> type
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public abstract class LPResultRunnable<T> extends ResultRunnable<T> {
|
||||
|
||||
public LPResultRunnable() {
|
||||
super();
|
||||
super.sameThread = true;
|
||||
}
|
||||
|
||||
public T getResult() {
|
||||
return super.result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -49,8 +49,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class MigrationZPermissions extends SubCommand<Object> {
|
||||
public MigrationZPermissions() {
|
||||
super("zpermissions", "Migration from zPermissions", "/%s migration zpermissions [world names]",
|
||||
Permission.MIGRATION, Predicate.alwaysFalse());
|
||||
super("zpermissions", "Migration from zPermissions", "[world names...]", Permission.MIGRATION, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.migration.subcommands.utils;
|
||||
|
||||
import com.github.cheesesoftware.PowerfulPermsAPI.ResultRunnable;
|
||||
|
||||
/**
|
||||
* Overrides the default ResultRunnable, callbacks will always run in the same thread. (an async one, hopefully.)
|
||||
* @param <T> type
|
||||
*/
|
||||
public abstract class LPResultRunnable<T> extends ResultRunnable<T> {
|
||||
public LPResultRunnable() {
|
||||
super();
|
||||
super.sameThread = true;
|
||||
}
|
||||
|
||||
public T getResult() {
|
||||
return super.result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,6 +38,7 @@ public class DebugCommand extends SingleMainCommand {
|
||||
|
||||
@Override
|
||||
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
|
||||
plugin.getLog().info(sender.getName() + " used the debug command.");
|
||||
Message.DEBUG.send(sender,
|
||||
plugin.getPlayerCount(),
|
||||
plugin.getUserManager().getAll().size(),
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.commands.misc;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.api.Logger;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SingleMainCommand;
|
||||
import me.lucko.luckperms.constants.Constants;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.storage.Datastore;
|
||||
import me.lucko.luckperms.tracks.Track;
|
||||
import me.lucko.luckperms.users.User;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ExportCommand extends SingleMainCommand {
|
||||
public ExportCommand() {
|
||||
super("Export", "/%s export <file>", 1, Permission.MIGRATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
|
||||
final Logger log = plugin.getLog();
|
||||
|
||||
if (!sender.getUuid().equals(Constants.getConsoleUUID())) {
|
||||
Message.MIGRATION_NOT_CONSOLE.send(sender);
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
File f = new File(plugin.getMainDir(), args.get(0));
|
||||
if (f.exists()) {
|
||||
Message.LOG_EXPORT_ALREADY_EXISTS.send(sender, f.getAbsolutePath());
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
try {
|
||||
f.createNewFile();
|
||||
} catch (IOException e) {
|
||||
Message.LOG_EXPORT_FAILURE.send(sender);
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
if (!Files.isWritable(f.toPath())) {
|
||||
Message.LOG_EXPORT_NOT_WRITABLE.send(sender, f.getAbsolutePath());
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
try (FileWriter fWriter = new FileWriter(f, true); BufferedWriter writer = new BufferedWriter(fWriter)) {
|
||||
log.info("Export: Starting export process.");
|
||||
|
||||
// Export Groups
|
||||
log.info("Export: Exporting all groups.");
|
||||
|
||||
// Create the groups first
|
||||
for (Group group : plugin.getGroupManager().getAll().values()) {
|
||||
write(writer, "/luckperms creategroup " + group.getName());
|
||||
}
|
||||
|
||||
int groupCount = 0;
|
||||
for (Group group : plugin.getGroupManager().getAll().values()) {
|
||||
groupCount++;
|
||||
for (Node node : group.getNodes()) {
|
||||
write(writer, nodeToString(node, group.getName(), true));
|
||||
}
|
||||
}
|
||||
log.info("Export: Exported " + groupCount + " groups.");
|
||||
|
||||
// Export tracks
|
||||
log.info("Export: Exporting all tracks.");
|
||||
|
||||
// Create the tracks first
|
||||
for (Track track : plugin.getTrackManager().getAll().values()) {
|
||||
write(writer, "/luckperms createtrack " + track.getName());
|
||||
}
|
||||
|
||||
int trackCount = 0;
|
||||
for (Track track : plugin.getTrackManager().getAll().values()) {
|
||||
trackCount++;
|
||||
for (String group : track.getGroups()) {
|
||||
write(writer, "/luckperms track " + track.getName() + " append " + group);
|
||||
}
|
||||
}
|
||||
log.info("Export: Exported " + trackCount + " tracks.");
|
||||
|
||||
// Export users
|
||||
log.info("Export: Exporting all users. Finding a list of unique users to export.");
|
||||
Datastore ds = plugin.getDatastore();
|
||||
Set<UUID> users = ds.getUniqueUsers();
|
||||
log.info("Export: Found " + users.size() + " unique users to export.");
|
||||
|
||||
int userCount = 0;
|
||||
for (UUID uuid : users) {
|
||||
userCount++;
|
||||
plugin.getDatastore().loadUser(uuid, "null");
|
||||
User user = plugin.getUserManager().get(uuid);
|
||||
|
||||
for (Node node : user.getNodes()) {
|
||||
if (node.isGroupNode() && node.getGroupName().equalsIgnoreCase("default")) {
|
||||
continue;
|
||||
}
|
||||
write(writer, nodeToString(node, user.getUuid().toString(), false));
|
||||
}
|
||||
|
||||
write(writer, "/luckperms user " + user.getUuid().toString() + " setprimarygroup " + user.getPrimaryGroup());
|
||||
plugin.getUserManager().cleanup(user);
|
||||
}
|
||||
log.info("Export: Exported " + userCount + " users.");
|
||||
|
||||
try {
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Message.LOG_EXPORT_SUCCESS.send(sender, f.getAbsolutePath());
|
||||
return CommandResult.SUCCESS;
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAuthorized(Sender sender) {
|
||||
return sender.getUuid().equals(Constants.getConsoleUUID());
|
||||
}
|
||||
|
||||
private static void write(BufferedWriter writer, String s) {
|
||||
try {
|
||||
writer.write(s);
|
||||
writer.newLine();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static String nodeToString(Node node, String id, boolean group) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("/luckperms ").append(group ? "group " : "user ").append(id).append(" ");
|
||||
|
||||
if (node.isGroupNode()) {
|
||||
if (node.isTemporary()) {
|
||||
sb.append(group ? "settempinherit " : "addtempgroup ");
|
||||
sb.append(node.getGroupName());
|
||||
sb.append(" ").append(node.getExpiryUnixTime());
|
||||
} else {
|
||||
sb.append(group ? "setinherit " : "addgroup ");
|
||||
sb.append(node.getGroupName());
|
||||
}
|
||||
|
||||
if (node.isWorldSpecific()) {
|
||||
sb.append(" ").append(node.getServer().get()).append(" ").append(node.getWorld().get());
|
||||
} else if (node.isServerSpecific()) {
|
||||
sb.append(" ").append(node.getServer().get());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
sb.append(node.isTemporary() ? "settemp " : "set ");
|
||||
sb.append(node.getPermission()).append(" ").append(node.getValue());
|
||||
|
||||
if (node.isTemporary()) {
|
||||
sb.append(" ").append(node.getExpiryUnixTime());
|
||||
}
|
||||
|
||||
if (node.isWorldSpecific()) {
|
||||
sb.append(" ").append(node.getServer().get()).append(" ").append(node.getWorld().get());
|
||||
} else if (node.isServerSpecific()) {
|
||||
sb.append(" ").append(node.getServer().get());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,9 +26,9 @@ import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.commands.CommandResult;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
import me.lucko.luckperms.commands.SingleMainCommand;
|
||||
import me.lucko.luckperms.config.LPConfiguration;
|
||||
import me.lucko.luckperms.constants.Message;
|
||||
import me.lucko.luckperms.constants.Permission;
|
||||
import me.lucko.luckperms.core.LPConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -44,14 +44,18 @@ public class InfoCommand extends SingleMainCommand {
|
||||
final LPConfiguration c = plugin.getConfiguration();
|
||||
Message.INFO.send(sender,
|
||||
plugin.getVersion(),
|
||||
plugin.getType().getFriendlyName(),
|
||||
plugin.getDatastore().getName(),
|
||||
c.getServer(),
|
||||
c.getSyncTime(),
|
||||
formatBoolean(c.getIncludeGlobalPerms()),
|
||||
formatBoolean(c.getOnlineMode()),
|
||||
formatBoolean(c.getApplyWildcards()),
|
||||
formatBoolean(c.getApplyRegex()),
|
||||
formatBoolean(c.getApplyShorthand())
|
||||
formatBoolean(c.isIncludingGlobalPerms()),
|
||||
formatBoolean(c.isIncludingGlobalWorldPerms()),
|
||||
formatBoolean(c.isApplyingGlobalGroups()),
|
||||
formatBoolean(c.isApplyingGlobalWorldGroups()),
|
||||
formatBoolean(c.isOnlineMode()),
|
||||
formatBoolean(c.isApplyingWildcards()),
|
||||
formatBoolean(c.isApplyingRegex()),
|
||||
formatBoolean(c.isApplyingShorthand())
|
||||
);
|
||||
|
||||
return CommandResult.SUCCESS;
|
||||
|
||||
@@ -36,8 +36,7 @@ import java.util.List;
|
||||
|
||||
public class TrackAppend extends SubCommand<Track> {
|
||||
public TrackAppend() {
|
||||
super("append", "Appends a group onto the end of the track", "/%s track <track> append <group>",
|
||||
Permission.TRACK_APPEND, Predicate.not(1));
|
||||
super("append", "Appends a group onto the end of the track", "<group>", Permission.TRACK_APPEND, Predicate.not(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,7 +44,7 @@ public class TrackAppend extends SubCommand<Track> {
|
||||
String groupName = args.get(0).toLowerCase();
|
||||
|
||||
if (ArgumentChecker.checkNode(groupName)) {
|
||||
sendUsage(sender, label);
|
||||
sendUsage(sender);
|
||||
return CommandResult.INVALID_ARGS;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,7 @@ import java.util.List;
|
||||
|
||||
public class TrackClear extends SubCommand<Track> {
|
||||
public TrackClear() {
|
||||
super("clear", "Clears the groups on the track", "/%s track <track> clear", Permission.TRACK_CLEAR,
|
||||
Predicate.alwaysFalse());
|
||||
super("clear", "Clears the groups on the track", "", Permission.TRACK_CLEAR, Predicate.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loaded 100 of 190 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user