Release 2.7

This commit is contained in:
Luck
2016-09-05 20:00:01 +01:00
Unverified
parent ba04fb320b
commit 60bcd5f643
53 changed files with 676 additions and 284 deletions
@@ -46,7 +46,7 @@ class BukkitListener extends AbstractListener implements Listener {
@EventHandler
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent e) {
if (!plugin.getDatastore().isAcceptingLogins()) {
// Datastore is disabled, prevent players from joining the server
// The datastore is disabled, prevent players from joining the server
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.toString());
return;
}
@@ -70,6 +70,11 @@ class BukkitListener extends AbstractListener implements Listener {
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);
} catch (Throwable t) {
t.printStackTrace();
@@ -25,6 +25,7 @@ package me.lucko.luckperms;
import lombok.Getter;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.api.implementation.ApiProvider;
import me.lucko.luckperms.api.vault.VaultHook;
import me.lucko.luckperms.commands.ConsecutiveExecutor;
@@ -161,8 +162,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
}
@Override
public Type getType() {
return Type.BUKKIT;
public PlatformType getType() {
return PlatformType.BUKKIT;
}
@Override
@@ -32,6 +32,7 @@ import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.users.User;
import net.milkbowl.vault.chat.Chat;
import java.util.Iterator;
import java.util.Map;
import static me.lucko.luckperms.utils.ArgumentChecker.escapeCharacters;
@@ -80,108 +81,30 @@ public class VaultChatHook extends Chat {
node = escapeCharacters(node);
value = escapeCharacters(value);
if (world == null || world.equals("")) {
try {
holder.setPermission("meta." + node + "." + value, true);
} catch (ObjectAlreadyHasException ignored) {}
} else {
try {
holder.setPermission("meta." + node + "." + value, true, "global", world);
} catch (ObjectAlreadyHasException ignored) {}
Iterator<Node> nodes = holder.getNodes().iterator();
while (nodes.hasNext()) {
Node n = nodes.next();
if (n.isMeta() && n.getMeta().getKey().equals(node)) {
nodes.remove();
}
}
Node.Builder metaNode = new me.lucko.luckperms.utils.Node.Builder("meta." + node + "." + value).setValue(true);
if (!perms.getServer().equalsIgnoreCase("global")) {
metaNode.setServer(perms.getServer());
}
if (world != null && !world.equals("")) {
metaNode.setServer(perms.getServer()).setWorld(world);
}
try {
holder.setPermission(metaNode.build());
} catch (ObjectAlreadyHasException ignored) {}
perms.objectSave(holder);
}
private static int getMeta(PermissionHolder holder, String world, String node, int defaultValue) {
if (holder == null) return defaultValue;
if (node.equals("")) return defaultValue;
node = escapeCharacters(node);
for (Node n : holder.getPermissions()) {
if (!n.isMeta()) {
continue;
}
if (!n.shouldApplyOnWorld(world, true, false)) {
continue;
}
Map.Entry<String, String> meta = n.getMeta();
if (meta.getKey().equalsIgnoreCase(node)) {
try {
return Integer.parseInt(unescapeCharacters(meta.getValue()));
} catch (Throwable t) {
return defaultValue;
}
}
}
return defaultValue;
}
private static double getMeta(PermissionHolder holder, String world, String node, double defaultValue) {
if (holder == null) return defaultValue;
if (node.equals("")) return defaultValue;
node = escapeCharacters(node);
for (Node n : holder.getPermissions()) {
if (!n.isMeta()) {
continue;
}
if (!n.shouldApplyOnWorld(world, true, false)) {
continue;
}
Map.Entry<String, String> meta = n.getMeta();
if (meta.getKey().equalsIgnoreCase(node)) {
try {
return Double.parseDouble(unescapeCharacters(meta.getValue()));
} catch (Throwable t) {
return defaultValue;
}
}
}
return defaultValue;
}
private static boolean getMeta(PermissionHolder holder, String world, String node, boolean defaultValue) {
if (holder == null) return defaultValue;
if (node.equals("")) return defaultValue;
node = escapeCharacters(node);
for (Node n : holder.getPermissions()) {
if (!n.isMeta()) {
continue;
}
if (!n.shouldApplyOnWorld(world, true, false)) {
continue;
}
Map.Entry<String, String> meta = n.getMeta();
if (meta.getKey().equalsIgnoreCase(node)) {
try {
return Boolean.parseBoolean(unescapeCharacters(meta.getValue()));
} catch (Throwable t) {
return defaultValue;
}
}
}
return defaultValue;
}
private static String getMeta(PermissionHolder holder, String world, String node, String defaultValue) {
private String getMeta(PermissionHolder holder, String world, String node, String defaultValue) {
if (holder == null) return defaultValue;
if (node.equals("")) return defaultValue;
node = escapeCharacters(node);
@@ -195,29 +118,50 @@ public class VaultChatHook extends Chat {
continue;
}
if (!n.shouldApplyOnWorld(world, true, false)) {
if (!perms.getServer().equalsIgnoreCase("global")) {
if (!n.shouldApplyOnServer(perms.getServer(), perms.isIncludeGlobal(), false)) {
continue;
}
}
if (!n.shouldApplyOnWorld(world, perms.isIncludeGlobal(), false)) {
continue;
}
Map.Entry<String, String> meta = n.getMeta();
if (meta.getKey().equalsIgnoreCase(node)) {
try {
return unescapeCharacters(meta.getValue());
} catch (Throwable t) {
return defaultValue;
}
return unescapeCharacters(meta.getValue());
}
}
return defaultValue;
}
private static String getChatMeta(boolean prefix, PermissionHolder holder, String world) {
private void setChatMeta(boolean prefix, PermissionHolder holder, String value, String world) {
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.setValue(true);
if (!perms.getServer().equalsIgnoreCase("global")) {
node.setServer(perms.getServer());
}
if (world != null && !world.equals("")) {
node.setServer(perms.getServer()).setWorld(world);
}
try {
holder.setPermission(node.build());
} catch (ObjectAlreadyHasException ignored) {}
perms.objectSave(holder);
}
private String getChatMeta(boolean prefix, PermissionHolder holder, String world) {
if (holder == null) return "";
int priority = -1000;
int priority = Integer.MIN_VALUE;
String meta = null;
for (Node n : holder.getAllNodes(null)) {
@@ -225,30 +169,24 @@ public class VaultChatHook extends Chat {
continue;
}
if (!n.shouldApplyOnWorld(world, true, false)) {
if (!perms.getServer().equalsIgnoreCase("global")) {
if (!n.shouldApplyOnServer(perms.getServer(), perms.isIncludeGlobal(), false)) {
continue;
}
}
if (!n.shouldApplyOnWorld(world, perms.isIncludeGlobal(), false)) {
continue;
}
if (prefix) {
if (!n.isPrefix()) {
continue;
}
if (prefix ? !n.isPrefix() : !n.isSuffix()) {
continue;
}
Map.Entry<Integer, String> prefixValue = n.getPrefix();
if (prefixValue.getKey() > priority) {
meta = prefixValue.getValue();
priority = prefixValue.getKey();
}
} else {
if (!n.isSuffix()) {
continue;
}
Map.Entry<Integer, String> suffixValue = n.getSuffix();
if (suffixValue.getKey() > priority) {
meta = suffixValue.getValue();
priority = suffixValue.getKey();
}
Map.Entry<Integer, String> value = prefix ? n.getPrefix() : n.getSuffix();
if (value.getKey() > priority) {
meta = value.getValue();
priority = value.getKey();
}
}
@@ -262,15 +200,7 @@ public class VaultChatHook extends Chat {
public void setPlayerPrefix(String world, @NonNull String player, @NonNull String prefix) {
final User user = plugin.getUserManager().get(player);
if (user == null) return;
if (prefix.equals("")) return;
try {
user.setPermission("prefix.1000." + escapeCharacters(prefix), true);
} catch (ObjectAlreadyHasException ignored) {}
perms.objectSave(user);
setChatMeta(true, user, prefix, world);
}
public String getPlayerSuffix(String world, @NonNull String player) {
@@ -280,15 +210,7 @@ public class VaultChatHook extends Chat {
public void setPlayerSuffix(String world, @NonNull String player, @NonNull String suffix) {
final User user = plugin.getUserManager().get(player);
if (user == null) return;
if (suffix.equals("")) return;
try {
user.setPermission("suffix.1000." + escapeCharacters(suffix), true);
} catch (ObjectAlreadyHasException ignored) {}
perms.objectSave(user);
setChatMeta(false, user, suffix, world);
}
public String getGroupPrefix(String world, @NonNull String group) {
@@ -298,15 +220,7 @@ public class VaultChatHook extends Chat {
public void setGroupPrefix(String world, @NonNull String group, @NonNull String prefix) {
final Group g = plugin.getGroupManager().get(group);
if (g == null) return;
if (prefix.equals("")) return;
try {
g.setPermission("prefix.1000." + escapeCharacters(prefix), true);
} catch (ObjectAlreadyHasException ignored) {}
perms.objectSave(g);
setChatMeta(true, g, prefix, world);
}
public String getGroupSuffix(String world, @NonNull String group) {
@@ -316,20 +230,16 @@ public class VaultChatHook extends Chat {
public void setGroupSuffix(String world, @NonNull String group, @NonNull String suffix) {
final Group g = plugin.getGroupManager().get(group);
if (g == null) return;
if (suffix.equals("")) return;
try {
g.setPermission("suffix.1000." + escapeCharacters(suffix), true);
} catch (ObjectAlreadyHasException ignored) {}
perms.objectSave(g);
setChatMeta(false, g, suffix, world);
}
public int getPlayerInfoInteger(String world, @NonNull String player, @NonNull String node, int defaultValue) {
final User user = plugin.getUserManager().get(player);
return getMeta(user, world, node, defaultValue);
try {
return Integer.parseInt(getMeta(user, world, node, String.valueOf(defaultValue)));
} catch (NumberFormatException e) {
return defaultValue;
}
}
public void setPlayerInfoInteger(String world, @NonNull String player, @NonNull String node, int value) {
@@ -339,7 +249,11 @@ public class VaultChatHook extends Chat {
public int getGroupInfoInteger(String world, @NonNull String group, @NonNull String node, int defaultValue) {
final Group g = plugin.getGroupManager().get(group);
return getMeta(g, world, node, defaultValue);
try {
return Integer.parseInt(getMeta(g, world, node, String.valueOf(defaultValue)));
} catch (NumberFormatException e) {
return defaultValue;
}
}
public void setGroupInfoInteger(String world, @NonNull String group, @NonNull String node, int value) {
@@ -349,7 +263,11 @@ public class VaultChatHook extends Chat {
public double getPlayerInfoDouble(String world, @NonNull String player, @NonNull String node, double defaultValue) {
final User user = plugin.getUserManager().get(player);
return getMeta(user, world, node, defaultValue);
try {
return Double.parseDouble(getMeta(user, world, node, String.valueOf(defaultValue)));
} catch (NumberFormatException e) {
return defaultValue;
}
}
public void setPlayerInfoDouble(String world, @NonNull String player, @NonNull String node, double value) {
@@ -359,7 +277,11 @@ public class VaultChatHook extends Chat {
public double getGroupInfoDouble(String world, @NonNull String group, @NonNull String node, double defaultValue) {
final Group g = plugin.getGroupManager().get(group);
return getMeta(g, world, node, defaultValue);
try {
return Double.parseDouble(getMeta(g, world, node, String.valueOf(defaultValue)));
} catch (NumberFormatException e) {
return defaultValue;
}
}
public void setGroupInfoDouble(String world, @NonNull String group, @NonNull String node, double value) {
@@ -369,7 +291,11 @@ public class VaultChatHook extends Chat {
public boolean getPlayerInfoBoolean(String world, @NonNull String player, @NonNull String node, boolean defaultValue) {
final User user = plugin.getUserManager().get(player);
return getMeta(user, world, node, defaultValue);
String s = getMeta(user, world, node, String.valueOf(defaultValue));
if (!s.equalsIgnoreCase("true") && !s.equalsIgnoreCase("false")) {
return defaultValue;
}
return Boolean.parseBoolean(s);
}
public void setPlayerInfoBoolean(String world, @NonNull String player, @NonNull String node, boolean value) {
@@ -379,7 +305,11 @@ public class VaultChatHook extends Chat {
public boolean getGroupInfoBoolean(String world, @NonNull String group, @NonNull String node, boolean defaultValue) {
final Group g = plugin.getGroupManager().get(group);
return getMeta(g, world, node, defaultValue);
String s = getMeta(g, world, node, String.valueOf(defaultValue));
if (!s.equalsIgnoreCase("true") && !s.equalsIgnoreCase("false")) {
return defaultValue;
}
return Boolean.parseBoolean(s);
}
public void setGroupInfoBoolean(String world, @NonNull String group, @NonNull String node, boolean value) {
@@ -39,6 +39,8 @@ public class VaultHook {
permissionHook = new VaultPermissionHook();
}
permissionHook.setPlugin(plugin);
permissionHook.setServer(plugin.getConfiguration().getVaultServer());
permissionHook.setIncludeGlobal(plugin.getConfiguration().getVaultIncludeGlobal());
if (chatHook == null) {
chatHook = new VaultChatHook(permissionHook);
@@ -22,6 +22,7 @@
package me.lucko.luckperms.api.vault;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import me.lucko.luckperms.LPBukkitPlugin;
@@ -38,6 +39,14 @@ public class VaultPermissionHook extends Permission {
@Setter
private LPBukkitPlugin plugin;
@Getter
@Setter
private String server = "global";
@Getter
@Setter
private boolean includeGlobal = true;
@Override
public String getName() {
return "LuckPerms";
@@ -57,9 +66,9 @@ public class VaultPermissionHook extends Permission {
if (object == null) return false;
if (world != null && !world.equals("")) {
return object.hasPermission(permission, true, "global", world);
return object.hasPermission(permission, true, server, world);
} else {
return object.hasPermission(permission, true);
return object.hasPermission(permission, true, server);
}
}
@@ -68,9 +77,9 @@ public class VaultPermissionHook extends Permission {
try {
if (world != null && !world.equals("")) {
object.setPermission(permission, true, "global", world);
object.setPermission(permission, true, server, world);
} else {
object.setPermission(permission, true);
object.setPermission(permission, true, server);
}
} catch (ObjectAlreadyHasException ignored) {}
@@ -83,9 +92,9 @@ public class VaultPermissionHook extends Permission {
try {
if (world != null && !world.equals("")) {
object.unsetPermission(permission, "global", world);
object.unsetPermission(permission, server, world);
} else {
object.unsetPermission(permission);
object.unsetPermission(permission, server);
}
} catch (ObjectLacksException ignored) {}
@@ -147,7 +156,7 @@ public class VaultPermissionHook extends Permission {
if (group1 == null) return false;
if (world != null && !world.equals("")) {
return user.isInGroup(group1, "global", world);
return user.isInGroup(group1, server, world);
} else {
return user.isInGroup(group1);
}
@@ -163,7 +172,7 @@ public class VaultPermissionHook extends Permission {
try {
if (world != null && !world.equals("")) {
user.addGroup(group, "global", world);
user.addGroup(group, server, world);
} else {
user.addGroup(group);
}
@@ -182,7 +191,7 @@ public class VaultPermissionHook extends Permission {
try {
if (world != null && !world.equals("")) {
user.removeGroup(group, "global", world);
user.removeGroup(group, server, world);
} else {
user.removeGroup(group);
}
@@ -195,7 +204,7 @@ public class VaultPermissionHook extends Permission {
public String[] getPlayerGroups(String world, @NonNull String player) {
final User user = plugin.getUserManager().get(player);
return (user == null) ? new String[0] :
world != null && !world.equals("") ? user.getGroups("global", world, true).toArray(new String[0]) :
world != null && !world.equals("") ? user.getGroups(server, world, includeGlobal).toArray(new String[0]) :
user.getGroupNames().toArray(new String[0]);
}
@@ -84,7 +84,7 @@ public class BukkitUser extends User {
);
try {
// The map in the LP PermissionAttachment is a ConcurrentHashMap. We can modify it's contents async.
// The map in the LP PermissionAttachment is a ConcurrentHashMap. We can modify and iterate over its contents async.
Map<String, Boolean> existing = attachment.getPermissions();
boolean different = false;
+7
View File
@@ -46,6 +46,13 @@ apply-shorthand: true
# If the plugin should send log notifications to users whenever permissions are modified.
log-notify: true
# The name of the server used within Vault operations. If you don't want Vault operations to be server specific, set this
# to "global".
vault-server: global
# If global permissions should be considered when retrieving meta or player groups
vault-include-global: true
# Which storage method the plugin should use.
# Currently supported: mysql, sqlite, h2, json, yaml, mongodb
# Fill out connection info below if you're using MySQL or MongoDB
+6 -2
View File
@@ -1,13 +1,17 @@
name: LuckPerms
author: Luck
version: ${release.version}.${git.closest.tag.commit.count}
description: A permissions plugin
author: Luck
website: https://github.com/lucko/LuckPerms
main: me.lucko.luckperms.LPBukkitPlugin
softdepend: [Vault, PermissionsEx, GroupManager, PowerfulPerms, zPermissions, bPermissions] # For migration
description: A permissions plugin
commands:
luckperms:
description: Manage permissions
aliases: [perms, permissions, lp, p, perm]
permissions:
luckperms.*:
description: Gives access to all LuckPerms commands