From d2bf9401051945cddfaf712875783ba0aa310271 Mon Sep 17 00:00:00 2001 From: Luck Date: Mon, 3 Jul 2017 16:07:33 +0100 Subject: [PATCH] Add option to use the servers uuid cache/lookup facility (#354) --- .../luckperms/bukkit/LPBukkitPlugin.java | 11 +++++ bukkit/src/main/resources/config.yml | 4 ++ bungee/pom.xml | 8 ++++ .../luckperms/bungee/LPBungeePlugin.java | 15 ++++++ .../bungee/util/RedisBungeeUtil.java | 48 +++++++++++++++++++ bungee/src/main/resources/config.yml | 7 +++ bungee/src/main/resources/plugin.yml | 1 + .../commands/abstraction/MainCommand.java | 2 +- .../commands/impl/group/GroupMainCommand.java | 1 + .../commands/impl/track/TrackMainCommand.java | 1 + .../commands/impl/user/UserMainCommand.java | 23 +++++---- .../luckperms/common/config/ConfigKeys.java | 5 ++ .../common/plugin/LuckPermsPlugin.java | 9 ++++ .../luckperms/sponge/LPSpongePlugin.java | 15 ++++++ sponge/src/main/resources/luckperms.conf | 4 ++ 15 files changed, 145 insertions(+), 9 deletions(-) create mode 100644 bungee/src/main/java/me/lucko/luckperms/bungee/util/RedisBungeeUtil.java diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java index e8935dc94..0068068dd 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java @@ -510,6 +510,17 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { return getServer().getPlayer(uuidCache.getExternalUUID(user.getUuid())); } + @Override + public Optional lookupUuid(String username) { + try { + //noinspection deprecation + return Optional.ofNullable(getServer().getOfflinePlayer(username)).flatMap(p -> Optional.ofNullable(p.getUniqueId())); + } catch (Exception e) { + e.printStackTrace(); + return Optional.empty(); + } + } + @Override public Contexts getContextForUser(User user) { Player player = getPlayer(user); diff --git a/bukkit/src/main/resources/config.yml b/bukkit/src/main/resources/config.yml index e47532b7f..759d6bcf9 100644 --- a/bukkit/src/main/resources/config.yml +++ b/bukkit/src/main/resources/config.yml @@ -66,6 +66,10 @@ apply-global-world-groups: true # forwarding. use-server-uuids: true +# If the servers own UUID cache/lookup facility should be used when there is no record for a player +# in the LuckPerms cache. +use-server-uuid-cache: false + # If the plugin should send log notifications to users whenever permissions are modified. log-notify: true diff --git a/bungee/pom.xml b/bungee/pom.xml index 8f7c994f8..1a93397fe 100644 --- a/bungee/pom.xml +++ b/bungee/pom.xml @@ -110,6 +110,14 @@ ${lombok.version} provided + + + com.imaginarycode.minecraft + RedisBungee + 0.4 + provided + + diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java b/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java index e6e8245cd..13abdb003 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java @@ -32,6 +32,7 @@ import me.lucko.luckperms.api.Logger; import me.lucko.luckperms.api.PlatformType; import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.bungee.messaging.BungeeMessagingService; +import me.lucko.luckperms.bungee.util.RedisBungeeUtil; import me.lucko.luckperms.common.api.ApiHandler; import me.lucko.luckperms.common.api.ApiProvider; import me.lucko.luckperms.common.caching.handlers.CachedStateManager; @@ -80,6 +81,7 @@ import java.io.InputStream; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -305,6 +307,19 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin { return getProxy().getPlayer(uuidCache.getExternalUUID(user.getUuid())); } + @Override + public Optional lookupUuid(String username) { + if (getProxy().getPluginManager().getPlugin("RedisBungee") != null) { + try { + return RedisBungeeUtil.lookupUuid(username); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + return Optional.empty(); + } + @Override public Contexts getContextForUser(User user) { ProxiedPlayer player = getPlayer(user); diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/util/RedisBungeeUtil.java b/bungee/src/main/java/me/lucko/luckperms/bungee/util/RedisBungeeUtil.java new file mode 100644 index 000000000..fae1cf494 --- /dev/null +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/util/RedisBungeeUtil.java @@ -0,0 +1,48 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * 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.bungee.util; + +import lombok.experimental.UtilityClass; + +import com.imaginarycode.minecraft.redisbungee.RedisBungee; + +import java.util.Optional; +import java.util.UUID; + +@UtilityClass +public class RedisBungeeUtil { + + /** + * Looks up a UUID from username via RedisBungee's uuid cache. + * + * @param username the username to lookup + * @return a uuid, if present + */ + public static Optional lookupUuid(String username) { + return Optional.ofNullable(RedisBungee.getApi()).flatMap(a -> Optional.ofNullable(a.getUuidFromName(username, true))); + } + +} diff --git a/bungee/src/main/resources/config.yml b/bungee/src/main/resources/config.yml index 4c362946d..fba444ba7 100644 --- a/bungee/src/main/resources/config.yml +++ b/bungee/src/main/resources/config.yml @@ -66,6 +66,13 @@ apply-global-world-groups: true # forwarding. use-server-uuids: true +# If the servers own UUID cache/lookup facility should be used when there is no record for a player +# in the LuckPerms cache. +# +# Since BungeeCord doesn't maintain it's own UUID cache, when this option is true, LuckPerms will +# try to find a uuid for a username using RedisBungee, if installed. +use-server-uuid-cache: false + # If the plugin should send log notifications to users whenever permissions are modified. log-notify: true diff --git a/bungee/src/main/resources/plugin.yml b/bungee/src/main/resources/plugin.yml index aaa852aaa..5b71869aa 100644 --- a/bungee/src/main/resources/plugin.yml +++ b/bungee/src/main/resources/plugin.yml @@ -3,3 +3,4 @@ version: ${full.version} description: A permissions plugin author: Luck main: me.lucko.luckperms.bungee.LPBungeePlugin +softDepends: ["RedisBungee"] \ No newline at end of file diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/abstraction/MainCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/abstraction/MainCommand.java index 5c4902ac9..4c42c9fb8 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/abstraction/MainCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/abstraction/MainCommand.java @@ -83,7 +83,7 @@ public abstract class MainCommand extends Command { return CommandResult.INVALID_ARGS; } - final String name = args.get(0).toLowerCase(); + final String name = args.get(0); T t = getTarget(name, plugin, sender); if (t != null) { CommandResult result; diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupMainCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupMainCommand.java index 990700ef9..988370c0b 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupMainCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupMainCommand.java @@ -65,6 +65,7 @@ public class GroupMainCommand extends MainCommand { @Override protected Group getTarget(String target, LuckPermsPlugin plugin, Sender sender) { + target = target.toLowerCase(); if (!plugin.getStorage().loadGroup(target).join()) { Message.GROUP_NOT_FOUND.send(sender); return null; diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/track/TrackMainCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/track/TrackMainCommand.java index 1ece09325..a9c6c8bb9 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/track/TrackMainCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/track/TrackMainCommand.java @@ -55,6 +55,7 @@ public class TrackMainCommand extends MainCommand { @Override protected Track getTarget(String target, LuckPermsPlugin plugin, Sender sender) { + target = target.toLowerCase(); if (!plugin.getStorage().loadTrack(target).join()) { Message.TRACK_NOT_FOUND.send(sender); return null; diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserMainCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserMainCommand.java index 8c8a612f8..d0bb3e86c 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserMainCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserMainCommand.java @@ -37,6 +37,7 @@ import me.lucko.luckperms.common.commands.impl.generic.parent.CommandParent; import me.lucko.luckperms.common.commands.impl.generic.permission.CommandPermission; import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.utils.Util; +import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.constants.DataConstraints; import me.lucko.luckperms.common.core.model.User; import me.lucko.luckperms.common.locale.CommandSpec; @@ -66,26 +67,32 @@ public class UserMainCommand extends MainCommand { @Override protected User getTarget(String target, LuckPermsPlugin plugin, Sender sender) { - UUID u = Util.parseUuid(target); + UUID u = Util.parseUuid(target.toLowerCase()); if (u == null) { - if (target.length() <= 16) { - if (!DataConstraints.PLAYER_USERNAME_TEST.test(target)) { - Message.USER_INVALID_ENTRY.send(sender, target); + if (!DataConstraints.PLAYER_USERNAME_TEST.test(target)) { + Message.USER_INVALID_ENTRY.send(sender, target); + return null; + } + + u = plugin.getStorage().getUUID(target.toLowerCase()).join(); + if (u == null) { + if (!plugin.getConfiguration().get(ConfigKeys.USE_SERVER_UUID_CACHE)) { + Message.USER_NOT_FOUND.send(sender); return null; } - u = plugin.getStorage().getUUID(target).join(); + u = plugin.lookupUuid(target).orElse(null); if (u == null) { Message.USER_NOT_FOUND.send(sender); return null; } - } else { - Message.USER_INVALID_ENTRY.send(sender, target); } } String name = plugin.getStorage().getName(u).join(); - if (name == null) name = "null"; + if (name == null) { + name = "null"; + } if (!plugin.getStorage().loadUser(u, name).join()) { Message.LOADING_ERROR.send(sender); diff --git a/common/src/main/java/me/lucko/luckperms/common/config/ConfigKeys.java b/common/src/main/java/me/lucko/luckperms/common/config/ConfigKeys.java index e8e027e69..eaedd8aeb 100644 --- a/common/src/main/java/me/lucko/luckperms/common/config/ConfigKeys.java +++ b/common/src/main/java/me/lucko/luckperms/common/config/ConfigKeys.java @@ -116,6 +116,11 @@ public class ConfigKeys { return c.contains("use-server-uuids") ? c.getBoolean("use-server-uuids", true) : c.getBoolean("online-mode", true); }); + /** + * # If the servers own UUID cache/lookup facility should be used when there is no record for a player in the LuckPerms cache. + */ + public static final ConfigKey USE_SERVER_UUID_CACHE = BooleanKey.of("use-server-uuid-cache", false); + /** * Controls how temporary add commands should behave */ diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java b/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java index d990acf49..3e76de158 100644 --- a/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java @@ -56,6 +56,7 @@ import java.io.InputStream; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.function.Consumer; @@ -285,6 +286,14 @@ public interface LuckPermsPlugin { */ Object getPlayer(User user); + /** + * Lookup a uuid from a username, using the servers internal uuid cache. + * + * @param username the username to lookup + * @return an optional uuid, if found + */ + Optional lookupUuid(String username); + /** * Gets a calculated context instance for the user using the rules of the platform. * diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java index 6e9c15ddb..5c39a41d8 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java @@ -93,6 +93,7 @@ import org.spongepowered.api.event.game.state.GamePostInitializationEvent; import org.spongepowered.api.event.game.state.GamePreInitializationEvent; import org.spongepowered.api.event.game.state.GameStoppingServerEvent; import org.spongepowered.api.plugin.Plugin; +import org.spongepowered.api.profile.GameProfile; import org.spongepowered.api.scheduler.AsynchronousExecutor; import org.spongepowered.api.scheduler.Scheduler; import org.spongepowered.api.scheduler.SpongeExecutorService; @@ -109,9 +110,12 @@ import java.util.AbstractCollection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; @Getter @@ -391,6 +395,17 @@ public class LPSpongePlugin implements LuckPermsPlugin { return game.getServer().getPlayer(uuidCache.getExternalUUID(user.getUuid())).orElse(null); } + @Override + public Optional lookupUuid(String username) { + CompletableFuture fut = game.getServer().getGameProfileManager().get(username); + try { + return Optional.of(fut.get().getUniqueId()); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + return Optional.empty(); + } + } + @Override public Contexts getContextForUser(User user) { Player player = getPlayer(user); diff --git a/sponge/src/main/resources/luckperms.conf b/sponge/src/main/resources/luckperms.conf index 240fff85f..6003d2db5 100644 --- a/sponge/src/main/resources/luckperms.conf +++ b/sponge/src/main/resources/luckperms.conf @@ -65,6 +65,10 @@ apply-global-world-groups=true # forwarding. use-server-uuids=true +# If the servers own UUID cache/lookup facility should be used when there is no record for a player +# in the LuckPerms cache. +use-server-uuid-cache=false + # If the plugin should send log notifications to users whenever permissions are modified. log-notify=true