diff --git a/build.gradle b/build.gradle index be4cf911..91aef399 100644 --- a/build.gradle +++ b/build.gradle @@ -61,6 +61,10 @@ allprojects { modImplementation "io.github.ladysnake:PlayerAbilityLib:${pal_version}" include "io.github.ladysnake:PlayerAbilityLib:${pal_version}" + modApi ("me.shedaniel.cloth:cloth-config-fabric:11.1.106") { + exclude(group: "net.fabricmc.fabric-api") + } + // Subprojects subprojects.each { implementation project(path: ":${it.name}", configuration: "namedElements") @@ -105,6 +109,9 @@ allprojects { repositories { mavenCentral() maven { name 'Fabric'; url 'https://maven.fabricmc.net/' } + // FIXME @jp: [BEFORE MERGE] Remove these if we're truly not using ClothConfig + maven { url "https://maven.shedaniel.me/" } + maven { url "https://maven.terraformersmc.com/releases/" } // maven { name 'TerraformersMC'; url 'https://maven.terraformersmc.com/' } // Add repositories to retrieve artifacts from in here. // You should only use this when depending on other mods because diff --git a/ec-core/src/main/java/dev/jpcode/eccore/config/Config.java b/ec-core/src/main/java/dev/jpcode/eccore/config/Config.java index 14227a71..0af5f923 100644 --- a/ec-core/src/main/java/dev/jpcode/eccore/config/Config.java +++ b/ec-core/src/main/java/dev/jpcode/eccore/config/Config.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.function.Consumer; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -67,15 +68,44 @@ public void loadOrCreateProperties() { } private void initProperties() { - Class cls = this.getClass(); // Cursed reflection reloading of all properties. - Arrays.stream(cls.getDeclaredFields()) + getAllOptions() + .forEach(opt -> opt.loadAndSave(props)); + } + + private List> options; + + private List> getOptions() { + if (this.options != null) { + return this.options; + } + + Class cls = this.getClass(); + return this.options = Arrays.stream(cls.getDeclaredFields()) .filter(field -> field.isAnnotationPresent(ConfigOption.class)) - .forEach(field -> { + .map(field -> { + try { + return ((Option) field.get(this)); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + }) + .toList(); + } + + public Stream> getAllOptions() { + return Stream.concat(getOptions().stream(), getSectionOptions()); + } + + private Stream> getSectionOptions() { + Class cls = this.getClass(); + return Arrays.stream(cls.getDeclaredFields()) + .filter(field -> ConfigSectionSkeleton.class.isAssignableFrom(field.getType())) + .flatMap(field -> { try { - ((Option) field.get(this)).loadAndSave(props); + return ((ConfigSectionSkeleton) field.get(this)).getOptions().stream(); } catch (IllegalAccessException e) { - e.printStackTrace(); + throw new RuntimeException(e); } }); } diff --git a/ec-core/src/main/java/dev/jpcode/eccore/config/ConfigSectionSkeleton.java b/ec-core/src/main/java/dev/jpcode/eccore/config/ConfigSectionSkeleton.java new file mode 100644 index 00000000..810f9f15 --- /dev/null +++ b/ec-core/src/main/java/dev/jpcode/eccore/config/ConfigSectionSkeleton.java @@ -0,0 +1,32 @@ +package dev.jpcode.eccore.config; + +import java.util.Arrays; +import java.util.List; + +public abstract class ConfigSectionSkeleton { + public final String name; + private List> options; + + protected ConfigSectionSkeleton(String name) { + this.name = name; + + } + + public List> getOptions() { + if (options != null) { + return options; + } + + Class cls = this.getClass(); + return this.options = Arrays.stream(cls.getDeclaredFields()) + .filter(field -> field.isAnnotationPresent(ConfigOption.class)) + .map(field -> { + try { + return ((Option) field.get(this)); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + }) + .toList(); + } +} diff --git a/src/main/java/com/fibermc/essentialcommands/config/AfkConfig.java b/src/main/java/com/fibermc/essentialcommands/config/AfkConfig.java new file mode 100644 index 00000000..54fc61d0 --- /dev/null +++ b/src/main/java/com/fibermc/essentialcommands/config/AfkConfig.java @@ -0,0 +1,25 @@ +package com.fibermc.essentialcommands.config; + +import java.time.Duration; + +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +import dev.jpcode.eccore.config.ConfigOption; +import dev.jpcode.eccore.config.ConfigSectionSkeleton; +import dev.jpcode.eccore.config.ConfigUtil; +import dev.jpcode.eccore.config.Option; +import dev.jpcode.eccore.util.TextUtil; + +import static dev.jpcode.eccore.util.TimeUtil.durationToTicks; + +public class AfkConfig extends ConfigSectionSkeleton { + @ConfigOption public final Option AFK_PREFIX = new Option<>("afk_prefix", Text.literal("[AFK] ").formatted(Formatting.GRAY), TextUtil::parseText, Text.Serializer::toJson); + @ConfigOption public final Option INVULN_WHILE_AFK = new Option<>("invuln_while_afk", false, Boolean::parseBoolean); + @ConfigOption public final Option AUTO_AFK_ENABLED = new Option<>("auto_afk_enabled", true, Boolean::parseBoolean); + @ConfigOption public final Option AUTO_AFK_TICKS = new Option<>("auto_afk_time", durationToTicks(Duration.ofMinutes(15)), ConfigUtil::parseDurationToTicks, ConfigUtil::serializeTicksAsDuration); + + protected AfkConfig(String name) { + super(name); + } +} diff --git a/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfig.java b/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfig.java index 1033bb96..a0223f22 100644 --- a/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfig.java +++ b/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfig.java @@ -1,161 +1,32 @@ package com.fibermc.essentialcommands.config; import java.nio.file.Path; -import java.time.Duration; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import com.fibermc.essentialcommands.ECPerms; -import com.fibermc.essentialcommands.EssentialCommands; -import com.fibermc.essentialcommands.ManagerLocator; -import com.fibermc.essentialcommands.playerdata.PlayerDataManager; -import com.fibermc.essentialcommands.types.RespawnCondition; import org.jetbrains.annotations.NotNull; -import net.minecraft.registry.RegistryKey; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; -import net.minecraft.world.World; - import dev.jpcode.eccore.config.Config; -import dev.jpcode.eccore.config.ConfigOption; -import dev.jpcode.eccore.config.ConfigUtil; import dev.jpcode.eccore.config.Option; -import dev.jpcode.eccore.config.expression.Expression; -import dev.jpcode.eccore.config.expression.PatternMatchingExpressionReader; -import dev.jpcode.eccore.util.TextUtil; import static com.fibermc.essentialcommands.EssentialCommands.LOGGER; -import static dev.jpcode.eccore.config.ConfigUtil.*; -import static dev.jpcode.eccore.util.TextUtil.parseText; -import static dev.jpcode.eccore.util.TimeUtil.durationToTicks; @SuppressWarnings("checkstyle:all") public final class EssentialCommandsConfig extends Config { - - @ConfigOption public final Option