diff --git a/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/PlayerManager.java b/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/PlayerManager.java index 76fd85f..01b5e05 100644 --- a/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/PlayerManager.java +++ b/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/PlayerManager.java @@ -21,11 +21,11 @@ public final class PlayerManager { this.minigame = minigame; } - public Stream participants() { + public Stream getParticipants() { return participants.stream().map(Bukkit::getPlayer); } - public Stream spectators() { + public Stream getSpectators() { return spectators.stream().map(Bukkit::getPlayer); } @@ -61,7 +61,7 @@ public final class PlayerManager { return spectators.remove(player.getUniqueId()); } - public Stream allPlayers() { - return Stream.concat(participants(), spectators()); + public Stream getAllPlayers() { + return Stream.concat(getParticipants(), getSpectators()); } } diff --git a/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/lobby/LobbyPhase.java b/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/lobby/LobbyPhase.java index 2303fa2..806387c 100644 --- a/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/lobby/LobbyPhase.java +++ b/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/lobby/LobbyPhase.java @@ -33,6 +33,7 @@ public class LobbyPhase extends CompositePhase { ctx.listeners().on(PlayerJoinEvent.class, EventPriority.LOWEST, this::onJoin); ctx.listeners().on(PlayerQuitEvent.class, EventPriority.LOWEST, this::onQuit); + //noinspection unchecked ctx.listeners().cancel( HangingBreakByEntityEvent.class, PlayerInteractAtEntityEvent.class, @@ -50,13 +51,13 @@ public class LobbyPhase extends CompositePhase { private void onJoin(PlayerJoinEvent ev) { ctx.players().addParticipant(ev.getPlayer()); - ctx.players().allPlayers().forEach(p -> + ctx.players().getAllPlayers().forEach(p -> p.sendMessage("§8[§a+§8] §7" + ev.getPlayer().getName())); } private void onQuit(PlayerQuitEvent ev) { if (ctx.players().removeParticipant(ev.getPlayer())) - ctx.players().allPlayers().forEach(p -> + ctx.players().getAllPlayers().forEach(p -> p.sendMessage("§8[§c-§8] §7" + ev.getPlayer().getName())); } diff --git a/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/lobby/WaitForMaximumPlayersPhase.java b/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/lobby/WaitForMaximumPlayersPhase.java index 2289699..6caddaf 100644 --- a/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/lobby/WaitForMaximumPlayersPhase.java +++ b/core/bukkit/api/main/java/de/kentoj/scrow/bukkit/minigame/lobby/WaitForMaximumPlayersPhase.java @@ -30,7 +30,7 @@ class WaitForMaximumPlayersPhase extends Phase { @Override protected void onTick(int tick) { if (tick % 20 == 0) { - ctx.players().allPlayers().forEach(player -> + ctx.players().getAllPlayers().forEach(player -> player.sendTitle("Game starting in " + secsLeft + " seconds", "have fun", 5, 20, 10) ); secsLeft--; diff --git a/core/common/src/main/java/de/kentoj/scrowlib/convention/ScrowMessageStyle.java b/core/common/src/main/java/de/kentoj/scrowlib/convention/ScrowMessageStyle.java index 052f13a..e58b376 100644 --- a/core/common/src/main/java/de/kentoj/scrowlib/convention/ScrowMessageStyle.java +++ b/core/common/src/main/java/de/kentoj/scrowlib/convention/ScrowMessageStyle.java @@ -21,9 +21,8 @@ public record ScrowMessageStyle( @Override public Component ok(Component msg) { - return ComponentUtils.resolveURLS( - 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 diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/ConfiguratorPlugin.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/ConfiguratorPlugin.java index af9ada3..5021959 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/ConfiguratorPlugin.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/ConfiguratorPlugin.java @@ -5,7 +5,10 @@ import org.bukkit.plugin.java.JavaPlugin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import site.lab0x13.scrow.configurator.command.ConfiguratorCommand; +import site.lab0x13.scrow.configurator.configfile.ConfigFile; import site.lab0x13.scrow.configurator.configfile.ConfigFileRegistry; +import site.lab0x13.scrow.configurator.storable.impl.VectorStorable; +import site.lab0x13.scrow.configurator.storable.impl.location.LocationStorable; import java.io.IOException; @@ -15,6 +18,19 @@ public class ConfiguratorPlugin extends JavaPlugin { @Override public void onEnable() { + ConfigFile hotPotatoConfig = ConfigFile.of(this.getDataPath().resolve("config.json")); + ConfigFileRegistry.get().register(hotPotatoConfig); + + var someVector = new VectorStorable(); + var someLocation = new LocationStorable(); + hotPotatoConfig.registerStorable("someVector", someVector); + hotPotatoConfig.registerStorable("someLocation", someLocation); + + try { + hotPotatoConfig.load(); + } catch (IOException e) { + throw new RuntimeException(e); + } ScrowAPI.commands().register(ConfiguratorCommand.rootLiteral(ConfigFileRegistry.get())); } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/action/SetAction.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/action/SetAction.java deleted file mode 100644 index 5450811..0000000 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/action/SetAction.java +++ /dev/null @@ -1,40 +0,0 @@ -package site.lab0x13.scrow.configurator.action; - -import de.kentoj.scrow.bukkit.command.ScrowBukkitCC; -import net.kyori.adventure.text.Component; -import org.jetbrains.annotations.Nullable; -import site.lab0x13.scrow.commands.model.argument.Argument; -import site.lab0x13.scrow.configurator.storable.Storable; - -import java.util.List; - -public abstract class SetAction implements StorableAction> { - - private final Argument argument = argument(); - protected abstract Argument argument(); - protected abstract @Nullable Component valueToPrettyString(T value); - - @Override - public String name() { - return "set"; - } - - @Override - public List> arguments(Storable __) { - return List.of(argument); - } - - @Override - public boolean requiresValue() { - return false; - } - - @Override - public void execute(Storable storable, ScrowBukkitCC ctx) { - var parsedArg = ctx.getArgument(argument); - storable.value(parsedArg.value()); - var prettyValue = valueToPrettyString(parsedArg.value()); - var valueAsString = prettyValue != null ? prettyValue : Component.text(parsedArg.rawValue()); - ctx.sender().sendMessage(ctx.style().ok("Set value to ").append(valueAsString)); - } -} diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/command/CheckLiteral.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/command/CheckLiteral.java index efeee3b..c378c45 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/command/CheckLiteral.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/command/CheckLiteral.java @@ -11,9 +11,9 @@ import static java.util.Objects.*; final class CheckLiteral { private final Literal literal; - private final ConfigFile configFile; + private final ConfigFile configFile; - public CheckLiteral(ConfigFile configFile) { + public CheckLiteral(ConfigFile configFile) { this.configFile = configFile; this.literal = Literal.builder("check") .withSyncExecutor(this::execute) diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/command/ConfigLiteral.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/command/ConfigLiteral.java index ede6267..7d89c56 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/command/ConfigLiteral.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/command/ConfigLiteral.java @@ -8,7 +8,7 @@ public final class ConfigLiteral { private ConfigLiteral() { } - public static Literal literal(ConfigFile cfg) { + public static Literal literal(ConfigFile cfg) { return Literal.builder(cfg.path().normalize().toString()) .withSubLiteral(new KeyLiteral(cfg).literal()) .withSubLiteral(new CheckLiteral(cfg).literal()) diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/command/KeyLiteral.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/command/KeyLiteral.java index bed26da..7f39a0c 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/command/KeyLiteral.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/command/KeyLiteral.java @@ -11,9 +11,9 @@ import site.lab0x13.scrow.configurator.action.StorableAction; final class KeyLiteral { private final Literal literal; - private final ConfigFile configFile; + private final ConfigFile configFile; - KeyLiteral(ConfigFile configFile) { + KeyLiteral(ConfigFile configFile) { this.configFile = configFile; literal = Literal.dynamic("key") .withSubLiteralMetas(() -> configFile.allKeys().stream().map(LiteralMeta::of).toList()) diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/configfile/ConfigFile.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/configfile/ConfigFile.java index f92d1e4..fad2e60 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/configfile/ConfigFile.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/configfile/ConfigFile.java @@ -1,59 +1,28 @@ package site.lab0x13.scrow.configurator.configfile; -import com.google.gson.JsonParser; import org.jetbrains.annotations.Nullable; import site.lab0x13.scrow.configurator.storable.Storable; -import site.lab0x13.scrow.configurator.storable.complex.ComplexStorable; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; import java.util.List; +import java.util.Map; -import static java.util.Objects.requireNonNull; +public interface ConfigFile extends Storable>> { -public abstract class ConfigFile extends ComplexStorable { - - private final Path path; - - public ConfigFile(Path path) { - this.path = path; + static ConfigFile of(Path path) { + return new ConfigFileImpl(path.normalize()); } - public void load() throws IOException { - this.loadJson(JsonParser.parseString(Files.readString(path))); - } + @Nullable Storable getStorable(String key); - public void save() throws IOException { - Files.writeString(path, this.toJson().toString()); - } + void registerStorable(String key, Storable storable); - public Storable getStorable(String key) { - Storable cur = this; - for (var fieldName : key.split("\\.")) { - cur = cur.getSubField(fieldName); - if (cur == null) return null; - } - return cur; - } + List allKeys(); - public List allKeys() { - var res = new ArrayList(); - addKeysRecursively(res, null, this); - return res; - } + void load() throws IOException; - private void addKeysRecursively(List res, @Nullable String parentKey, Storable storable) { - if (parentKey != null) - res.add(parentKey); - storable.subFieldNames().forEach(subFieldName -> { - var subKey = parentKey == null ? subFieldName : parentKey + "." + subFieldName; - addKeysRecursively(res, subKey, requireNonNull(storable.getSubField(subFieldName))); - }); - } + void save() throws IOException; - public Path path() { - return path; - } + Path path(); } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/configfile/ConfigFileImpl.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/configfile/ConfigFileImpl.java new file mode 100644 index 0000000..a743780 --- /dev/null +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/configfile/ConfigFileImpl.java @@ -0,0 +1,83 @@ +package site.lab0x13.scrow.configurator.configfile; + +import com.google.gson.JsonParser; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import site.lab0x13.scrow.configurator.storable.MapStorable; +import site.lab0x13.scrow.configurator.storable.Storable; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import static java.util.Objects.requireNonNull; + +class ConfigFileImpl extends MapStorable> implements ConfigFile { + + private static final Logger log = LoggerFactory.getLogger(ConfigFileImpl.class); + private final Path path; + + ConfigFileImpl(Path path) { + this.path = path; + } + + @Override + public @Nullable Storable getStorable(String key) { + var index = key.indexOf(':'); + if (index == -1) + return getSubField(key); + if (key.endsWith(":")) + return null; + + var fieldName = key.substring(0, index); + Storable storable = getSubField(fieldName); + if (storable == null) + return null; + for (String subFieldName : key.substring(index + 1).split(":")) { + if (subFieldName.isEmpty()) continue; + storable = storable.getSubField(subFieldName); + if (storable == null) + return null; + } + return storable; + } + + @Override + public void registerStorable(String key, Storable storable) { + registerEntry(key, (Storable) storable); + } + + @Override + public List allKeys() { + var res = new ArrayList(); + subFieldNames().forEach(key -> addKeysRecursively(res, key, requireNonNull(getSubField(key)))); + return res; + } + + private void addKeysRecursively(List result, String key, Storable storable) { + result.add(key); + storable.subFieldNames().forEach(subKey -> + addKeysRecursively(result, key + ":" + subKey, requireNonNull(storable.getSubField(subKey)))); + } + + @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; + } +} diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/configfile/ConfigFileRegistry.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/configfile/ConfigFileRegistry.java index 59b980c..eca8096 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/configfile/ConfigFileRegistry.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/configfile/ConfigFileRegistry.java @@ -1,33 +1,34 @@ package site.lab0x13.scrow.configurator.configfile; import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; public class ConfigFileRegistry { + private static final Logger log = LoggerFactory.getLogger(ConfigFileRegistry.class); private static final ConfigFileRegistry instance = new ConfigFileRegistry(); public static ConfigFileRegistry get() { return instance; } - private final Map> configFiles = new HashMap<>(); + private final Map configFiles = new HashMap<>(); - private ConfigFileRegistry() { + public void register(ConfigFile configFile) { + var oldValue = configFiles.put(configFile.path().toString(), configFile); + if (oldValue != null) + log.warn("Overwriting old config with same path '{}'", configFile.path()); } - public void register(ConfigFile configFile, S defaultValue) { - configFile.value(defaultValue); - configFiles.put(configFile.path().normalize().toString(), configFile); - } - - public Map> allConfigs() { + public Map allConfigs() { return new HashMap<>(configFiles); } - public @Nullable ConfigFile getConfigFile(String path) { + public @Nullable ConfigFile getConfigFile(String path) { return configFiles.get(path); } } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/AbstractStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/AbstractStorable.java index 4211805..b057995 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/AbstractStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/AbstractStorable.java @@ -1,9 +1,6 @@ package site.lab0x13.scrow.configurator.storable; -import com.google.gson.JsonElement; -import com.google.gson.JsonNull; import org.jetbrains.annotations.Nullable; -import site.lab0x13.scrow.configurator.action.StorableAction; import java.util.ArrayList; import java.util.List; @@ -11,36 +8,20 @@ import java.util.function.Predicate; public abstract class AbstractStorable implements Storable { private final List subscribers = new ArrayList<>(); - private final List> actions = new ArrayList<>(); + @Nullable + protected T value = null; + private final List> requirements = new ArrayList<>(); - private @Nullable T value = null; - - public AbstractStorable() { - actions.addAll(Storable.super.actions()); - } - - protected abstract JsonElement toJsonSafe(); - - protected abstract void loadJsonSafe(JsonElement json); protected void requireValue(Predicate predicate, String error) { requirements.add(new ValueRequirement<>(predicate, error)); } - protected void addAction(StorableAction action) { - actions.add(action); - } - @Override public void subscribe(ValueChangeSubscriber subscriber) { subscribers.add(subscriber); } - @Override - public List> actions() { - return actions; - } - @Override public @Nullable T value() { return value; @@ -48,13 +29,8 @@ public abstract class AbstractStorable implements Storable { @Override public void value(@Nullable T value) { - setValueSilently(value); - subscribers.forEach(ValueChangeSubscriber::notifyValueChange); - } - - @Override - public void setValueSilently(@Nullable T value) { this.value = value; + subscribers.forEach(ValueChangeSubscriber::notifyValueChange); } @Override @@ -65,20 +41,4 @@ public abstract class AbstractStorable implements Storable { } return null; } - - @Override - public void loadJson(JsonElement json) { - if (json == null || json.isJsonNull()) { - value(null); - return; - } - loadJsonSafe(json); - } - - @Override - public JsonElement toJson() { - if (value == null) - return JsonNull.INSTANCE; - return toJsonSafe(); - } } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/MapStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/MapStorable.java index 40b2dca..f1b6204 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/MapStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/MapStorable.java @@ -9,10 +9,6 @@ import java.util.Map; public class MapStorable extends ComplexStorable> { - public MapStorable() { - value(new HashMap<>()); - } - public void registerEntry(String name, Storable storable) { fieldRegistry().registerField(name, storable, map -> (S) map.get(name)); } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/Storable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/Storable.java index fc56e83..90354ca 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/Storable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/Storable.java @@ -2,13 +2,12 @@ package site.lab0x13.scrow.configurator.storable; import com.google.gson.JsonElement; import org.jetbrains.annotations.Nullable; +import site.lab0x13.scrow.configurator.action.StorableAction; import site.lab0x13.scrow.configurator.action.GlobalSetJsonAction; import site.lab0x13.scrow.configurator.action.GlobalShowAction; -import site.lab0x13.scrow.configurator.action.StorableAction; import java.util.ArrayList; import java.util.List; -import java.util.function.Supplier; public interface Storable { @@ -16,11 +15,6 @@ public interface Storable { void value(@Nullable T value); - /** - * Set value without notifying subscribers - */ - void setValueSilently(@Nullable T value); - JsonElement toJson(); void loadJson(JsonElement json); diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/WrappedStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/WrappedStorable.java index c752083..b27a8ec 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/WrappedStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/WrappedStorable.java @@ -26,24 +26,19 @@ public abstract class WrappedStorable extends AbstractStorable { @Override public void value(@Nullable T value) { + if (skipUpdates) + return; super.value(value); - if (skipUpdates) return; - - try { - skipUpdates = true; - realStorable.value(value != null ? unwrap(value) : null); - } finally { - skipUpdates = false; - } + skipUpdates(() -> realStorable.value(value == null ? null : unwrap(value))); } @Override - public JsonElement toJsonSafe() { + public JsonElement toJson() { return realStorable.toJson(); } @Override - public void loadJsonSafe(JsonElement json) { + public void loadJson(JsonElement json) { realStorable.loadJson(json); } @@ -56,4 +51,16 @@ public abstract class WrappedStorable extends AbstractStorable { public @Nullable Storable getSubField(String name) { return realStorable.getSubField(name); } + + /** + * Run action without updating the value + */ + private void skipUpdates(Action action) { + try { + skipUpdates = true; + action.apply(); + } finally { + skipUpdates = false; + } + } } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/ComplexStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/ComplexStorable.java index 767cb7c..11bbeb0 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/ComplexStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/ComplexStorable.java @@ -2,18 +2,18 @@ package site.lab0x13.scrow.configurator.storable.complex; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import org.jetbrains.annotations.Nullable; import site.lab0x13.scrow.configurator.storable.Storable; public abstract class ComplexStorable extends SubFieldedStorable { - public ComplexStorable() { - this.registerFields(fieldRegistry()); + @Override + protected @Nullable T defaultValue() { + return null; } - protected abstract void registerFields(FieldRegistry registry); - @Override - public JsonElement toJsonSafe() { + public JsonElement toJson() { var obj = new JsonObject(); fieldRegistry().subFields().forEach((subFieldName, subField) -> { var v = (Storable) subField.storable(); @@ -23,9 +23,10 @@ public abstract class ComplexStorable extends SubFieldedStorable { } @Override - public void loadJsonSafe(JsonElement json) { + public void loadJson(JsonElement json) { var obj = json.getAsJsonObject(); - fieldRegistry().subFields().forEach((subFieldName, subField) -> - subField.storable().loadJson(obj.get(subFieldName))); + skipUpdates(() -> fieldRegistry().subFields().forEach((subFieldName, subField) -> + subField.storable().loadJson(obj.get(subFieldName)))); + updateValue(); } } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/FieldRegistry.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/FieldRegistry.java index 6d5d838..c9e6ffd 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/FieldRegistry.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/FieldRegistry.java @@ -2,7 +2,6 @@ package site.lab0x13.scrow.configurator.storable.complex; import org.jetbrains.annotations.Nullable; import site.lab0x13.scrow.configurator.storable.Storable; -import site.lab0x13.scrow.configurator.storable.list.ListStorable; import java.util.HashMap; import java.util.Map; @@ -10,19 +9,11 @@ import java.util.function.Function; public class FieldRegistry { - private final Storable parent; private final Map> subFields = new HashMap<>(); - private final Runnable onFieldRegister; - - public FieldRegistry(Storable parent, Runnable onFieldRegister) { - this.parent = parent; - this.onFieldRegister = onFieldRegister; - } + // TODO move field stuff into own class where register field is one block and after that ready is called public void registerField(String name, Storable storable, Function getter) { subFields.put(name, new Field<>(storable, getter)); - parent.subscribe(() -> storable.setValueSilently(getter.apply(parent.value()))); - storable.subscribe(onFieldRegister::run); } public Map> subFields() { diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/SubFieldedStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/SubFieldedStorable.java index c6e2ea7..b130914 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/SubFieldedStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/complex/SubFieldedStorable.java @@ -2,20 +2,59 @@ package site.lab0x13.scrow.configurator.storable.complex; import org.jetbrains.annotations.Nullable; import site.lab0x13.scrow.configurator.storable.AbstractStorable; +import site.lab0x13.scrow.configurator.storable.Action; import site.lab0x13.scrow.configurator.storable.Storable; import java.util.ArrayList; import java.util.List; -import java.util.function.Supplier; public abstract class SubFieldedStorable extends AbstractStorable { - private final FieldRegistry fieldRegistry = new FieldRegistry<>(this, this::onFieldRegister); + private final FieldRegistry fieldRegistry = new FieldRegistry<>(); + private boolean skipUpdates = false; + + public SubFieldedStorable() { + this.registerFields(fieldRegistry); + fieldRegistry.subFields().values().forEach(f -> f.storable().subscribe(this::updateValue)); + } + + protected abstract void registerFields(FieldRegistry registry); protected abstract T construct(FieldReader reader); - private void onFieldRegister() { - this.setValueSilently(construct(new FieldReader<>(fieldRegistry))); + protected abstract @Nullable T defaultValue(); + + /** + * Run action without updating the value + */ + protected void skipUpdates(Action action) { + try { + skipUpdates = true; + action.apply(); + } finally { + skipUpdates = false; + } + } + + protected void updateValue() { + if (skipUpdates) + return; + super.value(construct(new FieldReader<>(fieldRegistry))); + } + + @Override + public void value(@Nullable T value) { + if (value == null) { + super.value(defaultValue()); + return; + } + super.value(value); + + // reflect value change no sub fields + skipUpdates(() -> fieldRegistry.subFields().values().forEach(_field -> { + var field = (Field) _field; + field.storable().value(field.getter().apply(value)); + })); } @Override diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/DurationStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/DurationStorable.java deleted file mode 100644 index 3d6e231..0000000 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/DurationStorable.java +++ /dev/null @@ -1,23 +0,0 @@ -package site.lab0x13.scrow.configurator.storable.impl; - -import site.lab0x13.scrow.configurator.storable.complex.ComplexStorable; -import site.lab0x13.scrow.configurator.storable.complex.FieldReader; -import site.lab0x13.scrow.configurator.storable.complex.FieldRegistry; -import site.lab0x13.scrow.configurator.storable.primitive.IntStorable; -import site.lab0x13.scrow.configurator.storable.primitive.LongStorable; - -import java.time.Duration; - -public final class DurationStorable extends ComplexStorable { - - @Override - protected void registerFields(FieldRegistry registry) { - registry.registerField("seconds", new LongStorable(), Duration::getSeconds); - registry.registerField("nanos", new IntStorable(), Duration::getNano); - } - - @Override - protected Duration construct(FieldReader reader) { - return Duration.ofSeconds(reader.read("seconds"), reader.read("nanos")); - } -} diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/VectorStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/VectorStorable.java index b3c046c..9ae25c0 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/VectorStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/VectorStorable.java @@ -6,7 +6,7 @@ import site.lab0x13.scrow.configurator.storable.complex.FieldReader; import site.lab0x13.scrow.configurator.storable.complex.FieldRegistry; import site.lab0x13.scrow.configurator.storable.primitive.DoubleStorable; -public final class VectorStorable extends ComplexStorable { +public class VectorStorable extends ComplexStorable { @Override protected void registerFields(FieldRegistry registry) { diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/component/ComponentStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/component/ComponentStorable.java deleted file mode 100644 index 2471a0b..0000000 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/component/ComponentStorable.java +++ /dev/null @@ -1,30 +0,0 @@ -package site.lab0x13.scrow.configurator.storable.impl.component; - -import de.kentoj.scrow.bukkit.command.ScrowBukkitCC; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import site.lab0x13.scrow.commands.model.argument.Argument; -import site.lab0x13.scrow.commands.model.argument.types.StringArgumentType; -import site.lab0x13.scrow.configurator.action.SetAction; -import site.lab0x13.scrow.configurator.storable.WrappedStorable; -import site.lab0x13.scrow.configurator.storable.primitive.StringStorable; - -public final class ComponentStorable extends WrappedStorable { - - private static final MiniMessage miniMessage = MiniMessage.miniMessage(); - - public ComponentStorable() { - super(new StringStorable()); - addAction(new SetComponentAction()); - } - - @Override - protected Component wrap(String real) { - return miniMessage.deserialize(real); - } - - @Override - protected String unwrap(Component value) { - return miniMessage.serialize(value); - } -} diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/component/SetComponentAction.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/component/SetComponentAction.java deleted file mode 100644 index 801f6e2..0000000 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/component/SetComponentAction.java +++ /dev/null @@ -1,21 +0,0 @@ -package site.lab0x13.scrow.configurator.storable.impl.component; - -import de.kentoj.scrow.bukkit.command.ScrowBukkitCC; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import site.lab0x13.scrow.commands.model.argument.Argument; -import site.lab0x13.scrow.commands.model.argument.types.StringArgumentType; -import site.lab0x13.scrow.configurator.action.SetAction; - -class SetComponentAction extends SetAction { - @Override - protected Argument argument() { - return Argument.builder("miniMessage", new StringArgumentType()) - .build(); - } - - @Override - protected Component valueToPrettyString(String value) { - return MiniMessage.miniMessage().deserialize(value); - } -} diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/list/ListExpandAction.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/list/ListExpandAction.java similarity index 93% rename from core/configurator/main/java/site/lab0x13/scrow/configurator/storable/list/ListExpandAction.java rename to core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/list/ListExpandAction.java index 0c14f84..3e9678d 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/list/ListExpandAction.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/list/ListExpandAction.java @@ -1,4 +1,4 @@ -package site.lab0x13.scrow.configurator.storable.list; +package site.lab0x13.scrow.configurator.storable.impl.list; import de.kentoj.scrow.bukkit.command.ScrowBukkitCC; import site.lab0x13.scrow.commands.model.argument.Argument; diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/list/ListStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/list/ListStorable.java new file mode 100644 index 0000000..bb75a8a --- /dev/null +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/list/ListStorable.java @@ -0,0 +1,82 @@ +package site.lab0x13.scrow.configurator.storable.impl.list; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import site.lab0x13.scrow.configurator.action.StorableAction; +import site.lab0x13.scrow.configurator.storable.AbstractStorable; +import site.lab0x13.scrow.configurator.storable.Storable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.IntStream; + +import static java.util.Objects.requireNonNull; + +public class ListStorable> extends AbstractStorable> { + + private final Supplier newElementSupplier; + private final List> actions; + + public ListStorable(Supplier newElementSupplier) { + this.newElementSupplier = newElementSupplier; + actions = super.actions(); + actions.add(new ListExpandAction<>()); + } + + @Override + public List> actions() { + return actions; + } + + @Override + public @NotNull List value() { + var v = super.value(); + if (v == null) { + v = new ArrayList<>(); + value(v); + } + return v; + } + + /** + * Expands the list with a default value storable + */ + public S expandList() { + var newElement = newElementSupplier.get(); + requireNonNull(value()).add(newElement); + return newElement; + } + + @Override + public JsonElement toJson() { + var out = new JsonArray(); + requireNonNull(value()).forEach(storable -> out.add(storable.toJson())); + return out; + } + + @Override + public void loadJson(JsonElement json) { + var in = json.getAsJsonArray(); + in.forEach(jsonElement -> expandList().loadJson(jsonElement)); + } + + @Override + public List subFieldNames() { + var v = value(); + if (v == null) return Collections.emptyList(); + return IntStream.range(0, v.size()) + .mapToObj(Integer::toString) + .toList(); + } + + @Override + public @Nullable Storable getSubField(String name) { + var v = value(); + if (v == null) return null; + return v.get(Integer.parseInt(name)); + } +} diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/location/LocationStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/location/LocationStorable.java index 04a01ff..605a0ec 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/location/LocationStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/location/LocationStorable.java @@ -1,18 +1,26 @@ package site.lab0x13.scrow.configurator.storable.impl.location; import org.bukkit.Location; +import site.lab0x13.scrow.configurator.action.StorableAction; import site.lab0x13.scrow.configurator.storable.complex.ComplexStorable; +import site.lab0x13.scrow.configurator.storable.primitive.DoubleStorable; +import site.lab0x13.scrow.configurator.storable.primitive.FloatStorable; +import site.lab0x13.scrow.configurator.storable.primitive.PrimitiveStorable; import site.lab0x13.scrow.configurator.storable.complex.FieldReader; import site.lab0x13.scrow.configurator.storable.complex.FieldRegistry; import site.lab0x13.scrow.configurator.storable.impl.world.WorldStorable; -import site.lab0x13.scrow.configurator.storable.primitive.DoubleStorable; -import site.lab0x13.scrow.configurator.storable.primitive.FloatStorable; -public final class LocationStorable extends ComplexStorable { +import java.util.ArrayList; +import java.util.List; + +public class LocationStorable extends ComplexStorable { + + private final List> actions; public LocationStorable() { - addAction(new LocationPickCurrentAction()); - addAction(new LocationTeleportAction()); + actions = new ArrayList<>(super.actions()); + actions.add(new LocationPickCurrentAction()); + actions.add(new LocationTeleportAction()); } @Override @@ -25,6 +33,11 @@ public final class LocationStorable extends ComplexStorable { registry.registerField("pitch", new FloatStorable(), Location::getPitch); } + @Override + public List> actions() { + return actions; + } + @Override protected Location construct(FieldReader reader) { return new Location( diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/location/LocationTeleportAction.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/location/LocationTeleportAction.java index 69bf3ba..83109ac 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/location/LocationTeleportAction.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/location/LocationTeleportAction.java @@ -8,9 +8,6 @@ import site.lab0x13.scrow.configurator.storable.Storable; import java.util.Collections; import java.util.List; -import java.util.Objects; - -import static java.util.Objects.*; class LocationTeleportAction implements StorableAction> { @@ -31,7 +28,8 @@ class LocationTeleportAction implements StorableAction node, ScrowBukkitCC ctx) { - ctx.player().teleport(requireNonNull(node.value())); + assert node.value() != null; + ctx.player().teleport(node.value()); ctx.player().sendMessage(ctx.style().ok("You've been teleported.")); } } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/world/SetWorldAction.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/world/SetWorldAction.java index a934b95..a8494b0 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/world/SetWorldAction.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/world/SetWorldAction.java @@ -1,21 +1,38 @@ package site.lab0x13.scrow.configurator.storable.impl.world; import de.kentoj.scrow.bukkit.command.ScrowBukkitCC; -import net.kyori.adventure.text.Component; import org.bukkit.World; import site.lab0x13.scrow.commands.bukkit.type.WorldArgumentType; import site.lab0x13.scrow.commands.model.argument.Argument; -import site.lab0x13.scrow.configurator.action.SetAction; +import site.lab0x13.scrow.configurator.action.StorableAction; +import site.lab0x13.scrow.configurator.storable.Storable; -class SetWorldAction extends SetAction { +import java.util.List; + +class SetWorldAction implements StorableAction> { + + private final Argument arg = + Argument.builder("world", new WorldArgumentType()).build(); @Override - protected Component valueToPrettyString(World value) { - return Component.text(value.getName() + "(" + value.getUID() + ")"); + public String name() { + return "set"; } @Override - protected Argument argument() { - return Argument.builder("world", new WorldArgumentType()).build(); + public List> arguments(Storable __) { + return List.of(arg); + } + + @Override + public boolean requiresValue() { + return false; + } + + @Override + public void execute(Storable node, ScrowBukkitCC ctx) { + World world = ctx.getArg(arg); + node.value(world); + ctx.sender().sendMessage(ctx.style().ok("Set world to " + world.getName() + "(" + world.getUID() + ")")); } } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/world/WorldStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/world/WorldStorable.java index 3ca4926..45737cf 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/world/WorldStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/impl/world/WorldStorable.java @@ -9,7 +9,7 @@ import site.lab0x13.scrow.configurator.storable.primitive.StringStorable; import java.util.ArrayList; import java.util.List; -public final class WorldStorable extends WrappedStorable { +public class WorldStorable extends WrappedStorable { private final List> actions; diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/list/ListStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/list/ListStorable.java deleted file mode 100644 index 3b62ba7..0000000 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/list/ListStorable.java +++ /dev/null @@ -1,95 +0,0 @@ -package site.lab0x13.scrow.configurator.storable.list; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import org.jetbrains.annotations.Nullable; -import site.lab0x13.scrow.configurator.action.StorableAction; -import site.lab0x13.scrow.configurator.storable.AbstractStorable; -import site.lab0x13.scrow.configurator.storable.Storable; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.IntStream; - -public class ListStorable extends AbstractStorable> { - - private final Supplier> newElementSupplier; - private final List> actions; - private final List> _value; - - public ListStorable(Supplier> newElementSupplier) { - this.newElementSupplier = newElementSupplier; - _value = new ArrayList<>(); - value(new ArrayList<>()); - actions = super.actions(); - actions.add(new ListExpandAction<>()); - } - - @Override - public void value(@Nullable List value) { - super.value(value != null ? value : new ArrayList<>()); - } - - @Override - public List> actions() { - return actions; - } - - /** - * Expands the list with a default value storable - */ - public Storable expandList() { - var newElement = newElementSupplier.get(); - newElement.subscribe(this::updateValue); - _value.add(newElement); - updateValue(); - return newElement; - } - - public void deleteAt(int index) { - _value.remove(index); - updateValue(); - } - - @Override - public JsonElement toJsonSafe() { - var out = new JsonArray(); - _value.forEach(storable -> out.add(storable.toJson())); - return out; - } - - @Override - public void loadJsonSafe(JsonElement json) { - var in = json.getAsJsonArray(); - _value.clear(); - in.forEach(jsonElement -> { - var element = newElementSupplier.get(); - element.loadJson(jsonElement); - _value.add(element); - }); - updateValue(); - } - - @Override - public List subFieldNames() { - return IntStream.range(0, _value.size()) - .mapToObj(Integer::toString) - .toList(); - } - - @Override - public @Nullable Storable getSubField(String name) { - int index; - try { - index = Integer.parseInt(name); - } catch (NumberFormatException _) { - return null; - } - return _value.get(index); - } - - private void updateValue() { - setValueSilently(_value.stream().map(Storable::value).toList()); - } -} diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/BooleanStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/BooleanStorable.java index bf00e74..3261450 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/BooleanStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/BooleanStorable.java @@ -2,13 +2,9 @@ package site.lab0x13.scrow.configurator.storable.primitive; import com.google.gson.JsonPrimitive; -public final class BooleanStorable extends PrimitiveStorable{ - public BooleanStorable(boolean defaultValue) { - super(defaultValue, JsonPrimitive::new, JsonPrimitive::getAsBoolean); - } - +public class BooleanStorable extends PrimitiveStorable{ public BooleanStorable() { - this(false); + super(false, JsonPrimitive::new, JsonPrimitive::getAsBoolean); } } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/ByteStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/ByteStorable.java index c6e3b19..e0da049 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/ByteStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/ByteStorable.java @@ -2,13 +2,9 @@ package site.lab0x13.scrow.configurator.storable.primitive; import com.google.gson.JsonPrimitive; -public final class ByteStorable extends PrimitiveStorable{ - public ByteStorable(byte defaultValue) { - super(defaultValue, JsonPrimitive::new, JsonPrimitive::getAsByte); - } - +public class ByteStorable extends PrimitiveStorable{ public ByteStorable() { - this((byte) 0); + super((byte)0, JsonPrimitive::new, JsonPrimitive::getAsByte); } } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/DoubleStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/DoubleStorable.java index fd31786..34d197d 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/DoubleStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/DoubleStorable.java @@ -2,13 +2,9 @@ package site.lab0x13.scrow.configurator.storable.primitive; import com.google.gson.JsonPrimitive; -public final class DoubleStorable extends PrimitiveStorable{ - public DoubleStorable(double defaultValue) { - super(defaultValue, JsonPrimitive::new, JsonPrimitive::getAsDouble); - } - +public class DoubleStorable extends PrimitiveStorable{ public DoubleStorable() { - this(0); + super(0D, JsonPrimitive::new, JsonPrimitive::getAsDouble); } } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/FloatStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/FloatStorable.java index 069d615..81353b2 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/FloatStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/FloatStorable.java @@ -2,13 +2,9 @@ package site.lab0x13.scrow.configurator.storable.primitive; import com.google.gson.JsonPrimitive; -public final class FloatStorable extends PrimitiveStorable{ - public FloatStorable(float defaultValue) { - super(defaultValue, JsonPrimitive::new, JsonPrimitive::getAsFloat); - } - +public class FloatStorable extends PrimitiveStorable{ public FloatStorable() { - this(0); + super(0F, JsonPrimitive::new, JsonPrimitive::getAsFloat); } } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/IntStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/IntStorable.java index 0d98135..dd54121 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/IntStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/IntStorable.java @@ -2,12 +2,9 @@ package site.lab0x13.scrow.configurator.storable.primitive; import com.google.gson.JsonPrimitive; -public final class IntStorable extends PrimitiveStorable{ - public IntStorable(int defaultValue) { - super(defaultValue, JsonPrimitive::new, JsonPrimitive::getAsInt); - } +public class IntStorable extends PrimitiveStorable{ public IntStorable() { - this(0); + super(0, JsonPrimitive::new, JsonPrimitive::getAsInt); } } diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/LongStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/LongStorable.java deleted file mode 100644 index 71df75e..0000000 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/LongStorable.java +++ /dev/null @@ -1,14 +0,0 @@ -package site.lab0x13.scrow.configurator.storable.primitive; - -import com.google.gson.JsonPrimitive; - -public final class LongStorable extends PrimitiveStorable { - public LongStorable(long defaultValue) { - super(defaultValue, JsonPrimitive::new, JsonPrimitive::getAsLong); - } - - public LongStorable() { - this(0); - } -} - diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/PrimitiveStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/PrimitiveStorable.java index 013a749..a1ee704 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/PrimitiveStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/PrimitiveStorable.java @@ -13,9 +13,9 @@ import java.util.function.Function; public class PrimitiveStorable extends AbstractStorable { + private final V defaultValue; private final Function serializer; private final Function deserializer; - private final V defaultValue; public PrimitiveStorable(V defaultValue, Function serializer, Function deserializer) { this.defaultValue = defaultValue; @@ -24,13 +24,23 @@ public class PrimitiveStorable extends AbstractStorable { } @Override - public JsonElement toJsonSafe() { + public JsonElement toJson() { + if (value() == null) + return JsonNull.INSTANCE; return serializer.apply(value()); } @Override - public void loadJsonSafe(JsonElement json) { - value(deserializer.apply(json.getAsJsonPrimitive())); + public void loadJson(JsonElement json) { + if (json.isJsonNull()) + value(defaultValue); + else + value(deserializer.apply(json.getAsJsonPrimitive())); + } + + @Override + public void value(@Nullable V value) { + super.value(value == null ? defaultValue : value); } @Override diff --git a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/StringStorable.java b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/StringStorable.java index 8b9a9de..0fdb8a5 100644 --- a/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/StringStorable.java +++ b/core/configurator/main/java/site/lab0x13/scrow/configurator/storable/primitive/StringStorable.java @@ -1,22 +1,10 @@ package site.lab0x13.scrow.configurator.storable.primitive; import com.google.gson.JsonPrimitive; -import site.lab0x13.scrow.configurator.action.StorableAction; - -import java.util.List; - -public final class StringStorable extends PrimitiveStorable{ - public StringStorable(String defaultValue) { - super(defaultValue, JsonPrimitive::new, JsonPrimitive::getAsString); - } +public class StringStorable extends PrimitiveStorable{ public StringStorable() { - this(""); - } - - @Override - public List> actions() { - return super.actions(); + super("", JsonPrimitive::new, JsonPrimitive::getAsString); } } diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/ExtractionGame.java b/minigame/extraction/site/lab0x13/scrow/extraction/ExtractionGame.java index 19ec818..4931ba0 100644 --- a/minigame/extraction/site/lab0x13/scrow/extraction/ExtractionGame.java +++ b/minigame/extraction/site/lab0x13/scrow/extraction/ExtractionGame.java @@ -5,30 +5,15 @@ import de.kentoj.scrow.bukkit.minigame.PlayerManager; import de.kentoj.scrow.bukkit.minigame.phaseflow.LinearPhaseFlow; import de.kentoj.scrowlib.convention.ScrowMessageStyle; import net.kyori.adventure.text.format.TextColor; -import site.lab0x13.scrow.extraction.config.ArenaConfig; import java.util.concurrent.CompletableFuture; -/* -While in the network lobby, players select a kit. then when enough players are found, -players are spread on a map and are tasked to extract some tokens. -extracting a token gives you points, items and a temporary health and speed-boost as well as temporary -wallhacks. extracting a token takes a while and other players want to stop you from doing so, so you'll -need to fight. - */ - public class ExtractionGame implements Minigame { private final ScrowMessageStyle style = new ScrowMessageStyle("PotatoRun", TextColor.color(0x8D7726)); private final PlayerManager playerManager = new PlayerManager(this); private final LinearPhaseFlow phaseFlow = new LinearPhaseFlow("potatoRun.root"); - private final ArenaConfig arenaConfig; - - public ExtractionGame(ArenaConfig arenaConfig) { - this.arenaConfig = arenaConfig; - } - @Override public int minParticipants() { return 0; @@ -52,8 +37,4 @@ public class ExtractionGame implements Minigame { public PlayerManager playerManager() { return playerManager; } - - public ArenaConfig arenaConfig() { - return arenaConfig; - } } diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/ExtractionPlugin.java b/minigame/extraction/site/lab0x13/scrow/extraction/ExtractionPlugin.java index 457e4d8..3da0648 100644 --- a/minigame/extraction/site/lab0x13/scrow/extraction/ExtractionPlugin.java +++ b/minigame/extraction/site/lab0x13/scrow/extraction/ExtractionPlugin.java @@ -1,26 +1,29 @@ package site.lab0x13.scrow.extraction; -import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import site.lab0x13.scrow.configurator.configfile.ConfigFile; import site.lab0x13.scrow.configurator.configfile.ConfigFileRegistry; import site.lab0x13.scrow.extraction.config.ExtractionConfig; -import site.lab0x13.scrow.extraction.config.ExtractionConfigStorable; + +import java.io.IOException; public class ExtractionPlugin extends JavaPlugin { - private static final Logger log = LoggerFactory.getLogger(ExtractionPlugin.class); - private static Plugin _plugin; - - public static Plugin plugin() { - return _plugin; - } + private final Logger log = LoggerFactory.getLogger(ExtractionPlugin.class); @Override public void onEnable() { - _plugin = this; - var config = new ExtractionConfigStorable(this.getDataPath().resolve("config.json")); - ConfigFileRegistry.get().register(config, ExtractionConfig.defaultConfig()); + log.info("loading"); + var cfg = ConfigFile.of(this.getDataPath().resolve("config.json")); + ConfigFileRegistry.get().register(cfg); + cfg.registerStorable("arenas", ExtractionConfig.arenas); + try { + cfg.load(); + } catch (IOException e) { + throw new RuntimeException(e); + } + log.info("loaded"); } } \ No newline at end of file diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/compass/CompassTarget.java b/minigame/extraction/site/lab0x13/scrow/extraction/compass/CompassTarget.java deleted file mode 100644 index bbdb7eb..0000000 --- a/minigame/extraction/site/lab0x13/scrow/extraction/compass/CompassTarget.java +++ /dev/null @@ -1,10 +0,0 @@ -package site.lab0x13.scrow.extraction.compass; - -import org.bukkit.Location; - -public interface CompassTarget { - - String targetName(); - - Location location(); -} diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/compass/CompassTargetRegistry.java b/minigame/extraction/site/lab0x13/scrow/extraction/compass/CompassTargetRegistry.java deleted file mode 100644 index a6a08d3..0000000 --- a/minigame/extraction/site/lab0x13/scrow/extraction/compass/CompassTargetRegistry.java +++ /dev/null @@ -1,48 +0,0 @@ -package site.lab0x13.scrow.extraction.compass; - -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import static com.google.common.base.Preconditions.checkArgument; - -public class CompassTargetRegistry { - - private final Map targets = new HashMap<>(); - - public void targetNearest(Player player, List targetList) { - var nearest = findNearest(player.getLocation(), targetList); - targets.put(player.getUniqueId(), nearest); - } - - public void setCompassTarget(Player player, @Nullable CompassTarget compassTarget) { - if (compassTarget == null) - targets.remove(player.getUniqueId()); - else - targets.put(player.getUniqueId(), compassTarget); - } - - public @Nullable CompassTarget getCompassTarget(Player player) { - return targets.get(player.getUniqueId()); - } - - private static CompassTarget findNearest(Location location, List targetList) { - checkArgument(!targetList.isEmpty(), "targetList is empty"); - - CompassTarget nearest = targetList.getFirst(); - double nearestDistanceSquared = Double.MAX_VALUE; - for (var target : targetList) { - var targetDistanceSquared = target.location().distanceSquared(location); - if (targetDistanceSquared < nearestDistanceSquared) { - nearestDistanceSquared = targetDistanceSquared; - nearest = target; - } - } - return nearest; - } -} diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/config/ArenaConfig.java b/minigame/extraction/site/lab0x13/scrow/extraction/config/ArenaConfig.java index e568b2f..204961a 100644 --- a/minigame/extraction/site/lab0x13/scrow/extraction/config/ArenaConfig.java +++ b/minigame/extraction/site/lab0x13/scrow/extraction/config/ArenaConfig.java @@ -1,19 +1,11 @@ package site.lab0x13.scrow.extraction.config; -import net.kyori.adventure.text.Component; import org.bukkit.Location; -import site.lab0x13.scrow.extraction.extractionpoint.ExtractionPoint; +import site.lab0x13.scrow.configurator.storable.Storable; -import java.util.ArrayList; import java.util.List; public record ArenaConfig( - String id, - Component name, - List spawnLocations, - List extractionPoints + List> spawnLocations ) { - public static ArenaConfig defaultConfig() { - return new ArenaConfig("", Component.empty(), new ArrayList<>(), new ArrayList<>()); - } } diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/config/ArenaConfigStorable.java b/minigame/extraction/site/lab0x13/scrow/extraction/config/ArenaConfigStorable.java index 8f84720..eb85905 100644 --- a/minigame/extraction/site/lab0x13/scrow/extraction/config/ArenaConfigStorable.java +++ b/minigame/extraction/site/lab0x13/scrow/extraction/config/ArenaConfigStorable.java @@ -3,31 +3,18 @@ package site.lab0x13.scrow.extraction.config; import site.lab0x13.scrow.configurator.storable.complex.ComplexStorable; import site.lab0x13.scrow.configurator.storable.complex.FieldReader; import site.lab0x13.scrow.configurator.storable.complex.FieldRegistry; -import site.lab0x13.scrow.configurator.storable.impl.component.ComponentStorable; +import site.lab0x13.scrow.configurator.storable.impl.list.ListStorable; import site.lab0x13.scrow.configurator.storable.impl.location.LocationStorable; -import site.lab0x13.scrow.configurator.storable.list.ListStorable; -import site.lab0x13.scrow.configurator.storable.primitive.StringStorable; public class ArenaConfigStorable extends ComplexStorable { @Override protected void registerFields(FieldRegistry registry) { - registry.registerField("id", new StringStorable(), ArenaConfig::id); - registry.registerField("name", new ComponentStorable(), ArenaConfig::name); - registry.registerField("spawnLocations", - new ListStorable<>(LocationStorable::new), ArenaConfig::spawnLocations); - registry.registerField("extractionPoints", - new ListStorable<>(ExtractionPointStorable::new), - ArenaConfig::extractionPoints); + registry.registerField("spawnLocations", new ListStorable<>(LocationStorable::new), ArenaConfig::spawnLocations); } @Override protected ArenaConfig construct(FieldReader reader) { - return new ArenaConfig( - reader.read("id"), - reader.read("name"), - reader.read("spawnLocations"), - reader.read("extractionPoints") - ); + return new ArenaConfig(reader.read("spawnLocations")); } } diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/config/ExtractionConfig.java b/minigame/extraction/site/lab0x13/scrow/extraction/config/ExtractionConfig.java index 8a7cae9..b97cda3 100644 --- a/minigame/extraction/site/lab0x13/scrow/extraction/config/ExtractionConfig.java +++ b/minigame/extraction/site/lab0x13/scrow/extraction/config/ExtractionConfig.java @@ -1,27 +1,10 @@ package site.lab0x13.scrow.extraction.config; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; +import site.lab0x13.scrow.configurator.storable.impl.list.ListStorable; -public record ExtractionConfig( - List arenas, - Duration extractionDuration -) { - private static ExtractionConfig instance; - - public static ExtractionConfig defaultConfig() { - return new ExtractionConfig( - new ArrayList<>(), - Duration.ofMillis(100) - ); +public final class ExtractionConfig { + private ExtractionConfig() { } - public ExtractionConfig { - instance = this; - } - - public static ExtractionConfig get() { - return instance; - } + public static final ListStorable arenas = new ListStorable<>(ArenaConfigStorable::new); } diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/config/ExtractionConfigStorable.java b/minigame/extraction/site/lab0x13/scrow/extraction/config/ExtractionConfigStorable.java deleted file mode 100644 index 275b62a..0000000 --- a/minigame/extraction/site/lab0x13/scrow/extraction/config/ExtractionConfigStorable.java +++ /dev/null @@ -1,29 +0,0 @@ -package site.lab0x13.scrow.extraction.config; - -import site.lab0x13.scrow.configurator.configfile.ConfigFile; -import site.lab0x13.scrow.configurator.storable.complex.FieldReader; -import site.lab0x13.scrow.configurator.storable.complex.FieldRegistry; -import site.lab0x13.scrow.configurator.storable.impl.DurationStorable; -import site.lab0x13.scrow.configurator.storable.list.ListStorable; - -import java.nio.file.Path; - -public class ExtractionConfigStorable extends ConfigFile { - public ExtractionConfigStorable(Path path) { - super(path); - } - - @Override - protected void registerFields(FieldRegistry registry) { - registry.registerField("arenas", new ListStorable<>(ArenaConfigStorable::new), ExtractionConfig::arenas); - registry.registerField("extractionDuration", new DurationStorable(), ExtractionConfig::extractionDuration); - } - - @Override - protected ExtractionConfig construct(FieldReader reader) { - return new ExtractionConfig( - reader.read("arenas"), - reader.read("extractionDuration") - ); - } -} diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/config/ExtractionPointStorable.java b/minigame/extraction/site/lab0x13/scrow/extraction/config/ExtractionPointStorable.java deleted file mode 100644 index d77276a..0000000 --- a/minigame/extraction/site/lab0x13/scrow/extraction/config/ExtractionPointStorable.java +++ /dev/null @@ -1,19 +0,0 @@ -package site.lab0x13.scrow.extraction.config; - -import site.lab0x13.scrow.configurator.storable.complex.ComplexStorable; -import site.lab0x13.scrow.configurator.storable.complex.FieldReader; -import site.lab0x13.scrow.configurator.storable.complex.FieldRegistry; -import site.lab0x13.scrow.configurator.storable.impl.location.LocationStorable; -import site.lab0x13.scrow.extraction.extractionpoint.ExtractionPoint; - -public class ExtractionPointStorable extends ComplexStorable { - @Override - protected void registerFields(FieldRegistry registry) { - registry.registerField("location", new LocationStorable(), ExtractionPoint::location); - } - - @Override - protected ExtractionPoint construct(FieldReader reader) { - return new ExtractionPoint(reader.read("location")); - } -} diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/extractionpoint/ExtractionPoint.java b/minigame/extraction/site/lab0x13/scrow/extraction/extractionpoint/ExtractionPoint.java deleted file mode 100644 index dd40a80..0000000 --- a/minigame/extraction/site/lab0x13/scrow/extraction/extractionpoint/ExtractionPoint.java +++ /dev/null @@ -1,33 +0,0 @@ -package site.lab0x13.scrow.extraction.extractionpoint; - -import org.bukkit.Location; -import org.bukkit.entity.Player; -import site.lab0x13.scrow.extraction.compass.CompassTarget; -import site.lab0x13.scrow.extraction.config.ExtractionConfig; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public final class ExtractionPoint implements CompassTarget { - private final Location location; - private final Map extractionProgress = new HashMap<>(); - - public ExtractionPoint(Location location) { - this.location = location; - } - - public ExtractionProgress getProgress(Player player) { - return extractionProgress.computeIfAbsent(player.getUniqueId(), _ -> new ExtractionProgress()); - } - - @Override - public String targetName() { - return "Extraction Point"; - } - - @Override - public Location location() { - return location; - } -} diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/extractionpoint/ExtractionProgress.java b/minigame/extraction/site/lab0x13/scrow/extraction/extractionpoint/ExtractionProgress.java deleted file mode 100644 index a803990..0000000 --- a/minigame/extraction/site/lab0x13/scrow/extraction/extractionpoint/ExtractionProgress.java +++ /dev/null @@ -1,89 +0,0 @@ -package site.lab0x13.scrow.extraction.extractionpoint; - -import org.bukkit.scheduler.BukkitRunnable; -import site.lab0x13.scrow.extraction.ExtractionPlugin; -import site.lab0x13.scrow.extraction.config.ExtractionConfig; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -import static java.util.Objects.requireNonNull; - -/** - * You extract by repeatedly calling {@link ExtractionProgress#advanceExtraction()} - * with little delay in between. - * If the delay is too long, progress is reset. - */ -public class ExtractionProgress { - - /** - * ticks(= 50ms) after which progress will be reset if {@link ExtractionProgress#advanceExtraction()} - * isn't called. - */ - private static final int MAX_DELAY_TICKS = 2; - - private final List> changeSubscribers = new ArrayList<>(); - private final long requiredMs; - /** - * System.currentTimeMillis() at first click (in this attempt to extract) - * or < 0 if extracting hasn't been attempted recently. - */ - private long clickingSince = -1; - /** - * System.currentTimeMillis() at last click - */ - private long lastClickMs = 0; - - /** - * @param extractionTime duration for which progress must be called repeatedly - */ - public ExtractionProgress(Duration extractionTime) { - this.requiredMs = extractionTime.toMillis(); - } - - public ExtractionProgress() { - this(ExtractionConfig.get().extractionDuration()); - } - - public void advanceExtraction() { - if (clickingSince < 0) - clickingSince = System.currentTimeMillis(); - lastClickMs = System.currentTimeMillis(); - notifyChangeSubscribers(); - - /* reset if not called again for a while */ - new BukkitRunnable() { - final long lastClickMsAtStart = lastClickMs; - - @Override - public void run() { - if (lastClickMsAtStart == lastClickMs) - resetProgress(); - } - }.runTaskLater(ExtractionPlugin.plugin(), MAX_DELAY_TICKS); - } - - public double progress() { - if (lastClickMs == 0) - return 0; - var delta = System.currentTimeMillis() - requiredMs; - return Math.max(1.0, (double) delta / (double) requiredMs); - } - - public void resetProgress() { - clickingSince = -1; - lastClickMs = 0; - notifyChangeSubscribers(); - } - - public void subscribeChange(Consumer onChange) { - changeSubscribers.add(onChange); - } - - private void notifyChangeSubscribers() { - var progress = progress(); - changeSubscribers.forEach(sub -> sub.accept(progress)); - } -} diff --git a/minigame/extraction/site/lab0x13/scrow/extraction/phase/MidgamePhase.java b/minigame/extraction/site/lab0x13/scrow/extraction/phase/MidgamePhase.java deleted file mode 100644 index b886677..0000000 --- a/minigame/extraction/site/lab0x13/scrow/extraction/phase/MidgamePhase.java +++ /dev/null @@ -1,30 +0,0 @@ -package site.lab0x13.scrow.extraction.phase; - -import de.kentoj.scrow.bukkit.minigame.phase.Phase; -import de.kentoj.scrow.bukkit.minigame.phaseflow.PhaseContext; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import site.lab0x13.scrow.extraction.ExtractionGame; -import site.lab0x13.scrow.extraction.compass.CompassTargetRegistry; - -public class MidgamePhase extends Phase { - - private final CompassTargetRegistry compassTargetRegistry; - - protected MidgamePhase(PhaseContext ctx, CompassTargetRegistry compassTargetRegistry) { - super(ctx); - this.compassTargetRegistry = compassTargetRegistry; - } - - @Override - protected void onStart() { - ctx.players().participants().forEach(player -> { - compassTargetRegistry.targetNearest(player, ctx.game().arenaConfig().extractionPoints()); - player.getInventory().addItem(ItemStack.of(Material.COMPASS)); - }); - } - - @Override - protected void onCancel() { - } -}