mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2024-11-24 19:46:09 +01:00
Implement support for property modification with ConfigModifyType and ListValueNode
This commit is contained in:
parent
6f014838e9
commit
94b1e77a98
@ -0,0 +1,73 @@
|
|||||||
|
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.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.commandtools.context.WorldConfigValue;
|
||||||
|
import org.mvplugins.multiverse.core.configuration.handle.ConfigModifyType;
|
||||||
|
import org.mvplugins.multiverse.core.worldnew.MultiverseWorld;
|
||||||
|
import org.mvplugins.multiverse.core.worldnew.WorldManager;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@CommandAlias("mv")
|
||||||
|
class ModifyCommand extends MultiverseCommand {
|
||||||
|
|
||||||
|
private final WorldManager worldManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ModifyCommand(@NotNull MVCommandManager commandManager, WorldManager worldManager) {
|
||||||
|
super(commandManager);
|
||||||
|
this.worldManager = worldManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* /mv modify [world] <set|add|remove|reset> <property> <value> */
|
||||||
|
@Subcommand("modify")
|
||||||
|
@CommandPermission("multiverse.core.modify")
|
||||||
|
@CommandCompletion("@mvworlds:scope=both @configmodifytype @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("")
|
||||||
|
ConfigModifyType configModifyType,
|
||||||
|
|
||||||
|
@Syntax("<property>")
|
||||||
|
@Description("")
|
||||||
|
String propertyName,
|
||||||
|
|
||||||
|
@Syntax("[value]")
|
||||||
|
@Description("")
|
||||||
|
WorldConfigValue propertyValue) {
|
||||||
|
Logging.fine("ModifyCommand.onModifyCommand: world=%s, configModifyType=%s, propertyName=%s, propertyValue=%s",
|
||||||
|
world, configModifyType, propertyName, propertyValue);
|
||||||
|
|
||||||
|
world.modifyProperty(configModifyType, propertyName, propertyValue.getValue()).onSuccess(ignore -> {
|
||||||
|
issuer.sendMessage("Property " + propertyName + " set to " + world.getProperty(propertyName).getOrNull()
|
||||||
|
+ " for world " + world.getName() + ".");
|
||||||
|
worldManager.saveWorldsConfig();
|
||||||
|
}).onFailure(exception -> {
|
||||||
|
issuer.sendMessage("Failed to " + configModifyType.name().toLowerCase() + " property " + propertyName
|
||||||
|
+ " to " + propertyValue.getValue() + " for world " + world.getName() + ".");
|
||||||
|
issuer.sendMessage(exception.getMessage());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package org.mvplugins.multiverse.core.commandtools;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -19,10 +20,12 @@ import com.google.common.collect.Sets;
|
|||||||
import io.vavr.control.Try;
|
import io.vavr.control.Try;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import org.bukkit.GameRule;
|
import org.bukkit.GameRule;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jvnet.hk2.annotations.Service;
|
import org.jvnet.hk2.annotations.Service;
|
||||||
|
|
||||||
import org.mvplugins.multiverse.core.config.MVCoreConfig;
|
import org.mvplugins.multiverse.core.config.MVCoreConfig;
|
||||||
|
import org.mvplugins.multiverse.core.configuration.handle.ConfigModifyType;
|
||||||
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
|
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
|
||||||
import org.mvplugins.multiverse.core.destination.ParsedDestination;
|
import org.mvplugins.multiverse.core.destination.ParsedDestination;
|
||||||
import org.mvplugins.multiverse.core.worldnew.LoadedMultiverseWorld;
|
import org.mvplugins.multiverse.core.worldnew.LoadedMultiverseWorld;
|
||||||
@ -37,27 +40,32 @@ public class MVCommandCompletions extends PaperCommandCompletions {
|
|||||||
private final DestinationsProvider destinationsProvider;
|
private final DestinationsProvider destinationsProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public MVCommandCompletions(
|
MVCommandCompletions(
|
||||||
@NotNull MVCommandManager mvCommandManager,
|
@NotNull MVCommandManager mvCommandManager,
|
||||||
@NotNull WorldManager worldManager,
|
@NotNull WorldManager worldManager,
|
||||||
@NotNull DestinationsProvider destinationsProvider,
|
@NotNull DestinationsProvider destinationsProvider,
|
||||||
@NotNull MVCoreConfig config
|
@NotNull MVCoreConfig config) {
|
||||||
) {
|
|
||||||
super(mvCommandManager);
|
super(mvCommandManager);
|
||||||
this.commandManager = mvCommandManager;
|
this.commandManager = mvCommandManager;
|
||||||
this.worldManager = worldManager;
|
this.worldManager = worldManager;
|
||||||
this.destinationsProvider = destinationsProvider;
|
this.destinationsProvider = destinationsProvider;
|
||||||
|
|
||||||
registerAsyncCompletion("commands", this::suggestCommands);
|
registerAsyncCompletion("commands", this::suggestCommands);
|
||||||
|
registerStaticCompletion("configmodifytype", suggestEnums(ConfigModifyType.class));
|
||||||
registerAsyncCompletion("destinations", this::suggestDestinations);
|
registerAsyncCompletion("destinations", this::suggestDestinations);
|
||||||
|
registerStaticCompletion("environments", suggestEnums(World.Environment.class));
|
||||||
registerAsyncCompletion("flags", this::suggestFlags);
|
registerAsyncCompletion("flags", this::suggestFlags);
|
||||||
registerStaticCompletion("gamerules", this::suggestGamerules);
|
registerStaticCompletion("gamerules", this::suggestGamerules);
|
||||||
registerStaticCompletion("mvconfigs", config.getNodes().getNames());
|
registerStaticCompletion("mvconfigs", config.getNodes().getNames());
|
||||||
registerAsyncCompletion("mvworlds", this::suggestMVWorlds);
|
registerAsyncCompletion("mvworlds", this::suggestMVWorlds);
|
||||||
|
registerAsyncCompletion("mvworldpropsname", this::suggestMVWorldPropsName);
|
||||||
|
registerAsyncCompletion("mvworldpropsvalue", this::suggestMVWorldPropsValue);
|
||||||
|
|
||||||
|
setDefaultCompletion("configmodifytype", ConfigModifyType.class);
|
||||||
setDefaultCompletion("destinations", ParsedDestination.class);
|
setDefaultCompletion("destinations", ParsedDestination.class);
|
||||||
setDefaultCompletion("flags", String[].class);
|
setDefaultCompletion("environments", World.Environment.class);
|
||||||
setDefaultCompletion("gamerules", GameRule.class);
|
setDefaultCompletion("gamerules", GameRule.class);
|
||||||
|
setDefaultCompletion("mvworlds", MultiverseWorld.class);
|
||||||
setDefaultCompletion("mvworlds", LoadedMultiverseWorld.class);
|
setDefaultCompletion("mvworlds", LoadedMultiverseWorld.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,4 +160,41 @@ public class MVCommandCompletions extends PaperCommandCompletions {
|
|||||||
Logging.severe("Invalid MVWorld scope: " + scope);
|
Logging.severe("Invalid MVWorld scope: " + scope);
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Collection<String> suggestMVWorldPropsName(BukkitCommandCompletionContext context) {
|
||||||
|
return Try.of(() -> {
|
||||||
|
MultiverseWorld mvWorld = context.getContextValue(MultiverseWorld.class);
|
||||||
|
ConfigModifyType modifyType = context.getContextValue(ConfigModifyType.class);
|
||||||
|
return mvWorld.getConfigurablePropertyNames(modifyType);
|
||||||
|
}).getOrElse(Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<String> suggestMVWorldPropsValue(BukkitCommandCompletionContext context) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return Try.of(() -> {
|
||||||
|
MultiverseWorld mvWorld = context.getContextValue(MultiverseWorld.class);
|
||||||
|
String propertyName = context.getContextValue(String.class);
|
||||||
|
Class type = mvWorld.getPropertyType(propertyName).get();
|
||||||
|
if (type.isEnum()) {
|
||||||
|
return suggestEnums(type);
|
||||||
|
}
|
||||||
|
if (type == Boolean.class) {
|
||||||
|
return List.of("true", "false");
|
||||||
|
}
|
||||||
|
if (type == Integer.class) {
|
||||||
|
return List.of("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
|
||||||
|
}
|
||||||
|
if (type == Double.class) {
|
||||||
|
return List.of("0.0", "1.0", "2.0", "3.0", "4.0", "5.0");
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}).getOrElse(Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Enum<T>> Collection<String> suggestEnums(Class<T> enumClass) {
|
||||||
|
return EnumSet.allOf(enumClass).stream()
|
||||||
|
.map(Enum::name)
|
||||||
|
.map(String::toLowerCase)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package org.mvplugins.multiverse.core.commandtools;
|
package org.mvplugins.multiverse.core.commandtools;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import co.aikar.commands.BukkitCommandExecutionContext;
|
import co.aikar.commands.BukkitCommandExecutionContext;
|
||||||
@ -8,8 +11,10 @@ import co.aikar.commands.BukkitCommandIssuer;
|
|||||||
import co.aikar.commands.InvalidCommandArgument;
|
import co.aikar.commands.InvalidCommandArgument;
|
||||||
import co.aikar.commands.PaperCommandContexts;
|
import co.aikar.commands.PaperCommandContexts;
|
||||||
import co.aikar.commands.contexts.ContextResolver;
|
import co.aikar.commands.contexts.ContextResolver;
|
||||||
|
import com.dumptruckman.minecraft.util.Logging;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
|
import io.vavr.control.Try;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import org.bukkit.GameRule;
|
import org.bukkit.GameRule;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -17,7 +22,9 @@ import org.jvnet.hk2.annotations.Service;
|
|||||||
|
|
||||||
import org.mvplugins.multiverse.core.commandtools.context.GameRuleValue;
|
import org.mvplugins.multiverse.core.commandtools.context.GameRuleValue;
|
||||||
import org.mvplugins.multiverse.core.commandtools.context.MVConfigValue;
|
import org.mvplugins.multiverse.core.commandtools.context.MVConfigValue;
|
||||||
|
import org.mvplugins.multiverse.core.commandtools.context.WorldConfigValue;
|
||||||
import org.mvplugins.multiverse.core.config.MVCoreConfig;
|
import org.mvplugins.multiverse.core.config.MVCoreConfig;
|
||||||
|
import org.mvplugins.multiverse.core.configuration.handle.ConfigModifyType;
|
||||||
import org.mvplugins.multiverse.core.configuration.node.Node;
|
import org.mvplugins.multiverse.core.configuration.node.Node;
|
||||||
import org.mvplugins.multiverse.core.configuration.node.ValueNode;
|
import org.mvplugins.multiverse.core.configuration.node.ValueNode;
|
||||||
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
|
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
|
||||||
@ -27,10 +34,11 @@ import org.mvplugins.multiverse.core.display.filters.DefaultContentFilter;
|
|||||||
import org.mvplugins.multiverse.core.display.filters.RegexContentFilter;
|
import org.mvplugins.multiverse.core.display.filters.RegexContentFilter;
|
||||||
import org.mvplugins.multiverse.core.utils.PlayerFinder;
|
import org.mvplugins.multiverse.core.utils.PlayerFinder;
|
||||||
import org.mvplugins.multiverse.core.worldnew.LoadedMultiverseWorld;
|
import org.mvplugins.multiverse.core.worldnew.LoadedMultiverseWorld;
|
||||||
|
import org.mvplugins.multiverse.core.worldnew.MultiverseWorld;
|
||||||
import org.mvplugins.multiverse.core.worldnew.WorldManager;
|
import org.mvplugins.multiverse.core.worldnew.WorldManager;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class MVCommandContexts extends PaperCommandContexts {
|
class MVCommandContexts extends PaperCommandContexts {
|
||||||
|
|
||||||
private final MVCommandManager mvCommandManager;
|
private final MVCommandManager mvCommandManager;
|
||||||
private final DestinationsProvider destinationsProvider;
|
private final DestinationsProvider destinationsProvider;
|
||||||
@ -38,12 +46,11 @@ public class MVCommandContexts extends PaperCommandContexts {
|
|||||||
private final MVCoreConfig config;
|
private final MVCoreConfig config;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public MVCommandContexts(
|
MVCommandContexts(
|
||||||
MVCommandManager mvCommandManager,
|
MVCommandManager mvCommandManager,
|
||||||
DestinationsProvider destinationsProvider,
|
DestinationsProvider destinationsProvider,
|
||||||
WorldManager worldManager,
|
WorldManager worldManager,
|
||||||
MVCoreConfig config
|
MVCoreConfig config) {
|
||||||
) {
|
|
||||||
super(mvCommandManager);
|
super(mvCommandManager);
|
||||||
this.mvCommandManager = mvCommandManager;
|
this.mvCommandManager = mvCommandManager;
|
||||||
this.destinationsProvider = destinationsProvider;
|
this.destinationsProvider = destinationsProvider;
|
||||||
@ -57,10 +64,12 @@ public class MVCommandContexts extends PaperCommandContexts {
|
|||||||
registerContext(GameRule.class, this::parseGameRule);
|
registerContext(GameRule.class, this::parseGameRule);
|
||||||
registerContext(GameRuleValue.class, this::parseGameRuleValue);
|
registerContext(GameRuleValue.class, this::parseGameRuleValue);
|
||||||
registerContext(MVConfigValue.class, this::parseMVConfigValue);
|
registerContext(MVConfigValue.class, this::parseMVConfigValue);
|
||||||
registerIssuerAwareContext(LoadedMultiverseWorld.class, this::parseMVWorld);
|
registerIssuerAwareContext(MultiverseWorld.class, this::parseWorld);
|
||||||
registerIssuerAwareContext(LoadedMultiverseWorld[].class, this::parseMVWorldArray);
|
registerIssuerAwareContext(LoadedMultiverseWorld.class, this::parseLoadedWorld);
|
||||||
|
registerIssuerAwareContext(LoadedMultiverseWorld[].class, this::parseLoadedWorldArray);
|
||||||
registerIssuerAwareContext(Player.class, this::parsePlayer);
|
registerIssuerAwareContext(Player.class, this::parsePlayer);
|
||||||
registerIssuerAwareContext(Player[].class, this::parsePlayerArray);
|
registerIssuerAwareContext(Player[].class, this::parsePlayerArray);
|
||||||
|
registerIssuerAwareContext(WorldConfigValue.class, this::parseWorldConfigValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MVCommandIssuer parseMVCommandIssuer(BukkitCommandExecutionContext context) {
|
private MVCommandIssuer parseMVCommandIssuer(BukkitCommandExecutionContext context) {
|
||||||
@ -162,13 +171,14 @@ public class MVCommandContexts extends PaperCommandContexts {
|
|||||||
return new MVConfigValue(resolvedValue);
|
return new MVConfigValue(resolvedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoadedMultiverseWorld parseMVWorld(BukkitCommandExecutionContext context) {
|
private MultiverseWorld parseWorld(BukkitCommandExecutionContext context) {
|
||||||
String resolve = context.getFlagValue("resolve", "");
|
String resolve = context.getFlagValue("resolve", "");
|
||||||
|
|
||||||
// Get world based on sender only
|
// Get world based on sender only
|
||||||
if (resolve.equals("issuerOnly")) {
|
if (resolve.equals("issuerOnly")) {
|
||||||
if (context.getIssuer().isPlayer()) {
|
if (context.getIssuer().isPlayer()) {
|
||||||
return worldManager.getLoadedWorld(context.getIssuer().getPlayer().getWorld()).getOrNull();
|
return worldManager.getWorld(context.getIssuer().getPlayer().getWorld())
|
||||||
|
.getOrElseThrow(() -> new InvalidCommandArgument("Player is not in a Multiverse World."));
|
||||||
}
|
}
|
||||||
if (context.isOptional()) {
|
if (context.isOptional()) {
|
||||||
return null;
|
return null;
|
||||||
@ -177,7 +187,7 @@ public class MVCommandContexts extends PaperCommandContexts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String worldName = context.getFirstArg();
|
String worldName = context.getFirstArg();
|
||||||
LoadedMultiverseWorld world = worldManager.getLoadedWorld(worldName).getOrNull();
|
MultiverseWorld world = worldManager.getWorld(worldName).getOrNull();
|
||||||
|
|
||||||
// Get world based on input, fallback to sender if input is not a world
|
// Get world based on input, fallback to sender if input is not a world
|
||||||
if (resolve.equals("issuerAware")) {
|
if (resolve.equals("issuerAware")) {
|
||||||
@ -186,7 +196,8 @@ public class MVCommandContexts extends PaperCommandContexts {
|
|||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
if (context.getIssuer().isPlayer()) {
|
if (context.getIssuer().isPlayer()) {
|
||||||
return worldManager.getLoadedWorld(context.getIssuer().getPlayer().getWorld()).getOrNull();
|
return worldManager.getWorld(context.getIssuer().getPlayer().getWorld())
|
||||||
|
.getOrElseThrow(() -> new InvalidCommandArgument("Player is not in a Multiverse World."));
|
||||||
}
|
}
|
||||||
if (context.isOptional()) {
|
if (context.isOptional()) {
|
||||||
return null;
|
return null;
|
||||||
@ -205,7 +216,53 @@ public class MVCommandContexts extends PaperCommandContexts {
|
|||||||
throw new InvalidCommandArgument("World " + worldName + " is not a loaded multiverse world.");
|
throw new InvalidCommandArgument("World " + worldName + " is not a loaded multiverse world.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoadedMultiverseWorld[] parseMVWorldArray(BukkitCommandExecutionContext context) {
|
|
||||||
|
private LoadedMultiverseWorld parseLoadedWorld(BukkitCommandExecutionContext context) {
|
||||||
|
String resolve = context.getFlagValue("resolve", "");
|
||||||
|
|
||||||
|
// Get world based on sender only
|
||||||
|
if (resolve.equals("issuerOnly")) {
|
||||||
|
if (context.getIssuer().isPlayer()) {
|
||||||
|
return worldManager.getLoadedWorld(context.getIssuer().getPlayer().getWorld())
|
||||||
|
.getOrElseThrow(() -> new InvalidCommandArgument("Player is not in a Multiverse World."));
|
||||||
|
}
|
||||||
|
if (context.isOptional()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw new InvalidCommandArgument("This command can only be used by a player in a Multiverse World.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String worldName = context.getFirstArg();
|
||||||
|
LoadedMultiverseWorld world = worldManager.getLoadedWorld(worldName).getOrNull();
|
||||||
|
|
||||||
|
// Get world based on input, fallback to sender if input is not a world
|
||||||
|
if (resolve.equals("issuerAware")) {
|
||||||
|
if (world != null) {
|
||||||
|
context.popFirstArg();
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
if (context.getIssuer().isPlayer()) {
|
||||||
|
return worldManager.getLoadedWorld(context.getIssuer().getPlayer().getWorld())
|
||||||
|
.getOrElseThrow(() -> new InvalidCommandArgument("Player is not in a Multiverse World."));
|
||||||
|
}
|
||||||
|
if (context.isOptional()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw new InvalidCommandArgument("Player is not in a Multiverse World.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get world based on input only
|
||||||
|
if (world != null) {
|
||||||
|
context.popFirstArg();
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
if (context.isOptional()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw new InvalidCommandArgument("World " + worldName + " is not a loaded multiverse world.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoadedMultiverseWorld[] parseLoadedWorldArray(BukkitCommandExecutionContext context) {
|
||||||
String resolve = context.getFlagValue("resolve", "");
|
String resolve = context.getFlagValue("resolve", "");
|
||||||
|
|
||||||
LoadedMultiverseWorld playerWorld = null;
|
LoadedMultiverseWorld playerWorld = null;
|
||||||
@ -309,7 +366,6 @@ public class MVCommandContexts extends PaperCommandContexts {
|
|||||||
throw new InvalidCommandArgument("Player " + playerIdentifier + " not found.");
|
throw new InvalidCommandArgument("Player " + playerIdentifier + " not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Player[] parsePlayerArray(BukkitCommandExecutionContext context) {
|
private Player[] parsePlayerArray(BukkitCommandExecutionContext context) {
|
||||||
String resolve = context.getFlagValue("resolve", "");
|
String resolve = context.getFlagValue("resolve", "");
|
||||||
|
|
||||||
@ -353,4 +409,50 @@ public class MVCommandContexts extends PaperCommandContexts {
|
|||||||
}
|
}
|
||||||
throw new InvalidCommandArgument("Player " + playerIdentifier + " not found.");
|
throw new InvalidCommandArgument("Player " + playerIdentifier + " not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private WorldConfigValue parseWorldConfigValue(BukkitCommandExecutionContext context) {
|
||||||
|
MultiverseWorld mvWorld = (MultiverseWorld) context.getResolvedArg(MultiverseWorld.class);
|
||||||
|
ConfigModifyType modifyType = (ConfigModifyType) context.getResolvedArg(ConfigModifyType.class);
|
||||||
|
String propertyName = (String) context.getResolvedArg(String.class);
|
||||||
|
if (mvWorld == null || modifyType == null || propertyName == null) {
|
||||||
|
throw new InvalidCommandArgument("No world or property specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modifyType == ConfigModifyType.RESET) {
|
||||||
|
if (context.popFirstArg() != null) {
|
||||||
|
throw new InvalidCommandArgument("No value should be specified for reset.");
|
||||||
|
}
|
||||||
|
return new WorldConfigValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?> type = mvWorld.getPropertyType(propertyName)
|
||||||
|
.getOrElseThrow(() -> {
|
||||||
|
return new InvalidCommandArgument("The property " + propertyName + " is not valid for world "
|
||||||
|
+ mvWorld.getName() + ".");
|
||||||
|
});
|
||||||
|
return new WorldConfigValue(parseType(context, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object parseType(BukkitCommandExecutionContext context, Class<?> type) {
|
||||||
|
Object value = context.getFirstArg();
|
||||||
|
if (value == null) {
|
||||||
|
throw new InvalidCommandArgument("No value specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case for enums
|
||||||
|
if (type.isEnum()) {
|
||||||
|
return Try.of(() -> Enum.valueOf((Class<? extends Enum>) type, context.popFirstArg().toUpperCase()))
|
||||||
|
.getOrElseThrow(() -> new InvalidCommandArgument(("The value %s is not a valid %s. "
|
||||||
|
+ "Valid values are: %s").formatted(
|
||||||
|
value,
|
||||||
|
type.getSimpleName(),
|
||||||
|
Arrays.stream(((Class<? extends Enum>) type).getEnumConstants())
|
||||||
|
.map(enumValue -> enumValue.name().toLowerCase())
|
||||||
|
.reduce((a, b) -> a + ", " + b)
|
||||||
|
.orElse(""))));
|
||||||
|
}
|
||||||
|
|
||||||
|
ContextResolver<?, BukkitCommandExecutionContext> resolver = getResolver(type);
|
||||||
|
return resolver == null ? value : resolver.getContext(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package org.mvplugins.multiverse.core.commandtools.context;
|
||||||
|
|
||||||
|
public class WorldConfigValue {
|
||||||
|
private final Object value;
|
||||||
|
|
||||||
|
public WorldConfigValue(Object value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "WorldConfigValue{"
|
||||||
|
+ "value=" + value
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
}
|
@ -76,7 +76,7 @@ public class CommentedYamlConfigHandle extends FileConfigHandle<CommentedConfigu
|
|||||||
valueNode.getDefaultValue())).onFailure(e -> {
|
valueNode.getDefaultValue())).onFailure(e -> {
|
||||||
Logging.warning("Failed to set node " + valueNode.getPath()
|
Logging.warning("Failed to set node " + valueNode.getPath()
|
||||||
+ " to " + valueNode.getDefaultValue());
|
+ " to " + valueNode.getDefaultValue());
|
||||||
setDefault(valueNode);
|
reset(valueNode);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package org.mvplugins.multiverse.core.configuration.handle;
|
||||||
|
|
||||||
|
public enum ConfigModifyType {
|
||||||
|
SET,
|
||||||
|
ADD,
|
||||||
|
REMOVE,
|
||||||
|
RESET
|
||||||
|
}
|
@ -1,7 +1,10 @@
|
|||||||
package org.mvplugins.multiverse.core.configuration.handle;
|
package org.mvplugins.multiverse.core.configuration.handle;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import io.vavr.control.Option;
|
||||||
import io.vavr.control.Try;
|
import io.vavr.control.Try;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
@ -10,6 +13,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import org.mvplugins.multiverse.core.configuration.migration.ConfigMigrator;
|
import org.mvplugins.multiverse.core.configuration.migration.ConfigMigrator;
|
||||||
import org.mvplugins.multiverse.core.configuration.node.ConfigNodeNotFoundException;
|
import org.mvplugins.multiverse.core.configuration.node.ConfigNodeNotFoundException;
|
||||||
|
import org.mvplugins.multiverse.core.configuration.node.ListValueNode;
|
||||||
import org.mvplugins.multiverse.core.configuration.node.NodeGroup;
|
import org.mvplugins.multiverse.core.configuration.node.NodeGroup;
|
||||||
import org.mvplugins.multiverse.core.configuration.node.ValueNode;
|
import org.mvplugins.multiverse.core.configuration.node.ValueNode;
|
||||||
|
|
||||||
@ -18,12 +22,12 @@ import org.mvplugins.multiverse.core.configuration.node.ValueNode;
|
|||||||
*/
|
*/
|
||||||
public abstract class GenericConfigHandle<C extends ConfigurationSection> {
|
public abstract class GenericConfigHandle<C extends ConfigurationSection> {
|
||||||
protected final @Nullable Logger logger;
|
protected final @Nullable Logger logger;
|
||||||
protected final @Nullable NodeGroup nodes;
|
protected final @NotNull NodeGroup nodes;
|
||||||
protected final @Nullable ConfigMigrator migrator;
|
protected final @Nullable ConfigMigrator migrator;
|
||||||
|
|
||||||
protected C config;
|
protected C config;
|
||||||
|
|
||||||
protected GenericConfigHandle(@Nullable Logger logger, @Nullable NodeGroup nodes, @Nullable ConfigMigrator migrator) {
|
protected GenericConfigHandle(@Nullable Logger logger, @NotNull NodeGroup nodes, @Nullable ConfigMigrator migrator) {
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
this.migrator = migrator;
|
this.migrator = migrator;
|
||||||
@ -67,8 +71,36 @@ public abstract class GenericConfigHandle<C extends ConfigurationSection> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<String> getNames() {
|
||||||
|
return nodes.getNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<String> getNamesThatSupports(ConfigModifyType configModifyType) {
|
||||||
|
return switch (configModifyType) {
|
||||||
|
case SET, RESET -> nodes.getNames();
|
||||||
|
case ADD, REMOVE -> nodes.stream()
|
||||||
|
.filter(node -> node instanceof ListValueNode)
|
||||||
|
.map(node -> ((ValueNode<?>) node).getName())
|
||||||
|
.filter(Option::isDefined)
|
||||||
|
.map(Option::get)
|
||||||
|
.toList();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public Try<Class> getTypeByName(@Nullable String name) {
|
||||||
|
return nodes.findNode(name, ValueNode.class)
|
||||||
|
.map(valueNode -> {
|
||||||
|
if (valueNode instanceof ListValueNode listValueNode) {
|
||||||
|
return listValueNode.getItemType();
|
||||||
|
}
|
||||||
|
return valueNode.getType();
|
||||||
|
})
|
||||||
|
.toTry(() -> new ConfigNodeNotFoundException(name));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value of a node, if the node has a default value, it will be returned if the node is not found.
|
* Gets the value of a node, if the node has a default value, it will be returned if the node is not found.
|
||||||
|
*
|
||||||
* @param name The name of the node.
|
* @param name The name of the node.
|
||||||
* @return The value of the node.
|
* @return The value of the node.
|
||||||
*/
|
*/
|
||||||
@ -78,17 +110,10 @@ public abstract class GenericConfigHandle<C extends ConfigurationSection> {
|
|||||||
.map(node -> get((ValueNode<Object>) node));
|
.map(node -> get((ValueNode<Object>) node));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public Try<Void> modify(@NotNull ConfigModifyType type, @Nullable String name, @Nullable Object value) {
|
||||||
* Gets the value of a node, if the node has a default value, it will be returned if the node is not found.
|
return nodes.findNode(name, ValueNode.class)
|
||||||
*
|
.toTry(() -> new ConfigNodeNotFoundException(name))
|
||||||
* @param node The node to get the value of.
|
.flatMapTry(node -> modify(type, node, value));
|
||||||
* @return The value of the node.
|
|
||||||
*/
|
|
||||||
public <T> T get(@NotNull ValueNode<T> node) {
|
|
||||||
if (node.getSerializer() == null) {
|
|
||||||
return config.getObject(node.getPath(), node.getType(), node.getDefaultValue());
|
|
||||||
}
|
|
||||||
return node.getSerializer().deserialize(config.get(node.getPath(), node.getDefaultValue()), node.getType());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,9 +124,68 @@ public abstract class GenericConfigHandle<C extends ConfigurationSection> {
|
|||||||
* @return True if the value was set, false otherwise.
|
* @return True if the value was set, false otherwise.
|
||||||
*/
|
*/
|
||||||
public Try<Void> set(@Nullable String name, Object value) {
|
public Try<Void> set(@Nullable String name, Object value) {
|
||||||
|
//noinspection unchecked
|
||||||
return nodes.findNode(name, ValueNode.class)
|
return nodes.findNode(name, ValueNode.class)
|
||||||
.toTry(() -> new ConfigNodeNotFoundException(name))
|
.toTry(() -> new ConfigNodeNotFoundException(name))
|
||||||
.flatMap(node -> set(node, value));
|
.flatMapTry(node -> set(node, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Try<Void> add(@Nullable String name, Object value) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return nodes.findNode(name, ListValueNode.class)
|
||||||
|
.toTry(() -> new ConfigNodeNotFoundException(name))
|
||||||
|
.flatMapTry(node -> add(node, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Try<Void> remove(@Nullable String name, Object value) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return nodes.findNode(name, ListValueNode.class)
|
||||||
|
.toTry(() -> new ConfigNodeNotFoundException(name))
|
||||||
|
.flatMapTry(node -> remove(node, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Try<Void> reset(@Nullable String name) {
|
||||||
|
return nodes.findNode(name, ValueNode.class)
|
||||||
|
.toTry(() -> new ConfigNodeNotFoundException(name))
|
||||||
|
.flatMapTry(this::reset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of a node, if the node has a default value, it will be returned if the node is not found.
|
||||||
|
*
|
||||||
|
* @param node The node to get the value of.
|
||||||
|
* @param <T> The type of the node value.
|
||||||
|
* @return The value of the node.
|
||||||
|
*/
|
||||||
|
public <T> T get(@NotNull ValueNode<T> node) {
|
||||||
|
if (node.getSerializer() == null) {
|
||||||
|
return config.getObject(node.getPath(), node.getType(), node.getDefaultValue());
|
||||||
|
}
|
||||||
|
return node.getSerializer().deserialize(config.get(node.getPath(), node.getDefaultValue()), node.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Try<Void> modify(@NotNull ConfigModifyType type, @NotNull ValueNode node, @Nullable Object value) {
|
||||||
|
return switch (type) {
|
||||||
|
case SET -> set(node, value);
|
||||||
|
case REMOVE -> {
|
||||||
|
if (!(node instanceof ListValueNode listNode)) {
|
||||||
|
yield Try.failure(new IllegalArgumentException("Node is not a list"));
|
||||||
|
}
|
||||||
|
yield remove(listNode, value);
|
||||||
|
}
|
||||||
|
case ADD -> {
|
||||||
|
if (!(node instanceof ListValueNode listNode)) {
|
||||||
|
yield Try.failure(new IllegalArgumentException("Node is not a list"));
|
||||||
|
}
|
||||||
|
yield add(listNode, value);
|
||||||
|
}
|
||||||
|
case RESET -> {
|
||||||
|
if (value != null) {
|
||||||
|
yield Try.failure(new IllegalArgumentException("Reset type cannot have a value"));
|
||||||
|
}
|
||||||
|
yield reset(node);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,30 +193,62 @@ public abstract class GenericConfigHandle<C extends ConfigurationSection> {
|
|||||||
*
|
*
|
||||||
* @param node The node to set the value of.
|
* @param node The node to set the value of.
|
||||||
* @param value The value to set.
|
* @param value The value to set.
|
||||||
* @return True if the value was set, false otherwise.
|
|
||||||
* @param <T> The type of the node value.
|
* @param <T> The type of the node value.
|
||||||
|
* @return Empty try if the value was set, try containing an error otherwise.
|
||||||
*/
|
*/
|
||||||
public <T> Try<Void> set(@NotNull ValueNode<T> node, T value) {
|
public <T> Try<Void> set(@NotNull ValueNode<T> node, T value) {
|
||||||
return node.validate(value).map(ignore -> {
|
return node.validate(value).map(ignore -> {
|
||||||
T oldValue = get(node);
|
T oldValue = get(node);
|
||||||
if (node.getSerializer() != null) {
|
var serialized = node.getSerializer() != null
|
||||||
var serialized = node.getSerializer().serialize(value, node.getType());
|
? node.getSerializer().serialize(value, node.getType())
|
||||||
|
: value;
|
||||||
config.set(node.getPath(), serialized);
|
config.set(node.getPath(), serialized);
|
||||||
} else {
|
|
||||||
config.set(node.getPath(), value);
|
|
||||||
}
|
|
||||||
node.onSetValue(oldValue, get(node));
|
node.onSetValue(oldValue, get(node));
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <I> Try<Void> add(@NotNull ListValueNode<I> node, I value) {
|
||||||
|
// TODO: Serialize value, Validate value
|
||||||
|
return Try.run(() -> {
|
||||||
|
var serialized = node.getItemSerializer() != null
|
||||||
|
? node.getItemSerializer().serialize(value, node.getItemType())
|
||||||
|
: value;
|
||||||
|
List list = get(node);
|
||||||
|
if (list == null) {
|
||||||
|
throw new IllegalArgumentException("List is null");
|
||||||
|
}
|
||||||
|
list.add(serialized);
|
||||||
|
config.set(node.getPath(), list);
|
||||||
|
node.onSetValue(list, get(node));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public <I> Try<Void> remove(@NotNull ListValueNode<I> node, I value) {
|
||||||
|
return Try.run(() -> {
|
||||||
|
var serialized = node.getItemSerializer() != null
|
||||||
|
? node.getItemSerializer().serialize(value, node.getItemType())
|
||||||
|
: value;
|
||||||
|
List list = get(node);
|
||||||
|
if (list == null) {
|
||||||
|
throw new IllegalArgumentException("List is null");
|
||||||
|
}
|
||||||
|
if (!list.remove(serialized)) {
|
||||||
|
throw new IllegalArgumentException("Value not found in list");
|
||||||
|
}
|
||||||
|
config.set(node.getPath(), list);
|
||||||
|
node.onSetItemValue(value, null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the default value of a node.
|
* Sets the default value of a node.
|
||||||
*
|
*
|
||||||
* @param node The node to set the default value of.
|
* @param node The node to set the default value of.
|
||||||
|
* @return Empty try if the value was set, try containing an error otherwise.
|
||||||
*/
|
*/
|
||||||
public void setDefault(@NotNull ValueNode node) {
|
public <T> Try<Void> reset(@NotNull ValueNode<T> node) {
|
||||||
config.set(node.getPath(), node.getDefaultValue());
|
return Try.run(() -> config.set(node.getPath(), node.getDefaultValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,7 +263,8 @@ public abstract class GenericConfigHandle<C extends ConfigurationSection> {
|
|||||||
protected @Nullable NodeGroup nodes;
|
protected @Nullable NodeGroup nodes;
|
||||||
protected @Nullable ConfigMigrator migrator;
|
protected @Nullable ConfigMigrator migrator;
|
||||||
|
|
||||||
protected Builder() {}
|
protected Builder() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the logger.
|
* Sets the logger.
|
||||||
|
@ -66,7 +66,7 @@ public class ConfigHeaderNode implements CommentedNode {
|
|||||||
comment = "# " + comment;
|
comment = "# " + comment;
|
||||||
}
|
}
|
||||||
comments.add(comment);
|
comments.add(comment);
|
||||||
return (B) this;
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,5 +77,10 @@ public class ConfigHeaderNode implements CommentedNode {
|
|||||||
public @NotNull ConfigHeaderNode build() {
|
public @NotNull ConfigHeaderNode build() {
|
||||||
return new ConfigHeaderNode(path, comments.toArray(new String[0]));
|
return new ConfigHeaderNode(path, comments.toArray(new String[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected B self() {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (B) this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package org.mvplugins.multiverse.core.configuration.node;
|
|||||||
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import io.vavr.control.Try;
|
import io.vavr.control.Try;
|
||||||
@ -10,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A node that contains a value.
|
* A node that contains a value.
|
||||||
|
*
|
||||||
* @param <T> The type of the value.
|
* @param <T> The type of the value.
|
||||||
*/
|
*/
|
||||||
public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
|
public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
|
||||||
@ -19,19 +21,18 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
|
|||||||
*
|
*
|
||||||
* @param path The path of the node.
|
* @param path The path of the node.
|
||||||
* @param type The type of the value.
|
* @param type The type of the value.
|
||||||
* @return The new builder.
|
|
||||||
* @param <T> The type of the value.
|
* @param <T> The type of the value.
|
||||||
|
* @return The new builder.
|
||||||
*/
|
*/
|
||||||
public static @NotNull <T> ConfigNode.Builder<T, ? extends ConfigNode.Builder<T, ?>> builder(
|
public static @NotNull <T> ConfigNode.Builder<T, ? extends ConfigNode.Builder<T, ?>> builder(
|
||||||
@NotNull String path,
|
@NotNull String path,
|
||||||
@NotNull Class<T> type
|
@NotNull Class<T> type) {
|
||||||
) {
|
|
||||||
return new ConfigNode.Builder<>(path, type);
|
return new ConfigNode.Builder<>(path, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final @Nullable String name;
|
protected final @Nullable String name;
|
||||||
protected final @NotNull Class<T> type;
|
protected final @NotNull Class<T> type;
|
||||||
protected final @Nullable T defaultValue;
|
protected final @Nullable Supplier<T> defaultValueSupplier;
|
||||||
protected final @Nullable NodeSerializer<T> serializer;
|
protected final @Nullable NodeSerializer<T> serializer;
|
||||||
protected final @Nullable Function<T, Try<Void>> validator;
|
protected final @Nullable Function<T, Try<Void>> validator;
|
||||||
protected final @Nullable BiConsumer<T, T> onSetValue;
|
protected final @Nullable BiConsumer<T, T> onSetValue;
|
||||||
@ -41,15 +42,14 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
|
|||||||
@NotNull String[] comments,
|
@NotNull String[] comments,
|
||||||
@Nullable String name,
|
@Nullable String name,
|
||||||
@NotNull Class<T> type,
|
@NotNull Class<T> type,
|
||||||
@Nullable T defaultValue,
|
@Nullable Supplier<T> defaultValueSupplier,
|
||||||
@Nullable NodeSerializer<T> serializer,
|
@Nullable NodeSerializer<T> serializer,
|
||||||
@Nullable Function<T, Try<Void>> validator,
|
@Nullable Function<T, Try<Void>> validator,
|
||||||
@Nullable BiConsumer<T, T> onSetValue
|
@Nullable BiConsumer<T, T> onSetValue) {
|
||||||
) {
|
|
||||||
super(path, comments);
|
super(path, comments);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.defaultValue = defaultValue;
|
this.defaultValueSupplier = defaultValueSupplier;
|
||||||
this.serializer = serializer;
|
this.serializer = serializer;
|
||||||
this.validator = validator;
|
this.validator = validator;
|
||||||
this.onSetValue = onSetValue;
|
this.onSetValue = onSetValue;
|
||||||
@ -76,7 +76,7 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public @Nullable T getDefaultValue() {
|
public @Nullable T getDefaultValue() {
|
||||||
return defaultValue;
|
return defaultValueSupplier != null ? defaultValueSupplier.get() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable NodeSerializer<T> getSerializer() {
|
public @Nullable NodeSerializer<T> getSerializer() {
|
||||||
@ -115,7 +115,7 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
|
|||||||
|
|
||||||
protected @Nullable String name;
|
protected @Nullable String name;
|
||||||
protected @NotNull final Class<T> type;
|
protected @NotNull final Class<T> type;
|
||||||
protected @Nullable T defaultValue;
|
protected @Nullable Supplier<T> defaultValueSupplier;
|
||||||
protected @Nullable NodeSerializer<T> serializer;
|
protected @Nullable NodeSerializer<T> serializer;
|
||||||
protected @Nullable Function<T, Try<Void>> validator;
|
protected @Nullable Function<T, Try<Void>> validator;
|
||||||
protected @Nullable BiConsumer<T, T> onSetValue;
|
protected @Nullable BiConsumer<T, T> onSetValue;
|
||||||
@ -142,8 +142,19 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
|
|||||||
* @return This builder.
|
* @return This builder.
|
||||||
*/
|
*/
|
||||||
public @NotNull B defaultValue(@NotNull T defaultValue) {
|
public @NotNull B defaultValue(@NotNull T defaultValue) {
|
||||||
this.defaultValue = defaultValue;
|
this.defaultValueSupplier = () -> defaultValue;
|
||||||
return (B) this;
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the default value for this node.
|
||||||
|
*
|
||||||
|
* @param defaultValueSupplier The supplier for the default value.
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public @NotNull B defaultValue(@NotNull Supplier<T> defaultValueSupplier) {
|
||||||
|
this.defaultValueSupplier = defaultValueSupplier;
|
||||||
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,17 +165,17 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
|
|||||||
*/
|
*/
|
||||||
public @NotNull B name(@Nullable String name) {
|
public @NotNull B name(@Nullable String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
return (B) this;
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull B serializer(@NotNull NodeSerializer<T> serializer) {
|
public @NotNull B serializer(@NotNull NodeSerializer<T> serializer) {
|
||||||
this.serializer = serializer;
|
this.serializer = serializer;
|
||||||
return (B) this;
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull B validator(@NotNull Function<T, Try<Void>> validator) {
|
public @NotNull B validator(@NotNull Function<T, Try<Void>> validator) {
|
||||||
this.validator = validator;
|
this.validator = validator;
|
||||||
return (B) this;
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,7 +186,7 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
|
|||||||
*/
|
*/
|
||||||
public @NotNull B onSetValue(@NotNull BiConsumer<T, T> onSetValue) {
|
public @NotNull B onSetValue(@NotNull BiConsumer<T, T> onSetValue) {
|
||||||
this.onSetValue = onSetValue;
|
this.onSetValue = onSetValue;
|
||||||
return (B) this;
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -183,7 +194,15 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ConfigNode<T> build() {
|
public @NotNull ConfigNode<T> build() {
|
||||||
return new ConfigNode<>(path, comments.toArray(new String[0]), name, type, defaultValue, serializer, validator, onSetValue);
|
return new ConfigNode<>(
|
||||||
|
path,
|
||||||
|
comments.toArray(new String[0]),
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
defaultValueSupplier,
|
||||||
|
serializer,
|
||||||
|
validator,
|
||||||
|
onSetValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,190 @@
|
|||||||
|
package org.mvplugins.multiverse.core.configuration.node;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import io.vavr.control.Try;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
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 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 NodeSerializer<List<I>> serializer,
|
||||||
|
@Nullable Function<List<I>, Try<Void>> validator,
|
||||||
|
@Nullable BiConsumer<List<I>, List<I>> onSetValue,
|
||||||
|
@NotNull Class<I> itemType,
|
||||||
|
@Nullable NodeSerializer<I> itemSerializer,
|
||||||
|
@Nullable Function<I, Try<Void>> itemValidator,
|
||||||
|
@Nullable BiConsumer<I, I> onSetItemValue) {
|
||||||
|
super(path, comments, name, type, defaultValueSupplier, serializer, validator, onSetValue);
|
||||||
|
this.itemType = itemType;
|
||||||
|
this.itemSerializer = itemSerializer;
|
||||||
|
this.itemValidator = itemValidator;
|
||||||
|
this.onSetItemValue = onSetItemValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public @NotNull Class<I> getItemType() {
|
||||||
|
return 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 NodeSerializer<I> itemSerializer;
|
||||||
|
protected Function<I, Try<Void>> itemValidator;
|
||||||
|
protected 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.defaultValueSupplier = () -> (List<I>) new ArrayList<Object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the serializer for the node.
|
||||||
|
*
|
||||||
|
* @param serializer The serializer for the node.
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public @NotNull B itemSerializer(@Nullable NodeSerializer<I> serializer) {
|
||||||
|
this.itemSerializer = serializer;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the validator for the node.
|
||||||
|
*
|
||||||
|
* @param validator The validator for the node.
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public @NotNull B itemValidator(@Nullable Function<I, Try<Void>> validator) {
|
||||||
|
this.itemValidator = validator;
|
||||||
|
if (validator == null) {
|
||||||
|
setDefaultValidator();
|
||||||
|
}
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDefaultValidator() {
|
||||||
|
this.validator = value -> {
|
||||||
|
if (value != null) {
|
||||||
|
return Try.sequence(value.stream().map(itemValidator).toList()).map(v -> null);
|
||||||
|
}
|
||||||
|
return Try.success(null);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the onSetValue for the node.
|
||||||
|
*
|
||||||
|
* @param onSetValue The onSetValue for the node.
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public @NotNull B onSetItemValue(@Nullable BiConsumer<I, I> onSetValue) {
|
||||||
|
this.onSetItemValue = onSetValue;
|
||||||
|
if (onSetValue == null) {
|
||||||
|
setDefaultOnSetValue();
|
||||||
|
}
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ListConfigNode<I> build() {
|
||||||
|
return new ListConfigNode<>(
|
||||||
|
path,
|
||||||
|
comments.toArray(new String[0]),
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
defaultValueSupplier,
|
||||||
|
serializer,
|
||||||
|
validator,
|
||||||
|
onSetValue,
|
||||||
|
itemType,
|
||||||
|
itemSerializer,
|
||||||
|
itemValidator,
|
||||||
|
onSetItemValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package org.mvplugins.multiverse.core.configuration.node;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.vavr.control.Try;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
@ -9,6 +9,7 @@ import java.util.Map;
|
|||||||
import io.github.townyadvanced.commentedconfiguration.setting.CommentedNode;
|
import io.github.townyadvanced.commentedconfiguration.setting.CommentedNode;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of {@link CommentedNode}s, with mappings to nodes by name.
|
* A collection of {@link CommentedNode}s, with mappings to nodes by name.
|
||||||
@ -49,10 +50,6 @@ public class NodeGroup implements Collection<Node> {
|
|||||||
return nodesMap.keySet();
|
return nodesMap.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Node> getNodesMap() {
|
|
||||||
return nodesMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the node with the given name.
|
* Gets the node with the given name.
|
||||||
*
|
*
|
||||||
@ -68,9 +65,10 @@ public class NodeGroup implements Collection<Node> {
|
|||||||
*
|
*
|
||||||
* @param name The name of the node to get.
|
* @param name The name of the node to get.
|
||||||
* @param type The type of the node to get.
|
* @param type The type of the node to get.
|
||||||
|
* @param <T> The type of the node.
|
||||||
* @return The node with the given name, or {@link Option.None} if no node with the given name exists.
|
* @return The node with the given name, or {@link Option.None} if no node with the given name exists.
|
||||||
*/
|
*/
|
||||||
public <T extends Node> Option<T> findNode(String name, Class<T> type) {
|
public <T extends Node> @NotNull Option<T> findNode(@Nullable String name, @NotNull Class<T> type) {
|
||||||
return Option.of(nodesMap.get(name)).map(node -> type.isAssignableFrom(node.getClass()) ? (T) node : null);
|
return Option.of(nodesMap.get(name)).map(node -> type.isAssignableFrom(node.getClass()) ? (T) node : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import org.mvplugins.multiverse.core.configuration.handle.ConfigModifyType;
|
||||||
import org.mvplugins.multiverse.core.world.configuration.AllowedPortalType;
|
import org.mvplugins.multiverse.core.world.configuration.AllowedPortalType;
|
||||||
import org.mvplugins.multiverse.core.worldnew.config.WorldConfig;
|
import org.mvplugins.multiverse.core.worldnew.config.WorldConfig;
|
||||||
|
|
||||||
@ -66,6 +67,14 @@ public class MultiverseWorld {
|
|||||||
return worldConfig.getConfigurablePropertyNames();
|
return worldConfig.getConfigurablePropertyNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<String> getConfigurablePropertyNames(ConfigModifyType configModifyType) {
|
||||||
|
return worldConfig.getConfigurablePropertyNames(configModifyType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Try<Class> getPropertyType(String name) {
|
||||||
|
return worldConfig.getPropertyType(name);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a property on this world.
|
* Gets a property on this world.
|
||||||
*
|
*
|
||||||
@ -87,6 +96,10 @@ public class MultiverseWorld {
|
|||||||
return worldConfig.setProperty(name, value);
|
return worldConfig.setProperty(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Try<Void> modifyProperty(ConfigModifyType type, String name, Object value) {
|
||||||
|
return worldConfig.modifyProperty(type, name, value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether or not Multiverse should auto-adjust the spawn for this world.
|
* Gets whether or not Multiverse should auto-adjust the spawn for this world.
|
||||||
*
|
*
|
||||||
|
@ -737,6 +737,17 @@ public class WorldManager {
|
|||||||
return !isLoadedWorld(worldName) && isWorld(worldName);
|
return !isLoadedWorld(worldName) && isWorld(worldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a world that may or may not be loaded. It will an {@link LoadedMultiverseWorld} if the world is loaded,
|
||||||
|
* otherwise returns an {@link MultiverseWorld} instance.
|
||||||
|
*
|
||||||
|
* @param world The bukkit world to get.
|
||||||
|
* @return The world if it exists.
|
||||||
|
*/
|
||||||
|
public Option<MultiverseWorld> getWorld(@Nullable World world) {
|
||||||
|
return world == null ? Option.none() : getWorld(world.getName());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a world that may or may not be loaded. It will an {@link LoadedMultiverseWorld} if the world is loaded,
|
* Get a world that may or may not be loaded. It will an {@link LoadedMultiverseWorld} if the world is loaded,
|
||||||
* otherwise returns an {@link MultiverseWorld} instance.
|
* otherwise returns an {@link MultiverseWorld} instance.
|
||||||
|
@ -14,6 +14,7 @@ import org.bukkit.configuration.ConfigurationSection;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import org.mvplugins.multiverse.core.configuration.handle.ConfigModifyType;
|
||||||
import org.mvplugins.multiverse.core.configuration.handle.ConfigurationSectionHandle;
|
import org.mvplugins.multiverse.core.configuration.handle.ConfigurationSectionHandle;
|
||||||
import org.mvplugins.multiverse.core.configuration.migration.BooleanMigratorAction;
|
import org.mvplugins.multiverse.core.configuration.migration.BooleanMigratorAction;
|
||||||
import org.mvplugins.multiverse.core.configuration.migration.ConfigMigrator;
|
import org.mvplugins.multiverse.core.configuration.migration.ConfigMigrator;
|
||||||
@ -116,7 +117,15 @@ public final class WorldConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> getConfigurablePropertyNames() {
|
public Collection<String> getConfigurablePropertyNames() {
|
||||||
return configNodes.getNodes().getNames();
|
return configHandle.getNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<String> getConfigurablePropertyNames(ConfigModifyType configModifyType) {
|
||||||
|
return configHandle.getNamesThatSupports(configModifyType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Try<Class> getPropertyType(String name) {
|
||||||
|
return configHandle.getTypeByName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Try<Object> getProperty(String name) {
|
public Try<Object> getProperty(String name) {
|
||||||
@ -127,6 +136,10 @@ public final class WorldConfig {
|
|||||||
return configHandle.set(name, value);
|
return configHandle.set(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Try<Void> modifyProperty(ConfigModifyType type, String name, Object value) {
|
||||||
|
return configHandle.modify(type, name, value);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getAdjustSpawn() {
|
public boolean getAdjustSpawn() {
|
||||||
return configHandle.get(configNodes.ADJUST_SPAWN);
|
return configHandle.get(configNodes.ADJUST_SPAWN);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import org.bukkit.World;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import org.mvplugins.multiverse.core.configuration.node.ConfigNode;
|
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.Node;
|
||||||
import org.mvplugins.multiverse.core.configuration.node.NodeGroup;
|
import org.mvplugins.multiverse.core.configuration.node.NodeGroup;
|
||||||
import org.mvplugins.multiverse.core.world.configuration.AllowedPortalType;
|
import org.mvplugins.multiverse.core.world.configuration.AllowedPortalType;
|
||||||
@ -212,9 +213,8 @@ public class WorldConfigNodes {
|
|||||||
})
|
})
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
final ConfigNode<List> SPAWNING_ANIMALS_EXCEPTIONS = node(ConfigNode
|
final ListConfigNode<String> SPAWNING_ANIMALS_EXCEPTIONS = node(ListConfigNode
|
||||||
.builder("spawning.animals.exceptions", List.class)
|
.listBuilder("spawning.animals.exceptions", String.class)
|
||||||
.defaultValue(new ArrayList<>())
|
|
||||||
.name("spawning-animals-exceptions")
|
.name("spawning-animals-exceptions")
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
@ -238,14 +238,13 @@ public class WorldConfigNodes {
|
|||||||
})
|
})
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
final ConfigNode<List> SPAWNING_MONSTERS_EXCEPTIONS = node(ConfigNode
|
final ListConfigNode<String> SPAWNING_MONSTERS_EXCEPTIONS = node(ListConfigNode
|
||||||
.builder("spawning.monsters.exceptions", List.class)
|
.listBuilder("spawning.monsters.exceptions", String.class)
|
||||||
.defaultValue(new ArrayList<>())
|
|
||||||
.name("spawning-monsters-exceptions")
|
.name("spawning-monsters-exceptions")
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
final ConfigNode<List> WORLD_BLACKLIST = node(ConfigNode.builder("world-blacklist", List.class)
|
final ListConfigNode<String> WORLD_BLACKLIST = node(ListConfigNode
|
||||||
.defaultValue(new ArrayList<>())
|
.listBuilder("world-blacklist", String.class)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
final ConfigNode<Double> VERSION = node(ConfigNode.builder("version", Double.class)
|
final ConfigNode<Double> VERSION = node(ConfigNode.builder("version", Double.class)
|
||||||
|
Loading…
Reference in New Issue
Block a user