feat: Implement config names and basic config command

This commit is contained in:
Ben Woo 2023-03-23 23:59:19 +08:00
parent f1a9d3a723
commit 7759a37b4e
No known key found for this signature in database
GPG Key ID: FB2A3645536E12C8
9 changed files with 214 additions and 32 deletions

View File

@ -23,6 +23,7 @@ import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.commands.CheckCommand;
import com.onarandombox.MultiverseCore.commands.CloneCommand;
import com.onarandombox.MultiverseCore.commands.ConfigCommand;
import com.onarandombox.MultiverseCore.commands.ConfirmCommand;
import com.onarandombox.MultiverseCore.commands.CreateCommand;
import com.onarandombox.MultiverseCore.commands.DebugCommand;
@ -89,7 +90,7 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
private final MVWorldManager worldManager = new SimpleMVWorldManager(this);
// Configurations
private DefaultMVConfig config;
private MVConfig config;
// Listeners
private MVChatListener chatListener;
@ -196,6 +197,7 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
this.commandManager = new MVCommandManager(this);
this.commandManager.registerCommand(new CheckCommand(this));
this.commandManager.registerCommand(new CloneCommand(this));
this.commandManager.registerCommand(new ConfigCommand(this));
this.commandManager.registerCommand(new ConfirmCommand(this));
this.commandManager.registerCommand(new CreateCommand(this));
this.commandManager.registerCommand(new DebugCommand(this));
@ -369,9 +371,7 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
*/
@Override
public void loadConfigs() {
config = new DefaultMVConfig(this);
config.load();
config.save();
config = DefaultMVConfig.init(this);
this.worldManager.loadWorldConfig(new File(getDataFolder(), "worlds.yml"));

View File

@ -1,6 +1,14 @@
package com.onarandombox.MultiverseCore.api;
public interface MVConfig {
boolean load();
void save();
Object getProperty(String name);
void setProperty(String name, Object value);
/**
* Sets enforceAccess.
* @param enforceAccess The new value.

View File

@ -0,0 +1,50 @@
package com.onarandombox.MultiverseCore.commands;
import co.aikar.commands.BukkitCommandIssuer;
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.Optional;
import co.aikar.commands.annotation.Single;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVConfig;
import org.jetbrains.annotations.NotNull;
@CommandAlias("mv")
public class ConfigCommand extends MultiverseCoreCommand {
private final MVConfig config;
public ConfigCommand(@NotNull MultiverseCore plugin) {
super(plugin);
this.config = plugin.getMVConfig();
}
@Subcommand("config")
@CommandPermission("multiverse.core.config")
@CommandCompletion("@mvconfig") //TODO
@Syntax("<name> [new-value]")
@Description("") //TODO
public void onConfigCommand(BukkitCommandIssuer issuer,
@Syntax("<name>")
@Description("") //TODO
String name,
@Optional
@Single
@Syntax("[new-value]")
@Description("") //TODO
String value
) {
if (value == null) {
issuer.sendMessage(name + "is currently set to " + config.getProperty(name));
return;
}
config.setProperty(name, value);
config.save();
issuer.sendMessage("Set " + name + " to " + value);
}
}

View File

@ -17,6 +17,19 @@ public class DefaultMVConfig implements MVConfig {
public static final String CONFIG_FILENAME = "config.yml";
public static final double CONFIG_VERSION = 5.0;
/**
* Creates a new DefaultMVConfig instance and loads the configuration automatically.
*
* @param core The MultiverseCore instance.
* @return The new DefaultMVConfig instance.
*/
public static DefaultMVConfig init(MultiverseCore core) {
var config = new DefaultMVConfig(core);
config.load();
config.save();
return config;
}
private final Path configPath;
private final MVSettings settings;
@ -27,7 +40,7 @@ public class DefaultMVConfig implements MVConfig {
settings = MVSettings.builder(configPath)
.logger(Logging.getLogger())
.defaultNodes(MVConfigNodes.getNodes())
.nodes(MVConfigNodes.getNodes())
.migrator(ConfigMigrator.builder(MVConfigNodes.VERSION)
.addVersionMigrator(VersionMigrator.builder(5.0)
.addAction(MoveMigratorAction.of("multiverse-configuration.enforceaccess", "world.enforce-access"))
@ -67,14 +80,26 @@ public class DefaultMVConfig implements MVConfig {
}
}
@Override
public boolean load() {
return settings.load();
}
@Override
public void save() {
settings.save();
}
@Override
public Object getProperty(String name) {
return settings.get(name);
}
@Override
public void setProperty(String name, Object value) {
settings.set(name, value);
}
@Override
public void setEnforceAccess(boolean enforceAccess) {
settings.set(MVConfigNodes.ENFORCE_ACCESS, enforceAccess);

View File

@ -1,16 +1,18 @@
package com.onarandombox.MultiverseCore.configuration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.onarandombox.MultiverseCore.utils.settings.node.MVCommentedNode;
import com.onarandombox.MultiverseCore.utils.settings.node.MVValueNode;
import com.onarandombox.MultiverseCore.utils.settings.node.NodeGroup;
import io.github.townyadvanced.commentedconfiguration.setting.CommentedNode;
public class MVConfigNodes {
private static final List<CommentedNode> nodes = new ArrayList<>();
private static final NodeGroup nodes = new NodeGroup();
public static List<CommentedNode> getNodes() {
public static NodeGroup getNodes() {
return nodes;
}
@ -54,6 +56,7 @@ public class MVConfigNodes {
.comment("If this is set to true, players will only be able to enter worlds they have")
.comment("the `mv.access.<worldname>` permission.")
.defaultValue(false)
.name("enforce-access")
.build());
public static final MVValueNode<Boolean> ENFORCE_GAMEMODE = node(MVValueNode.builder("world.enforce-gamemode", Boolean.class)
@ -166,5 +169,6 @@ public class MVConfigNodes {
.comment("This just signifies the version number so we can see what version of config you have.")
.comment("NEVER TOUCH THIS VALUE")
.defaultValue(DefaultMVConfig.CONFIG_VERSION)
.name(null)
.build());
}

View File

@ -3,10 +3,11 @@ package com.onarandombox.MultiverseCore.utils.settings;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Collection;
import java.util.logging.Logger;
import com.onarandombox.MultiverseCore.utils.settings.migration.ConfigMigrator;
import com.onarandombox.MultiverseCore.utils.settings.node.NodeGroup;
import io.github.townyadvanced.commentedconfiguration.CommentedConfiguration;
import io.github.townyadvanced.commentedconfiguration.setting.CommentedNode;
import io.github.townyadvanced.commentedconfiguration.setting.TypedValueNode;
@ -27,7 +28,7 @@ public class MVSettings {
protected final Path configPath;
protected final Logger logger;
protected final List<CommentedNode> defaultNodes;
protected final NodeGroup nodes;
protected final ConfigMigrator migrator;
@ -38,12 +39,12 @@ public class MVSettings {
*
* @param configPath The path to the configuration file.
* @param logger The Logger to use for error messages.
* @param defaultNodes The default node values to add to the configuration.
* @param nodes All the node path and values for the configuration.
* @param migrator The migrator to use for migrating the configuration.
*/
protected MVSettings(@NotNull Path configPath, @Nullable Logger logger, @Nullable List<CommentedNode> defaultNodes, ConfigMigrator migrator) {
protected MVSettings(@NotNull Path configPath, @Nullable Logger logger, @NotNull NodeGroup nodes, ConfigMigrator migrator) {
this.configPath = configPath;
this.defaultNodes = defaultNodes;
this.nodes = nodes;
this.logger = logger;
this.migrator = migrator;
}
@ -86,6 +87,9 @@ public class MVSettings {
return true;
}
/**
* Migration of the configuration based on {@link ConfigMigrator}.
*/
protected void migrateConfig() {
migrator.migrate(this);
}
@ -94,17 +98,16 @@ public class MVSettings {
* Adds default node values to the configuration if they are not already present.
*/
protected void addDefaultNodes() {
if (defaultNodes == null || defaultNodes.isEmpty()) {
if (nodes.isEmpty()) {
return;
}
CommentedConfiguration tempConfig = new CommentedConfiguration(configPath, logger);
for (CommentedNode node : defaultNodes) {
for (CommentedNode node : nodes) {
if (node.getComments().length > 0) {
tempConfig.addComment(node.getPath(), node.getComments());
}
if (node instanceof ValueNode) {
ValueNode valueNode = (ValueNode) node;
if (node instanceof ValueNode valueNode) {
tempConfig.set(node.getPath(), get(valueNode));
}
}
@ -133,6 +136,18 @@ public class MVSettings {
return config.get(node.getPath(), node.getDefaultValue());
}
/**
* Get the value of the node by name.
*
* @param name The name of the node to get the value of.
* @return The value of the node.
*/
public Object get(@NotNull String name) {
return nodes.findNode(name)
.map(node -> (node instanceof ValueNode valueNode) ? get(valueNode) : null)
.orElse(null);
}
/**
* Gets the value of a node, if the node has a default value, it will be returned if the node is not found.
*
@ -166,6 +181,20 @@ public class MVSettings {
config.set(node.getPath(), value);
}
/**
* Set the value of the node by name.
*
* @param name The name of the node to set the value of.
* @param value The value to set.
*/
public void set(@NotNull String name, Object value) {
nodes.findNode(name).ifPresent(node -> {
if (node instanceof ValueNode valueNode) {
set(valueNode, value);
}
});
}
/**
* Sets the value of a node, if the validator is not null, it will be tested first.
*
@ -177,12 +206,18 @@ public class MVSettings {
config.set(node.getPath(), value);
}
/**
* Sets the default value of a node.
*
* @param node The node to set the default value of.
* @param <T> The type of the node value.
*/
public <T> void setDefault(@NotNull TypedValueNode<T> node) {
config.set(node.getPath(), node.getDefaultValue());
}
/**
* Gets the configuration object.
* Gets the inner configuration object.
*
* @return The configuration object.
*/
@ -194,7 +229,7 @@ public class MVSettings {
private final Path configPath;
private Logger logger;
private List<CommentedNode> defaultNodes;
private NodeGroup nodes;
private ConfigMigrator migrator;
@ -215,8 +250,8 @@ public class MVSettings {
return this;
}
public Builder defaultNodes(@Nullable List<CommentedNode> defaultNodes) {
this.defaultNodes = defaultNodes;
public Builder nodes(@Nullable NodeGroup nodes) {
this.nodes = nodes;
return this;
}
@ -226,7 +261,7 @@ public class MVSettings {
}
public MVSettings build() {
return new MVSettings(configPath, logger, defaultNodes, migrator);
return new MVSettings(configPath, logger, nodes, migrator);
}
}
}

View File

@ -1,23 +1,23 @@
package com.onarandombox.MultiverseCore.utils.settings.node;
import io.github.townyadvanced.commentedconfiguration.setting.TypedValueNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class MVValueNode<T> extends MVCommentedNode implements TypedValueNode<T> {
public class MVValueNode<T> extends MVCommentedNode implements NamedValueNode<T> {
public static <T> Builder<T, ? extends Builder> builder(String path, Class<T> type) {
return new Builder<>(path, type);
}
protected final Class<T> type;
protected final T defaultValue;
protected final String name;
private final T defaultValue;
protected MVValueNode(String path, String[] comments, Class<T> type, T defaultValue) {
protected MVValueNode(String path, String[] comments, Class<T> type, T defaultValue, String name) {
super(path, comments);
this.type = type;
this.defaultValue = defaultValue;
this.name = name;
}
@Override
@ -30,14 +30,21 @@ public class MVValueNode<T> extends MVCommentedNode implements TypedValueNode<T>
return defaultValue;
}
@Override
public String getName() {
return name;
}
public static class Builder<T, B extends Builder<T, B>> extends MVCommentedNode.Builder<B> {
protected final Class<T> type;
protected T defaultValue;
private String name;
public Builder(String path, Class<T> type) {
super(path);
this.type = type;
this.name = path;
}
public B defaultValue(T defaultValue) {
@ -45,9 +52,14 @@ public class MVValueNode<T> extends MVCommentedNode implements TypedValueNode<T>
return (B) this;
}
public B name(String name) {
this.name = name;
return (B) this;
}
@Override
public MVValueNode<T> build() {
return new MVValueNode<>(path, comments.toArray(new String[0]), type, defaultValue);
return new MVValueNode<>(path, comments.toArray(new String[0]), type, defaultValue, name);
}
}
}

View File

@ -0,0 +1,7 @@
package com.onarandombox.MultiverseCore.utils.settings.node;
import io.github.townyadvanced.commentedconfiguration.setting.TypedValueNode;
public interface NamedValueNode<T> extends TypedValueNode<T> {
String getName();
}

View File

@ -1,18 +1,51 @@
package com.onarandombox.MultiverseCore.utils.settings.node;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import com.dumptruckman.minecraft.util.Logging;
import io.github.townyadvanced.commentedconfiguration.setting.CommentedNode;
import org.jetbrains.annotations.NotNull;
public class NodesCollection implements Collection<CommentedNode> {
public class NodeGroup implements Collection<CommentedNode> {
private final Collection<CommentedNode> nodes;
private final Map<String, CommentedNode> nodesMap;
public NodesCollection(Collection<CommentedNode> nodes) {
this.nodes = nodes;
public NodeGroup() {
this.nodes = new ArrayList<>();
this.nodesMap = new HashMap<>();
}
public NodeGroup(Collection<CommentedNode> nodes) {
this.nodes = nodes;
this.nodesMap = new HashMap<>(nodes.size());
nodes.forEach(this::addNodeIndex);
}
private void addNodeIndex(CommentedNode node) {
if (node instanceof NamedValueNode namedValueNode && namedValueNode.getName() != null) {
nodesMap.put(namedValueNode.getName(), node);
}
}
private void removeNodeIndex(CommentedNode node) {
if (node instanceof NamedValueNode namedValueNode) {
nodesMap.remove(namedValueNode.getName());
}
}
public Collection<String> getNames() {
return nodesMap.keySet();
}
public Optional<CommentedNode> findNode(String name) {
return Optional.ofNullable(nodesMap.get(name));
}
@Override
public int size() {
@ -49,12 +82,20 @@ public class NodesCollection implements Collection<CommentedNode> {
@Override
public boolean add(CommentedNode commentedNode) {
return nodes.add(commentedNode);
if (nodes.add(commentedNode)) {
addNodeIndex(commentedNode);
return true;
}
return false;
}
@Override
public boolean remove(Object o) {
return nodes.remove(o);
if (nodes.remove(o) && o instanceof CommentedNode) {
removeNodeIndex((CommentedNode) o);
return true;
}
return false;
}
@Override