mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-29 12:37:40 +01:00
Add some PlaceholderAPI placeholders
This commit is contained in:
parent
f9c1cdb4bd
commit
21d0c9ab0e
52
bukkit-placeholders/pom.xml
Normal file
52
bukkit-placeholders/pom.xml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?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.5-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>luckperms-bukkit-placeholders</artifactId>
|
||||||
|
<build>
|
||||||
|
<finalName>LuckPermsPlaceholderExpansion</finalName>
|
||||||
|
<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>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- LuckPerms API -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>me.lucko.luckperms</groupId>
|
||||||
|
<artifactId>luckperms-api</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- BukkitAPI -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bukkit</groupId>
|
||||||
|
<artifactId>bukkit</artifactId>
|
||||||
|
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- PlaceholderAPI -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>me.clip</groupId>
|
||||||
|
<artifactId>placeholderapi</artifactId>
|
||||||
|
<version>2.2.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
* 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.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 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.
|
||||||
|
*
|
||||||
|
* Placeholders:
|
||||||
|
* - group_name
|
||||||
|
* - has_permission_<node>
|
||||||
|
* - inherits_permission_<node>
|
||||||
|
* - in_group_<name>
|
||||||
|
* - inherits_group_<name>
|
||||||
|
* - on_track_<track>
|
||||||
|
* - expiry_time_<node>
|
||||||
|
* - group_expiry_time_<group>
|
||||||
|
* - prefix
|
||||||
|
* - suffix
|
||||||
|
* - meta_<node>
|
||||||
|
*/
|
||||||
|
public class LuckPermsPlaceholderExpansion extends PlaceholderExpansion {
|
||||||
|
private static final String IDENTIFIER = "LuckPerms";
|
||||||
|
private static final String PLUGIN_NAME = "LuckPerms";
|
||||||
|
private static final String AUTHOR = "Luck";
|
||||||
|
|
||||||
|
private LuckPermsApi api = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canRegister() {
|
||||||
|
return Bukkit.getServicesManager().isProvidedFor(LuckPermsApi.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean register() {
|
||||||
|
if (!canRegister()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
api = Bukkit.getServicesManager().getRegistration(LuckPermsApi.class).getProvider();
|
||||||
|
return super.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersion() {
|
||||||
|
return api == null ? "null" : api.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String onPlaceholderRequest(Player player, String identifier) {
|
||||||
|
if (player == null || api == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<User> u = api.getUserSafe(player.getUniqueId());
|
||||||
|
if (!u.isPresent()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
identifier = identifier.toLowerCase();
|
||||||
|
final User user = u.get();
|
||||||
|
|
||||||
|
if (identifier.equalsIgnoreCase("group_name")) {
|
||||||
|
return user.getPrimaryGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (identifier.startsWith("has_permission_") && identifier.length() > "has_permission_".length()) {
|
||||||
|
String node = identifier.substring("has_permission_".length());
|
||||||
|
return formatBoolean(user.hasPermission(node, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (identifier.startsWith("inherits_permission_") && identifier.length() > "inherits_permission_".length()) {
|
||||||
|
String node = identifier.substring("inherits_permission_".length());
|
||||||
|
return formatBoolean(user.inheritsPermission(node, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (identifier.startsWith("in_group_") && identifier.length() > "in_group_".length()) {
|
||||||
|
String groupName = identifier.substring("in_group_".length());
|
||||||
|
return formatBoolean(user.getGroupNames().contains(groupName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (identifier.startsWith("inherits_group_") && identifier.length() > "inherits_group_".length()) {
|
||||||
|
String groupName = identifier.substring("inherits_group_".length());
|
||||||
|
return formatBoolean(user.getLocalGroups("global").contains(groupName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (identifier.startsWith("on_track_") && identifier.length() > "on_track_".length()) {
|
||||||
|
String trackName = identifier.substring("on_track_".length());
|
||||||
|
|
||||||
|
Optional<Track> track = api.getTrackSafe(trackName);
|
||||||
|
if (!track.isPresent()) return "";
|
||||||
|
|
||||||
|
return formatBoolean(track.get().containsGroup(user.getPrimaryGroup()));
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TimeUtil.getTime((int) (e.getValue() - currentTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TimeUtil.getTime((int) (e.getValue() - currentTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (identifier.equalsIgnoreCase("prefix")) {
|
||||||
|
return getChatMeta(PREFIX_PATTERN, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (identifier.equalsIgnoreCase("suffix")) {
|
||||||
|
return getChatMeta(SUFFIX_PATTERN, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return IDENTIFIER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPlugin() {
|
||||||
|
return PLUGIN_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAuthor() {
|
||||||
|
return AUTHOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@ -37,6 +37,7 @@ import java.util.Map;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static me.lucko.luckperms.utils.ArgumentChecker.escapeCharacters;
|
import static me.lucko.luckperms.utils.ArgumentChecker.escapeCharacters;
|
||||||
|
import static me.lucko.luckperms.utils.ArgumentChecker.unescapeCharacters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Vault Chat service through the use of normal permission nodes.
|
* Provides the Vault Chat service through the use of normal permission nodes.
|
||||||
@ -117,7 +118,7 @@ class VaultChatHook extends Chat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Integer.parseInt(parts[2]);
|
return Integer.parseInt(unescapeCharacters(parts[2]));
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
@ -146,7 +147,7 @@ class VaultChatHook extends Chat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Double.parseDouble(parts[2]);
|
return Double.parseDouble(unescapeCharacters(parts[2]));
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
@ -175,7 +176,7 @@ class VaultChatHook extends Chat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Boolean.parseBoolean(parts[2]);
|
return Boolean.parseBoolean(unescapeCharacters(parts[2]));
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
@ -203,7 +204,7 @@ class VaultChatHook extends Chat {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parts[2];
|
return unescapeCharacters(parts[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
@ -228,7 +229,7 @@ class VaultChatHook extends Chat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return meta == null ? "" : meta;
|
return meta == null ? "" : unescapeCharacters(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPlayerPrefix(String world, @NonNull String player) {
|
public String getPlayerPrefix(String world, @NonNull String player) {
|
||||||
|
@ -56,4 +56,12 @@ public class ArgumentChecker {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String unescapeCharacters(String s) {
|
||||||
|
s = s.replace("{SEP}", ".");
|
||||||
|
s = s.replace("{FSEP}", "/");
|
||||||
|
s = s.replace("{DSEP}", "$");
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
5
pom.xml
5
pom.xml
@ -11,6 +11,7 @@
|
|||||||
<module>common</module>
|
<module>common</module>
|
||||||
<module>api</module>
|
<module>api</module>
|
||||||
<module>bukkit</module>
|
<module>bukkit</module>
|
||||||
|
<module>bukkit-placeholders</module>
|
||||||
<module>bungee</module>
|
<module>bungee</module>
|
||||||
<module>sponge</module>
|
<module>sponge</module>
|
||||||
</modules>
|
</modules>
|
||||||
@ -83,5 +84,9 @@
|
|||||||
<id>bungeeperms-repo</id>
|
<id>bungeeperms-repo</id>
|
||||||
<url>http://repo.wea-ondara.net/repository/public/</url>
|
<url>http://repo.wea-ondara.net/repository/public/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>placeholderapi</id>
|
||||||
|
<url>http://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
</project>
|
</project>
|
||||||
|
Loading…
Reference in New Issue
Block a user