.
This commit is contained in:
parent
46978ae799
commit
ce56c6e105
53 changed files with 776 additions and 891 deletions
|
|
@ -0,0 +1,25 @@
|
|||
package site.lab0x13.scrow.configurator;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface ConfigApi {
|
||||
|
||||
<V> void register(ConfigKey<V> key, @Nullable V defaultValue);
|
||||
|
||||
default <V> void register(ConfigKey<V> key) {
|
||||
this.register(key, null);
|
||||
}
|
||||
|
||||
<V> @Nullable ConfigNode<V> getNode(ConfigKey<V> key);
|
||||
|
||||
default <V> @Nullable V get(ConfigKey<V> key) {
|
||||
var n = getNode(key);
|
||||
if (n == null) return null;
|
||||
return n.value();
|
||||
}
|
||||
|
||||
Map<String, ConfigNode<?>> allNodes();
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package site.lab0x13.scrow.configurator;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConfigApiImpl implements ConfigApi {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(ConfigApiImpl.class);
|
||||
|
||||
private final Map<String, ConfigNode<?>> nodes = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public <V> void register(ConfigKey<V> key, @Nullable V defaultValue) {
|
||||
var oldValue = nodes.put(key.id(), new ConfigNode<>(key.type(), defaultValue));
|
||||
if (oldValue != null)
|
||||
log.warn("Overwriting config key {}", key);
|
||||
}
|
||||
|
||||
/*
|
||||
Sub-Nodes make this a bit difficult. We need to get the last real registered node in the
|
||||
identifier first, and then descend into the Sub-Nodes.
|
||||
*/
|
||||
@Override
|
||||
public @Nullable <V> ConfigNode<V> getNode(ConfigKey<V> key) {
|
||||
ConfigNode<Object> node;
|
||||
var id = key.id();
|
||||
var fields = new ArrayDeque<String>();
|
||||
while (true) {
|
||||
node = (ConfigNode<Object>) nodes.get(id);
|
||||
if (node != null)
|
||||
break;
|
||||
var dot = id.lastIndexOf('.');
|
||||
if (dot < 0)
|
||||
return null;
|
||||
fields.add(id.substring(dot + 1));
|
||||
id = id.substring(0, dot);
|
||||
}
|
||||
|
||||
while (!fields.isEmpty()) {
|
||||
var field = fields.pop();
|
||||
if (node.value() == null)
|
||||
return null;
|
||||
if (node.type().getSubNodeNames(node.value()).isEmpty())
|
||||
return null;
|
||||
node = (ConfigNode<Object>) node.type().getSubNode(node.value(), field);
|
||||
if (node == null)
|
||||
return null;
|
||||
}
|
||||
return (ConfigNode<V>) node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ConfigNode<?>> allNodes() {
|
||||
var result = new HashMap<String, ConfigNode<?>>();
|
||||
nodes.forEach((id, node) -> addNodeRecursively(result, id, (ConfigNode<Object>) node));
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addNodeRecursively(Map<String, ConfigNode<?>> result, String nodeId, ConfigNode<Object> node) {
|
||||
result.put(nodeId, node);
|
||||
if (node.value() != null)
|
||||
for (String fieldName : node.type().getSubNodeNames(node.value())) {
|
||||
var subNode = (ConfigNode<Object>) node.type().getSubNode(node.value(), fieldName);
|
||||
if (subNode == null)
|
||||
continue;
|
||||
addNodeRecursively(result, nodeId + "." + fieldName, subNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package site.lab0x13.scrow.configurator;
|
||||
|
||||
import site.lab0x13.scrow.configurator.type.ConfigType;
|
||||
|
||||
/**
|
||||
* @param id unique identifier with, e.g `foo.bar`
|
||||
* @param <V> type of the value
|
||||
*/
|
||||
public record ConfigKey<V>(String id, ConfigType<V> type) {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(id=" + id + ",type=" + type.getClass().getCanonicalName() + ")";
|
||||
}
|
||||
}
|
||||
|
|
@ -3,8 +3,6 @@ package site.lab0x13.scrow.configurator;
|
|||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import site.lab0x13.scrow.configurator.command.ConfigCommand;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigRootNode;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigValueNode;
|
||||
import site.lab0x13.scrow.configurator.type.location.LocationConfigType;
|
||||
|
||||
public class ConfiguratorPlugin extends JavaPlugin {
|
||||
|
|
@ -12,7 +10,7 @@ public class ConfiguratorPlugin extends JavaPlugin {
|
|||
@Override
|
||||
public void onEnable() {
|
||||
ConfigRootNode nodeRegistry = new ConfigRootNode();
|
||||
nodeRegistry.register("spawnLocation", new ConfigValueNode<>(LocationConfigType.INSTANCE));
|
||||
nodeRegistry.register("spawnLocation", new Config<>(LocationConfigType.INSTANCE));
|
||||
ScrowAPI.playerCommands().register(new ConfigCommand(nodeRegistry).rootLiteral());
|
||||
}
|
||||
}
|
||||
|
|
@ -2,25 +2,20 @@ package site.lab0x13.scrow.configurator.action;
|
|||
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ConfigOptionAction<T> {
|
||||
|
||||
/* FIXME not too clean */
|
||||
List<ConfigOptionAction<?>> GLOBAL_ACTIONS = List.of(new GlobalShowAction<>());
|
||||
|
||||
/**
|
||||
* @param <N> type of ConfigNode
|
||||
*/
|
||||
public interface ConfigAction<N extends ConfigNode<?>> {
|
||||
String name();
|
||||
|
||||
List<CommandArgumentSpec<Player, ?>> arguments();
|
||||
|
||||
boolean requiresValue();
|
||||
|
||||
void execute(
|
||||
MessageStyle style,
|
||||
T node,
|
||||
CommandContext<Player> ctx
|
||||
);
|
||||
void execute(N node, CommandContext<Player> ctx);
|
||||
}
|
||||
|
|
@ -5,16 +5,15 @@ import com.google.gson.GsonBuilder;
|
|||
import com.google.gson.JsonElement;
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
import site.lab0x13.scrow.configurator.type.ConfigType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class GlobalShowAction<S extends ConfigNode<S>> implements ConfigOptionAction<S> {
|
||||
public final class GlobalShowAction implements ConfigAction<ConfigNode<Object>> {
|
||||
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
|
|
@ -34,11 +33,11 @@ public final class GlobalShowAction<S extends ConfigNode<S>> implements ConfigOp
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(MessageStyle style, S node, CommandContext<Player> ctx) {
|
||||
public void execute(ConfigNode<Object> node, CommandContext<Player> ctx) {
|
||||
var jsonElement = node.type().serialize(node.value());
|
||||
var prettyJson = GSON.toJson(jsonElement, JsonElement.class);
|
||||
var component = Component.text(prettyJson + " [click to copy]")
|
||||
.clickEvent(ClickEvent.copyToClipboard(prettyJson));
|
||||
ctx.sender().sendMessage(style.ok(component));
|
||||
ctx.sender().sendMessage(ctx.style().ok(component));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package site.lab0x13.scrow.configurator.action;
|
|||
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
|
|
@ -13,9 +12,9 @@ import java.util.concurrent.CompletableFuture;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
public abstract class PickAction<S, T extends ConfigNode<S>> implements ConfigOptionAction<T> {
|
||||
public abstract class PickAction<V, N extends ConfigNode<V>> implements ConfigAction<N> {
|
||||
|
||||
protected abstract CompletableFuture<S> pick(Player player);
|
||||
protected abstract CompletableFuture<V> pick(Player player);
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
|
|
@ -28,16 +27,21 @@ public abstract class PickAction<S, T extends ConfigNode<S>> implements ConfigOp
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(MessageStyle style, T node, CommandContext<Player> ctx) {
|
||||
public boolean requiresValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(N node, CommandContext<Player> ctx) {
|
||||
pick(ctx.sender())
|
||||
.orTimeout(10, TimeUnit.MINUTES)
|
||||
.whenComplete((picked, ex) -> {
|
||||
if (ex instanceof TimeoutException) {
|
||||
ctx.sender().sendMessage(style.err("Timed out picking value."));
|
||||
ctx.sender().sendMessage(ctx.style().err("Timed out picking value."));
|
||||
return;
|
||||
}
|
||||
|
||||
node.value(picked);
|
||||
ctx.sender().playSound(ctx.sender().getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 0.5f, 0f);
|
||||
node.value(picked);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,17 +5,17 @@ import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
|||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigRootNode;
|
||||
import site.lab0x13.scrow.configurator.ConfigApi;
|
||||
import site.lab0x13.scrow.configurator.noderegistry.ConfigNodeWalker;
|
||||
|
||||
public final class ConfigCommand {
|
||||
private final RootLiteral<Player> rootLiteral;
|
||||
|
||||
public ConfigCommand(ConfigRootNode nodeRegistry) {
|
||||
public ConfigCommand(ConfigApi configApi) {
|
||||
var style = new ScrowMessageStyle("config", TextColor.color(0x28B088));
|
||||
rootLiteral = Literal.<Player>builder("config", "cfg")
|
||||
.withPermission("command.config")
|
||||
.withLiteral(new KeyLiteral(style, new ConfigNodeWalker(nodeRegistry)).literal())
|
||||
.withLiteral(new KeyLiteral(style, configApi).literal())
|
||||
.asRootLiteral(style);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,14 +5,10 @@ import com.leakyabstractions.result.core.Results;
|
|||
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
||||
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigListNode;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigRootNode;
|
||||
import site.lab0x13.scrow.configurator.node.SubFielded;
|
||||
import site.lab0x13.scrow.configurator.noderegistry.ConfigNodeWalker;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class ConfigNodeArgumentType implements ArgumentType<Player, ConfigNode<?>> {
|
||||
|
||||
|
|
@ -37,17 +33,16 @@ public class ConfigNodeArgumentType implements ArgumentType<Player, ConfigNode<?
|
|||
return (_, input) -> {
|
||||
var res = nodeWalker.walk(input);
|
||||
switch (res.type()) {
|
||||
case NO_FIELDS, SUCCESS -> Collections.emptyList();
|
||||
case NO_SUCH_FIELD, INDEX_OUT_OF_RANGE, INDEX_EXPECTED -> {
|
||||
if (res.node() instanceof ConfigListNode<?> list)
|
||||
return IntStream.range(0, list.size()).mapToObj(Integer::toString).toList();
|
||||
if (res.node() instanceof SubFielded subFielded)
|
||||
return subFielded.fields().keySet().stream()
|
||||
.map(it -> res.parentKey() + "." + it)
|
||||
.toList();
|
||||
assert res.node() != null;
|
||||
return res.node().getFieldNames().stream()
|
||||
.map(it -> res.parentKey() + "." + it)
|
||||
.toList();
|
||||
}
|
||||
default -> {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import de.kentoj.kencommandapi.api.literal.Literal;
|
|||
import de.kentoj.kencommandapi.api.literal.LiteralBuilder;
|
||||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.lab0x13.scrow.configurator.action.ConfigOptionAction;
|
||||
import site.lab0x13.scrow.configurator.ConfigApi;
|
||||
import site.lab0x13.scrow.configurator.action.ConfigAction;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
import site.lab0x13.scrow.configurator.noderegistry.ConfigNodeWalker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -16,23 +16,41 @@ class KeyLiteral {
|
|||
private final ScrowMessageStyle style;
|
||||
private final Literal<Player> literal;
|
||||
|
||||
KeyLiteral(ScrowMessageStyle style, ConfigNodeWalker nodeWalker) {
|
||||
KeyLiteral(ScrowMessageStyle style, ConfigApi api) {
|
||||
/*
|
||||
All registered nodes should be added as literals. SubNoded nodes should be added
|
||||
recursively.
|
||||
When foo is a list node(implements SubNoded):
|
||||
/cfg key foo <- list node itself is registered, has actions like append, delete, etc.
|
||||
/cfg key foo.0 <- operate on first element, has actions of foo.0's type
|
||||
*/
|
||||
this.style = style;
|
||||
|
||||
var builder = Literal.<Player>builder("key");
|
||||
nodeWalker.getAllNodes().forEach((key, node) ->
|
||||
api.allNodes().forEach((key, node) ->
|
||||
addNodeLiteral(builder, key, node));
|
||||
literal = builder.build();
|
||||
this.literal = builder.build();
|
||||
}
|
||||
|
||||
private void addNodeLiteral(LiteralBuilder<Player> builder, String key, ConfigNode<?> node) {
|
||||
var nodeLiteralBuilder = Literal.<Player>builder(key);
|
||||
addNodeActionLiteral(nodeLiteralBuilder, (ConfigNode<Object>) node, new ArrayList<>(node.type().actions()));
|
||||
addNodeActionLiteral(nodeLiteralBuilder, (ConfigNode<Object>) node, ConfigOptionAction.GLOBAL_ACTIONS);
|
||||
/*
|
||||
FUCK ME WE NEED TO ADD LITERALS AT RUNTIME.
|
||||
I just need /cfg key <node> <actions dependent on node>
|
||||
except nodes are registered at runtime so we need to register literals at runtime.
|
||||
or we make it an argument, but then we can't make action's work nicely(only hackishly at best);
|
||||
or a dy
|
||||
*/
|
||||
for (String fieldName : node.type().getSubNodeNames(node.value())) {
|
||||
var subNode = node.type().getSubNode(node.value(), fieldName);
|
||||
if (subNode == null) continue;
|
||||
addNodeActionLiteral();
|
||||
}
|
||||
builder.withLiteral(nodeLiteralBuilder.build());
|
||||
}
|
||||
|
||||
private void addNodeActionLiteral(LiteralBuilder<Player> builder, ConfigNode<Object> node, List<ConfigOptionAction<?>> actions) {
|
||||
private void addNodeActionLiteral(LiteralBuilder<Player> builder, ConfigNode<Object> node, List<ConfigAction<?>> actions) {
|
||||
for (var _action : actions) {
|
||||
var action = (ConfigOptionAction<ConfigNode<Object>>) _action;
|
||||
var actionLiteralBuilder = Literal.<Player>builder(action.name());
|
||||
|
|
@ -43,7 +61,7 @@ class KeyLiteral {
|
|||
ctx.sender().sendMessage(style.err("No value set."));
|
||||
return;
|
||||
}
|
||||
action.execute(style, node, ctx);
|
||||
action.execute(node, ctx);
|
||||
});
|
||||
builder.withLiteral(actionLiteralBuilder.build());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
package site.lab0x13.scrow.configurator.command;
|
||||
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class KeyLiteralImpl implements Literal<Player> {
|
||||
private final ConfigNode<?> node;
|
||||
|
||||
public KeyLiteralImpl(String key, ConfigNode<?> node) {
|
||||
this.key = key;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Literal<Player> getLiteral(@NotNull String name) {
|
||||
node.
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<Literal<Player>> literals() {
|
||||
gh
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String[] names() {
|
||||
return new String[]{key};
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String description() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommandArgumentSpec<Player, ?>> arguments() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable CommandExecutor<Player> executor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String permission() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
package site.lab0x13.scrow.configurator.node;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import site.lab0x13.scrow.configurator.type.ConfigType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class ConfigListNode<T>
|
||||
extends ArrayList<ConfigNode<T>>
|
||||
implements ConfigNode<List<ConfigNode<T>>>, List<ConfigNode<T>> {
|
||||
|
||||
private final ConfigType<ConfigNode<T>> elementType;
|
||||
|
||||
public ConfigListNode(ConfigType<ConfigNode<T>> elementType) {
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
public ConfigType<ConfigNode<T>> elementType() {
|
||||
return this.elementType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigType<List<ConfigNode<T>>> type() {
|
||||
return new ConfigType<>() {
|
||||
@Override
|
||||
public JsonElement serialize(List<ConfigNode<T>> value) {
|
||||
var list = new JsonArray();
|
||||
forEach(n -> list.add(n.type().serialize(n.value())));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConfigNode<T>> deserialize(JsonElement json) {
|
||||
var res = new ArrayList<ConfigNode<T>>();
|
||||
var list = json.getAsJsonArray();
|
||||
list.forEach(e -> res.add(elementType.deserialize(e)));
|
||||
return res;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConfigNode<T>> value() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(List<ConfigNode<T>> value) {
|
||||
this.clear();
|
||||
this.addAll(value);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,36 @@
|
|||
package site.lab0x13.scrow.configurator.node;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import site.lab0x13.scrow.configurator.type.ConfigType;
|
||||
|
||||
public sealed interface ConfigNode<T> permits ConfigValueNode, ConfigListNode, ConfigRootNode {
|
||||
ConfigType<T> type();
|
||||
/**
|
||||
* @param <V> type of the value
|
||||
*/
|
||||
public final class ConfigNode<V> {
|
||||
|
||||
T value();
|
||||
private final ConfigType<V> type;
|
||||
private final @Nullable V defaultValue;
|
||||
private @Nullable V value;
|
||||
|
||||
void value(T value);
|
||||
public ConfigNode(ConfigType<V> type, @Nullable V defaultValue) {
|
||||
this.type = type;
|
||||
this.defaultValue = defaultValue;
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.value(defaultValue);
|
||||
}
|
||||
|
||||
public V value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void value(V value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public ConfigType<V> type() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
package site.lab0x13.scrow.configurator.node;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import site.lab0x13.scrow.configurator.type.ConfigMapType;
|
||||
import site.lab0x13.scrow.configurator.type.ConfigType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class ConfigRootNode implements ConfigNode<Map<String, ConfigNode<?>>>, SubFielded {
|
||||
|
||||
private final ConfigMapType<ConfigNode<?>> type = new ConfigMapType<>(new HashMap<>());
|
||||
private Map<String, ConfigNode<?>> value = new HashMap<>();
|
||||
|
||||
public void register(String name, ConfigNode<?> node) {
|
||||
value.put(name, node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigType<Map<String, ConfigNode<?>>> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ConfigNode<?>> value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Map<String, ConfigNode<?>> value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ConfigNode<?>> fields() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ConfigNode<?> getField(String name) {
|
||||
return value.get(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
package site.lab0x13.scrow.configurator.node;
|
||||
|
||||
import site.lab0x13.scrow.configurator.type.ConfigType;
|
||||
|
||||
public final class ConfigValueNode<T> implements ConfigNode<T> {
|
||||
private final ConfigType<T> type;
|
||||
private final T defaultValue;
|
||||
private T value;
|
||||
|
||||
public ConfigValueNode(ConfigType<T> type, T defaultValue) {
|
||||
this.type = type;
|
||||
this.defaultValue = defaultValue;
|
||||
this.value = defaultValue;
|
||||
}
|
||||
|
||||
public ConfigValueNode(ConfigType<T> type) {
|
||||
this(type, null);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.value = defaultValue;
|
||||
}
|
||||
|
||||
public T defaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public T value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void value(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean required() {
|
||||
return defaultValue == null;
|
||||
}
|
||||
|
||||
public ConfigType<T> type() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package site.lab0x13.scrow.configurator.node;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface SubFielded {
|
||||
Map<String, ConfigNode<?>> fields();
|
||||
|
||||
@Nullable ConfigNode<?> getField(String name);
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
package site.lab0x13.scrow.configurator.noderegistry;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigListNode;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigRootNode;
|
||||
import site.lab0x13.scrow.configurator.node.SubFielded;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public final class ConfigNodeWalker {
|
||||
|
||||
private final ConfigRootNode rootNode;
|
||||
|
||||
public ConfigNodeWalker(ConfigRootNode rootNode) {
|
||||
this.rootNode = rootNode;
|
||||
}
|
||||
|
||||
public Map<String, ConfigNode<?>> getAllNodes() {
|
||||
var result = new HashMap<String, ConfigNode<?>>();
|
||||
processNode("", result, rootNode);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void processNode(String key, Map<String, ConfigNode<?>> result, ConfigNode<?> node) {
|
||||
result.put(key, node);
|
||||
if (node instanceof ConfigListNode<?> list) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
var element = list.get(i);
|
||||
processNode(key + "." + i, result, element);
|
||||
}
|
||||
} else {
|
||||
/* FIXME not clean at all */
|
||||
SubFielded sf = null;
|
||||
if (node instanceof SubFielded n)
|
||||
sf = n;
|
||||
else if (node.type() instanceof SubFielded n)
|
||||
sf = n;
|
||||
if (sf != null)
|
||||
sf.fields().forEach((name, v) ->
|
||||
processNode(key + "." + name, result, v));
|
||||
}
|
||||
}
|
||||
|
||||
public WalkResult walk(String key) {
|
||||
return walk(Arrays.stream(key.split("\\.")).iterator());
|
||||
}
|
||||
|
||||
public WalkResult walk(Iterator<String> iter) {
|
||||
var cursor = new Cursor(iter);
|
||||
ConfigNode<?> cur = rootNode;
|
||||
String token;
|
||||
|
||||
while ((token = cursor.nextToken()) != null) {
|
||||
if (token.isEmpty()) continue;
|
||||
if (cur instanceof ConfigListNode<?> list) {
|
||||
int index;
|
||||
try {
|
||||
index = Integer.parseInt(token);
|
||||
} catch (NumberFormatException _) {
|
||||
return new WalkResult(WalkResult.Type.INDEX_EXPECTED, cursor.key(), cur);
|
||||
}
|
||||
if (index < 0 || index >= list.size())
|
||||
return new WalkResult(WalkResult.Type.INDEX_OUT_OF_RANGE, cursor.key(), cur);
|
||||
cur = list.get(index);
|
||||
} else if (cur.type() instanceof SubFielded subFielded) {
|
||||
cur = subFielded.getField(token);
|
||||
if (cur == null)
|
||||
return new WalkResult(WalkResult.Type.NO_SUCH_FIELD, cursor.key(), cur);
|
||||
} else {
|
||||
return new WalkResult(WalkResult.Type.NO_FIELDS, cursor.key(), cur);
|
||||
}
|
||||
}
|
||||
|
||||
return new WalkResult(WalkResult.Type.SUCCESS, cursor.key(), cur);
|
||||
}
|
||||
|
||||
private static class Cursor {
|
||||
private String key = "";
|
||||
|
||||
private final Iterator<String> iter;
|
||||
|
||||
private Cursor(Iterator<String> iter) {
|
||||
this.iter = iter;
|
||||
}
|
||||
|
||||
public @Nullable String nextToken() {
|
||||
if (!iter.hasNext()) return null;
|
||||
var token = iter.next();
|
||||
key += "." + token;
|
||||
key = key.replaceFirst("\\.", "");
|
||||
return token;
|
||||
}
|
||||
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package site.lab0x13.scrow.configurator.noderegistry;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public record WalkResult(
|
||||
Type type,
|
||||
String key,
|
||||
@Nullable ConfigNode<?> node
|
||||
) {
|
||||
public String parentKey() {
|
||||
var dotInd = key.lastIndexOf('.');
|
||||
return dotInd < 0 ? "" : key.substring(0, dotInd - 1);
|
||||
}
|
||||
|
||||
public @Nullable String error() {
|
||||
return type().message.apply(this);
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
INDEX_EXPECTED(r -> "Numeric index expected at " + r.key() + "."),
|
||||
INDEX_OUT_OF_RANGE(_ -> "Index out of range."),
|
||||
NO_FIELDS(r -> r.key() + " has no fields."),
|
||||
NO_SUCH_FIELD(r -> "Invalid key " + r.key()),
|
||||
SUCCESS(_ -> null);
|
||||
|
||||
private final Function<WalkResult, String> message;
|
||||
|
||||
Type(Function<WalkResult, String> message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,27 +2,24 @@ package site.lab0x13.scrow.configurator.type;
|
|||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import site.lab0x13.scrow.configurator.node.SubFielded;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class ConfigComplexType<T> implements ConfigType<T>, SubFielded {
|
||||
public abstract class ConfigComplexType<T> implements ConfigType<T> {
|
||||
|
||||
private final Map<String, ConfigNode<?>> entries = new HashMap<>();
|
||||
private final Map<String, Field<T, ?>> fields = new HashMap<>();
|
||||
|
||||
protected abstract T deserialize(JsonObject obj);
|
||||
|
||||
protected void addEntry(String name, ConfigNode<?> node) {
|
||||
entries.put(name, node);
|
||||
protected <S> void addField(String name, ConfigType<S> type, Function<T, S> getter) {
|
||||
fields.put(name, new Field<>(type, getter));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <S> S readNode(JsonObject object, String name) {
|
||||
var node = (ConfigNode<Object>) entries.get(name);
|
||||
return (S) node.type().deserialize(object.get(name));
|
||||
protected <S> S readField(JsonObject object, String name) {
|
||||
var field = fields.get(name);
|
||||
return (S) field.type().deserialize(object.get(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -33,20 +30,19 @@ public abstract class ConfigComplexType<T> implements ConfigType<T>, SubFielded
|
|||
@Override
|
||||
public JsonElement serialize(T value) {
|
||||
var obj = new JsonObject();
|
||||
entries.forEach((name, node) -> writeNode(obj, name, node));
|
||||
fields.forEach((name, field) -> writeNode(obj, name, field, value));
|
||||
return obj;
|
||||
}
|
||||
|
||||
private static <S> void writeNode(JsonObject object, String name, ConfigNode<S> node) {
|
||||
var value = node.type().serialize(node.value());
|
||||
object.add(name, value);
|
||||
private <S> void writeNode(JsonObject object, String name, Field<T, S> field, T value) {
|
||||
var fieldValue = field.getter.apply(value);
|
||||
var serializedFieldValue = field.type().serialize(fieldValue);
|
||||
object.add(name, serializedFieldValue);
|
||||
}
|
||||
|
||||
public Map<String, ConfigNode<?>> fields() {
|
||||
return new HashMap<>(entries);
|
||||
}
|
||||
|
||||
public @Nullable ConfigNode<?> getField(String name) {
|
||||
return entries.get(name);
|
||||
public record Field<T, S>(
|
||||
ConfigType<S> type,
|
||||
Function<T, S> getter
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
package site.lab0x13.scrow.configurator.type;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public record ConfigListType<V>(
|
||||
ConfigType<V> elementType
|
||||
) implements ConfigType<List<ConfigNode<V>>> {
|
||||
|
||||
@Override
|
||||
public List<ConfigNode<V>> deserialize(JsonElement json) {
|
||||
var result = new ArrayList<ConfigNode<V>>();
|
||||
var obj = json.getAsJsonObject();
|
||||
obj.asMap().forEach((k, v) -> {
|
||||
var subNode = new ConfigNode<>(elementType, null);
|
||||
subNode.value(elementType.deserialize(v));
|
||||
result.set(Integer.parseInt(k), subNode);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(List<ConfigNode<V>> value) {
|
||||
var res = new JsonObject();
|
||||
for (int i = 0; i < value.size(); i++) {
|
||||
var subNodeValue = value.get(i).value();
|
||||
if (subNodeValue == null) continue;
|
||||
var element = elementType.serialize(subNodeValue);
|
||||
res.add(Integer.toString(i), element);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSubNodeNames(List<ConfigNode<V>> value) {
|
||||
return IntStream.range(0, value.size())
|
||||
.mapToObj(Integer::toString)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ConfigNode<V> getSubNode(List<ConfigNode<V>> value, String name) {
|
||||
return value.get(Integer.parseInt(name));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
package site.lab0x13.scrow.configurator.type;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
import site.lab0x13.scrow.configurator.node.SubFielded;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConfigMapType<T> implements ConfigType<Map<String, T>>, SubFielded {
|
||||
|
||||
private final Map<String, ConfigType<?>> types;
|
||||
|
||||
public ConfigMapType(Map<String, ConfigType<?>> types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Map<String, T> deserialize(JsonElement json) {
|
||||
var result = new HashMap<String, T>();
|
||||
var obj = json.getAsJsonObject();
|
||||
types.forEach((k, v) -> {
|
||||
var type = (ConfigType<Object>) v;
|
||||
var value = (T) type.deserialize(obj.get(k));
|
||||
result.put(k, value);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public JsonElement serialize(Map<String, T> value) {
|
||||
var res = new JsonObject();
|
||||
types.forEach((k, v) -> {
|
||||
var type = (ConfigType<T>) v;
|
||||
var serialized = type.serialize(value.get(k));
|
||||
res.add(k, serialized);
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ConfigNode<?>> fields() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ConfigNode<?> getField(String name) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ import com.google.gson.JsonPrimitive;
|
|||
import java.math.BigInteger;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ConfigPrimitiveType<T> implements ConfigType<T> {
|
||||
public final class ConfigPrimitiveType<V> implements ConfigType<V> {
|
||||
|
||||
public static final ConfigPrimitiveType<Double> DOUBLE =
|
||||
new ConfigPrimitiveType<>(JsonPrimitive::new, JsonPrimitive::getAsDouble);
|
||||
|
|
@ -25,21 +25,21 @@ public class ConfigPrimitiveType<T> implements ConfigType<T> {
|
|||
public static final ConfigPrimitiveType<Byte> BYTE =
|
||||
new ConfigPrimitiveType<>(JsonPrimitive::new, JsonPrimitive::getAsByte);
|
||||
|
||||
private final Function<T, JsonPrimitive> serializer;
|
||||
private final Function<JsonPrimitive, T> deserializer;
|
||||
private final Function<V, JsonPrimitive> serializer;
|
||||
private final Function<JsonPrimitive, V> deserializer;
|
||||
|
||||
private ConfigPrimitiveType(Function<T, JsonPrimitive> serializer, Function<JsonPrimitive, T> deserializer) {
|
||||
private ConfigPrimitiveType(Function<V, JsonPrimitive> serializer, Function<JsonPrimitive, V> deserializer) {
|
||||
this.serializer = serializer;
|
||||
this.deserializer = deserializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(T value) {
|
||||
public JsonElement serialize(V value) {
|
||||
return serializer.apply(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T deserialize(JsonElement json) {
|
||||
public V deserialize(JsonElement json) {
|
||||
return deserializer.apply(json.getAsJsonPrimitive());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,26 @@
|
|||
package site.lab0x13.scrow.configurator.type;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import site.lab0x13.scrow.configurator.action.ConfigOptionAction;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import site.lab0x13.scrow.configurator.action.ConfigAction;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public interface ConfigType<T> {
|
||||
/**
|
||||
* @param <V> type of the stored value
|
||||
*/
|
||||
public interface ConfigType<V> extends Serializable<V> {
|
||||
|
||||
default List<ConfigOptionAction<?>> actions() {
|
||||
default List<ConfigAction<?>> actions() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
JsonElement serialize(T value);
|
||||
|
||||
T deserialize(JsonElement json);
|
||||
|
||||
default String toJson(T value) {
|
||||
return serialize(value).toString();
|
||||
default List<String> getSubNodeNames(V value) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
default T fromJson(String json) {
|
||||
return deserialize(JsonParser.parseString(json));
|
||||
default @Nullable ConfigNode<?> getSubNode(V value, String name) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
package site.lab0x13.scrow.configurator.type;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
public interface Serializable<V> {
|
||||
|
||||
JsonElement serialize(V value);
|
||||
|
||||
V deserialize(JsonElement json);
|
||||
|
||||
default String toJson(V value) {
|
||||
return serialize(value).toString();
|
||||
}
|
||||
|
||||
default V fromJson(String json) {
|
||||
return deserialize(JsonParser.parseString(json));
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,7 @@ package site.lab0x13.scrow.configurator.type.location;
|
|||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.bukkit.Location;
|
||||
import site.lab0x13.scrow.configurator.action.ConfigOptionAction;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigValueNode;
|
||||
import site.lab0x13.scrow.configurator.action.ConfigAction;
|
||||
import site.lab0x13.scrow.configurator.type.ConfigComplexType;
|
||||
import site.lab0x13.scrow.configurator.type.ConfigPrimitiveType;
|
||||
import site.lab0x13.scrow.configurator.type.world.WorldConfigType;
|
||||
|
|
@ -16,31 +14,28 @@ public class LocationConfigType extends ConfigComplexType<Location> {
|
|||
public static final LocationConfigType INSTANCE = new LocationConfigType();
|
||||
|
||||
private LocationConfigType() {
|
||||
addEntry("world", new ConfigValueNode<>(WorldConfigType.INSTANCE));
|
||||
addEntry("x", new ConfigValueNode<>(ConfigPrimitiveType.DOUBLE));
|
||||
addEntry("y", new ConfigValueNode<>(ConfigPrimitiveType.DOUBLE));
|
||||
addEntry("z", new ConfigValueNode<>(ConfigPrimitiveType.DOUBLE));
|
||||
addEntry("yaw", new ConfigValueNode<>(ConfigPrimitiveType.FLOAT));
|
||||
addEntry("pitch", new ConfigValueNode<>(ConfigPrimitiveType.FLOAT));
|
||||
addField("world", WorldConfigType.INSTANCE, Location::getWorld);
|
||||
addField("x", ConfigPrimitiveType.DOUBLE, Location::getX);
|
||||
addField("y", ConfigPrimitiveType.DOUBLE, Location::getY);
|
||||
addField("z", ConfigPrimitiveType.DOUBLE, Location::getZ);
|
||||
addField("yaw", ConfigPrimitiveType.FLOAT, Location::getYaw);
|
||||
addField("pitch", ConfigPrimitiveType.FLOAT, Location::getPitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConfigOptionAction<?>> actions() {
|
||||
return List.of(
|
||||
new LocationTeleportAction(),
|
||||
new LocationPickCurrentAction()
|
||||
);
|
||||
public List<ConfigAction<?>> actions() {
|
||||
return List.of(new LocationTeleportAction(), new LocationPickCurrentAction());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location deserialize(JsonObject obj) {
|
||||
return new Location(
|
||||
readNode(obj, "world"),
|
||||
readNode(obj, "x"),
|
||||
readNode(obj, "y"),
|
||||
readNode(obj, "z"),
|
||||
readNode(obj, "yaw"),
|
||||
readNode(obj, "pitch")
|
||||
readField(obj, "world"),
|
||||
readField(obj, "x"),
|
||||
readField(obj, "y"),
|
||||
readField(obj, "z"),
|
||||
readField(obj, "yaw"),
|
||||
readField(obj, "pitch")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,11 +13,6 @@ class LocationPickCurrentAction extends PickAction<Location, ConfigNode<Location
|
|||
return "pick-current";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Location> pick(Player player) {
|
||||
return CompletableFuture.completedFuture(player.getLocation());
|
||||
|
|
|
|||
|
|
@ -2,17 +2,15 @@ package site.lab0x13.scrow.configurator.type.location;
|
|||
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.lab0x13.scrow.configurator.action.ConfigOptionAction;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigValueNode;
|
||||
import site.lab0x13.scrow.configurator.action.ConfigAction;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
class LocationTeleportAction implements ConfigOptionAction<ConfigValueNode<Location>> {
|
||||
class LocationTeleportAction implements ConfigAction<ConfigNode<Location>> {
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
|
|
@ -30,8 +28,8 @@ class LocationTeleportAction implements ConfigOptionAction<ConfigValueNode<Locat
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(MessageStyle style, ConfigValueNode<Location> node, CommandContext<Player> ctx) {
|
||||
public void execute(ConfigNode<Location> node, CommandContext<Player> ctx) {
|
||||
ctx.sender().teleport(node.value());
|
||||
ctx.sender().sendMessage(style.ok("You've been teleported."));
|
||||
ctx.sender().sendMessage(ctx.style().ok("You've been teleported."));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
package site.lab0x13.scrow.configurator.type.world;
|
||||
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.type.WorldArgumentType;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.lab0x13.scrow.configurator.action.ConfigAction;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class SetWorldAction implements ConfigAction<ConfigNode<World>> {
|
||||
|
||||
private final CommandArgumentSpec<Player, World> arg =
|
||||
CommandArgumentSpec.builder("world", new WorldArgumentType<Player>()).build();
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "set";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommandArgumentSpec<Player, ?>> arguments() {
|
||||
return List.of(arg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ConfigNode<World> node, CommandContext<Player> ctx) {
|
||||
World world = ctx.getArg(arg);
|
||||
node.value(world);
|
||||
ctx.sender().sendMessage(ctx.style().ok("Set world to " + world.getName() + "(" + world.getUID() + ")"));
|
||||
}
|
||||
}
|
||||
|
|
@ -2,18 +2,9 @@ package site.lab0x13.scrow.configurator.type.world;
|
|||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.leakyabstractions.result.api.Result;
|
||||
import com.leakyabstractions.result.core.Results;
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||
import de.kentoj.kencommandapi.type.WorldArgumentType;
|
||||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.lab0x13.scrow.configurator.action.ConfigOptionAction;
|
||||
import site.lab0x13.scrow.configurator.node.ConfigValueNode;
|
||||
import site.lab0x13.scrow.configurator.action.ConfigAction;
|
||||
import site.lab0x13.scrow.configurator.type.ConfigType;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -37,33 +28,7 @@ public class WorldConfigType implements ConfigType<World> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ConfigOptionAction<?>> actions() {
|
||||
return List.of(new SetAction());
|
||||
}
|
||||
|
||||
private static class SetAction implements ConfigOptionAction<ConfigValueNode<World>> {
|
||||
@Override
|
||||
public String name() {
|
||||
return "set";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommandArgumentSpec<Player, ?>> arguments() {
|
||||
return List.of(
|
||||
CommandArgumentSpec.builder("world", new WorldArgumentType<Player>()).build()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(MessageStyle style, ConfigValueNode<World> node, CommandContext<Player> ctx) {
|
||||
World world = ctx.getArg("world");
|
||||
node.value(world);
|
||||
ctx.sender().sendMessage(style.ok("Set world to " + world.getName() + "("+ world.getUID() + ")"));
|
||||
}
|
||||
public List<ConfigAction<?>> actions() {
|
||||
return List.of(new SetWorldAction());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue