diff --git a/src/main/java/org/mvplugins/multiverse/core/config/handle/StringPropertyHandle.java b/src/main/java/org/mvplugins/multiverse/core/config/handle/StringPropertyHandle.java index 7a2e9d95d..8b2fb6aab 100644 --- a/src/main/java/org/mvplugins/multiverse/core/config/handle/StringPropertyHandle.java +++ b/src/main/java/org/mvplugins/multiverse/core/config/handle/StringPropertyHandle.java @@ -43,6 +43,7 @@ public Collection getAllPropertyNames() { /** * Get property names that can be modified. ADD and REMOVE actions can only be used on list nodes. + * * @param action The target action * @return The property names modifiable for the action. */ @@ -141,7 +142,7 @@ public Try getProperty(@Nullable String name) { /** * Sets the value of the specified property name. * - * @param name The name of the property. + * @param name The name of the property. * @param value The value to set. * @return A Try indicating success or failure. */ @@ -152,7 +153,7 @@ public Try setProperty(@Nullable String name, @Nullable Object value) { /** * Adds a value to a list property name. * - * @param name The name of the property. + * @param name The name of the property. * @param value The value to add. * @return A Try indicating success or failure. */ @@ -163,7 +164,7 @@ public Try addProperty(@Nullable String name, @Nullable Object value) { /** * Removes a value from a list property name. * - * @param name The name of the property. + * @param name The name of the property. * @param value The value to remove. * @return A Try indicating success or failure. */ @@ -184,9 +185,9 @@ public Try resetProperty(@Nullable String name) { /** * Modifies a property name based on the given action. * - * @param name The name of the property. - * @param value The new value (if applicable). - * @param action The modification action. + * @param name The name of the property. + * @param value The new value (if applicable). + * @param action The modification action. * @return A Try indicating success or failure. */ public Try modifyProperty( @@ -203,59 +204,128 @@ public Try modifyProperty( /** * Sets the property value from a string representation. * - * @param name The name of the property. + * @param name The name of the property. * @param value The string value to set. * @return A Try indicating success or failure. */ public Try setPropertyString(@Nullable String name, @Nullable String value) { + return setPropertyString(Bukkit.getConsoleSender(), name, value); + } + + /** + * Sets the property value from a string representation with a sender context. + * + * @param sender The sender context. + * @param name The name of the property. + * @param value The string value to set. + * @return A Try indicating success or failure. + * + * @since 5.1 + */ + @ApiStatus.AvailableSince("5.1") + public Try setPropertyString(@NotNull CommandSender sender, @Nullable String name, @Nullable String value) { return findNode(name, ValueNode.class) - .flatMap(node -> node.parseFromString(value) + .flatMap(node -> node.parseFromString(sender, value) .flatMap(parsedValue -> handle.set(node, parsedValue))); } /** * Adds a value to a list property using its string representation. * - * @param name The name of the property. + * @param name The name of the property. * @param value The string value to add. * @return A Try indicating success or failure. */ public Try addPropertyString(@Nullable String name, @Nullable String value) { + return addPropertyString(Bukkit.getConsoleSender(), name, value); + } + + /** + * Adds a value to a list property using its string representation with a sender context. + * + * @param sender The sender context. + * @param name The name of the property. + * @param value The string value to add. + * @return A Try indicating success or failure. + * + * @since 5.1 + */ + @ApiStatus.AvailableSince("5.1") + public Try addPropertyString(@NotNull CommandSender sender, @Nullable String name, @Nullable String value) { return findNode(name, ListValueNode.class) - .flatMap(node -> node.parseItemFromString(value) + .flatMap(node -> node.parseItemFromString(sender, value) .flatMap(parsedValue -> handle.add(node, parsedValue))); } /** * Removes a value from a list property using its string representation. * - * @param name The name of the property. + * @param name The name of the property. * @param value The string value to remove. * @return A Try indicating success or failure. */ public Try removePropertyString(@Nullable String name, @Nullable String value) { + return removePropertyString(Bukkit.getConsoleSender(), name, value); + } + + /** + * Removes a value from a list property using its string representation with a sender context. + * + * @param sender The sender context. + * @param name The name of the property. + * @param value The string value to remove. + * @return A Try indicating success or failure. + * + * @since 5.1 + */ + @ApiStatus.AvailableSince("5.1") + public Try removePropertyString(@NotNull CommandSender sender, @Nullable String name, @Nullable String value) { return findNode(name, ListValueNode.class) - .flatMap(node -> node.parseItemFromString(value) + .flatMap(node -> node.parseItemFromString(sender, value) .flatMap(parsedValue -> handle.remove(node, parsedValue))); } /** * Modifies a property using a string value based on the given action. * - * @param name The name of the property. - * @param value The string value (if applicable). - * @param action The modification action. + * @param name The name of the property. + * @param value The string value (if applicable). + * @param action The modification action. * @return A Try indicating success or failure. */ public Try modifyPropertyString( - @Nullable String name, @Nullable String value, @NotNull PropertyModifyAction action) { + @Nullable String name, + @Nullable String value, + @NotNull PropertyModifyAction action + ) { + return modifyPropertyString(Bukkit.getConsoleSender(), name, value, action); + } + + /** + * Modifies a property using a string value based on the given action with a sender context. + * + * @param sender The sender context. + * @param name The name of the property. + * @param value The string value (if applicable). + * @param action The modification action. + * @return A Try indicating success or failure. + * + * @since 5.1 + */ + @ApiStatus.AvailableSince("5.1") + public Try modifyPropertyString( + @NotNull CommandSender sender, + @Nullable String name, + @Nullable String value, + @NotNull PropertyModifyAction action + ) { if (action.isRequireValue() && (value == null)) { return Try.failure(new IllegalArgumentException("Value is required for PropertyModifyAction: " + action)); } return switch (action) { - case SET -> setPropertyString(name, value); - case ADD -> addPropertyString(name, value); - case REMOVE -> removePropertyString(name, value); + case SET -> setPropertyString(sender, name, value); + case ADD -> addPropertyString(sender, name, value); + case REMOVE -> removePropertyString(sender, name, value); case RESET -> resetProperty(name); default -> Try.failure(new IllegalArgumentException("Unknown action: " + action)); }; @@ -264,9 +334,9 @@ public Try modifyPropertyString( /** * Finds a configuration node by name and type. * - * @param name The name of the node. - * @param type The expected class type of the node. - * @param The type of node. + * @param name The name of the node. + * @param type The expected class type of the node. + * @param The type of node. * @return A Try containing the found node or a failure if not found. */ private Try findNode(@Nullable String name, @NotNull Class type) { diff --git a/src/main/java/org/mvplugins/multiverse/core/config/node/ConfigNode.java b/src/main/java/org/mvplugins/multiverse/core/config/node/ConfigNode.java index 4459404de..30e77df34 100644 --- a/src/main/java/org/mvplugins/multiverse/core/config/node/ConfigNode.java +++ b/src/main/java/org/mvplugins/multiverse/core/config/node/ConfigNode.java @@ -14,6 +14,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.mvplugins.multiverse.core.config.node.functions.SenderNodeStringParser; import org.mvplugins.multiverse.core.config.node.functions.SenderNodeSuggester; import org.mvplugins.multiverse.core.config.node.serializer.DefaultSerializerProvider; import org.mvplugins.multiverse.core.config.node.functions.DefaultStringParserProvider; @@ -152,6 +153,17 @@ protected ConfigNode( return Try.failure(new UnsupportedOperationException("No string parser for type " + type.getName())); } + /** + * {@inheritDoc} + */ + @Override + public @NotNull Try parseFromString(@NotNull CommandSender sender, @Nullable String input) { + if (stringParser != null && stringParser instanceof SenderNodeStringParser senderStringParser) { + return senderStringParser.parse(sender, input, type); + } + return parseFromString(input); + } + /** * {@inheritDoc} */ @@ -320,6 +332,20 @@ protected Builder(@NotNull String path, @NotNull Class type) { return self(); } + /** + * Sets the string parser for this node with sender context. + * + * @param stringParser The string parser for this node. + * @return This builder. + * + * @since 5.1 + */ + @ApiStatus.AvailableSince("5.1") + public @NotNull B stringParser(@NotNull SenderNodeStringParser stringParser) { + this.stringParser = stringParser; + return self(); + } + /** * Sets the serializer for this node. * diff --git a/src/main/java/org/mvplugins/multiverse/core/config/node/ListConfigNode.java b/src/main/java/org/mvplugins/multiverse/core/config/node/ListConfigNode.java index ce520c283..138c2fed6 100644 --- a/src/main/java/org/mvplugins/multiverse/core/config/node/ListConfigNode.java +++ b/src/main/java/org/mvplugins/multiverse/core/config/node/ListConfigNode.java @@ -21,6 +21,7 @@ import org.mvplugins.multiverse.core.config.node.functions.DefaultSuggesterProvider; import org.mvplugins.multiverse.core.config.node.functions.NodeStringParser; import org.mvplugins.multiverse.core.config.node.functions.NodeSuggester; +import org.mvplugins.multiverse.core.config.node.functions.SenderNodeStringParser; import org.mvplugins.multiverse.core.config.node.functions.SenderNodeSuggester; import org.mvplugins.multiverse.core.config.node.serializer.DefaultSerializerProvider; import org.mvplugins.multiverse.core.config.node.serializer.NodeSerializer; @@ -219,6 +220,17 @@ private void setDefaultOnSetValue() { return Try.failure(new UnsupportedOperationException("No item string parser for type " + itemType)); } + /** + * {@inheritDoc} + */ + @Override + public @NotNull Try parseItemFromString(@NotNull CommandSender sender, @Nullable String input) { + if (itemStringParser != null && itemStringParser instanceof SenderNodeStringParser senderStringParser) { + return senderStringParser.parse(sender, input, itemType); + } + return parseItemFromString(input); + } + /** * {@inheritDoc} */ @@ -306,6 +318,20 @@ protected Builder(@NotNull String path, @NotNull Class itemType) { return self(); } + /** + * Sets the string parser for an individual item in the list with sender context. + * + * @param itemStringParser The string parser. + * @return This builder. + * + * @since 5.1 + */ + @ApiStatus.AvailableSince("5.1") + public @NotNull B itemStringParser(@NotNull SenderNodeStringParser itemStringParser) { + this.itemStringParser = itemStringParser; + return self(); + } + /** * Sets the serializer for an individual item in the list. * diff --git a/src/main/java/org/mvplugins/multiverse/core/config/node/ListValueNode.java b/src/main/java/org/mvplugins/multiverse/core/config/node/ListValueNode.java index b540d15c0..cb5d0671f 100644 --- a/src/main/java/org/mvplugins/multiverse/core/config/node/ListValueNode.java +++ b/src/main/java/org/mvplugins/multiverse/core/config/node/ListValueNode.java @@ -44,7 +44,9 @@ public interface ListValueNode extends ValueNode> { * @since 5.1 */ @ApiStatus.AvailableSince("5.1") - @NotNull Collection suggestItem(@NotNull CommandSender sender, @Nullable String input); + default @NotNull Collection suggestItem(@NotNull CommandSender sender, @Nullable String input) { + return suggestItem(input); + } /** * Parses the given string into a value of type {@link I}. Used for property set by user input. @@ -54,6 +56,20 @@ public interface ListValueNode extends ValueNode> { */ @NotNull Try parseItemFromString(@Nullable String input); + /** + * Parses the given string into a value of type {@link I}. Used for property set by user input. + * + * @param sender The sender context. + * @param input The string to parse. + * @return The parsed value, or given exception if parsing failed. + * + * @since 5.1 + */ + @ApiStatus.AvailableSince("5.1") + default @NotNull Try parseItemFromString(@NotNull CommandSender sender, @Nullable String input) { + return parseItemFromString(input); + } + /** * Gets the serializer for this node. * diff --git a/src/main/java/org/mvplugins/multiverse/core/config/node/ValueNode.java b/src/main/java/org/mvplugins/multiverse/core/config/node/ValueNode.java index 7f2245b31..aaf62fa73 100644 --- a/src/main/java/org/mvplugins/multiverse/core/config/node/ValueNode.java +++ b/src/main/java/org/mvplugins/multiverse/core/config/node/ValueNode.java @@ -77,6 +77,21 @@ public interface ValueNode extends Node { */ @NotNull Try parseFromString(@Nullable String input); + /** + * Parses the given string into a value of type {@link T} with context from the sender. + * Used for property set by user input. + * + * @param sender The sender context. + * @param input The string to parse. + * @return The parsed value, or given exception if parsing failed. + * + * @since 5.1 + */ + @ApiStatus.AvailableSince("5.1") + default @NotNull Try parseFromString(@NotNull CommandSender sender, @Nullable String input) { + return parseFromString(input); + } + /** * Gets the serializer for this node. * diff --git a/src/main/java/org/mvplugins/multiverse/core/config/node/functions/NodeSuggester.java b/src/main/java/org/mvplugins/multiverse/core/config/node/functions/NodeSuggester.java index 7a72c15db..9ec8c3371 100644 --- a/src/main/java/org/mvplugins/multiverse/core/config/node/functions/NodeSuggester.java +++ b/src/main/java/org/mvplugins/multiverse/core/config/node/functions/NodeSuggester.java @@ -6,7 +6,8 @@ import org.jetbrains.annotations.Nullable; /** - * A function that suggests possible values for a node value. + * A function that suggests possible values for a node value. These suggestions must be able to be used to parse the + * value from string with {@link NodeStringParser}. */ @FunctionalInterface public interface NodeSuggester { diff --git a/src/main/java/org/mvplugins/multiverse/core/config/node/functions/SenderNodeStringParser.java b/src/main/java/org/mvplugins/multiverse/core/config/node/functions/SenderNodeStringParser.java new file mode 100644 index 000000000..b008dd287 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/core/config/node/functions/SenderNodeStringParser.java @@ -0,0 +1,35 @@ +package org.mvplugins.multiverse.core.config.node.functions; + +import io.vavr.control.Try; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A function that parses a string into a node value object of type {@link T} with contextual information from the sender. + * + * @param The type of the object to parse. + */ +@ApiStatus.AvailableSince("5.1") +public interface SenderNodeStringParser extends NodeStringParser { + /** + * Parses a string into a node value object of type {@link T} with contextual information from the sender. + * This ties in with {@link SenderNodeSuggester} that provides suggestions based on the sender context. + * + * @param sender The sender context. + * @param string The string to parse. + * @param type The type of the object to parse. + * @return The parsed object, or {@link Try.Failure} if the string could not be parsed. + * + * @since 5.1 + */ + @ApiStatus.AvailableSince("5.1") + @NotNull Try parse(@NotNull CommandSender sender, @Nullable String string, @NotNull Class type); + + @Override + default @NotNull Try parse(@Nullable String string, @NotNull Class type) { + return parse(Bukkit.getConsoleSender(), string, type); + } +}