diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/AbstractVaultChat.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/AbstractVaultChat.java index 1b8b8c33..3aca25a7 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/AbstractVaultChat.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/AbstractVaultChat.java @@ -26,9 +26,7 @@ package me.lucko.luckperms.bukkit.vault; import net.milkbowl.vault.chat.Chat; -import net.milkbowl.vault.permission.Permission; -import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.entity.Player; @@ -60,15 +58,15 @@ public abstract class AbstractVaultChat extends Chat { protected Function worldMappingFunction = Function.identity(); // the permission api instance - private final Permission permissionApi; + private final AbstractVaultPermission permissionApi; - public AbstractVaultChat(Permission permissionApi) { + public AbstractVaultChat(AbstractVaultPermission permissionApi) { super(permissionApi); this.permissionApi = permissionApi; } @Override - public boolean isEnabled() { + public final boolean isEnabled() { // always return true return true; } @@ -130,22 +128,6 @@ public abstract class AbstractVaultChat extends Chat { return def; } - // utility methods for upgrading legacy requests - - private static UUID player(String player) { - if (player == null) { - return null; - } - return player(Bukkit.getPlayerExact(player)); - } - - private static UUID player(OfflinePlayer player) { - if (player == null) { - return null; - } - return player.getUniqueId(); - } - private String world(String world) { return this.worldMappingFunction.apply(world); } @@ -165,547 +147,547 @@ public abstract class AbstractVaultChat extends Chat { } @Override - public String getPlayerPrefix(String world, String player) { + public final String getPlayerPrefix(String world, String player) { Objects.requireNonNull(player, "player"); - return getUserChatPrefix(world(world), player(player)); + return getUserChatPrefix(world(world), this.permissionApi.lookupUuid(player)); } @Override - public String getPlayerPrefix(String world, OfflinePlayer player) { + public final String getPlayerPrefix(String world, OfflinePlayer player) { Objects.requireNonNull(player, "player"); - return getUserChatPrefix(world(world), player(player)); + return getUserChatPrefix(world(world), player.getUniqueId()); } @Override - public String getPlayerPrefix(World world, String player) { + public final String getPlayerPrefix(World world, String player) { Objects.requireNonNull(player, "player"); - return getUserChatPrefix(world(world), player(player)); + return getUserChatPrefix(world(world), this.permissionApi.lookupUuid(player)); } @Override - public String getPlayerPrefix(Player player) { + public final String getPlayerPrefix(Player player) { Objects.requireNonNull(player, "player"); - return getUserChatPrefix(world(player), player(player)); + return getUserChatPrefix(world(player), ((OfflinePlayer) player).getUniqueId()); } @Override - public void setPlayerPrefix(String world, String player, String prefix) { + public final void setPlayerPrefix(String world, String player, String prefix) { Objects.requireNonNull(player, "player"); - setUserChatPrefix(world(world), player(player), prefix); + setUserChatPrefix(world(world), this.permissionApi.lookupUuid(player), prefix); } @Override - public void setPlayerPrefix(String world, OfflinePlayer player, String prefix) { + public final void setPlayerPrefix(String world, OfflinePlayer player, String prefix) { Objects.requireNonNull(player, "player"); - setUserChatPrefix(world(world), player(player), prefix); + setUserChatPrefix(world(world), player.getUniqueId(), prefix); } @Override - public void setPlayerPrefix(World world, String player, String prefix) { + public final void setPlayerPrefix(World world, String player, String prefix) { Objects.requireNonNull(player, "player"); - setUserChatPrefix(world(world), player(player), prefix); + setUserChatPrefix(world(world), this.permissionApi.lookupUuid(player), prefix); } @Override - public void setPlayerPrefix(Player player, String prefix) { + public final void setPlayerPrefix(Player player, String prefix) { Objects.requireNonNull(player, "player"); - setUserChatPrefix(world(player), player(player), prefix); + setUserChatPrefix(world(player), ((OfflinePlayer) player).getUniqueId(), prefix); } @Override - public String getPlayerSuffix(String world, String player) { + public final String getPlayerSuffix(String world, String player) { Objects.requireNonNull(player, "player"); - return getUserChatSuffix(world(world), player(player)); + return getUserChatSuffix(world(world), this.permissionApi.lookupUuid(player)); } @Override - public String getPlayerSuffix(String world, OfflinePlayer player) { + public final String getPlayerSuffix(String world, OfflinePlayer player) { Objects.requireNonNull(player, "player"); - return getUserChatSuffix(world(world), player(player)); + return getUserChatSuffix(world(world), player.getUniqueId()); } @Override - public String getPlayerSuffix(World world, String player) { + public final String getPlayerSuffix(World world, String player) { Objects.requireNonNull(player, "player"); - return getUserChatSuffix(world(world), player(player)); + return getUserChatSuffix(world(world), this.permissionApi.lookupUuid(player)); } @Override - public String getPlayerSuffix(Player player) { + public final String getPlayerSuffix(Player player) { Objects.requireNonNull(player, "player"); - return getUserChatSuffix(world(player), player(player)); + return getUserChatSuffix(world(player), ((OfflinePlayer) player).getUniqueId()); } @Override - public void setPlayerSuffix(String world, String player, String suffix) { + public final void setPlayerSuffix(String world, String player, String suffix) { Objects.requireNonNull(player, "player"); - setUserChatSuffix(world(world), player(player), suffix); + setUserChatSuffix(world(world), this.permissionApi.lookupUuid(player), suffix); } @Override - public void setPlayerSuffix(String world, OfflinePlayer player, String suffix) { + public final void setPlayerSuffix(String world, OfflinePlayer player, String suffix) { Objects.requireNonNull(player, "player"); - setUserChatSuffix(world(world), player(player), suffix); + setUserChatSuffix(world(world), player.getUniqueId(), suffix); } @Override - public void setPlayerSuffix(World world, String player, String suffix) { + public final void setPlayerSuffix(World world, String player, String suffix) { Objects.requireNonNull(player, "player"); - setUserChatSuffix(world(world), player(player), suffix); + setUserChatSuffix(world(world), this.permissionApi.lookupUuid(player), suffix); } @Override - public void setPlayerSuffix(Player player, String suffix) { + public final void setPlayerSuffix(Player player, String suffix) { Objects.requireNonNull(player, "player"); - setUserChatSuffix(world(player), player(player), suffix); + setUserChatSuffix(world(player), ((OfflinePlayer) player).getUniqueId(), suffix); } @Override - public String getGroupPrefix(String world, String group) { + public final String getGroupPrefix(String world, String group) { Objects.requireNonNull(group, "group"); return getGroupChatPrefix(world(world), group); } @Override - public String getGroupPrefix(World world, String group) { + public final String getGroupPrefix(World world, String group) { Objects.requireNonNull(group, "group"); return getGroupChatPrefix(world(world), group); } @Override - public void setGroupPrefix(String world, String group, String prefix) { + public final void setGroupPrefix(String world, String group, String prefix) { Objects.requireNonNull(group, "group"); setGroupChatPrefix(world(world), group, prefix); } @Override - public void setGroupPrefix(World world, String group, String prefix) { + public final void setGroupPrefix(World world, String group, String prefix) { Objects.requireNonNull(group, "group"); setGroupChatPrefix(world(world), group, prefix); } @Override - public String getGroupSuffix(String world, String group) { + public final String getGroupSuffix(String world, String group) { Objects.requireNonNull(group, "group"); return getGroupChatSuffix(world(world), group); } @Override - public String getGroupSuffix(World world, String group) { + public final String getGroupSuffix(World world, String group) { Objects.requireNonNull(group, "group"); return getGroupChatSuffix(world(world), group); } @Override - public void setGroupSuffix(String world, String group, String suffix) { + public final void setGroupSuffix(String world, String group, String suffix) { Objects.requireNonNull(group, "group"); setGroupChatSuffix(world(world), group, suffix); } @Override - public void setGroupSuffix(World world, String group, String suffix) { + public final void setGroupSuffix(World world, String group, String suffix) { Objects.requireNonNull(group, "group"); setGroupChatSuffix(world(world), group, suffix); } @Override - public int getPlayerInfoInteger(String world, OfflinePlayer player, String node, int defaultValue) { + public final int getPlayerInfoInteger(String world, OfflinePlayer player, String node, int defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return intConvert(getUserMeta(world(world), player(player), node), defaultValue); + return intConvert(getUserMeta(world(world), player.getUniqueId(), node), defaultValue); } @Override - public int getPlayerInfoInteger(String world, String player, String node, int defaultValue) { + public final int getPlayerInfoInteger(String world, String player, String node, int defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return intConvert(getUserMeta(world(world), player(player), node), defaultValue); + return intConvert(getUserMeta(world(world), this.permissionApi.lookupUuid(player), node), defaultValue); } @Override - public int getPlayerInfoInteger(World world, String player, String node, int defaultValue) { + public final int getPlayerInfoInteger(World world, String player, String node, int defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return intConvert(getUserMeta(world(world), player(player), node), defaultValue); + return intConvert(getUserMeta(world(world), this.permissionApi.lookupUuid(player), node), defaultValue); } @Override - public int getPlayerInfoInteger(Player player, String node, int defaultValue) { + public final int getPlayerInfoInteger(Player player, String node, int defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return intConvert(getUserMeta(world(player), player(player), node), defaultValue); + return intConvert(getUserMeta(world(player), ((OfflinePlayer) player).getUniqueId(), node), defaultValue); } @Override - public void setPlayerInfoInteger(String world, OfflinePlayer player, String node, int value) { + public final void setPlayerInfoInteger(String world, OfflinePlayer player, String node, int value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), player.getUniqueId(), node, value); } @Override - public void setPlayerInfoInteger(String world, String player, String node, int value) { + public final void setPlayerInfoInteger(String world, String player, String node, int value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), this.permissionApi.lookupUuid(player), node, value); } @Override - public void setPlayerInfoInteger(World world, String player, String node, int value) { + public final void setPlayerInfoInteger(World world, String player, String node, int value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), this.permissionApi.lookupUuid(player), node, value); } @Override - public void setPlayerInfoInteger(Player player, String node, int value) { + public final void setPlayerInfoInteger(Player player, String node, int value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(player), player(player), node, value); + setUserMeta(world(player), ((OfflinePlayer) player).getUniqueId(), node, value); } @Override - public int getGroupInfoInteger(String world, String group, String node, int defaultValue) { + public final int getGroupInfoInteger(String world, String group, String node, int defaultValue) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); return intConvert(getGroupMeta(world(world), group, node), defaultValue); } @Override - public int getGroupInfoInteger(World world, String group, String node, int defaultValue) { + public final int getGroupInfoInteger(World world, String group, String node, int defaultValue) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); return intConvert(getGroupMeta(world(world), group, node), defaultValue); } @Override - public void setGroupInfoInteger(String world, String group, String node, int value) { + public final void setGroupInfoInteger(String world, String group, String node, int value) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); setGroupMeta(world(world), group, node, value); } @Override - public void setGroupInfoInteger(World world, String group, String node, int value) { + public final void setGroupInfoInteger(World world, String group, String node, int value) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); setGroupMeta(world(world), group, node, value); } @Override - public double getPlayerInfoDouble(String world, OfflinePlayer player, String node, double defaultValue) { + public final double getPlayerInfoDouble(String world, OfflinePlayer player, String node, double defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return doubleConvert(getUserMeta(world(world), player(player), node), defaultValue); + return doubleConvert(getUserMeta(world(world), player.getUniqueId(), node), defaultValue); } @Override - public double getPlayerInfoDouble(String world, String player, String node, double defaultValue) { + public final double getPlayerInfoDouble(String world, String player, String node, double defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return doubleConvert(getUserMeta(world(world), player(player), node), defaultValue); + return doubleConvert(getUserMeta(world(world), this.permissionApi.lookupUuid(player), node), defaultValue); } @Override - public double getPlayerInfoDouble(World world, String player, String node, double defaultValue) { + public final double getPlayerInfoDouble(World world, String player, String node, double defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return doubleConvert(getUserMeta(world(world), player(player), node), defaultValue); + return doubleConvert(getUserMeta(world(world), this.permissionApi.lookupUuid(player), node), defaultValue); } @Override - public double getPlayerInfoDouble(Player player, String node, double defaultValue) { + public final double getPlayerInfoDouble(Player player, String node, double defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return doubleConvert(getUserMeta(world(player), player(player), node), defaultValue); + return doubleConvert(getUserMeta(world(player), ((OfflinePlayer) player).getUniqueId(), node), defaultValue); } @Override - public void setPlayerInfoDouble(String world, OfflinePlayer player, String node, double value) { + public final void setPlayerInfoDouble(String world, OfflinePlayer player, String node, double value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), player.getUniqueId(), node, value); } @Override - public void setPlayerInfoDouble(String world, String player, String node, double value) { + public final void setPlayerInfoDouble(String world, String player, String node, double value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), this.permissionApi.lookupUuid(player), node, value); } @Override - public void setPlayerInfoDouble(World world, String player, String node, double value) { + public final void setPlayerInfoDouble(World world, String player, String node, double value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), this.permissionApi.lookupUuid(player), node, value); } @Override - public void setPlayerInfoDouble(Player player, String node, double value) { + public final void setPlayerInfoDouble(Player player, String node, double value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(player), player(player), node, value); + setUserMeta(world(player), ((OfflinePlayer) player).getUniqueId(), node, value); } @Override - public double getGroupInfoDouble(String world, String group, String node, double defaultValue) { + public final double getGroupInfoDouble(String world, String group, String node, double defaultValue) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); return doubleConvert(getGroupMeta(world(world), group, node), defaultValue); } @Override - public double getGroupInfoDouble(World world, String group, String node, double defaultValue) { + public final double getGroupInfoDouble(World world, String group, String node, double defaultValue) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); return doubleConvert(getGroupMeta(world(world), group, node), defaultValue); } @Override - public void setGroupInfoDouble(String world, String group, String node, double value) { + public final void setGroupInfoDouble(String world, String group, String node, double value) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); setGroupMeta(world(world), group, node, value); } @Override - public void setGroupInfoDouble(World world, String group, String node, double value) { + public final void setGroupInfoDouble(World world, String group, String node, double value) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); setGroupMeta(world(world), group, node, value); } @Override - public boolean getPlayerInfoBoolean(String world, OfflinePlayer player, String node, boolean defaultValue) { + public final boolean getPlayerInfoBoolean(String world, OfflinePlayer player, String node, boolean defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return booleanConvert(getUserMeta(world(world), player(player), node), defaultValue); + return booleanConvert(getUserMeta(world(world), player.getUniqueId(), node), defaultValue); } @Override - public boolean getPlayerInfoBoolean(String world, String player, String node, boolean defaultValue) { + public final boolean getPlayerInfoBoolean(String world, String player, String node, boolean defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return booleanConvert(getUserMeta(world(world), player(player), node), defaultValue); + return booleanConvert(getUserMeta(world(world), this.permissionApi.lookupUuid(player), node), defaultValue); } @Override - public boolean getPlayerInfoBoolean(World world, String player, String node, boolean defaultValue) { + public final boolean getPlayerInfoBoolean(World world, String player, String node, boolean defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return booleanConvert(getUserMeta(world(world), player(player), node), defaultValue); + return booleanConvert(getUserMeta(world(world), this.permissionApi.lookupUuid(player), node), defaultValue); } @Override - public boolean getPlayerInfoBoolean(Player player, String node, boolean defaultValue) { + public final boolean getPlayerInfoBoolean(Player player, String node, boolean defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return booleanConvert(getUserMeta(world(player), player(player), node), defaultValue); + return booleanConvert(getUserMeta(world(player), ((OfflinePlayer) player).getUniqueId(), node), defaultValue); } @Override - public void setPlayerInfoBoolean(String world, OfflinePlayer player, String node, boolean value) { + public final void setPlayerInfoBoolean(String world, OfflinePlayer player, String node, boolean value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), player.getUniqueId(), node, value); } @Override - public void setPlayerInfoBoolean(String world, String player, String node, boolean value) { + public final void setPlayerInfoBoolean(String world, String player, String node, boolean value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), this.permissionApi.lookupUuid(player), node, value); } @Override - public void setPlayerInfoBoolean(World world, String player, String node, boolean value) { + public final void setPlayerInfoBoolean(World world, String player, String node, boolean value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), this.permissionApi.lookupUuid(player), node, value); } @Override - public void setPlayerInfoBoolean(Player player, String node, boolean value) { + public final void setPlayerInfoBoolean(Player player, String node, boolean value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(player), player(player), node, value); + setUserMeta(world(player), ((OfflinePlayer) player).getUniqueId(), node, value); } @Override - public boolean getGroupInfoBoolean(String world, String group, String node, boolean defaultValue) { + public final boolean getGroupInfoBoolean(String world, String group, String node, boolean defaultValue) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); return booleanConvert(getGroupMeta(world(world), group, node), defaultValue); } @Override - public boolean getGroupInfoBoolean(World world, String group, String node, boolean defaultValue) { + public final boolean getGroupInfoBoolean(World world, String group, String node, boolean defaultValue) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); return booleanConvert(getGroupMeta(world(world), group, node), defaultValue); } @Override - public void setGroupInfoBoolean(String world, String group, String node, boolean value) { + public final void setGroupInfoBoolean(String world, String group, String node, boolean value) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); setGroupMeta(world(world), group, node, value); } @Override - public void setGroupInfoBoolean(World world, String group, String node, boolean value) { + public final void setGroupInfoBoolean(World world, String group, String node, boolean value) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); setGroupMeta(world(world), group, node, value); } @Override - public String getPlayerInfoString(String world, OfflinePlayer player, String node, String defaultValue) { + public final String getPlayerInfoString(String world, OfflinePlayer player, String node, String defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return strConvert(getUserMeta(world(world), player(player), node), defaultValue); + return strConvert(getUserMeta(world(world), player.getUniqueId(), node), defaultValue); } @Override - public String getPlayerInfoString(String world, String player, String node, String defaultValue) { + public final String getPlayerInfoString(String world, String player, String node, String defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return strConvert(getUserMeta(world(world), player(player), node), defaultValue); + return strConvert(getUserMeta(world(world), this.permissionApi.lookupUuid(player), node), defaultValue); } @Override - public String getPlayerInfoString(World world, String player, String node, String defaultValue) { + public final String getPlayerInfoString(World world, String player, String node, String defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return strConvert(getUserMeta(world(world), player(player), node), defaultValue); + return strConvert(getUserMeta(world(world), this.permissionApi.lookupUuid(player), node), defaultValue); } @Override - public String getPlayerInfoString(Player player, String node, String defaultValue) { + public final String getPlayerInfoString(Player player, String node, String defaultValue) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - return strConvert(getUserMeta(world(player), player(player), node), defaultValue); + return strConvert(getUserMeta(world(player), ((OfflinePlayer) player).getUniqueId(), node), defaultValue); } @Override - public void setPlayerInfoString(String world, OfflinePlayer player, String node, String value) { + public final void setPlayerInfoString(String world, OfflinePlayer player, String node, String value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), player.getUniqueId(), node, value); } @Override - public void setPlayerInfoString(String world, String player, String node, String value) { + public final void setPlayerInfoString(String world, String player, String node, String value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), this.permissionApi.lookupUuid(player), node, value); } @Override - public void setPlayerInfoString(World world, String player, String node, String value) { + public final void setPlayerInfoString(World world, String player, String node, String value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(world), player(player), node, value); + setUserMeta(world(world), this.permissionApi.lookupUuid(player), node, value); } @Override - public void setPlayerInfoString(Player player, String node, String value) { + public final void setPlayerInfoString(Player player, String node, String value) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(node, "node"); - setUserMeta(world(player), player(player), node, value); + setUserMeta(world(player), ((OfflinePlayer) player).getUniqueId(), node, value); } @Override - public String getGroupInfoString(String world, String group, String node, String defaultValue) { + public final String getGroupInfoString(String world, String group, String node, String defaultValue) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); return strConvert(getGroupMeta(world(world), group, node), defaultValue); } @Override - public String getGroupInfoString(World world, String group, String node, String defaultValue) { + public final String getGroupInfoString(World world, String group, String node, String defaultValue) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); return strConvert(getGroupMeta(world(world), group, node), defaultValue); } @Override - public void setGroupInfoString(String world, String group, String node, String value) { + public final void setGroupInfoString(String world, String group, String node, String value) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); setGroupMeta(world(world), group, node, value); } @Override - public void setGroupInfoString(World world, String group, String node, String value) { + public final void setGroupInfoString(World world, String group, String node, String value) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(node, "node"); setGroupMeta(world(world), group, node, value); } @Override - public boolean playerInGroup(String world, OfflinePlayer player, String group) { + public final boolean playerInGroup(String world, OfflinePlayer player, String group) { return this.permissionApi.playerInGroup(world, player, group); } @Override - public boolean playerInGroup(String world, String player, String group) { + public final boolean playerInGroup(String world, String player, String group) { return this.permissionApi.playerInGroup(world, player, group); } @Override - public boolean playerInGroup(World world, String player, String group) { + public final boolean playerInGroup(World world, String player, String group) { return this.permissionApi.playerInGroup(world, player, group); } @Override - public boolean playerInGroup(Player player, String group) { + public final boolean playerInGroup(Player player, String group) { return this.permissionApi.playerInGroup(player, group); } @Override - public String[] getPlayerGroups(String world, OfflinePlayer player) { + public final String[] getPlayerGroups(String world, OfflinePlayer player) { return this.permissionApi.getPlayerGroups(world, player); } @Override - public String[] getPlayerGroups(String world, String player) { + public final String[] getPlayerGroups(String world, String player) { return this.permissionApi.getPlayerGroups(world, player); } @Override - public String[] getPlayerGroups(World world, String player) { + public final String[] getPlayerGroups(World world, String player) { return this.permissionApi.getPlayerGroups(world, player); } @Override - public String[] getPlayerGroups(Player player) { + public final String[] getPlayerGroups(Player player) { return this.permissionApi.getPlayerGroups(player); } @Override - public String getPrimaryGroup(String world, OfflinePlayer player) { + public final String getPrimaryGroup(String world, OfflinePlayer player) { return this.permissionApi.getPrimaryGroup(world, player); } @Override - public String getPrimaryGroup(String world, String player) { + public final String getPrimaryGroup(String world, String player) { return this.permissionApi.getPrimaryGroup(world, player); } @Override - public String getPrimaryGroup(World world, String player) { + public final String getPrimaryGroup(World world, String player) { return this.permissionApi.getPrimaryGroup(world, player); } @Override - public String getPrimaryGroup(Player player) { + public final String getPrimaryGroup(Player player) { return this.permissionApi.getPrimaryGroup(player); } @Override - public String[] getGroups() { + public final String[] getGroups() { return this.permissionApi.getGroups(); } diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/AbstractVaultPermission.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/AbstractVaultPermission.java index b529984c..8e0beac5 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/AbstractVaultPermission.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/AbstractVaultPermission.java @@ -27,7 +27,6 @@ package me.lucko.luckperms.bukkit.vault; import net.milkbowl.vault.permission.Permission; -import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.entity.Player; @@ -64,24 +63,25 @@ public abstract class AbstractVaultPermission extends Permission { } @Override - public boolean isEnabled() { + public final boolean isEnabled() { // always return true return true; } @Override - public boolean hasSuperPermsCompat() { + public final boolean hasSuperPermsCompat() { // always return true return true; } @Override - public boolean hasGroupSupport() { + public final boolean hasGroupSupport() { // always return true return true; } // methods subclasses are expected to implement + public abstract UUID lookupUuid(String player); public abstract boolean userHasPermission(String world, UUID uuid, String permission); public abstract boolean userAddPermission(String world, UUID uuid, String permission); public abstract boolean userRemovePermission(String world, UUID uuid, String permission); @@ -94,22 +94,6 @@ public abstract class AbstractVaultPermission extends Permission { public abstract boolean groupAddPermission(String world, String name, String permission); public abstract boolean groupRemovePermission(String world, String name, String permission); - // utility methods for upgrading legacy requests - - private static UUID player(String player) { - if (player == null) { - return null; - } - return player(Bukkit.getPlayerExact(player)); - } - - private static UUID player(OfflinePlayer player) { - if (player == null) { - return null; - } - return player.getUniqueId(); - } - private String world(String world) { return this.worldMappingFunction.apply(world); } @@ -129,281 +113,281 @@ public abstract class AbstractVaultPermission extends Permission { } @Override - public boolean has(String world, String player, String permission) { + public final boolean has(String world, String player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userHasPermission(world(world), player(player), permission); + return userHasPermission(world(world), lookupUuid(player), permission); } @Override - public boolean has(World world, String player, String permission) { + public final boolean has(World world, String player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userHasPermission(world(world), player(player), permission); + return userHasPermission(world(world), lookupUuid(player), permission); } @Override - public boolean has(Player player, String permission) { + public final boolean has(Player player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userHasPermission(world(player), player(player), permission); + return player.hasPermission(permission); } @Override - public boolean playerHas(String world, String player, String permission) { + public final boolean playerHas(String world, String player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userHasPermission(world(world), player(player), permission); + return userHasPermission(world(world), lookupUuid(player), permission); } @Override - public boolean playerHas(World world, String player, String permission) { + public final boolean playerHas(World world, String player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userHasPermission(world(world), player(player), permission); + return userHasPermission(world(world), lookupUuid(player), permission); } @Override - public boolean playerHas(String world, OfflinePlayer player, String permission) { + public final boolean playerHas(String world, OfflinePlayer player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userHasPermission(world(world), player(player), permission); + return userHasPermission(world(world), player.getUniqueId(), permission); } @Override - public boolean playerHas(Player player, String permission) { + public final boolean playerHas(Player player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userHasPermission(world(player), player(player), permission); + return player.hasPermission(permission); } @Override - public boolean playerAdd(String world, String player, String permission) { + public final boolean playerAdd(String world, String player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userAddPermission(world(world), player(player), permission); + return userAddPermission(world(world), lookupUuid(player), permission); } @Override - public boolean playerAdd(World world, String player, String permission) { + public final boolean playerAdd(World world, String player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userAddPermission(world(world), player(player), permission); + return userAddPermission(world(world), lookupUuid(player), permission); } @Override - public boolean playerAdd(String world, OfflinePlayer player, String permission) { + public final boolean playerAdd(String world, OfflinePlayer player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userAddPermission(world(world), player(player), permission); + return userAddPermission(world(world), player.getUniqueId(), permission); } @Override - public boolean playerAdd(Player player, String permission) { + public final boolean playerAdd(Player player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userAddPermission(world(player), player(player), permission); + return userAddPermission(world(player), ((OfflinePlayer) player).getUniqueId(), permission); } @Override - public boolean playerRemove(String world, String player, String permission) { + public final boolean playerRemove(String world, String player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userRemovePermission(world(world), player(player), permission); + return userRemovePermission(world(world), lookupUuid(player), permission); } @Override - public boolean playerRemove(String world, OfflinePlayer player, String permission) { + public final boolean playerRemove(String world, OfflinePlayer player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userRemovePermission(world(world), player(player), permission); + return userRemovePermission(world(world), player.getUniqueId(), permission); } @Override - public boolean playerRemove(World world, String player, String permission) { + public final boolean playerRemove(World world, String player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userRemovePermission(world(world), player(player), permission); + return userRemovePermission(world(world), lookupUuid(player), permission); } @Override - public boolean playerRemove(Player player, String permission) { + public final boolean playerRemove(Player player, String permission) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(permission, "permission"); - return userRemovePermission(world(player), player(player), permission); + return userRemovePermission(world(player), ((OfflinePlayer) player).getUniqueId(), permission); } @Override - public boolean groupHas(String world, String group, String permission) { + public final boolean groupHas(String world, String group, String permission) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(permission, "permission"); return groupHasPermission(world(world), group, permission); } @Override - public boolean groupHas(World world, String group, String permission) { + public final boolean groupHas(World world, String group, String permission) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(permission, "permission"); return groupHasPermission(world(world), group, permission); } @Override - public boolean groupAdd(String world, String group, String permission) { + public final boolean groupAdd(String world, String group, String permission) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(permission, "permission"); return groupAddPermission(world(world), group, permission); } @Override - public boolean groupAdd(World world, String group, String permission) { + public final boolean groupAdd(World world, String group, String permission) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(permission, "permission"); return groupAddPermission(world(world), group, permission); } @Override - public boolean groupRemove(String world, String group, String permission) { + public final boolean groupRemove(String world, String group, String permission) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(permission, "permission"); return groupRemovePermission(world(world), group, permission); } @Override - public boolean groupRemove(World world, String group, String permission) { + public final boolean groupRemove(World world, String group, String permission) { Objects.requireNonNull(group, "group"); Objects.requireNonNull(permission, "permission"); return groupRemovePermission(world(world), group, permission); } @Override - public boolean playerInGroup(String world, String player, String group) { + public final boolean playerInGroup(String world, String player, String group) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(group, "group"); - return userInGroup(world(world), player(player), group); + return userInGroup(world(world), lookupUuid(player), group); } @Override - public boolean playerInGroup(World world, String player, String group) { + public final boolean playerInGroup(World world, String player, String group) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(group, "group"); - return userInGroup(world(world), player(player), group); + return userInGroup(world(world), lookupUuid(player), group); } @Override - public boolean playerInGroup(String world, OfflinePlayer player, String group) { + public final boolean playerInGroup(String world, OfflinePlayer player, String group) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(group, "group"); - return userInGroup(world(world), player(player), group); + return userInGroup(world(world), player.getUniqueId(), group); } @Override - public boolean playerInGroup(Player player, String group) { + public final boolean playerInGroup(Player player, String group) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(group, "group"); - return userInGroup(world(player), player(player), group); + return userInGroup(world(player), ((OfflinePlayer) player).getUniqueId(), group); } @Override - public boolean playerAddGroup(String world, String player, String group) { + public final boolean playerAddGroup(String world, String player, String group) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(group, "group"); - return userAddGroup(world(world), player(player), group); + return userAddGroup(world(world), lookupUuid(player), group); } @Override - public boolean playerAddGroup(World world, String player, String group) { + public final boolean playerAddGroup(World world, String player, String group) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(group, "group"); - return userAddGroup(world(world), player(player), group); + return userAddGroup(world(world), lookupUuid(player), group); } @Override - public boolean playerAddGroup(String world, OfflinePlayer player, String group) { + public final boolean playerAddGroup(String world, OfflinePlayer player, String group) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(group, "group"); - return userAddGroup(world(world), player(player), group); + return userAddGroup(world(world), player.getUniqueId(), group); } @Override - public boolean playerAddGroup(Player player, String group) { + public final boolean playerAddGroup(Player player, String group) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(group, "group"); - return userAddGroup(world(player), player(player), group); + return userAddGroup(world(player), ((OfflinePlayer) player).getUniqueId(), group); } @Override - public boolean playerRemoveGroup(String world, String player, String group) { + public final boolean playerRemoveGroup(String world, String player, String group) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(group, "group"); - return userRemoveGroup(world(world), player(player), group); + return userRemoveGroup(world(world), lookupUuid(player), group); } @Override - public boolean playerRemoveGroup(World world, String player, String group) { + public final boolean playerRemoveGroup(World world, String player, String group) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(group, "group"); - return userRemoveGroup(world(world), player(player), group); + return userRemoveGroup(world(world), lookupUuid(player), group); } @Override - public boolean playerRemoveGroup(String world, OfflinePlayer player, String group) { + public final boolean playerRemoveGroup(String world, OfflinePlayer player, String group) { Objects.requireNonNull(player, "player"); Objects.requireNonNull(group, "group"); - return userRemoveGroup(world(world), player(player), group); + return userRemoveGroup(world(world), player.getUniqueId(), group); } @Override - public boolean playerRemoveGroup(Player player, String group) { + public final boolean playerRemoveGroup(Player player, String group) { Objects.requireNonNull(player, "player"); - return userRemoveGroup(world(player), player(player), group); + return userRemoveGroup(world(player), ((OfflinePlayer) player).getUniqueId(), group); } @Override - public String[] getPlayerGroups(String world, String player) { + public final String[] getPlayerGroups(String world, String player) { Objects.requireNonNull(player, "player"); - return userGetGroups(world(world), player(player)); + return userGetGroups(world(world), lookupUuid(player)); } @Override - public String[] getPlayerGroups(World world, String player) { + public final String[] getPlayerGroups(World world, String player) { Objects.requireNonNull(player, "player"); - return userGetGroups(world(world), player(player)); + return userGetGroups(world(world), lookupUuid(player)); } @Override - public String[] getPlayerGroups(String world, OfflinePlayer player) { + public final String[] getPlayerGroups(String world, OfflinePlayer player) { Objects.requireNonNull(player, "player"); - return userGetGroups(world(world), player(player)); + return userGetGroups(world(world), player.getUniqueId()); } @Override - public String[] getPlayerGroups(Player player) { + public final String[] getPlayerGroups(Player player) { Objects.requireNonNull(player, "player"); - return userGetGroups(world(player), player(player)); + return userGetGroups(world(player), ((OfflinePlayer) player).getUniqueId()); } @Override - public String getPrimaryGroup(String world, String player) { + public final String getPrimaryGroup(String world, String player) { Objects.requireNonNull(player, "player"); - return userGetPrimaryGroup(world(world), player(player)); + return userGetPrimaryGroup(world(world), lookupUuid(player)); } @Override - public String getPrimaryGroup(World world, String player) { + public final String getPrimaryGroup(World world, String player) { Objects.requireNonNull(player, "player"); - return userGetPrimaryGroup(world(world), player(player)); + return userGetPrimaryGroup(world(world), lookupUuid(player)); } @Override - public String getPrimaryGroup(String world, OfflinePlayer player) { + public final String getPrimaryGroup(String world, OfflinePlayer player) { Objects.requireNonNull(player, "player"); - return userGetPrimaryGroup(world(world), player(player)); + return userGetPrimaryGroup(world(world), player.getUniqueId()); } @Override - public String getPrimaryGroup(Player player) { + public final String getPrimaryGroup(Player player) { Objects.requireNonNull(player, "player"); - return userGetPrimaryGroup(world(player), player(player)); + return userGetPrimaryGroup(world(player), ((OfflinePlayer) player).getUniqueId()); } } diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java index eef205c7..3f88b2c3 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java @@ -56,13 +56,10 @@ import java.util.UUID; * time to execute. (database queries, re-population of caches, etc) In these cases, the * methods will return immediately and the change will be executed asynchronously. * - * Users of the Vault API expect these methods to be "main thread friendly", so unfortunately, - * we have to favour so called "performance" for consistency. The Vault API really wasn't designed - * with database backed permission plugins in mind. :( - * - * The methods which query offline players will explicitly FAIL if the corresponding player is not online. - * We cannot risk blocking the main thread to load in their data. Again, this is due to crap Vault - * design. There is nothing I can do about it. + * Methods that have to query data from the database will throw exceptions when called + * from the main thread. Users of the Vault API expect these methods to be "main thread friendly", + * which they simply cannot be, as LP utilises databases for data storage. Server admins + * willing to take the risk of lagging their server can disable these exceptions in the config file. */ public class VaultChatHook extends AbstractVaultChat { @@ -86,13 +83,9 @@ public class VaultChatHook extends AbstractVaultChat { @Override public String getUserChatPrefix(String world, UUID uuid) { - if (uuid == null) { - return null; - } - User user = getUser(uuid); - if (user == null) { - return null; - } + Objects.requireNonNull(uuid, "uuid"); + + User user = this.permissionHook.lookupUser(uuid); Contexts contexts = this.permissionHook.contextForLookup(user, world); MetaCache metaData = user.getCachedData().getMetaData(contexts); String ret = metaData.getPrefix(); @@ -104,13 +97,9 @@ public class VaultChatHook extends AbstractVaultChat { @Override public String getUserChatSuffix(String world, UUID uuid) { - if (uuid == null) { - return null; - } - User user = getUser(uuid); - if (user == null) { - return null; - } + Objects.requireNonNull(uuid, "uuid"); + + User user = this.permissionHook.lookupUser(uuid); Contexts contexts = this.permissionHook.contextForLookup(user, world); MetaCache metaData = user.getCachedData().getMetaData(contexts); String ret = metaData.getSuffix(); @@ -122,38 +111,26 @@ public class VaultChatHook extends AbstractVaultChat { @Override public void setUserChatPrefix(String world, UUID uuid, String prefix) { - if (uuid == null) { - return; - } - User user = getUser(uuid); - if (user == null) { - return; - } + Objects.requireNonNull(uuid, "uuid"); + + User user = this.permissionHook.lookupUser(uuid); setChatMeta(user, ChatMetaType.PREFIX, prefix, world); } @Override public void setUserChatSuffix(String world, UUID uuid, String suffix) { - if (uuid == null) { - return; - } - User user = getUser(uuid); - if (user == null) { - return; - } + Objects.requireNonNull(uuid, "uuid"); + + User user = this.permissionHook.lookupUser(uuid); setChatMeta(user, ChatMetaType.SUFFIX, suffix, world); } @Override public String getUserMeta(String world, UUID uuid, String key) { - if (uuid == null) { - return null; - } + Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(key, "key"); - User user = getUser(uuid); - if (user == null) { - return null; - } + + User user = this.permissionHook.lookupUser(uuid); Contexts contexts = this.permissionHook.contextForLookup(user, world); MetaCache metaData = user.getCachedData().getMetaData(contexts); String ret = metaData.getMeta().get(key); @@ -165,14 +142,10 @@ public class VaultChatHook extends AbstractVaultChat { @Override public void setUserMeta(String world, UUID uuid, String key, Object value) { - if (uuid == null) { - return; - } + Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(key, "key"); - User user = getUser(uuid); - if (user == null) { - return; - } + + User user = this.permissionHook.lookupUser(uuid); setMeta(user, key, value, world); } @@ -258,10 +231,6 @@ public class VaultChatHook extends AbstractVaultChat { // utility methods for getting user and group instances - private User getUser(UUID uuid) { - return this.plugin.getUserManager().getIfLoaded(uuid); - } - private Group getGroup(String name) { return this.plugin.getGroupManager().getByDisplayName(name); } diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java index 344a1a4f..95e76b6d 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java @@ -44,6 +44,7 @@ import me.lucko.luckperms.common.verbose.CheckOrigin; import net.milkbowl.vault.permission.Permission; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import java.util.Arrays; @@ -62,13 +63,10 @@ import java.util.concurrent.Executors; * time to execute. (database queries, re-population of caches, etc) In these cases, the * methods will return immediately and the change will be executed asynchronously. * - * Users of the Vault API expect these methods to be "main thread friendly", so unfortunately, - * we have to favour so called "performance" for consistency. The Vault API really wasn't designed - * with database backed permission plugins in mind. :( - * - * The methods which query offline players will explicitly FAIL if the corresponding player is not online. - * We cannot risk blocking the main thread to load in their data. Again, this is due to crap Vault - * design. There is nothing I can do about it. + * Methods that have to query data from the database will throw exceptions when called + * from the main thread. Users of the Vault API expect these methods to be "main thread friendly", + * which they simply cannot be, as LP utilises databases for data storage. Server admins + * willing to take the risk of lagging their server can disable these exceptions in the config file. */ public class VaultPermissionHook extends AbstractVaultPermission { @@ -97,16 +95,66 @@ public class VaultPermissionHook extends AbstractVaultPermission { return "LuckPerms"; } - // override this check to delegate to Player#hasPermission @Override - public boolean has(Player player, String permission) { - return player.hasPermission(permission); + public UUID lookupUuid(String player) { + Objects.requireNonNull(player, "player"); + + // are they online? + Player onlinePlayer = Bukkit.getPlayerExact(player); + if (onlinePlayer != null) { + return onlinePlayer.getUniqueId(); + } + + // are we on the main thread? + if (Bukkit.isPrimaryThread() && !this.plugin.getConfiguration().get(ConfigKeys.VAULT_UNSAFE_LOOKUPS)) { + throw new RuntimeException( + "Unable to lookup a UUID for '" + player + "'. \n" + + "This request was made on the main server thread. \n" + + "It is not safe to execute a request to load username data from the database in this context. \n" + + "If you are a plugin author, please either make your request asynchronously, \n" + + "or provide an 'OfflinePlayer' object with the UUID already populated. \n" + + "Server admins can disable this catch by setting 'vault-unsafe-lookups' to true in the LP config, \n" + + "but should consider the consequences (lag) before doing so." + ); + } + + // lookup a username from the database + UUID uuid = plugin.getStorage().getPlayerUuid(player.toLowerCase()).join(); + if (uuid == null) { + uuid = plugin.getBootstrap().lookupUuid(player).orElse(null); + } + + // unable to find a user, throw an exception + if (uuid == null) { + throw new IllegalArgumentException("Unable to find a UUID for player '" + player + "'."); + } + + return uuid; } - // override this check to delegate to Player#hasPermission - @Override - public boolean playerHas(Player player, String permission) { - return player.hasPermission(permission); + public User lookupUser(UUID uuid) { + Objects.requireNonNull(uuid, "uuid"); + + // loaded already? + User user = this.plugin.getUserManager().getIfLoaded(uuid); + if (user != null) { + return user; + } + + // are we on the main thread? + if (Bukkit.isPrimaryThread() && !this.plugin.getConfiguration().get(ConfigKeys.VAULT_UNSAFE_LOOKUPS)) { + throw new RuntimeException( + "Unable to obtain user data for '" + uuid + "'. \n" + + "This request was made on the main server thread. \n" + + "It is not safe to execute a request to load user data from the database in this context. \n" + + "If you are a plugin author, please consider making your request asynchronously. \n" + + "Server admins can disable this catch by setting 'vault-unsafe-lookups' to true in the LP config, \n" + + "but should consider the consequences (lag) before doing so." + ); + } + + // load an instance from the DB + return this.plugin.getStorage().loadUser(uuid, null).join(); } @Override @@ -118,16 +166,10 @@ public class VaultPermissionHook extends AbstractVaultPermission { @Override public boolean userHasPermission(String world, UUID uuid, String permission) { - if (uuid == null) { - return false; - } + Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(permission, "permission"); - User user = getUser(uuid); - if (user == null) { - return false; - } - + User user = lookupUser(uuid); Contexts contexts = contextForLookup(user, world); PermissionCache permissionData = user.getCachedData().getPermissionData(contexts); @@ -140,74 +182,50 @@ public class VaultPermissionHook extends AbstractVaultPermission { @Override public boolean userAddPermission(String world, UUID uuid, String permission) { - if (uuid == null) { - return false; - } + Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(permission, "permission"); - User user = getUser(uuid); - if (user == null) { - return false; - } - + User user = lookupUser(uuid); holderAddPermission(user, permission, world); return true; } @Override public boolean userRemovePermission(String world, UUID uuid, String permission) { - if (uuid == null) { - return false; - } + Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(permission, "permission"); - User user = getUser(uuid); - if (user == null) { - return false; - } - + User user = lookupUser(uuid); holderRemovePermission(user, permission, world); return true; } @Override public boolean userInGroup(String world, UUID uuid, String group) { - if (uuid == null) { - return false; - } + Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(group, "group"); return userHasPermission(world, uuid, NodeFactory.groupNode(rewriteGroupName(group))); } @Override public boolean userAddGroup(String world, UUID uuid, String group) { - if (uuid == null) { - return false; - } + Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(group, "group"); return checkGroupExists(group) && userAddPermission(world, uuid, NodeFactory.groupNode(rewriteGroupName(group))); } @Override public boolean userRemoveGroup(String world, UUID uuid, String group) { - if (uuid == null) { - return false; - } + Objects.requireNonNull(uuid, "uuid"); Objects.requireNonNull(group, "group"); return checkGroupExists(group) && userRemovePermission(world, uuid, NodeFactory.groupNode(rewriteGroupName(group))); } @Override public String[] userGetGroups(String world, UUID uuid) { - if (uuid == null) { - return new String[0]; - } - - User user = getUser(uuid); - if (user == null) { - return new String[0]; - } + Objects.requireNonNull(uuid, "uuid"); + User user = lookupUser(uuid); ContextSet contexts = contextForLookup(user, world).getContexts(); String[] ret = user.enduringData().immutable().values().stream() @@ -231,15 +249,9 @@ public class VaultPermissionHook extends AbstractVaultPermission { @Override public String userGetPrimaryGroup(String world, UUID uuid) { - if (uuid == null) { - return null; - } - - User user = getUser(uuid); - if (user == null) { - return null; - } + Objects.requireNonNull(uuid, "uuid"); + User user = lookupUser(uuid); String value = user.getPrimaryGroup().getValue(); Group group = getGroup(value); if (group != null) { @@ -303,10 +315,6 @@ public class VaultPermissionHook extends AbstractVaultPermission { // utility methods for getting user and group instances - private User getUser(UUID uuid) { - return this.plugin.getUserManager().getIfLoaded(uuid); - } - private Group getGroup(String name) { return this.plugin.getGroupManager().getByDisplayName(name); } diff --git a/bukkit/src/main/resources/config.yml b/bukkit/src/main/resources/config.yml index 752c3657..71bc6587 100644 --- a/bukkit/src/main/resources/config.yml +++ b/bukkit/src/main/resources/config.yml @@ -480,6 +480,17 @@ commands-allow-op: true # | Vault integration settings | # # +----------------------------------------------------------------------------------------------+ # +# If Vault lookups for offline players on the main server thread should be enabled. +# +# LuckPerms has a "catch" for plugins attempting to perform unsafe offline player data lookups +# from the main server thread. This catch raises an exception (causes an error to occur) when unsafe +# lookups are made, instead of allowing the lookup to happen, which would likely cause the server +# to lag. +# +# However, if you're willing to accept the consequences, the catch can be disabled by setting this +# option to 'true. +vault-unsafe-lookups: false + # If the vault-server option below should be used. # # - When this option is set to false, the server value defined above under "server" is used. 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 b912f3e9..2af532ef 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 @@ -321,6 +321,11 @@ public final class ConfigKeys { */ public static final ConfigKey COMMANDS_ALLOW_OP = EnduringKey.wrap(BooleanKey.of("commands-allow-op", true)); + /** + * If Vault lookups for offline players on the main server thread should be enabled + */ + public static final ConfigKey VAULT_UNSAFE_LOOKUPS = BooleanKey.of("vault-unsafe-lookups", false); + /** * If the vault server option should be used */