mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2024-11-22 02:25:41 +01:00
Merge pull request #3033 from Multiverse/ben/mv5/list-value-node
Implement ListValueNode and modify actions
This commit is contained in:
commit
0c37c9e934
@ -0,0 +1,77 @@
|
||||
package org.mvplugins.multiverse.core.commands;
|
||||
|
||||
import co.aikar.commands.annotation.CommandAlias;
|
||||
import co.aikar.commands.annotation.CommandCompletion;
|
||||
import co.aikar.commands.annotation.CommandPermission;
|
||||
import co.aikar.commands.annotation.Description;
|
||||
import co.aikar.commands.annotation.Flags;
|
||||
import co.aikar.commands.annotation.Optional;
|
||||
import co.aikar.commands.annotation.Subcommand;
|
||||
import co.aikar.commands.annotation.Syntax;
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import jakarta.inject.Inject;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
import org.mvplugins.multiverse.core.commandtools.MVCommandIssuer;
|
||||
import org.mvplugins.multiverse.core.commandtools.MVCommandManager;
|
||||
import org.mvplugins.multiverse.core.commandtools.MultiverseCommand;
|
||||
import org.mvplugins.multiverse.core.configuration.handle.PropertyModifyAction;
|
||||
import org.mvplugins.multiverse.core.configuration.handle.StringPropertyHandle;
|
||||
import org.mvplugins.multiverse.core.world.MultiverseWorld;
|
||||
import org.mvplugins.multiverse.core.world.WorldManager;
|
||||
|
||||
@Service
|
||||
@CommandAlias("mv")
|
||||
class ModifyCommand extends MultiverseCommand {
|
||||
|
||||
private final WorldManager worldManager;
|
||||
|
||||
@Inject
|
||||
ModifyCommand(@NotNull MVCommandManager commandManager, WorldManager worldManager) {
|
||||
super(commandManager);
|
||||
this.worldManager = worldManager;
|
||||
}
|
||||
|
||||
@Subcommand("modify")
|
||||
@CommandPermission("multiverse.core.modify")
|
||||
@CommandCompletion("@mvworlds:scope=both @propsmodifyaction @mvworldpropsname @mvworldpropsvalue")
|
||||
@Syntax("[world] <set|add|remove|reset> <property> <value>")
|
||||
@Description("")
|
||||
void onModifyCommand(
|
||||
MVCommandIssuer issuer,
|
||||
|
||||
@Flags("resolve=issuerAware")
|
||||
@Syntax("[world]")
|
||||
@Description("")
|
||||
MultiverseWorld world,
|
||||
|
||||
@Syntax("<set|add|remove|reset>")
|
||||
@Description("")
|
||||
PropertyModifyAction action,
|
||||
|
||||
@Syntax("<property>")
|
||||
@Description("")
|
||||
String propertyName,
|
||||
|
||||
@Optional
|
||||
@Syntax("[value]")
|
||||
@Description("")
|
||||
String propertyValue) {
|
||||
StringPropertyHandle worldPropertyHandle = world.getStringPropertyHandle();
|
||||
worldPropertyHandle.modifyProperty(propertyName, propertyValue, action).onSuccess(ignore -> {
|
||||
issuer.sendMessage("Property %s set to %s for world %s.".formatted(
|
||||
propertyName,
|
||||
worldPropertyHandle.getProperty(propertyName).getOrNull(),
|
||||
world.getName()));
|
||||
worldManager.saveWorldsConfig();
|
||||
}).onFailure(exception -> {
|
||||
issuer.sendMessage("Failed to %s property %s to %s for world %s.".formatted(
|
||||
action.name().toLowerCase(),
|
||||
propertyName,
|
||||
propertyValue,
|
||||
world.getName()));
|
||||
issuer.sendMessage(exception.getMessage());
|
||||
});
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
import org.mvplugins.multiverse.core.config.MVCoreConfig;
|
||||
import org.mvplugins.multiverse.core.configuration.handle.PropertyModifyAction;
|
||||
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
|
||||
import org.mvplugins.multiverse.core.destination.ParsedDestination;
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
|
||||
@ -60,9 +61,12 @@ class MVCommandCompletions extends PaperCommandCompletions {
|
||||
registerAsyncCompletion("flags", this::suggestFlags);
|
||||
registerStaticCompletion("gamemodes", suggestEnums(GameMode.class));
|
||||
registerStaticCompletion("gamerules", this::suggestGamerules);
|
||||
registerStaticCompletion("mvconfigs", config.getStringPropertyHandle().getPropertyNames());
|
||||
registerStaticCompletion("mvconfigs", config.getStringPropertyHandle().getAllPropertyNames());
|
||||
registerAsyncCompletion("mvconfigvalues", this::suggestMVConfigValues);
|
||||
registerAsyncCompletion("mvworlds", this::suggestMVWorlds);
|
||||
registerAsyncCompletion("mvworldpropsname", this::suggestMVWorldPropsName);
|
||||
registerAsyncCompletion("mvworldpropsvalue", this::suggestMVWorldPropsValue);
|
||||
registerStaticCompletion("propsmodifyaction", suggestEnums(PropertyModifyAction.class));
|
||||
|
||||
setDefaultCompletion("destinations", ParsedDestination.class);
|
||||
setDefaultCompletion("difficulties", Difficulty.class);
|
||||
@ -124,7 +128,7 @@ class MVCommandCompletions extends PaperCommandCompletions {
|
||||
private Collection<String> suggestMVConfigValues(BukkitCommandCompletionContext context) {
|
||||
return Try.of(() -> context.getContextValue(String.class))
|
||||
.map(propertyName -> config.getStringPropertyHandle()
|
||||
.getPropertySuggestedValues(propertyName, context.getInput()))
|
||||
.getSuggestedPropertyValue(propertyName, context.getInput(), PropertyModifyAction.SET))
|
||||
.getOrElse(Collections.emptyList());
|
||||
}
|
||||
|
||||
@ -172,6 +176,23 @@ class MVCommandCompletions extends PaperCommandCompletions {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private Collection<String> suggestMVWorldPropsName(BukkitCommandCompletionContext context) {
|
||||
return Try.of(() -> {
|
||||
MultiverseWorld world = context.getContextValue(MultiverseWorld.class);
|
||||
PropertyModifyAction action = context.getContextValue(PropertyModifyAction.class);
|
||||
return world.getStringPropertyHandle().getModifiablePropertyNames(action);
|
||||
}).getOrElse(Collections.emptyList());
|
||||
}
|
||||
|
||||
private Collection<String> suggestMVWorldPropsValue(BukkitCommandCompletionContext context) {
|
||||
return Try.of(() -> {
|
||||
MultiverseWorld world = context.getContextValue(MultiverseWorld.class);
|
||||
PropertyModifyAction action = context.getContextValue(PropertyModifyAction.class);
|
||||
String propertyName = context.getContextValue(String.class);
|
||||
return world.getStringPropertyHandle().getSuggestedPropertyValue(propertyName, context.getInput(), action);
|
||||
}).getOrElse(Collections.emptyList());
|
||||
}
|
||||
|
||||
private <T extends Enum<T>> Collection<String> suggestEnums(Class<T> enumClass) {
|
||||
return EnumSet.allOf(enumClass).stream()
|
||||
.map(Enum::name)
|
||||
|
@ -252,7 +252,7 @@ class MVCommandContexts extends PaperCommandContexts {
|
||||
return world;
|
||||
}
|
||||
if (context.getIssuer().isPlayer()) {
|
||||
return worldManager.getLoadedWorld(context.getIssuer().getPlayer().getWorld()).getOrNull();
|
||||
return worldManager.getWorld(context.getIssuer().getPlayer().getWorld()).getOrNull();
|
||||
}
|
||||
if (context.isOptional()) {
|
||||
return null;
|
||||
|
@ -77,7 +77,7 @@ public class CommentedYamlConfigHandle extends FileConfigHandle<CommentedConfigu
|
||||
valueNode.getDefaultValue())).onFailure(e -> {
|
||||
Logging.warning("Failed to set node " + valueNode.getPath()
|
||||
+ " to " + valueNode.getDefaultValue());
|
||||
setDefault(valueNode);
|
||||
reset(valueNode);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.mvplugins.multiverse.core.configuration.handle;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import io.vavr.control.Try;
|
||||
@ -9,6 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import org.mvplugins.multiverse.core.configuration.migration.ConfigMigrator;
|
||||
import org.mvplugins.multiverse.core.configuration.node.ListValueNode;
|
||||
import org.mvplugins.multiverse.core.configuration.node.NodeGroup;
|
||||
import org.mvplugins.multiverse.core.configuration.node.ValueNode;
|
||||
|
||||
@ -105,12 +107,53 @@ public abstract class GenericConfigHandle<C extends ConfigurationSection> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configuration. Mainly used for {@link StringPropertyHandle}.
|
||||
* Adds an item to a list node.
|
||||
*
|
||||
* @return The configuration.
|
||||
* @param node The list node to add the item to.
|
||||
* @param itemValue The value of the item to add.
|
||||
* @param <I> The type of the list item.
|
||||
* @return Empty try if the item was added, try containing an error otherwise.
|
||||
*/
|
||||
@NotNull NodeGroup getNodes() {
|
||||
return nodes;
|
||||
public <I> Try<Void> add(@NotNull ListValueNode<I> node, I itemValue) {
|
||||
return node.validateItem(itemValue).map(ignore -> {
|
||||
var serialized = node.getItemSerializer() != null
|
||||
? node.getItemSerializer().serialize(itemValue, node.getItemType())
|
||||
: itemValue;
|
||||
List valueList = config.getList(node.getPath());
|
||||
if (valueList == null) {
|
||||
throw new IllegalArgumentException("Cannot add item to non-list node");
|
||||
}
|
||||
valueList.add(serialized);
|
||||
config.set(node.getPath(), valueList);
|
||||
node.onSetItemValue(null, itemValue);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an item from a list node.
|
||||
*
|
||||
* @param node The list node to remove the item from.
|
||||
* @param itemValue The value of the item to remove.
|
||||
* @param <I> The type of the list item.
|
||||
* @return Empty try if the item was removed, try containing an error otherwise.
|
||||
*/
|
||||
public <I> Try<Void> remove(@NotNull ListValueNode<I> node, I itemValue) {
|
||||
return node.validateItem(itemValue).map(ignore -> {
|
||||
var serialized = node.getItemSerializer() != null
|
||||
? node.getItemSerializer().serialize(itemValue, node.getItemType())
|
||||
: itemValue;
|
||||
List valueList = config.getList(node.getPath());
|
||||
if (valueList == null) {
|
||||
throw new IllegalArgumentException("Cannot remove item from non-list node");
|
||||
}
|
||||
if (!valueList.remove(serialized)) {
|
||||
throw new IllegalArgumentException("Cannot remove item from list node");
|
||||
}
|
||||
config.set(node.getPath(), valueList);
|
||||
node.onSetItemValue(itemValue, null);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,9 +161,19 @@ public abstract class GenericConfigHandle<C extends ConfigurationSection> {
|
||||
*
|
||||
* @param node The node to set the default value of.
|
||||
* @param <T> The type of the node value.
|
||||
* @return Empty try if the value was set, try containing an error otherwise.
|
||||
*/
|
||||
public <T> void setDefault(@NotNull ValueNode<T> node) {
|
||||
config.set(node.getPath(), node.getDefaultValue());
|
||||
public <T> Try<Void> reset(@NotNull ValueNode<T> node) {
|
||||
return Try.run(() -> config.set(node.getPath(), node.getDefaultValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configuration. Mainly used for {@link StringPropertyHandle}.
|
||||
*
|
||||
* @return The configuration.
|
||||
*/
|
||||
@NotNull NodeGroup getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,11 @@
|
||||
package org.mvplugins.multiverse.core.configuration.handle;
|
||||
|
||||
/**
|
||||
* The type of modification to a config.
|
||||
*/
|
||||
public enum PropertyModifyAction {
|
||||
SET,
|
||||
ADD,
|
||||
REMOVE,
|
||||
RESET
|
||||
}
|
@ -3,11 +3,13 @@ package org.mvplugins.multiverse.core.configuration.handle;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import io.vavr.control.Option;
|
||||
import io.vavr.control.Try;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import org.mvplugins.multiverse.core.configuration.node.ConfigNodeNotFoundException;
|
||||
import org.mvplugins.multiverse.core.configuration.node.ListValueNode;
|
||||
import org.mvplugins.multiverse.core.configuration.node.Node;
|
||||
import org.mvplugins.multiverse.core.configuration.node.ValueNode;
|
||||
|
||||
@ -31,10 +33,31 @@ public class StringPropertyHandle {
|
||||
*
|
||||
* @return The names of all properties in this handle.
|
||||
*/
|
||||
public Collection<String> getPropertyNames() {
|
||||
public Collection<String> getAllPropertyNames() {
|
||||
return handle.getNodes().getNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of all properties in this handle that can be modified by the given action.
|
||||
*
|
||||
* @param action The action to perform.
|
||||
* @return The names of all properties in this handle that can be modified by the given action.
|
||||
*/
|
||||
public Collection<String> getModifiablePropertyNames(PropertyModifyAction action) {
|
||||
return switch (action) {
|
||||
case SET, RESET -> handle.getNodes().getNames();
|
||||
|
||||
case ADD, REMOVE -> handle.getNodes().stream()
|
||||
.filter(node -> node instanceof ListValueNode)
|
||||
.map(node -> ((ValueNode<?>) node).getName())
|
||||
.filter(Option::isDefined)
|
||||
.map(Option::get)
|
||||
.toList();
|
||||
|
||||
default -> Collections.emptyList();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of property.
|
||||
*
|
||||
@ -52,10 +75,26 @@ public class StringPropertyHandle {
|
||||
* @param input The current user input.
|
||||
* @return A collection of possible string values.
|
||||
*/
|
||||
public Collection<String> getPropertySuggestedValues(@Nullable String name, @Nullable String input) {
|
||||
return findNode(name, ValueNode.class)
|
||||
.map(node -> node.suggest(input))
|
||||
.getOrElse(Collections.emptyList());
|
||||
public Collection<String> getSuggestedPropertyValue(
|
||||
@Nullable String name, @Nullable String input, @NotNull PropertyModifyAction action) {
|
||||
return switch (action) {
|
||||
case SET -> findNode(name, ValueNode.class)
|
||||
.map(node -> node.suggest(input))
|
||||
.getOrElse(Collections.emptyList());
|
||||
|
||||
case ADD -> findNode(name, ListValueNode.class)
|
||||
.map(node -> node.suggestItem(input))
|
||||
.getOrElse(Collections.emptyList());
|
||||
|
||||
case REMOVE -> findNode(name, ListValueNode.class)
|
||||
.map(node -> handle.get((ListValueNode<?>) node))
|
||||
.map(valueList -> valueList.stream()
|
||||
.map(String::valueOf)
|
||||
.toList())
|
||||
.getOrElse(Collections.emptyList());
|
||||
|
||||
default -> Collections.emptyList();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,7 +108,7 @@ public class StringPropertyHandle {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a node, if the validator is not null, it will be tested first.
|
||||
* Sets the value of a node.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param value The value to set.
|
||||
@ -80,7 +119,58 @@ public class StringPropertyHandle {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the string value of a node, if the validator is not null, it will be tested first.
|
||||
* Adds a value to a list node.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param value The value to add.
|
||||
* @return Empty try if the value was added, try containing an error otherwise.
|
||||
*/
|
||||
public Try<Void> addProperty(@Nullable String name, @Nullable Object value) {
|
||||
return findNode(name, ListValueNode.class).flatMap(node -> handle.add(node, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a value from a list node.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param value The value to remove.
|
||||
* @return Empty try if the value was removed, try containing an error otherwise.
|
||||
*/
|
||||
public Try<Void> removeProperty(@Nullable String name, @Nullable Object value) {
|
||||
return findNode(name, ListValueNode.class).flatMap(node -> handle.remove(node, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the value of a node to its default value.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @return Empty try if the value was reset, try containing an error otherwise.
|
||||
*/
|
||||
public Try<Void> resetProperty(@Nullable String name) {
|
||||
return findNode(name, ValueNode.class).flatMap(node -> handle.reset(node));
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the value of a node based on the given action.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param value The value to modify.
|
||||
* @param action The action to perform.
|
||||
* @return Empty try if the value was modified, try containing an error otherwise.
|
||||
*/
|
||||
public Try<Void> modifyProperty(
|
||||
@Nullable String name, @Nullable Object value, @NotNull PropertyModifyAction action) {
|
||||
return switch (action) {
|
||||
case SET -> setProperty(name, value);
|
||||
case ADD -> addProperty(name, value);
|
||||
case REMOVE -> removeProperty(name, value);
|
||||
case RESET -> resetProperty(name);
|
||||
default -> Try.failure(new IllegalArgumentException("Unknown action: " + action));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the string value of a node.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param value The string value to set.
|
||||
@ -92,6 +182,51 @@ public class StringPropertyHandle {
|
||||
.flatMap(parsedValue -> handle.set(node, parsedValue)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a string value to a list node.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param value The string value to add.
|
||||
* @return Empty try if the value was added, try containing an error otherwise.
|
||||
*/
|
||||
public Try<Void> addPropertyString(@Nullable String name, @Nullable String value) {
|
||||
return findNode(name, ListValueNode.class)
|
||||
.flatMap(node -> node.parseItemFromString(value)
|
||||
.flatMap(parsedValue -> handle.add(node, parsedValue)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a string value from a list node.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param value The string value to remove.
|
||||
* @return Empty try if the value was removed, try containing an error otherwise.
|
||||
*/
|
||||
public Try<Void> removePropertyString(@Nullable String name, @Nullable String value) {
|
||||
return findNode(name, ListValueNode.class)
|
||||
.flatMap(node -> node.parseItemFromString(value)
|
||||
.flatMap(parsedValue -> handle.remove(node, parsedValue)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the value of a node based on the given action.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param value The string value to modify.
|
||||
* @param action The action to perform.
|
||||
* @return Empty try if the value was modified, try containing an error otherwise.
|
||||
*/
|
||||
public Try<Void> modifyPropertyString(
|
||||
@Nullable String name, @Nullable String value, @NotNull PropertyModifyAction action) {
|
||||
return switch (action) {
|
||||
case SET -> setPropertyString(name, value);
|
||||
case ADD -> addPropertyString(name, value);
|
||||
case REMOVE -> removePropertyString(name, value);
|
||||
case RESET -> resetProperty(name);
|
||||
default -> Try.failure(new IllegalArgumentException("Unknown action: " + action));
|
||||
};
|
||||
}
|
||||
|
||||
private <T extends Node> Try<T> findNode(@Nullable String name, @NotNull Class<T> type) {
|
||||
return handle.getNodes().findNode(name, type)
|
||||
.toTry(() -> new ConfigNodeNotFoundException(name));
|
||||
|
@ -42,11 +42,11 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
|
||||
protected final @Nullable String name;
|
||||
protected final @NotNull Class<T> type;
|
||||
protected final @Nullable Supplier<T> defaultValue;
|
||||
protected final @Nullable NodeSuggester suggester;
|
||||
protected final @Nullable NodeStringParser<T> stringParser;
|
||||
protected final @Nullable NodeSerializer<T> serializer;
|
||||
protected final @Nullable Function<T, Try<Void>> validator;
|
||||
protected final @Nullable BiConsumer<T, T> onSetValue;
|
||||
protected @Nullable NodeSuggester suggester;
|
||||
protected @Nullable NodeStringParser<T> stringParser;
|
||||
protected @Nullable NodeSerializer<T> serializer;
|
||||
protected @Nullable Function<T, Try<Void>> validator;
|
||||
protected @Nullable BiConsumer<T, T> onSetValue;
|
||||
|
||||
protected ConfigNode(
|
||||
@NotNull String path,
|
||||
|
@ -0,0 +1,329 @@
|
||||
package org.mvplugins.multiverse.core.configuration.node;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.vavr.Value;
|
||||
import io.vavr.control.Try;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import org.mvplugins.multiverse.core.configuration.functions.DefaultStringParserProvider;
|
||||
import org.mvplugins.multiverse.core.configuration.functions.DefaultSuggesterProvider;
|
||||
import org.mvplugins.multiverse.core.configuration.functions.NodeSerializer;
|
||||
import org.mvplugins.multiverse.core.configuration.functions.NodeStringParser;
|
||||
import org.mvplugins.multiverse.core.configuration.functions.NodeSuggester;
|
||||
|
||||
/**
|
||||
* A config node that contains a list of values.
|
||||
*
|
||||
* @param <I> The type of the value.
|
||||
*/
|
||||
public class ListConfigNode<I> extends ConfigNode<List<I>> implements ListValueNode<I> {
|
||||
|
||||
/**
|
||||
* Creates a new builder for a {@link ConfigNode}.
|
||||
*
|
||||
* @param path The path of the node.
|
||||
* @param type The type of the value.
|
||||
* @param <I> The type of the value.
|
||||
* @return The new builder.
|
||||
*/
|
||||
public static @NotNull <I> Builder<I, ? extends Builder<I, ?>> listBuilder(
|
||||
@NotNull String path,
|
||||
@NotNull Class<I> type) {
|
||||
return new Builder<>(path, type);
|
||||
}
|
||||
|
||||
protected final Class<I> itemType;
|
||||
protected final NodeSuggester itemSuggester;
|
||||
protected final NodeStringParser<I> itemStringParser;
|
||||
protected final NodeSerializer<I> itemSerializer;
|
||||
protected final Function<I, Try<Void>> itemValidator;
|
||||
protected final BiConsumer<I, I> onSetItemValue;
|
||||
|
||||
protected ListConfigNode(
|
||||
@NotNull String path,
|
||||
@NotNull String[] comments,
|
||||
@Nullable String name,
|
||||
@NotNull Class<List<I>> type,
|
||||
@Nullable Supplier<List<I>> defaultValueSupplier,
|
||||
@Nullable NodeSuggester suggester,
|
||||
@Nullable NodeStringParser<List<I>> stringParser,
|
||||
@Nullable NodeSerializer<List<I>> serializer,
|
||||
@Nullable Function<List<I>, Try<Void>> validator,
|
||||
@Nullable BiConsumer<List<I>, List<I>> onSetValue,
|
||||
@NotNull Class<I> itemType,
|
||||
@Nullable NodeSuggester itemSuggester,
|
||||
@Nullable NodeStringParser<I> itemStringParser,
|
||||
@Nullable NodeSerializer<I> itemSerializer,
|
||||
@Nullable Function<I, Try<Void>> itemValidator,
|
||||
@Nullable BiConsumer<I, I> onSetItemValue) {
|
||||
super(path, comments, name, type, defaultValueSupplier, suggester, stringParser, serializer,
|
||||
validator, onSetValue);
|
||||
this.itemType = itemType;
|
||||
this.itemSuggester = itemSuggester != null
|
||||
? itemSuggester
|
||||
: DefaultSuggesterProvider.getDefaultSuggester(itemType);
|
||||
this.itemStringParser = itemStringParser != null
|
||||
? itemStringParser
|
||||
: DefaultStringParserProvider.getDefaultStringParser(itemType);
|
||||
this.itemSerializer = itemSerializer;
|
||||
this.itemValidator = itemValidator;
|
||||
this.onSetItemValue = onSetItemValue;
|
||||
|
||||
setDefaults();
|
||||
}
|
||||
|
||||
private void setDefaults() {
|
||||
if (this.itemSuggester != null && this.suggester == null) {
|
||||
setDefaultSuggester();
|
||||
}
|
||||
if (this.itemStringParser != null && this.stringParser == null) {
|
||||
setDefaultStringParser();
|
||||
}
|
||||
if (this.itemValidator != null && this.validator == null) {
|
||||
setDefaultValidator();
|
||||
}
|
||||
if (this.itemSerializer != null && this.serializer == null) {
|
||||
setDefaultSerialiser();
|
||||
}
|
||||
if (this.onSetItemValue != null && this.onSetValue == null) {
|
||||
setDefaultOnSetValue();
|
||||
}
|
||||
}
|
||||
|
||||
private void setDefaultSuggester() {
|
||||
this.suggester = input -> {
|
||||
int lastIndexOf = input == null ? -1 : input.lastIndexOf(',');
|
||||
if (lastIndexOf == -1) {
|
||||
return itemSuggester.suggest(input);
|
||||
}
|
||||
|
||||
String lastInput = input.substring(lastIndexOf + 1);
|
||||
String inputBeforeLast = input.substring(0, lastIndexOf + 1);
|
||||
Set<String> inputs = Set.of(inputBeforeLast.split(","));
|
||||
return itemSuggester.suggest(lastInput).stream()
|
||||
.filter(item -> !inputs.contains(item))
|
||||
.map(item -> inputBeforeLast + item)
|
||||
.toList();
|
||||
};
|
||||
}
|
||||
|
||||
private void setDefaultStringParser() {
|
||||
this.stringParser = (input, type) -> {
|
||||
if (input == null) {
|
||||
return Try.failure(new IllegalArgumentException("Input cannot be null"));
|
||||
}
|
||||
return Try.sequence(Arrays.stream(input.split(","))
|
||||
.map(inputItem -> itemStringParser.parse(inputItem, itemType))
|
||||
.toList()).map(Value::toJavaList);
|
||||
};
|
||||
}
|
||||
|
||||
private void setDefaultValidator() {
|
||||
this.validator = value -> {
|
||||
if (value != null) {
|
||||
return Try.sequence(value.stream().map(itemValidator).toList()).map(v -> null);
|
||||
}
|
||||
return Try.success(null);
|
||||
};
|
||||
}
|
||||
|
||||
private void setDefaultSerialiser() {
|
||||
this.serializer = new NodeSerializer<>() {
|
||||
@Override
|
||||
public List<I> deserialize(Object object, Class<List<I>> type) {
|
||||
if (object instanceof List list) {
|
||||
return list.stream().map(item -> itemSerializer.deserialize(item, itemType)).toList();
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object serialize(List<I> object, Class<List<I>> type) {
|
||||
if (object != null) {
|
||||
return object.stream().map(item -> itemSerializer.serialize(item, itemType)).toList();
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void setDefaultOnSetValue() {
|
||||
this.onSetValue = (oldValue, newValue) -> {
|
||||
if (oldValue != null) {
|
||||
oldValue.stream()
|
||||
.filter(value -> !newValue.contains(value))
|
||||
.forEach(item -> onSetItemValue.accept(item, null));
|
||||
}
|
||||
newValue.forEach(item -> onSetItemValue.accept(null, item));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Class<I> getItemType() {
|
||||
return itemType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Collection<String> suggestItem(@Nullable String input) {
|
||||
if (itemSuggester != null) {
|
||||
return itemSuggester.suggest(input);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Try<I> parseItemFromString(@Nullable String input) {
|
||||
if (itemStringParser != null) {
|
||||
return itemStringParser.parse(input, itemType);
|
||||
}
|
||||
return Try.failure(new UnsupportedOperationException("No item string parser for type " + itemType));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @Nullable NodeSerializer<I> getItemSerializer() {
|
||||
return itemSerializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Try<Void> validateItem(@Nullable I value) {
|
||||
if (itemValidator != null) {
|
||||
return itemValidator.apply(value);
|
||||
}
|
||||
return Try.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void onSetItemValue(@Nullable I oldValue, @Nullable I newValue) {
|
||||
if (onSetItemValue != null) {
|
||||
onSetItemValue.accept(oldValue, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder<I, B extends ListConfigNode.Builder<I, B>> extends ConfigNode.Builder<List<I>, B> {
|
||||
|
||||
protected final @NotNull Class<I> itemType;
|
||||
protected @Nullable NodeSuggester itemSuggester;
|
||||
protected @Nullable NodeStringParser<I> itemStringParser;
|
||||
protected @Nullable NodeSerializer<I> itemSerializer;
|
||||
protected @Nullable Function<I, Try<Void>> itemValidator;
|
||||
protected @Nullable BiConsumer<I, I> onSetItemValue;
|
||||
|
||||
/**
|
||||
* Creates a new builder.
|
||||
*
|
||||
* @param path The path of the node.
|
||||
* @param itemType The type of the item value in list.
|
||||
*/
|
||||
protected Builder(@NotNull String path, @NotNull Class<I> itemType) {
|
||||
//noinspection unchecked
|
||||
super(path, (Class<List<I>>) (Object) List.class);
|
||||
this.itemType = itemType;
|
||||
this.defaultValue = () -> (List<I>) new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the suggester for an individual item in the list.
|
||||
*
|
||||
* @param itemSuggester The suggester.
|
||||
* @return This builder.
|
||||
*/
|
||||
public @NotNull B itemSuggester(@NotNull NodeSuggester itemSuggester) {
|
||||
this.itemSuggester = itemSuggester;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the string parser for an individual item in the list.
|
||||
*
|
||||
* @param itemStringParser The string parser.
|
||||
* @return This builder.
|
||||
*/
|
||||
public @NotNull B itemStringParser(@NotNull NodeStringParser<I> itemStringParser) {
|
||||
this.itemStringParser = itemStringParser;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the serializer for an individual item in the list.
|
||||
*
|
||||
* @param serializer The serializer.
|
||||
* @return This builder.
|
||||
*/
|
||||
public @NotNull B itemSerializer(@NotNull NodeSerializer<I> serializer) {
|
||||
this.itemSerializer = serializer;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the validator for an individual item in the list.
|
||||
*
|
||||
* @param itemValidator The validator.
|
||||
* @return This builder.
|
||||
*/
|
||||
public @NotNull B itemValidator(@NotNull Function<I, Try<Void>> itemValidator) {
|
||||
this.itemValidator = itemValidator;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the onSetValue for an individual item in the list.
|
||||
*
|
||||
* @param onSetItemValue The onSetValue.
|
||||
* @return This builder.
|
||||
*/
|
||||
public @NotNull B onSetItemValue(@Nullable BiConsumer<I, I> onSetItemValue) {
|
||||
this.onSetItemValue = onSetItemValue;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @NotNull ListConfigNode<I> build() {
|
||||
return new ListConfigNode<>(
|
||||
path,
|
||||
comments.toArray(new String[0]),
|
||||
name,
|
||||
type,
|
||||
defaultValue,
|
||||
suggester,
|
||||
stringParser,
|
||||
serializer,
|
||||
validator,
|
||||
onSetValue,
|
||||
itemType,
|
||||
itemSuggester, itemStringParser, itemSerializer,
|
||||
itemValidator,
|
||||
onSetItemValue);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package org.mvplugins.multiverse.core.configuration.node;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import io.vavr.control.Try;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import org.mvplugins.multiverse.core.configuration.functions.NodeSerializer;
|
||||
|
||||
/**
|
||||
* A node that holds a list of values of a specific type.
|
||||
*
|
||||
* @param <I> The type of list item.
|
||||
*/
|
||||
public interface ListValueNode<I> extends ValueNode<List<I>> {
|
||||
|
||||
/**
|
||||
* Gets the class type of list item.
|
||||
*
|
||||
* @return The class type of list item.
|
||||
*/
|
||||
@NotNull Class<I> getItemType();
|
||||
|
||||
/**
|
||||
* Suggests possible string values for this node.
|
||||
*
|
||||
* @param input The input string.
|
||||
* @return A collection of possible string values.
|
||||
*/
|
||||
@NotNull Collection<String> suggestItem(@Nullable String input);
|
||||
|
||||
/**
|
||||
* Parses the given string into a value of type {@link I}. Used for property set by user input.
|
||||
*
|
||||
* @param input The string to parse.
|
||||
* @return The parsed value, or given exception if parsing failed.
|
||||
*/
|
||||
@NotNull Try<I> parseItemFromString(@Nullable String input);
|
||||
|
||||
/**
|
||||
* Gets the serializer for this node.
|
||||
*
|
||||
* @return The serializer for this node.
|
||||
*/
|
||||
@Nullable NodeSerializer<I> getItemSerializer();
|
||||
|
||||
/**
|
||||
* Validates the value of this node.
|
||||
*
|
||||
* @param value The value to validate.
|
||||
* @return True if the value is valid, false otherwise.
|
||||
*/
|
||||
Try<Void> validateItem(@Nullable I value);
|
||||
|
||||
/**
|
||||
* Called when the value of this node is set.
|
||||
*
|
||||
* @param oldValue The old value.
|
||||
* @param newValue The new value.
|
||||
*/
|
||||
void onSetItemValue(@Nullable I oldValue, @Nullable I newValue);
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package org.mvplugins.multiverse.core.world;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
@ -13,6 +12,7 @@ import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import org.mvplugins.multiverse.core.configuration.handle.StringPropertyHandle;
|
||||
import org.mvplugins.multiverse.core.world.config.AllowedPortalType;
|
||||
import org.mvplugins.multiverse.core.world.config.WorldConfig;
|
||||
|
||||
@ -57,34 +57,12 @@ public class MultiverseWorld {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties that can be configured on this world. Can be used for {@link #getProperty(String)} and
|
||||
* {@link #setProperty(String, Object)}.
|
||||
* Gets the properties handler of this world.
|
||||
*
|
||||
* @return A collection of property names.
|
||||
* @return The properties handler of this world.
|
||||
*/
|
||||
public Collection<String> getConfigurablePropertyNames() {
|
||||
return worldConfig.getConfigurablePropertyNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a property on this world.
|
||||
*
|
||||
* @param name The name of the property.
|
||||
* @return The value of the property.
|
||||
*/
|
||||
public Try<Object> getProperty(String name) {
|
||||
return worldConfig.getProperty(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a property on this world.
|
||||
*
|
||||
* @param name The name of the property.
|
||||
* @param value The value of the property.
|
||||
* @return Result of setting property.
|
||||
*/
|
||||
public Try<Void> setProperty(String name, Object value) {
|
||||
return worldConfig.setProperty(name, value);
|
||||
public StringPropertyHandle getStringPropertyHandle() {
|
||||
return worldConfig.getStringPropertyHandle();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,22 +112,14 @@ public final class WorldConfig {
|
||||
return configHandle.load(section);
|
||||
}
|
||||
|
||||
public StringPropertyHandle getStringPropertyHandle() {
|
||||
return stringPropertyHandle;
|
||||
}
|
||||
|
||||
public String getWorldName() {
|
||||
return worldName;
|
||||
}
|
||||
|
||||
public Collection<String> getConfigurablePropertyNames() {
|
||||
return configNodes.getNodes().getNames();
|
||||
}
|
||||
|
||||
public Try<Object> getProperty(String name) {
|
||||
return stringPropertyHandle.getProperty(name);
|
||||
}
|
||||
|
||||
public Try<Void> setProperty(String name, Object value) {
|
||||
return stringPropertyHandle.setProperty(name, value);
|
||||
}
|
||||
|
||||
public boolean getAdjustSpawn() {
|
||||
return configHandle.get(configNodes.ADJUST_SPAWN);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package org.mvplugins.multiverse.core.world.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Difficulty;
|
||||
import org.bukkit.GameMode;
|
||||
@ -12,6 +11,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import org.mvplugins.multiverse.core.MultiverseCore;
|
||||
import org.mvplugins.multiverse.core.configuration.node.ConfigNode;
|
||||
import org.mvplugins.multiverse.core.configuration.node.ListConfigNode;
|
||||
import org.mvplugins.multiverse.core.configuration.node.Node;
|
||||
import org.mvplugins.multiverse.core.configuration.node.NodeGroup;
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
|
||||
@ -212,8 +212,8 @@ public class WorldConfigNodes {
|
||||
})
|
||||
.build());
|
||||
|
||||
final ConfigNode<List> SPAWNING_ANIMALS_EXCEPTIONS = node(ConfigNode
|
||||
.builder("spawning.animals.exceptions", List.class)
|
||||
final ListConfigNode<String> SPAWNING_ANIMALS_EXCEPTIONS = node(ListConfigNode
|
||||
.listBuilder("spawning.animals.exceptions", String.class)
|
||||
.defaultValue(new ArrayList<>())
|
||||
.name("spawning-animals-exceptions")
|
||||
.build());
|
||||
@ -238,14 +238,13 @@ public class WorldConfigNodes {
|
||||
})
|
||||
.build());
|
||||
|
||||
final ConfigNode<List> SPAWNING_MONSTERS_EXCEPTIONS = node(ConfigNode
|
||||
.builder("spawning.monsters.exceptions", List.class)
|
||||
final ListConfigNode<String> SPAWNING_MONSTERS_EXCEPTIONS = node(ListConfigNode
|
||||
.listBuilder("spawning.monsters.exceptions", String.class)
|
||||
.defaultValue(new ArrayList<>())
|
||||
.name("spawning-monsters-exceptions")
|
||||
.build());
|
||||
|
||||
final ConfigNode<List> WORLD_BLACKLIST = node(ConfigNode.builder("world-blacklist", List.class)
|
||||
.defaultValue(new ArrayList<>())
|
||||
final ListConfigNode<String> WORLD_BLACKLIST = node(ListConfigNode.listBuilder("world-blacklist", String.class)
|
||||
.build());
|
||||
|
||||
final ConfigNode<Double> VERSION = node(ConfigNode.builder("version", Double.class)
|
||||
|
@ -10,6 +10,7 @@ import org.bukkit.GameRule;
|
||||
import org.bukkit.World;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
import org.mvplugins.multiverse.core.configuration.handle.StringPropertyHandle;
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
|
||||
|
||||
/**
|
||||
@ -90,7 +91,8 @@ public interface DataStore<T> {
|
||||
@Override
|
||||
public WorldConfigStore copyFrom(LoadedMultiverseWorld world) {
|
||||
this.configMap = new HashMap<>();
|
||||
world.getConfigurablePropertyNames().forEach(name -> world.getProperty(name)
|
||||
StringPropertyHandle worldPropertyHandler = world.getStringPropertyHandle();
|
||||
worldPropertyHandler.getAllPropertyNames().forEach(name -> worldPropertyHandler.getProperty(name)
|
||||
.peek(value -> configMap.put(name, value)).onFailure(e -> {
|
||||
Logging.warning("Failed to get property " + name + " from world "
|
||||
+ world.getName() + ": " + e.getMessage());
|
||||
@ -106,12 +108,11 @@ public interface DataStore<T> {
|
||||
if (configMap == null) {
|
||||
return this;
|
||||
}
|
||||
configMap.forEach((name, value) -> {
|
||||
world.setProperty(name, value).onFailure(e -> {
|
||||
Logging.warning("Failed to set property %s to %s for world %s: %s",
|
||||
name, value, world.getName(), e.getMessage());
|
||||
});
|
||||
});
|
||||
StringPropertyHandle worldPropertyHandler = world.getStringPropertyHandle();
|
||||
configMap.forEach((name, value) -> worldPropertyHandler.setProperty(name, value).onFailure(e -> {
|
||||
Logging.warning("Failed to set property %s to %s for world %s: %s",
|
||||
name, value, world.getName(), e.getMessage());
|
||||
}));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -68,9 +68,9 @@ class WorldConfigMangerTest : TestWithMockBukkit() {
|
||||
val worldConfig = worldConfigManager.getWorldConfig("world").orNull
|
||||
assertNotNull(worldConfig)
|
||||
|
||||
worldConfig.setProperty("adjust-spawn", true)
|
||||
worldConfig.setProperty("alias", "newalias")
|
||||
worldConfig.setProperty("spawn-location", SpawnLocation(-64.0, 64.0, 48.0))
|
||||
worldConfig.stringPropertyHandle.setProperty("adjust-spawn", true)
|
||||
worldConfig.stringPropertyHandle.setProperty("alias", "newalias")
|
||||
worldConfig.stringPropertyHandle.setProperty("spawn-location", SpawnLocation(-64.0, 64.0, 48.0))
|
||||
assertTrue(worldConfigManager.save().isSuccess)
|
||||
}
|
||||
|
||||
|
@ -30,14 +30,14 @@ class WorldConfigTest : TestWithMockBukkit() {
|
||||
|
||||
@Test
|
||||
fun `Getting existing world property with getProperty returns expected value`() {
|
||||
assertEquals("my world", worldConfig.getProperty("alias").get())
|
||||
assertEquals(false, worldConfig.getProperty("hidden").get())
|
||||
assertEquals("my world", worldConfig.stringPropertyHandle.getProperty("alias").get())
|
||||
assertEquals(false, worldConfig.stringPropertyHandle.getProperty("hidden").get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Getting non-existing world property with getProperty returns null`() {
|
||||
assertTrue(worldConfig.getProperty("invalid-property").isFailure)
|
||||
assertTrue(worldConfig.getProperty("version").isFailure)
|
||||
assertTrue(worldConfig.stringPropertyHandle.getProperty("invalid-property").isFailure)
|
||||
assertTrue(worldConfig.stringPropertyHandle.getProperty("version").isFailure)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -48,23 +48,23 @@ class WorldConfigTest : TestWithMockBukkit() {
|
||||
|
||||
@Test
|
||||
fun `Updating an existing world property with setProperty reflects the changes in getProperty`() {
|
||||
assertTrue(worldConfig.setProperty("adjust-spawn", true).isSuccess)
|
||||
assertEquals(true, worldConfig.getProperty("adjust-spawn").get())
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("adjust-spawn", true).isSuccess)
|
||||
assertEquals(true, worldConfig.stringPropertyHandle.getProperty("adjust-spawn").get())
|
||||
|
||||
assertTrue(worldConfig.setProperty("alias", "abc").isSuccess)
|
||||
assertEquals("abc", worldConfig.getProperty("alias").get())
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("alias", "abc").isSuccess)
|
||||
assertEquals("abc", worldConfig.stringPropertyHandle.getProperty("alias").get())
|
||||
|
||||
assertTrue(worldConfig.setProperty("scale", 2.0).isSuccess)
|
||||
assertEquals(2.0, worldConfig.getProperty("scale").get())
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("scale", 2.0).isSuccess)
|
||||
assertEquals(2.0, worldConfig.stringPropertyHandle.getProperty("scale").get())
|
||||
|
||||
val blacklists = listOf("a", "b", "c")
|
||||
assertTrue(worldConfig.setProperty("world-blacklist", blacklists).isSuccess)
|
||||
assertEquals(blacklists, worldConfig.getProperty("world-blacklist").get())
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("world-blacklist", blacklists).isSuccess)
|
||||
assertEquals(blacklists, worldConfig.stringPropertyHandle.getProperty("world-blacklist").get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Updating a non-existing property with setProperty returns false`() {
|
||||
assertTrue(worldConfig.setProperty("invalid-property", false).isFailure)
|
||||
assertTrue(worldConfig.setProperty("version", 1.1).isFailure)
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("invalid-property", false).isFailure)
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("version", 1.1).isFailure)
|
||||
}
|
||||
}
|
||||
|
@ -34,9 +34,9 @@ class WorldManagerTest : TestWithMockBukkit() {
|
||||
val world = worldManager.getLoadedWorld("world_nether").get()
|
||||
assertNotNull(world)
|
||||
assertEquals("world_nether", world.name)
|
||||
assertEquals(World.Environment.NETHER, world.getProperty("environment").get())
|
||||
assertEquals("", world.getProperty("generator").get())
|
||||
assertEquals(1234L, world.getProperty("seed").get())
|
||||
assertEquals(World.Environment.NETHER, world.environment)
|
||||
assertEquals("", world.generator)
|
||||
assertEquals(1234L, world.seed)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user