From ca8e244dae029cb6952cd234da2b18e8c1cc21bb Mon Sep 17 00:00:00 2001 From: Marc Baloup Date: Sun, 10 Apr 2022 01:11:12 +0200 Subject: [PATCH] Supports for permissions range (like essentials.home.limit.) --- .../lib/core/permissions/PermEntity.java | 45 +++++++++++++++++++ .../lib/core/players/IOffPlayer.java | 41 ++++++++++++++++- .../lib/core/players/IOnlinePlayer.java | 22 +++++++++ 3 files changed, 106 insertions(+), 2 deletions(-) diff --git a/Core/src/main/java/fr/pandacube/lib/core/permissions/PermEntity.java b/Core/src/main/java/fr/pandacube/lib/core/permissions/PermEntity.java index 6d3bba9..39f9267 100644 --- a/Core/src/main/java/fr/pandacube/lib/core/permissions/PermEntity.java +++ b/Core/src/main/java/fr/pandacube/lib/core/permissions/PermEntity.java @@ -3,7 +3,9 @@ package fr.pandacube.lib.core.permissions; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.OptionalLong; import java.util.Set; +import java.util.stream.LongStream; import fr.pandacube.lib.core.chat.ChatUtil.DisplayTreeNode; import fr.pandacube.lib.core.permissions.PermissionsCachedBackendReader.CachedEntity; @@ -91,6 +93,49 @@ public abstract class PermEntity { } + public LongStream getPermissionRangeValues(String permissionPrefix) { + return getPermissionRangeValues(permissionPrefix, null, null); + } + + public LongStream getPermissionRangeValues(String permissionPrefix, String server) { + return getPermissionRangeValues(permissionPrefix, server, null); + } + + public LongStream getPermissionRangeValues(String permissionPrefix, String server, String world) { + String prefixWithEndingDot = permissionPrefix.endsWith(".") ? permissionPrefix : (permissionPrefix + "."); + int prefixLength = prefixWithEndingDot.length(); + return listEffectivePermissions(server, world).entrySet().stream() + .filter(e -> e.getValue()) // permission must be positive + .map(e -> e.getKey()) // keep only the permission node (key), since the value is always true + .filter(p -> p.startsWith(prefixWithEndingDot)) // keep only relevant permissions + .map(p -> p.substring(prefixLength)) // keep only what is after the prefix + .map(suffix -> { // convert to long + try { + return Long.parseLong(suffix); + } + catch (NumberFormatException e) { + return null; + } + }) + .filter(longSuffix -> longSuffix != null) + .mapToLong(longSuffix -> longSuffix) + .sorted(); + } + + + public OptionalLong getPermissionRangeMax(String permissionPrefix) { + return getPermissionRangeMax(permissionPrefix, null, null); + } + + public OptionalLong getPermissionRangeMax(String permissionPrefix, String server) { + return getPermissionRangeMax(permissionPrefix, server, null); + } + + public OptionalLong getPermissionRangeMax(String permissionPrefix, String server, String world) { + return getPermissionRangeValues(permissionPrefix, server, world).max(); + } + + public Boolean hasPermission(String permission) { return hasPermission(permission, null, null); } diff --git a/Core/src/main/java/fr/pandacube/lib/core/players/IOffPlayer.java b/Core/src/main/java/fr/pandacube/lib/core/players/IOffPlayer.java index abe9c0e..d77f7cc 100644 --- a/Core/src/main/java/fr/pandacube/lib/core/players/IOffPlayer.java +++ b/Core/src/main/java/fr/pandacube/lib/core/players/IOffPlayer.java @@ -1,7 +1,9 @@ package fr.pandacube.lib.core.players; import java.util.Calendar; +import java.util.OptionalLong; import java.util.UUID; +import java.util.stream.LongStream; import fr.pandacube.lib.core.chat.ChatColorUtil; import fr.pandacube.lib.core.db.DBException; @@ -158,8 +160,7 @@ public interface IOffPlayer { return online.hasPermission(permission); // at this point, the player is offline - Boolean res = getPermissionUser().hasPermission(permission); - return res != null ? res : false; + return getPermissionUser().hasPermissionOr(permission, null, null, false); } /** @@ -183,6 +184,42 @@ public interface IOffPlayer { return getPermissionUser().hasPermissionExpression(permissionExpression, null, null); } + /** + * Lists all the values for a set of permission indicating an integer in a range. + *

+ * A permission range is used to easily attribute a number to a group or player, + * like the maximum number of homes allowed. For instance, if the player has the permission + * {@code essentials.home.12}, this method would return a stream containing the value 12, + * if the parameter {@code permissionPrefix} is {@code "essentials.home."}. + *

+ * The use of a stream allow the caller to get either the maximum, the minimum, or do any + * other treatment to the values. + * @param permissionPrefix the permission prefix to search for. + * @return a LongStream containing all the values found for the specified permission prefix. + */ + public default LongStream getPermissionRangeValues(String permissionPrefix) { + IOnlinePlayer online = getOnlineInstance(); + + if (online != null) + return online.getPermissionRangeValues(permissionPrefix); + + // at this point, the player is offline + return getPermissionUser().getPermissionRangeValues(permissionPrefix, null, null); + } + + /** + * Returns the maximum value returned by {@link IOffPlayer#getPermissionRangeValues(String)}. + */ + public default OptionalLong getPermissionRangeMax(String permissionPrefix) { + IOnlinePlayer online = getOnlineInstance(); + + if (online != null) + return online.getPermissionRangeMax(permissionPrefix); + + // at this point, the player is offline + return getPermissionUser().getPermissionRangeMax(permissionPrefix, null, null); + } + /** * Tells if the this player is part of the specified group * diff --git a/Core/src/main/java/fr/pandacube/lib/core/players/IOnlinePlayer.java b/Core/src/main/java/fr/pandacube/lib/core/players/IOnlinePlayer.java index 2ef39eb..1aa1d4e 100644 --- a/Core/src/main/java/fr/pandacube/lib/core/players/IOnlinePlayer.java +++ b/Core/src/main/java/fr/pandacube/lib/core/players/IOnlinePlayer.java @@ -1,7 +1,9 @@ package fr.pandacube.lib.core.players; import java.util.Locale; +import java.util.OptionalLong; import java.util.UUID; +import java.util.stream.LongStream; import org.geysermc.floodgate.api.FloodgateApi; import org.geysermc.floodgate.api.player.FloodgatePlayer; @@ -100,6 +102,26 @@ public interface IOnlinePlayer extends IOffPlayer { * or it may result in a {@link StackOverflowError}. */ public abstract boolean hasPermissionExpression(String permission); + + /** + * Lists all the values for a set of permission indicating an integer in a range. + *

+ * A permission range is used to easily attribute a number to a group or player, + * like the maximum number of homes allowed. For instance, if the player has the permission + * {@code essentials.home.12}, this method would return a stream containing the value 12, + * if the parameter {@code permissionPrefix} is {@code "essentials.home."}. + *

+ * The use of a stream allow the caller to get either the maximum, the minimum, or do any + * other treatment to the values. + * @param permissionPrefix the permission prefix to search for. + * @return a LongStream containing all the values found for the specified permission prefix. + */ + public abstract LongStream getPermissionRangeValues(String permissionPrefix); + + /** + * Returns the maximum value returned by {@link IOffPlayer#getPermissionRangeValues(String)}. + */ + public abstract OptionalLong getPermissionRangeMax(String permissionPrefix);