Add config categories

This commit is contained in:
Linnea Gräf
2024-10-13 21:46:46 +02:00
parent 0cc77949c9
commit 4e9b0ded27
32 changed files with 337 additions and 220 deletions

View File

@@ -4,11 +4,12 @@ import com.mrcrayfish.configured.api.IConfigEntry
import com.mrcrayfish.configured.api.IConfigValue import com.mrcrayfish.configured.api.IConfigValue
import net.minecraft.text.Text import net.minecraft.text.Text
import moe.nea.firmament.gui.config.AllConfigsGui import moe.nea.firmament.gui.config.AllConfigsGui
import moe.nea.firmament.gui.config.ManagedConfig
object BaseConfigNode : IConfigEntry { object BaseConfigNode : IConfigEntry {
override fun getChildren(): List<IConfigEntry> { override fun getChildren(): List<IConfigEntry> {
return AllConfigsGui.allConfigs.map { return ManagedConfig.allManagedConfigs.getAll().map {
ConfigNode(it) ConfigNode(it) // TODO: fix add categories here
} }
} }

View File

@@ -6,6 +6,7 @@ import com.mrcrayfish.configured.api.IModConfigProvider
import com.mrcrayfish.configured.api.ModContext import com.mrcrayfish.configured.api.ModContext
import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament
import moe.nea.firmament.gui.config.AllConfigsGui import moe.nea.firmament.gui.config.AllConfigsGui
import moe.nea.firmament.gui.config.ManagedConfig
/** /**
* Registered in `fabric.mod.json` at `custom.configured.providers` * Registered in `fabric.mod.json` at `custom.configured.providers`
@@ -23,7 +24,7 @@ class ConfiguredCompat : IModConfigProvider {
return "firmament.config.all-configs" return "firmament.config.all-configs"
} }
}) })
AllConfigsGui.allConfigs.mapTo(this) { ConfigCategory(it) } ManagedConfig.allManagedConfigs.getAll().mapTo(this) { ConfigCategory(it) }
} }
} }
} }

View File

@@ -6,6 +6,7 @@ import dev.isxander.yacl3.api.ButtonOption
import dev.isxander.yacl3.api.ConfigCategory import dev.isxander.yacl3.api.ConfigCategory
import dev.isxander.yacl3.api.LabelOption import dev.isxander.yacl3.api.LabelOption
import dev.isxander.yacl3.api.Option import dev.isxander.yacl3.api.Option
import dev.isxander.yacl3.api.OptionGroup
import dev.isxander.yacl3.api.YetAnotherConfigLib import dev.isxander.yacl3.api.YetAnotherConfigLib
import dev.isxander.yacl3.api.controller.ControllerBuilder import dev.isxander.yacl3.api.controller.ControllerBuilder
import dev.isxander.yacl3.api.controller.DoubleSliderControllerBuilder import dev.isxander.yacl3.api.controller.DoubleSliderControllerBuilder
@@ -17,7 +18,6 @@ import kotlin.time.Duration.Companion.seconds
import kotlin.time.DurationUnit import kotlin.time.DurationUnit
import net.minecraft.client.gui.screen.Screen import net.minecraft.client.gui.screen.Screen
import net.minecraft.text.Text import net.minecraft.text.Text
import moe.nea.firmament.gui.config.AllConfigsGui
import moe.nea.firmament.gui.config.BooleanHandler import moe.nea.firmament.gui.config.BooleanHandler
import moe.nea.firmament.gui.config.ClickHandler import moe.nea.firmament.gui.config.ClickHandler
import moe.nea.firmament.gui.config.DurationHandler import moe.nea.firmament.gui.config.DurationHandler
@@ -36,15 +36,20 @@ import moe.nea.firmament.util.FirmFormatters
@AutoService(FirmamentConfigScreenProvider::class) @AutoService(FirmamentConfigScreenProvider::class)
class YaclIntegration : FirmamentConfigScreenProvider { class YaclIntegration : FirmamentConfigScreenProvider {
fun buildCategories() = fun buildCategories() =
AllConfigsGui.allConfigs ManagedConfig.Category.entries
.map(::buildCategory) .map(::buildCategory)
private fun buildCategory(managedConfig: ManagedConfig): ConfigCategory { private fun buildCategory(category: ManagedConfig.Category): ConfigCategory {
return ConfigCategory.createBuilder() return ConfigCategory.createBuilder()
.name(managedConfig.labelText) .name(category.labelText)
.also { .also { categoryB ->
it.rootGroupBuilder() category.configs.forEach {
.options(buildOptions(managedConfig.sortedOptions)) categoryB.group(
OptionGroup.createBuilder()
.name(it.labelText)
.options(buildOptions(it.sortedOptions))
.build())
}
} }
.build() .build()
} }
@@ -54,7 +59,10 @@ class YaclIntegration : FirmamentConfigScreenProvider {
private fun <T : Any> buildOption(managedOption: ManagedOption<T>): Option<*> { private fun <T : Any> buildOption(managedOption: ManagedOption<T>): Option<*> {
val handler = managedOption.handler val handler = managedOption.handler
val binding = Binding.generic(managedOption.default(), managedOption::value, managedOption::value.setter) val binding = Binding.generic(managedOption.default(),
managedOption::value,
{ managedOption.value = it; managedOption.element.save() })
fun <T> createDefaultBinding(function: (Option<T>) -> ControllerBuilder<T>): Option.Builder<T> { fun <T> createDefaultBinding(function: (Option<T>) -> ControllerBuilder<T>): Option.Builder<T> {
return Option.createBuilder<T>() return Option.createBuilder<T>()
.name(managedOption.labelText) .name(managedOption.labelText)

View File

@@ -17,6 +17,7 @@ import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen
import moe.nea.firmament.features.inventory.storageoverlay.StorageOverviewScreen import moe.nea.firmament.features.inventory.storageoverlay.StorageOverviewScreen
import moe.nea.firmament.gui.config.AllConfigsGui import moe.nea.firmament.gui.config.AllConfigsGui
import moe.nea.firmament.gui.config.BooleanHandler import moe.nea.firmament.gui.config.BooleanHandler
import moe.nea.firmament.gui.config.ManagedConfig
import moe.nea.firmament.gui.config.ManagedOption import moe.nea.firmament.gui.config.ManagedOption
import moe.nea.firmament.init.MixinPlugin import moe.nea.firmament.init.MixinPlugin
import moe.nea.firmament.repo.HypixelStaticData import moe.nea.firmament.repo.HypixelStaticData
@@ -39,11 +40,11 @@ fun firmamentCommand() = literal("firmament") {
thenLiteral("toggle") { thenLiteral("toggle") {
thenArgument("config", string()) { config -> thenArgument("config", string()) { config ->
suggestsList { suggestsList {
AllConfigsGui.allConfigs.asSequence().map { it.name }.asIterable() ManagedConfig.allManagedConfigs.getAll().asSequence().map { it.name }.asIterable()
} }
thenArgument("property", string()) { property -> thenArgument("property", string()) { property ->
suggestsList { suggestsList {
(AllConfigsGui.allConfigs.find { it.name == this[config] } ?: return@suggestsList listOf()) (ManagedConfig.allManagedConfigs.getAll().find { it.name == this[config] } ?: return@suggestsList listOf())
.allOptions.entries.asSequence().filter { it.value.handler is BooleanHandler } .allOptions.entries.asSequence().filter { it.value.handler is BooleanHandler }
.map { it.key } .map { it.key }
.asIterable() .asIterable()
@@ -52,7 +53,7 @@ fun firmamentCommand() = literal("firmament") {
val config = this[config] val config = this[config]
val property = this[property] val property = this[property]
val configObj = AllConfigsGui.allConfigs.find { it.name == config } val configObj = ManagedConfig.allManagedConfigs.getAll().find { it.name == config }
if (configObj == null) { if (configObj == null) {
source.sendFeedback( source.sendFeedback(
Text.stringifiedTranslatable( Text.stringifiedTranslatable(

View File

@@ -1,5 +1,3 @@
package moe.nea.firmament.features.chat package moe.nea.firmament.features.chat
import com.mojang.brigadier.arguments.StringArgumentType.string import com.mojang.brigadier.arguments.StringArgumentType.string
@@ -17,41 +15,41 @@ import moe.nea.firmament.util.MC
object AutoCompletions : FirmamentFeature { object AutoCompletions : FirmamentFeature {
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.CHAT) {
val provideWarpTabCompletion by toggle("warp-complete") { true } val provideWarpTabCompletion by toggle("warp-complete") { true }
val replaceWarpIsByWarpIsland by toggle("warp-is") { true } val replaceWarpIsByWarpIsland by toggle("warp-is") { true }
} }
override val config: ManagedConfig? override val config: ManagedConfig?
get() = TConfig get() = TConfig
override val identifier: String override val identifier: String
get() = "auto-completions" get() = "auto-completions"
@Subscribe @Subscribe
fun onMaskCommands(event: MaskCommands) { fun onMaskCommands(event: MaskCommands) {
if (TConfig.provideWarpTabCompletion) { if (TConfig.provideWarpTabCompletion) {
event.mask("warp") event.mask("warp")
} }
} }
@Subscribe @Subscribe
fun onCommandEvent(event: CommandEvent) { fun onCommandEvent(event: CommandEvent) {
if (!TConfig.provideWarpTabCompletion) return if (!TConfig.provideWarpTabCompletion) return
event.deleteCommand("warp") event.deleteCommand("warp")
event.register("warp") { event.register("warp") {
thenArgument("to", string()) { toArg -> thenArgument("to", string()) { toArg ->
suggestsList { suggestsList {
RepoManager.neuRepo.constants?.islands?.warps?.flatMap { listOf(it.warp) + it.aliases } ?: listOf() RepoManager.neuRepo.constants?.islands?.warps?.flatMap { listOf(it.warp) + it.aliases } ?: listOf()
} }
thenExecute { thenExecute {
val warpName = get(toArg) val warpName = get(toArg)
if (warpName == "is" && TConfig.replaceWarpIsByWarpIsland) { if (warpName == "is" && TConfig.replaceWarpIsByWarpIsland) {
MC.sendServerCommand("warp island") MC.sendServerCommand("warp island")
} else { } else {
MC.sendServerCommand("warp $warpName") MC.sendServerCommand("warp $warpName")
} }
} }
} }
} }
} }
} }

View File

@@ -35,7 +35,7 @@ object ChatLinks : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "chat-links" get() = "chat-links"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.CHAT) {
val enableLinks by toggle("links-enabled") { true } val enableLinks by toggle("links-enabled") { true }
val imageEnabled by toggle("image-enabled") { true } val imageEnabled by toggle("image-enabled") { true }
val allowAllHosts by toggle("allow-all-hosts") { false } val allowAllHosts by toggle("allow-all-hosts") { false }

View File

@@ -26,7 +26,7 @@ object DeveloperFeatures : FirmamentFeature {
.iterate { it.parent } .iterate { it.parent }
.find { it.resolve("settings.gradle.kts").exists() } .find { it.resolve("settings.gradle.kts").exists() }
object TConfig : ManagedConfig("developer") { object TConfig : ManagedConfig("developer", Category.DEV) {
val autoRebuildResources by toggle("auto-rebuild") { false } val autoRebuildResources by toggle("auto-rebuild") { false }
} }

View File

@@ -37,7 +37,7 @@ object PowerUserTools : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "power-user" get() = "power-user"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.DEV) {
val showItemIds by toggle("show-item-id") { false } val showItemIds by toggle("show-item-id") { false }
val copyItemId by keyBindingWithDefaultUnbound("copy-item-id") val copyItemId by keyBindingWithDefaultUnbound("copy-item-id")
val copyTexturePackId by keyBindingWithDefaultUnbound("copy-texture-pack-id") val copyTexturePackId by keyBindingWithDefaultUnbound("copy-texture-pack-id")

View File

@@ -10,7 +10,7 @@ object DianaWaypoints : FirmamentFeature {
override val identifier get() = "diana" override val identifier get() = "diana"
override val config get() = TConfig override val config get() = TConfig
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.EVENTS) {
val ancestralSpadeSolver by toggle("ancestral-spade") { true } val ancestralSpadeSolver by toggle("ancestral-spade") { true }
val ancestralSpadeTeleport by keyBindingWithDefaultUnbound("ancestral-teleport") val ancestralSpadeTeleport by keyBindingWithDefaultUnbound("ancestral-teleport")
val nearbyWaypoints by toggle("nearby-waypoints") { true } val nearbyWaypoints by toggle("nearby-waypoints") { true }

View File

@@ -28,7 +28,7 @@ object AnniversaryFeatures : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "anniversary" get() = "anniversary"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.EVENTS) {
val enableShinyPigTracker by toggle("shiny-pigs") {true} val enableShinyPigTracker by toggle("shiny-pigs") {true}
val trackPigCooldown by position("pig-hud", 200, 300) { Point(0.1, 0.2) } val trackPigCooldown by position("pig-hud", 200, 300) { Point(0.1, 0.2) }
} }

View File

@@ -5,7 +5,7 @@ import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.gui.config.ManagedConfig
object CarnivalFeatures : FirmamentFeature { object CarnivalFeatures : FirmamentFeature {
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.EVENTS) {
val enableBombSolver by toggle("bombs-solver") { true } val enableBombSolver by toggle("bombs-solver") { true }
val displayTutorials by toggle("tutorials") { true } val displayTutorials by toggle("tutorials") { true }
} }

View File

@@ -16,7 +16,7 @@ object CompatibliltyFeatures : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "compatibility" get() = "compatibility"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.INTEGRATIONS) {
val enhancedExplosions by toggle("explosion-enabled") { false } val enhancedExplosions by toggle("explosion-enabled") { false }
val explosionSize by integer("explosion-power", 10, 50) { 1 } val explosionSize by integer("explosion-power", 10, 50) { 1 }
} }

View File

@@ -21,7 +21,7 @@ object Fixes : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "fixes" get() = "fixes"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.MISC) { // TODO: split this config
val fixUnsignedPlayerSkins by toggle("player-skins") { true } val fixUnsignedPlayerSkins by toggle("player-skins") { true }
var autoSprint by toggle("auto-sprint") { false } var autoSprint by toggle("auto-sprint") { false }
val autoSprintKeyBinding by keyBindingWithDefaultUnbound("auto-sprint-keybinding") val autoSprintKeyBinding by keyBindingWithDefaultUnbound("auto-sprint-keybinding")

View File

@@ -22,7 +22,7 @@ object ItemRarityCosmetics : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "item-rarity-cosmetics" get() = "item-rarity-cosmetics"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val showItemRarityBackground by toggle("background") { false } val showItemRarityBackground by toggle("background") { false }
val showItemRarityInHotbar by toggle("background-hotbar") { false } val showItemRarityInHotbar by toggle("background-hotbar") { false }
} }

View File

@@ -7,7 +7,6 @@ import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.gui.config.ManagedConfig
import moe.nea.firmament.util.MC import moe.nea.firmament.util.MC
import moe.nea.firmament.util.petData import moe.nea.firmament.util.petData
import moe.nea.firmament.util.unformattedString
import moe.nea.firmament.util.useMatch import moe.nea.firmament.util.useMatch
object PetFeatures : FirmamentFeature { object PetFeatures : FirmamentFeature {
@@ -17,7 +16,7 @@ object PetFeatures : FirmamentFeature {
override val config: ManagedConfig? override val config: ManagedConfig?
get() = TConfig get() = TConfig
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val highlightEquippedPet by toggle("highlight-pet") { true } val highlightEquippedPet by toggle("highlight-pet") { true }
} }

View File

@@ -15,7 +15,7 @@ object PriceData : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "price-data" get() = "price-data"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val tooltipEnabled by toggle("enable-always") { true } val tooltipEnabled by toggle("enable-always") { true }
val enableKeybinding by keyBindingWithDefaultUnbound("enable-keybind") val enableKeybinding by keyBindingWithDefaultUnbound("enable-keybind")
} }

View File

@@ -15,7 +15,7 @@ object SaveCursorPosition : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "save-cursor-position" get() = "save-cursor-position"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val enable by toggle("enable") { true } val enable by toggle("enable") { true }
val tolerance by duration("tolerance", 10.milliseconds, 5000.milliseconds) { 500.milliseconds } val tolerance by duration("tolerance", 10.milliseconds, 5000.milliseconds) { 500.milliseconds }
} }

View File

@@ -46,7 +46,7 @@ object SlotLocking : FirmamentFeature {
val lockedUUIDs: MutableSet<UUID> = mutableSetOf(), val lockedUUIDs: MutableSet<UUID> = mutableSetOf(),
) )
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val lockSlot by keyBinding("lock") { GLFW.GLFW_KEY_L } val lockSlot by keyBinding("lock") { GLFW.GLFW_KEY_L }
val lockUUID by keyBindingWithOutDefaultModifiers("lock-uuid") { val lockUUID by keyBindingWithOutDefaultModifiers("lock-uuid") {
SavedKeyBinding(GLFW.GLFW_KEY_L, shift = true) SavedKeyBinding(GLFW.GLFW_KEY_L, shift = true)

View File

@@ -20,7 +20,7 @@ object InventoryButtons : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "inventory-buttons" get() = "inventory-buttons"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val _openEditor by button("open-editor") { val _openEditor by button("open-editor") {
openEditor() openEditor()
} }

View File

@@ -27,7 +27,7 @@ object StorageOverlay : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "storage-overlay" get() = "storage-overlay"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val alwaysReplace by toggle("always-replace") { true } val alwaysReplace by toggle("always-replace") { true }
val columns by integer("rows", 1, 10) { 3 } val columns by integer("rows", 1, 10) { 3 }
val scrollSpeed by integer("scroll-speed", 1, 50) { 10 } val scrollSpeed by integer("scroll-speed", 1, 50) { 10 }

View File

@@ -39,7 +39,7 @@ object PickaxeAbility : FirmamentFeature {
get() = "pickaxe-info" get() = "pickaxe-info"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.MINING) {
val cooldownEnabled by toggle("ability-cooldown") { true } val cooldownEnabled by toggle("ability-cooldown") { true }
val cooldownScale by integer("ability-scale", 16, 64) { 16 } val cooldownScale by integer("ability-scale", 16, 64) { 16 }
val drillFuelBar by toggle("fuel-bar") { true } val drillFuelBar by toggle("fuel-bar") { true }

View File

@@ -49,7 +49,7 @@ object PristineProfitTracker : FirmamentFeature {
override val config: ManagedConfig? override val config: ManagedConfig?
get() = TConfig get() = TConfig
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.MINING) {
val timeout by duration("timeout", 0.seconds, 120.seconds) { 30.seconds } val timeout by duration("timeout", 0.seconds, 120.seconds) { 30.seconds }
val gui by position("position", 80, 30) { Point(0.05, 0.2) } val gui by position("position", 80, 30) { Point(0.05, 0.2) }
} }

View File

@@ -26,7 +26,7 @@ object CustomSkyBlockTextures : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "custom-skyblock-textures" get() = "custom-skyblock-textures"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.INTEGRATIONS) { // TODO: should this be its own thing?
val enabled by toggle("enabled") { true } val enabled by toggle("enabled") { true }
val skullsEnabled by toggle("skulls-enabled") { true } val skullsEnabled by toggle("skulls-enabled") { true }
val cacheForever by toggle("cache-forever") { true } val cacheForever by toggle("cache-forever") { true }

View File

@@ -38,7 +38,7 @@ object FairySouls : FirmamentFeature {
object DConfig : ProfileSpecificDataHolder<Data>(serializer(), "found-fairysouls", ::Data) object DConfig : ProfileSpecificDataHolder<Data>(serializer(), "found-fairysouls", ::Data)
object TConfig : ManagedConfig("fairy-souls") { object TConfig : ManagedConfig("fairy-souls", Category.MISC) {
val displaySouls by toggle("show") { false } val displaySouls by toggle("show") { false }
val resetSouls by button("reset") { val resetSouls by button("reset") {
DConfig.data?.foundSouls?.clear() != null DConfig.data?.foundSouls?.clear() != null

View File

@@ -38,7 +38,7 @@ object Waypoints : FirmamentFeature {
override val identifier: String override val identifier: String
get() = "waypoints" get() = "waypoints"
object TConfig : ManagedConfig(identifier) { object TConfig : ManagedConfig(identifier, Category.MINING) { // TODO: add to misc
val tempWaypointDuration by duration("temp-waypoint-duration", 0.seconds, 1.hours) { 30.seconds } val tempWaypointDuration by duration("temp-waypoint-duration", 0.seconds, 1.hours) { 30.seconds }
val showIndex by toggle("show-index") { true } val showIndex by toggle("show-index") { true }
val skipToNearest by toggle("skip-to-nearest") { false } val skipToNearest by toggle("skip-to-nearest") { false }

View File

@@ -4,24 +4,35 @@ import io.github.notenoughupdates.moulconfig.observer.ObservableList
import io.github.notenoughupdates.moulconfig.xml.Bind import io.github.notenoughupdates.moulconfig.xml.Bind
import net.minecraft.client.gui.screen.Screen import net.minecraft.client.gui.screen.Screen
import net.minecraft.text.Text import net.minecraft.text.Text
import moe.nea.firmament.features.FeatureManager
import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.MC import moe.nea.firmament.util.MC
import moe.nea.firmament.util.MoulConfigUtils import moe.nea.firmament.util.MoulConfigUtils
import moe.nea.firmament.util.ScreenUtil.setScreenLater import moe.nea.firmament.util.ScreenUtil.setScreenLater
object AllConfigsGui { object AllConfigsGui {
//
// val allConfigs
// get() = listOf(
// RepoManager.Config
// ) + FeatureManager.allFeatures.mapNotNull { it.config }
val allConfigs object ConfigConfig : ManagedConfig("configconfig", Category.META) {
get() = listOf( val enableYacl by toggle("enable-yacl") { false }
RepoManager.Config }
) + FeatureManager.allFeatures.mapNotNull { it.config }
fun <T> List<T>.toObservableList(): ObservableList<T> = ObservableList(this) fun <T> List<T>.toObservableList(): ObservableList<T> = ObservableList(this)
class MainMapping(val allConfigs: List<ManagedConfig>) { class CategoryMapping(val category: ManagedConfig.Category) {
@get:Bind("configs") @get:Bind("configs")
val configs = allConfigs.map { EntryMapping(it) }.toObservableList() val configs = category.configs.map { EntryMapping(it) }.toObservableList()
@Bind
fun name() = category.labelText.string
@Bind
fun close() {
MC.screen?.close()
}
class EntryMapping(val config: ManagedConfig) { class EntryMapping(val config: ManagedConfig) {
@Bind @Bind
@@ -34,12 +45,29 @@ object AllConfigsGui {
} }
} }
class CategoryView {
@get:Bind("categories")
val categories = ManagedConfig.Category.entries
.map { CategoryEntry(it) }
.toObservableList()
class CategoryEntry(val category: ManagedConfig.Category) {
@Bind
fun name() = category.labelText.string
@Bind
fun open() {
MC.screen = MoulConfigUtils.loadScreen("config/category", CategoryMapping(category), MC.screen)
}
}
}
fun makeBuiltInScreen(parent: Screen? = null): Screen { fun makeBuiltInScreen(parent: Screen? = null): Screen {
return MoulConfigUtils.loadScreen("config/main", MainMapping(allConfigs), parent) return MoulConfigUtils.loadScreen("config/main", CategoryView(), parent)
} }
fun makeScreen(parent: Screen? = null): Screen { fun makeScreen(parent: Screen? = null): Screen {
val wantedKey = if (RepoManager.Config.enableYacl) "yacl" else "builtin" val wantedKey = if (ConfigConfig.enableYacl) "yacl" else "builtin"
val provider = FirmamentConfigScreenProvider.providers.find { it.key == wantedKey } val provider = FirmamentConfigScreenProvider.providers.find { it.key == wantedKey }
?: FirmamentConfigScreenProvider.providers.first() ?: FirmamentConfigScreenProvider.providers.first()
return provider.open(parent) return provider.open(parent)

View File

@@ -1,5 +1,3 @@
package moe.nea.firmament.gui.config package moe.nea.firmament.gui.config
import io.github.notenoughupdates.moulconfig.gui.CloseEventListener import io.github.notenoughupdates.moulconfig.gui.CloseEventListener
@@ -26,157 +24,191 @@ import moe.nea.firmament.Firmament
import moe.nea.firmament.gui.FirmButtonComponent import moe.nea.firmament.gui.FirmButtonComponent
import moe.nea.firmament.keybindings.SavedKeyBinding import moe.nea.firmament.keybindings.SavedKeyBinding
import moe.nea.firmament.util.ScreenUtil.setScreenLater import moe.nea.firmament.util.ScreenUtil.setScreenLater
import moe.nea.firmament.util.collections.InstanceList
abstract class ManagedConfig(override val name: String) : ManagedConfigElement() { abstract class ManagedConfig(
override val name: String,
val category: Category,
// TODO: allow vararg secondaryCategories: Category,
) : ManagedConfigElement() {
enum class Category {
// Böse Kategorie, nicht benutzten lol
MISC,
CHAT,
INVENTORY,
MINING,
EVENTS,
INTEGRATIONS,
META,
DEV,
;
interface OptionHandler<T : Any> { val labelText: Text = Text.translatable("firmament.config.category.${name.lowercase()}")
fun initOption(opt: ManagedOption<T>) {} val configs: MutableList<ManagedConfig> = mutableListOf()
fun toJson(element: T): JsonElement? }
fun fromJson(element: JsonElement): T
fun emitGuiElements(opt: ManagedOption<T>, guiAppender: GuiAppender)
}
val file = Firmament.CONFIG_DIR.resolve("$name.json") companion object {
val data: JsonObject by lazy { val allManagedConfigs = InstanceList<ManagedConfig>("ManagedConfig")
try { }
Firmament.json.decodeFromString(
file.readText()
)
} catch (e: Exception) {
Firmament.logger.info("Could not read config $name. Loading empty config.")
JsonObject(mutableMapOf())
}
}
fun save() { interface OptionHandler<T : Any> {
val data = JsonObject(allOptions.mapNotNull { (key, value) -> fun initOption(opt: ManagedOption<T>) {}
value.toJson()?.let { fun toJson(element: T): JsonElement?
key to it fun fromJson(element: JsonElement): T
} fun emitGuiElements(opt: ManagedOption<T>, guiAppender: GuiAppender)
}.toMap()) }
file.parent.createDirectories()
file.writeText(Firmament.json.encodeToString(data)) init {
} allManagedConfigs.getAll().forEach {
require(it.name != name) { "Duplicate name '$name' used for config" }
}
allManagedConfigs.add(this)
category.configs.add(this)
}
val file = Firmament.CONFIG_DIR.resolve("$name.json")
val data: JsonObject by lazy {
try {
Firmament.json.decodeFromString(
file.readText()
)
} catch (e: Exception) {
Firmament.logger.info("Could not read config $name. Loading empty config.")
JsonObject(mutableMapOf())
}
}
fun save() {
val data = JsonObject(allOptions.mapNotNull { (key, value) ->
value.toJson()?.let {
key to it
}
}.toMap())
file.parent.createDirectories()
file.writeText(Firmament.json.encodeToString(data))
}
val allOptions = mutableMapOf<String, ManagedOption<*>>() val allOptions = mutableMapOf<String, ManagedOption<*>>()
val sortedOptions = mutableListOf<ManagedOption<*>>() val sortedOptions = mutableListOf<ManagedOption<*>>()
private var latestGuiAppender: GuiAppender? = null private var latestGuiAppender: GuiAppender? = null
protected fun <T : Any> option( protected fun <T : Any> option(
propertyName: String, propertyName: String,
default: () -> T, default: () -> T,
handler: OptionHandler<T> handler: OptionHandler<T>
): ManagedOption<T> { ): ManagedOption<T> {
if (propertyName in allOptions) error("Cannot register the same name twice") if (propertyName in allOptions) error("Cannot register the same name twice")
return ManagedOption(this, propertyName, default, handler).also { return ManagedOption(this, propertyName, default, handler).also {
it.handler.initOption(it) it.handler.initOption(it)
it.load(data) it.load(data)
allOptions[propertyName] = it allOptions[propertyName] = it
sortedOptions.add(it) sortedOptions.add(it)
} }
} }
protected fun toggle(propertyName: String, default: () -> Boolean): ManagedOption<Boolean> { protected fun toggle(propertyName: String, default: () -> Boolean): ManagedOption<Boolean> {
return option(propertyName, default, BooleanHandler(this)) return option(propertyName, default, BooleanHandler(this))
} }
protected fun duration( protected fun duration(
propertyName: String, propertyName: String,
min: Duration, min: Duration,
max: Duration, max: Duration,
default: () -> Duration, default: () -> Duration,
): ManagedOption<Duration> { ): ManagedOption<Duration> {
return option(propertyName, default, DurationHandler(this, min, max)) return option(propertyName, default, DurationHandler(this, min, max))
} }
protected fun position( protected fun position(
propertyName: String, propertyName: String,
width: Int, width: Int,
height: Int, height: Int,
default: () -> Point, default: () -> Point,
): ManagedOption<HudMeta> { ): ManagedOption<HudMeta> {
val label = Text.translatable("firmament.config.${name}.${propertyName}") val label = Text.translatable("firmament.config.${name}.${propertyName}")
return option(propertyName, { return option(propertyName, {
val p = default() val p = default()
HudMeta(HudPosition(p.x, p.y, 1F), label, width, height) HudMeta(HudPosition(p.x, p.y, 1F), label, width, height)
}, HudMetaHandler(this, label, width, height)) }, HudMetaHandler(this, label, width, height))
} }
protected fun keyBinding( protected fun keyBinding(
propertyName: String, propertyName: String,
default: () -> Int, default: () -> Int,
): ManagedOption<SavedKeyBinding> = keyBindingWithOutDefaultModifiers(propertyName) { SavedKeyBinding(default()) } ): ManagedOption<SavedKeyBinding> = keyBindingWithOutDefaultModifiers(propertyName) { SavedKeyBinding(default()) }
protected fun keyBindingWithOutDefaultModifiers( protected fun keyBindingWithOutDefaultModifiers(
propertyName: String, propertyName: String,
default: () -> SavedKeyBinding, default: () -> SavedKeyBinding,
): ManagedOption<SavedKeyBinding> { ): ManagedOption<SavedKeyBinding> {
return option(propertyName, default, KeyBindingHandler("firmament.config.${name}.${propertyName}", this)) return option(propertyName, default, KeyBindingHandler("firmament.config.${name}.${propertyName}", this))
} }
protected fun keyBindingWithDefaultUnbound( protected fun keyBindingWithDefaultUnbound(
propertyName: String, propertyName: String,
): ManagedOption<SavedKeyBinding> { ): ManagedOption<SavedKeyBinding> {
return keyBindingWithOutDefaultModifiers(propertyName) { SavedKeyBinding(GLFW.GLFW_KEY_UNKNOWN) } return keyBindingWithOutDefaultModifiers(propertyName) { SavedKeyBinding(GLFW.GLFW_KEY_UNKNOWN) }
} }
protected fun integer( protected fun integer(
propertyName: String, propertyName: String,
min: Int, min: Int,
max: Int, max: Int,
default: () -> Int, default: () -> Int,
): ManagedOption<Int> { ): ManagedOption<Int> {
return option(propertyName, default, IntegerHandler(this, min, max)) return option(propertyName, default, IntegerHandler(this, min, max))
} }
protected fun button(propertyName: String, runnable: () -> Unit): ManagedOption<Unit> { protected fun button(propertyName: String, runnable: () -> Unit): ManagedOption<Unit> {
return option(propertyName, { }, ClickHandler(this, runnable)) return option(propertyName, { }, ClickHandler(this, runnable))
} }
protected fun string(propertyName: String, default: () -> String): ManagedOption<String> { protected fun string(propertyName: String, default: () -> String): ManagedOption<String> {
return option(propertyName, default, StringHandler(this)) return option(propertyName, default, StringHandler(this))
} }
fun reloadGui() { fun reloadGui() {
latestGuiAppender?.reloadables?.forEach { it() } latestGuiAppender?.reloadables?.forEach { it() }
} }
val translationKey get() = "firmament.config.${name}" val translationKey get() = "firmament.config.${name}"
val labelText = Text.translatable(translationKey) val labelText = Text.translatable(translationKey)
fun getConfigEditor(parent: Screen? = null): Screen { fun getConfigEditor(parent: Screen? = null): Screen {
var screen: Screen? = null var screen: Screen? = null
val guiapp = GuiAppender(400) { requireNotNull(screen) { "Screen Accessor called too early" } } val guiapp = GuiAppender(400) { requireNotNull(screen) { "Screen Accessor called too early" } }
latestGuiAppender = guiapp latestGuiAppender = guiapp
guiapp.appendFullRow(RowComponent( guiapp.appendFullRow(RowComponent(
FirmButtonComponent(TextComponent("")) { FirmButtonComponent(TextComponent("")) {
if (parent != null) { if (parent != null) {
save() save()
setScreenLater(parent) setScreenLater(parent)
} else { } else {
AllConfigsGui.showAllGuis() AllConfigsGui.showAllGuis()
} }
} }
)) ))
sortedOptions.forEach { it.appendToGui(guiapp) } sortedOptions.forEach { it.appendToGui(guiapp) }
guiapp.reloadables.forEach { it() } guiapp.reloadables.forEach { it() }
val component = CenterComponent(PanelComponent(ScrollPanelComponent(400, 300, ColumnComponent(guiapp.panel)), 10, PanelComponent.DefaultBackgroundRenderer.VANILLA)) val component = CenterComponent(PanelComponent(ScrollPanelComponent(400, 300, ColumnComponent(guiapp.panel)),
screen = object : GuiComponentWrapper(GuiContext(component)) { 10,
override fun close() { PanelComponent.DefaultBackgroundRenderer.VANILLA))
if (context.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) { screen = object : GuiComponentWrapper(GuiContext(component)) {
client!!.setScreen(parent) override fun close() {
} if (context.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) {
} client!!.setScreen(parent)
} }
return screen }
} }
return screen
}
fun showConfigEditor(parent: Screen? = null) { fun showConfigEditor(parent: Screen? = null) {
setScreenLater(getConfigEditor(parent)) setScreenLater(getConfigEditor(parent))
} }
} }

View File

@@ -11,7 +11,7 @@ import net.minecraft.text.Text
import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament
class ManagedOption<T : Any>( class ManagedOption<T : Any>(
val element: ManagedConfigElement, val element: ManagedConfig,
val propertyName: String, val propertyName: String,
val default: () -> T, val default: () -> T,
val handler: ManagedConfig.OptionHandler<T> val handler: ManagedConfig.OptionHandler<T>

View File

@@ -19,7 +19,7 @@ import moe.nea.firmament.util.MinecraftDispatcher
import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.SkyblockId
object RepoManager { object RepoManager {
object Config : ManagedConfig("repo") { object Config : ManagedConfig("repo", Category.META) {
var username by string("username") { "NotEnoughUpdates" } var username by string("username") { "NotEnoughUpdates" }
var reponame by string("reponame") { "NotEnoughUpdates-REPO" } var reponame by string("reponame") { "NotEnoughUpdates-REPO" }
var branch by string("branch") { "master" } var branch by string("branch") { "master" }
@@ -31,8 +31,6 @@ object RepoManager {
save() save()
} }
val enableYacl by toggle("enable-yacl") { false }
val disableItemGroups by toggle("disable-item-groups") { true } val disableItemGroups by toggle("disable-item-groups") { true }
val reload by button("reload") { val reload by button("reload") {
save() save()

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Root xmlns="http://notenoughupdates.org/moulconfig"
xmlns:firm="http://firmament.nea.moe/moulconfig">
<Center>
<Panel background="VANILLA" insets="10">
<Column>
<Row>
<Align vertical="CENTER">
<firm:Button onClick="@close">
<Text text="Back"/>
</firm:Button>
</Align>
<Align vertical="CENTER">
<Row>
<Text text=" "/>
<Text text="@name"/>
</Row>
</Align>
</Row>
<Spacer height="5"/>
<ScrollPanel width="400" height="300">
<Array data="@configs">
<firm:Fixed width="380" height="30">
<Panel background="VANILLA">
<Center>
<Row>
<Center>
<Text text="@name"/>
</Center>
<firm:Button onClick="@openEditor">
<Text text="Edit"/>
</firm:Button>
</Row>
</Center>
</Panel>
</firm:Fixed>
</Array>
</ScrollPanel>
</Column>
</Panel>
</Center>
</Root>

View File

@@ -6,7 +6,7 @@
<Column> <Column>
<Text text="Firmament Config"/> <Text text="Firmament Config"/>
<ScrollPanel width="400" height="300"> <ScrollPanel width="400" height="300">
<Array data="@configs"> <Array data="@categories">
<firm:Fixed width="380" height="30"> <firm:Fixed width="380" height="30">
<Panel background="VANILLA"> <Panel background="VANILLA">
<Center> <Center>
@@ -14,8 +14,8 @@
<Center> <Center>
<Text text="@name"/> <Text text="@name"/>
</Center> </Center>
<firm:Button onClick="@openEditor"> <firm:Button onClick="@open">
<Text text="Edit"/> <Text text="Open"/>
</firm:Button> </firm:Button>
</Row> </Row>
</Center> </Center>

View File

@@ -73,15 +73,24 @@
"firmament.config.repo.username.hint": "NotEnoughUpdates", "firmament.config.repo.username.hint": "NotEnoughUpdates",
"firmament.config.repo.reponame": "Repo Name", "firmament.config.repo.reponame": "Repo Name",
"firmament.config.repo.reponame.hint": "NotEnoughUpdates-REPO", "firmament.config.repo.reponame.hint": "NotEnoughUpdates-REPO",
"firmament.config.repo.enable-yacl": "Use YACL Config", "firmament.config.configconfig.enable-yacl": "Use YACL Config",
"firmament.config.repo.branch": "Repo Branch", "firmament.config.repo.branch": "Repo Branch",
"firmament.config.repo.branch.hint": "dangerous", "firmament.config.configconfig": "Firmaments Config",
"firmament.config.repo.branch.hint": "dangerous",
"firmament.config.repo.reset": "Reset", "firmament.config.repo.reset": "Reset",
"firmament.config.repo.disable-item-groups": "Disable Item Groups", "firmament.config.repo.disable-item-groups": "Disable Item Groups",
"firmament.config.repo.reload": "Reload Item List", "firmament.config.repo.reload": "Reload Item List",
"firmament.config.repo.redownload": "Redownload Item List", "firmament.config.repo.redownload": "Redownload Item List",
"firmament.config.pets": "Pets", "firmament.config.pets": "Pets",
"firmament.config.pets.highlight-pet": "Highlight active pet", "firmament.config.pets.highlight-pet": "Highlight active pet",
"firmament.config.category.misc": "Miscellaneous",
"firmament.config.category.mining": "Mining",
"firmament.config.category.events": "Events",
"firmament.config.category.chat": "Chat",
"firmament.config.category.inventory": "Inventory",
"firmament.config.category.integrations": "Integrations & Textures",
"firmament.config.category.meta": "Meta & Firmament",
"firmament.config.category.dev": "Developer & Debug",
"firmament.ursa.debugrequest.start": "Ursa request launched", "firmament.ursa.debugrequest.start": "Ursa request launched",
"firmament.ursa.debugrequest.result": "Ursa request succeeded: %s", "firmament.ursa.debugrequest.result": "Ursa request succeeded: %s",
"firmament.sbinfo.nolocraw": "No locraw data available", "firmament.sbinfo.nolocraw": "No locraw data available",