This commit is contained in:
kento2 2026-08-29 20:51:28 +02:00
parent 812a1b1b21
commit 855050c2d1
17 changed files with 158 additions and 29 deletions

View file

@ -9,21 +9,38 @@ import site.lab0x13.scrow.configurator.config.ConfigRegistry;
import site.lab0x13.scrow.configurator.type.list.ConfigListType;
import site.lab0x13.scrow.configurator.type.location.LocationConfigType;
import java.io.IOException;
import java.util.ArrayList;
public class ConfiguratorPlugin extends JavaPlugin {
private final ConfigRegistry configRegistry = new ConfigRegistry();
@Override
public void onEnable() {
ConfigRegistry configRegistry = new ConfigRegistry();
Config hotPotatoConfig = new ConfigImpl(this.getDataPath().resolve("config.json"));
configRegistry.register(hotPotatoConfig);
Config hotPotatoConfig = new ConfigImpl();
configRegistry.register("hot-potato", hotPotatoConfig);
var centerLocation = new ConfigKey<>("centerLocation", new LocationConfigType());
var spawnLocations = new ConfigKey<>("spawnLocations", new ConfigListType<>(new LocationConfigType()));
hotPotatoConfig.register(centerLocation);
hotPotatoConfig.register(spawnLocations, new ArrayList<>());
try {
hotPotatoConfig.load();
} catch (IOException e) {
throw new RuntimeException(e);
}
ScrowAPI.commands().register(new ConfigCommand(configRegistry).rootLiteral());
}
@Override
public void onDisable() {
try {
for (var cfg : configRegistry.allConfigs().values())
cfg.save();
} catch (IOException e) {
throw new RuntimeException("Failed saving config", e);
}
}
}

View file

@ -0,0 +1,43 @@
package site.lab0x13.scrow.configurator.action;
import com.google.gson.JsonElement;
import de.kentoj.scrow.bukkit.command.ScrowBukkitCC;
import de.kentoj.scrowlib.command.type.JsonArgumentType;
import site.lab0x13.scrow.commands.model.argument.Argument;
import site.lab0x13.scrow.configurator.ConfigNode;
import java.util.List;
public final class GlobalSetJsonAction implements ConfigAction<Object> {
private final Argument<ScrowBukkitCC, JsonElement> valueArg =
Argument.builder("jsonValue", new JsonArgumentType<ScrowBukkitCC>()).build();
@Override
public String name() {
return "set-json";
}
@Override
public List<Argument<ScrowBukkitCC, ?>> arguments(ConfigNode<Object> __) {
return List.of(valueArg);
}
@Override
public boolean requiresValue() {
return false;
}
@Override
public void execute(ConfigNode<Object> node, ScrowBukkitCC ctx) {
Object value;
try {
value = node.type().deserialize(ctx.getArg(valueArg));
} catch (Exception ex) {
ctx.sender().sendMessage(ctx.style().err("Failed serializing: " + ex.getMessage()));
return;
}
node.value(value);
ctx.sender().sendMessage(ctx.style().ok("Value set."));
}
}

View file

@ -13,11 +13,11 @@ import java.util.List;
public final class GlobalShowAction implements ConfigAction<Object> {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
@Override
public String name() {
return "show";
return "show-json";
}
@Override

View file

@ -16,11 +16,6 @@ public abstract class PickAction<V> implements ConfigAction<V> {
protected abstract CompletableFuture<V> pick(Player player);
@Override
public String name() {
return "pick";
}
@Override
public List<Argument<ScrowBukkitCC, ?>> arguments(ConfigNode<V> __) {
return Collections.emptyList();

View file

@ -18,6 +18,7 @@ public final class ConfigCommand {
public ConfigCommand(ConfigRegistry configRegistry) {
this.configRegistry = configRegistry;
// TODO undo literal that undoes the last set command
this.rootLiteral = Literal.<ScrowBukkitCC>dynamic("cfg")
.withSubLiteralMetas(this::subLiteralMetas)
.withSubLiteralProvider(this::configLiteral)

View file

@ -11,7 +11,7 @@ import site.lab0x13.scrow.configurator.config.Config;
final class ShowLiteral {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
private final Literal<ScrowBukkitCC> literal;
private final Config cfg;

View file

@ -5,10 +5,16 @@ import org.jetbrains.annotations.Nullable;
import site.lab0x13.scrow.configurator.ConfigKey;
import site.lab0x13.scrow.configurator.ConfigNode;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Map;
public interface Config {
void save() throws IOException;
Path path();
<V> void register(ConfigKey<V> key, @Nullable V defaultValue);
default <V> void register(ConfigKey<V> key) {
@ -32,4 +38,6 @@ public interface Config {
JsonElement toJson();
void loadJson(JsonElement json);
void load() throws IOException;
}

View file

@ -2,21 +2,30 @@ package site.lab0x13.scrow.configurator.config;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import site.lab0x13.scrow.configurator.ConfigKey;
import site.lab0x13.scrow.configurator.ConfigNode;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Map;
public class ConfigImpl implements Config {
public final class ConfigImpl implements Config {
private final Logger log = LoggerFactory.getLogger(ConfigImpl.class);
private static final Logger log = LoggerFactory.getLogger(ConfigImpl.class);
private final Map<String, ConfigNode<?>> nodes = new HashMap<>();
private final Path path;
public ConfigImpl(Path path) {
this.path = path;
}
@Override
public <V> void register(ConfigKey<V> key, @Nullable V defaultValue) {
@ -78,8 +87,8 @@ public class ConfigImpl implements Config {
@Override
public void loadJson(JsonElement json) {
var obj = json.getAsJsonObject();
allNodes().forEach((key, _node) -> {
var node = (ConfigNode<Object>)_node;
nodes.forEach((key, _node) -> {
var node = (ConfigNode<Object>) _node;
var nodeValue = obj.get(key);
node.value(node.type().deserialize(nodeValue));
});
@ -88,11 +97,29 @@ public class ConfigImpl implements Config {
@Override
public JsonElement toJson() {
var obj = new JsonObject();
allNodes().forEach((key, _node) -> {
var node = (ConfigNode<Object>)_node;
nodes.forEach((key, _node) -> {
var node = (ConfigNode<Object>) _node;
var nodeValue = node.type().serialize(node.value());
obj.add(key, nodeValue);
});
return obj;
}
@Override
public void load() throws IOException {
if (!Files.exists(this.path)) return;
var json = Files.readString(this.path());
this.loadJson(JsonParser.parseString(json));
}
@Override
public void save() throws IOException {
Files.createDirectories(this.path().getParent());
Files.writeString(this.path(), this.toJson().toString());
}
@Override
public Path path() {
return path;
}
}

View file

@ -12,17 +12,17 @@ public class ConfigRegistry {
private static final Logger log = LoggerFactory.getLogger(ConfigRegistry.class);
private final Map<String, Config> configs = new HashMap<>();
public void register(String name, Config config) {
var oldValue = configs.put(name, config);
public void register(Config config) {
var oldValue = configs.put(config.path().toString(), config);
if (oldValue != null)
log.warn("Overwriting old config with same name '{}'", name);
log.warn("Overwriting old config with same path '{}'", config.path());
}
public Map<String, Config> allConfigs() {
return new HashMap<>(configs);
}
public @Nullable Config getConfig(String name) {
return configs.get(name);
public @Nullable Config getConfig(String path) {
return configs.get(path);
}
}

View file

@ -2,9 +2,10 @@ package site.lab0x13.scrow.configurator.type;
import de.kentoj.scrowlib.utils.Serializer;
import org.jetbrains.annotations.Nullable;
import site.lab0x13.scrow.configurator.action.ConfigAction;
import site.lab0x13.scrow.configurator.action.GlobalShowAction;
import site.lab0x13.scrow.configurator.ConfigNode;
import site.lab0x13.scrow.configurator.action.ConfigAction;
import site.lab0x13.scrow.configurator.action.GlobalSetJsonAction;
import site.lab0x13.scrow.configurator.action.GlobalShowAction;
import java.util.ArrayList;
import java.util.Collections;
@ -17,7 +18,8 @@ public interface ConfigType<V> extends Serializer<V> {
default List<ConfigAction<?>> actions() {
return new ArrayList<>(List.of(
new GlobalShowAction()
new GlobalShowAction(),
new GlobalSetJsonAction()
));
}

View file

@ -35,7 +35,7 @@ public final class ConfigListType<V> implements ConfigType<List<ConfigNode<V>>>
for (int i = 0; i < array.asList().size(); i++) {
var subNode = new ConfigNode<>(elementType, null);
subNode.value(elementType.deserialize(array.get(i)));
result.set(i, subNode);
result.add(i, subNode);
}
return result;
}

View file

@ -5,14 +5,18 @@ import org.bukkit.Location;
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.ConfigType;
import site.lab0x13.scrow.configurator.type.world.WorldConfigType;
import java.util.ArrayList;
import java.util.List;
public class LocationConfigType extends ConfigComplexType<Location> {
public static final LocationConfigType INSTANCE = new LocationConfigType();
private final List<ConfigAction<?>> actions;
public LocationConfigType() {
addField("world", WorldConfigType.INSTANCE, Location::getWorld);
addField("x", ConfigPrimitiveType.DOUBLE, Location::getX);
@ -20,11 +24,15 @@ public class LocationConfigType extends ConfigComplexType<Location> {
addField("z", ConfigPrimitiveType.DOUBLE, Location::getZ);
addField("yaw", ConfigPrimitiveType.FLOAT, Location::getYaw);
addField("pitch", ConfigPrimitiveType.FLOAT, Location::getPitch);
actions = new ArrayList<>(super.actions());
actions.add(new LocationPickCurrentAction());
actions.add(new LocationTeleportAction());
}
@Override
public List<ConfigAction<?>> actions() {
return List.of(new LocationTeleportAction(), new LocationPickCurrentAction());
return actions;
}
@Override

View file

@ -0,0 +1,24 @@
package de.kentoj.scrowlib.command.type;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import site.lab0x13.scrow.commands.model.CommandContext;
import site.lab0x13.scrow.commands.model.SuggestionProvider;
import site.lab0x13.scrow.commands.model.argument.ArgumentType;
import java.util.List;
public class JsonArgumentType<C extends CommandContext<C>> implements ArgumentType<C, JsonElement> {
@Override
public Result<JsonElement, String> parseInput(String input) {
return Results.ofCallable(() -> JsonParser.parseString(input))
.mapFailure(Throwable::getMessage);
}
@Override
public SuggestionProvider<C> defaultSuggestionProvider() {
return (_, _) -> List.of("{}");
}
}

View file

@ -1,5 +1,6 @@
package de.kentoj.scrowlib.convention;
import de.kentoj.scrowlib.utils.ComponentUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
@ -20,8 +21,8 @@ public record ScrowMessageStyle(
@Override
public Component ok(Component msg) {
return prefix.append(Component.text("").color(NamedTextColor.GRAY))
.append(msg.colorIfAbsent(NamedTextColor.GRAY));
return ComponentUtils.resolveURLS(prefix.append(Component.text("").color(NamedTextColor.GRAY))
.append(msg.colorIfAbsent(NamedTextColor.GRAY)));
}
@Override

View file

@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Deprecated
public class InMemoryEconomyService implements EconomyService {
private final Map<UUID, Integer> coins = new HashMap<>();

View file

@ -9,6 +9,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
@Deprecated
public class InMemoryFriendshipService implements FriendshipService {
private final Map<OrderedUUIDPair, Friendship> friendships = new HashMap<>();

View file

@ -8,6 +8,7 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
@Deprecated
public class InMemoryFriendRequestService implements FriendRequestService {
private final Set<FriendRequest> requests = new HashSet<>();