Improve the way Vault lookups for offline players are handled (#1150)

1) The behaviour of online player lookups is unchanged - this only affects offline player data lookups.
2) If a 'offline player' request is made from an async task, it is executed normally. (the data is loaded)
3) If a 'offline player' request that cannot be immediately fulfilled is made from the main server thread, an exception is thrown.

The exception thrown as a result of 3) can be disabled in the config. In this case, the query is performed anyway. The main server thread will block until the request is complete.
This commit is contained in:
Luck 2018-08-11 19:02:57 +01:00
parent 56df15caf8
commit 56c55d71fe
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
6 changed files with 329 additions and 370 deletions

View File

@ -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<String, String> 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();
}

View File

@ -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());
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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.

View File

@ -321,6 +321,11 @@ public final class ConfigKeys {
*/
public static final ConfigKey<Boolean> 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<Boolean> VAULT_UNSAFE_LOOKUPS = BooleanKey.of("vault-unsafe-lookups", false);
/**
* If the vault server option should be used
*/