aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compat/jade/java/moe/nea/firmament/compat/jade/JadeIntegration.kt4
-rw-r--r--src/compat/moulconfig/java/MCConfigEditorIntegration.kt4
-rw-r--r--src/compat/moulconfig/java/ProcessedCategoryFirm.kt2
-rw-r--r--src/compat/moulconfig/java/ProcessedEditableOptionFirm.kt4
-rw-r--r--src/compat/yacl/java/YaclIntegration.kt8
-rw-r--r--src/main/java/moe/nea/firmament/gui/config/storage/ArrayIndexedJsonPointer.kt17
-rw-r--r--src/main/java/moe/nea/firmament/gui/config/storage/ConfigEditor.kt104
-rw-r--r--src/main/java/moe/nea/firmament/gui/config/storage/ConfigFixEvent.kt38
-rw-r--r--src/main/java/moe/nea/firmament/gui/config/storage/JsonPointer.kt8
-rw-r--r--src/main/java/moe/nea/firmament/gui/config/storage/ObjectIndexedJsonPointer.kt17
-rw-r--r--src/main/java/moe/nea/firmament/mixins/FirmKeybindsInVanillaControlsPatch.java1
-rw-r--r--src/main/java/moe/nea/firmament/util/data/ManagedConfig.kt (renamed from src/main/kotlin/gui/config/ManagedConfig.kt)94
-rw-r--r--src/main/kotlin/Firmament.kt3
-rw-r--r--src/main/kotlin/commands/rome.kt4
-rw-r--r--src/main/kotlin/features/FeatureManager.kt6
-rw-r--r--src/main/kotlin/features/FirmamentFeature.kt2
-rw-r--r--src/main/kotlin/features/chat/AutoCompletions.kt4
-rw-r--r--src/main/kotlin/features/chat/ChatLinks.kt4
-rw-r--r--src/main/kotlin/features/chat/CopyChat.kt4
-rw-r--r--src/main/kotlin/features/chat/PartyCommands.kt4
-rw-r--r--src/main/kotlin/features/chat/QuickCommands.kt2
-rw-r--r--src/main/kotlin/features/debug/DeveloperFeatures.kt4
-rw-r--r--src/main/kotlin/features/debug/PowerUserTools.kt4
-rw-r--r--src/main/kotlin/features/diana/DianaWaypoints.kt4
-rw-r--r--src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt4
-rw-r--r--src/main/kotlin/features/events/anniversity/CenturyRaffleFeatures.kt4
-rw-r--r--src/main/kotlin/features/events/carnival/CarnivalFeatures.kt6
-rw-r--r--src/main/kotlin/features/fixes/CompatibliltyFeatures.kt4
-rw-r--r--src/main/kotlin/features/fixes/Fixes.kt4
-rw-r--r--src/main/kotlin/features/garden/HideComposterNoises.kt4
-rw-r--r--src/main/kotlin/features/inventory/ItemHotkeys.kt4
-rw-r--r--src/main/kotlin/features/inventory/ItemRarityCosmetics.kt4
-rw-r--r--src/main/kotlin/features/inventory/JunkHighlighter.kt4
-rw-r--r--src/main/kotlin/features/inventory/PetFeatures.kt4
-rw-r--r--src/main/kotlin/features/inventory/PriceData.kt4
-rw-r--r--src/main/kotlin/features/inventory/REIDependencyWarner.kt2
-rw-r--r--src/main/kotlin/features/inventory/SaveCursorPosition.kt4
-rw-r--r--src/main/kotlin/features/inventory/SlotLocking.kt4
-rw-r--r--src/main/kotlin/features/inventory/TimerInLore.kt4
-rw-r--r--src/main/kotlin/features/inventory/WardrobeKeybinds.kt4
-rw-r--r--src/main/kotlin/features/inventory/buttons/InventoryButtons.kt4
-rw-r--r--src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt4
-rw-r--r--src/main/kotlin/features/items/BlockZapperOverlay.kt4
-rw-r--r--src/main/kotlin/features/items/BonemerangOverlay.kt4
-rw-r--r--src/main/kotlin/features/items/EtherwarpOverlay.kt4
-rw-r--r--src/main/kotlin/features/macros/ComboProcessor.kt6
-rw-r--r--src/main/kotlin/features/macros/MacroData.kt7
-rw-r--r--src/main/kotlin/features/macros/RadialMenu.kt5
-rw-r--r--src/main/kotlin/features/mining/CommissionFeatures.kt8
-rw-r--r--src/main/kotlin/features/mining/HotmPresets.kt2
-rw-r--r--src/main/kotlin/features/mining/PickaxeAbility.kt4
-rw-r--r--src/main/kotlin/features/mining/PristineProfitTracker.kt4
-rw-r--r--src/main/kotlin/features/misc/CustomCapes.kt4
-rw-r--r--src/main/kotlin/features/misc/Hud.kt4
-rw-r--r--src/main/kotlin/features/world/FairySouls.kt6
-rw-r--r--src/main/kotlin/features/world/Waypoints.kt4
-rw-r--r--src/main/kotlin/gui/config/AllConfigsGui.kt3
-rw-r--r--src/main/kotlin/gui/config/BooleanHandler.kt3
-rw-r--r--src/main/kotlin/gui/config/ChoiceHandler.kt1
-rw-r--r--src/main/kotlin/gui/config/ClickHandler.kt1
-rw-r--r--src/main/kotlin/gui/config/ColourHandler.kt3
-rw-r--r--src/main/kotlin/gui/config/DurationHandler.kt1
-rw-r--r--src/main/kotlin/gui/config/HudMetaHandler.kt1
-rw-r--r--src/main/kotlin/gui/config/IntegerHandler.kt1
-rw-r--r--src/main/kotlin/gui/config/KeyBindingHandler.kt3
-rw-r--r--src/main/kotlin/gui/config/ManagedConfigElement.kt8
-rw-r--r--src/main/kotlin/gui/config/ManagedOption.kt7
-rw-r--r--src/main/kotlin/gui/config/StringHandler.kt3
-rw-r--r--src/main/kotlin/gui/config/storage/ConfigLoadContext.kt65
-rw-r--r--src/main/kotlin/gui/config/storage/ConfigStorageClass.kt8
-rw-r--r--src/main/kotlin/gui/config/storage/FirmamentConfigLoader.kt204
-rw-r--r--src/main/kotlin/gui/config/storage/FirstLevelSplitJsonFolder.kt83
-rw-r--r--src/main/kotlin/gui/config/storage/LegacyImporter.kt63
-rw-r--r--src/main/kotlin/jarvis/JarvisIntegration.kt2
-rw-r--r--src/main/kotlin/repo/RepoManager.kt8
-rw-r--r--src/main/kotlin/util/SBData.kt4
-rw-r--r--src/main/kotlin/util/data/Config.kt15
-rw-r--r--src/main/kotlin/util/data/DataHolder.kt58
-rw-r--r--src/main/kotlin/util/data/IDataHolder.kt136
-rw-r--r--src/main/kotlin/util/data/MultiFileDataHolder.kt1
-rw-r--r--src/main/kotlin/util/data/ProfileSpecificDataHolder.kt83
-rw-r--r--src/main/kotlin/util/json/jsonConversion.kt66
-rw-r--r--src/main/kotlin/util/skyblock/SackUtil.kt11
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt4
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentRootPredicateSerializer.kt1
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/StringMatcher.kt58
86 files changed, 1014 insertions, 375 deletions
diff --git a/src/compat/jade/java/moe/nea/firmament/compat/jade/JadeIntegration.kt b/src/compat/jade/java/moe/nea/firmament/compat/jade/JadeIntegration.kt
index d411c26..57749da 100644
--- a/src/compat/jade/java/moe/nea/firmament/compat/jade/JadeIntegration.kt
+++ b/src/compat/jade/java/moe/nea/firmament/compat/jade/JadeIntegration.kt
@@ -7,9 +7,11 @@ import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.ErrorUtil
import net.minecraft.block.Block
import moe.nea.firmament.events.ReloadRegistrationEvent
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.Config
+import moe.nea.firmament.util.data.ManagedConfig
object JadeIntegration {
+ @Config
object TConfig : ManagedConfig("jade-integration", Category.INTEGRATIONS) {
val miningProgress by toggle("progress") { true }
val blockDetection by toggle("blocks") { true }
diff --git a/src/compat/moulconfig/java/MCConfigEditorIntegration.kt b/src/compat/moulconfig/java/MCConfigEditorIntegration.kt
index a568c19..f0e7f16 100644
--- a/src/compat/moulconfig/java/MCConfigEditorIntegration.kt
+++ b/src/compat/moulconfig/java/MCConfigEditorIntegration.kt
@@ -53,7 +53,7 @@ import moe.nea.firmament.gui.config.HudMeta
import moe.nea.firmament.gui.config.HudMetaHandler
import moe.nea.firmament.gui.config.IntegerHandler
import moe.nea.firmament.gui.config.KeyBindingHandler
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.gui.config.ManagedOption
import moe.nea.firmament.gui.config.StringHandler
import moe.nea.firmament.gui.toMoulConfig
@@ -335,7 +335,7 @@ class MCConfigEditorIntegration : FirmamentConfigScreenProvider {
val configObject = object : Config() {
override fun saveNow() {
- ManagedConfig.allManagedConfigs.getAll().forEach { it.save() }
+ ManagedConfig.allManagedConfigs.getAll().forEach { it.markDirty() }
}
override fun shouldAutoFocusSearchbar(): Boolean {
diff --git a/src/compat/moulconfig/java/ProcessedCategoryFirm.kt b/src/compat/moulconfig/java/ProcessedCategoryFirm.kt
index 38a613a..7c99528 100644
--- a/src/compat/moulconfig/java/ProcessedCategoryFirm.kt
+++ b/src/compat/moulconfig/java/ProcessedCategoryFirm.kt
@@ -5,7 +5,7 @@ import io.github.notenoughupdates.moulconfig.gui.editors.GuiOptionEditorAccordio
import io.github.notenoughupdates.moulconfig.platform.MoulConfigPlatform
import io.github.notenoughupdates.moulconfig.processor.ProcessedCategory
import io.github.notenoughupdates.moulconfig.processor.ProcessedOption
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
class ProcessedCategoryFirm(
val category: ManagedConfig.Category,
diff --git a/src/compat/moulconfig/java/ProcessedEditableOptionFirm.kt b/src/compat/moulconfig/java/ProcessedEditableOptionFirm.kt
index ac23ec7..e1ad217 100644
--- a/src/compat/moulconfig/java/ProcessedEditableOptionFirm.kt
+++ b/src/compat/moulconfig/java/ProcessedEditableOptionFirm.kt
@@ -36,11 +36,11 @@ abstract class ProcessedEditableOptionFirm<T : Any>(
ErrorUtil.softError("Failed to set value p0 in $this")
return false
}
- managedConfig.save()
+ managedConfig.markDirty()
return true
}
override fun explicitNotifyChange() {
- managedConfig.save()
+ managedConfig.markDirty()
}
}
diff --git a/src/compat/yacl/java/YaclIntegration.kt b/src/compat/yacl/java/YaclIntegration.kt
index 285d60c..79ab528 100644
--- a/src/compat/yacl/java/YaclIntegration.kt
+++ b/src/compat/yacl/java/YaclIntegration.kt
@@ -38,7 +38,7 @@ import moe.nea.firmament.gui.config.HudMeta
import moe.nea.firmament.gui.config.HudMetaHandler
import moe.nea.firmament.gui.config.IntegerHandler
import moe.nea.firmament.gui.config.KeyBindingHandler
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.gui.config.ManagedOption
import moe.nea.firmament.gui.config.StringHandler
import moe.nea.firmament.keybindings.SavedKeyBinding
@@ -77,7 +77,7 @@ class YaclIntegration : FirmamentConfigScreenProvider {
val binding = Binding.generic(
managedOption.default(),
managedOption::value,
- { managedOption.value = it; managedOption.element.save() })
+ { managedOption.value = it; managedOption.element.markDirty() })
fun <T> createDefaultBinding(function: (Option<T>) -> ControllerBuilder<T>): Option.Builder<T> {
return Option.createBuilder<T>()
@@ -118,7 +118,7 @@ class YaclIntegration : FirmamentConfigScreenProvider {
{
managedOption.value =
it.toChromaWithoutAnimation(managedOption.value.timeForFullRotationInMillis)
- managedOption.element.save()
+ managedOption.element.markDirty()
})
val speedBinding =
Binding.generic(
@@ -126,7 +126,7 @@ class YaclIntegration : FirmamentConfigScreenProvider {
{ managedOption.value.timeForFullRotationInMillis },
{
managedOption.value = managedOption.value.copy(timeForFullRotationInMillis = it)
- managedOption.element.save()
+ managedOption.element.markDirty()
}
)
diff --git a/src/main/java/moe/nea/firmament/gui/config/storage/ArrayIndexedJsonPointer.kt b/src/main/java/moe/nea/firmament/gui/config/storage/ArrayIndexedJsonPointer.kt
new file mode 100644
index 0000000..1e204d6
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/gui/config/storage/ArrayIndexedJsonPointer.kt
@@ -0,0 +1,17 @@
+package moe.nea.firmament.gui.config.storage
+
+import com.google.gson.JsonArray
+import com.google.gson.JsonElement
+
+data class ArrayIndexedJsonPointer(
+ val owner: JsonArray,
+ val index: Int
+) : JsonPointer {
+ override fun get(): JsonElement {
+ return owner.get(index)
+ }
+
+ override fun set(value: JsonElement) {
+ owner.set(index, value)
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/gui/config/storage/ConfigEditor.kt b/src/main/java/moe/nea/firmament/gui/config/storage/ConfigEditor.kt
new file mode 100644
index 0000000..df1ed33
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/gui/config/storage/ConfigEditor.kt
@@ -0,0 +1,104 @@
+package moe.nea.firmament.gui.config.storage
+
+import com.google.gson.JsonArray
+import com.google.gson.JsonObject
+import kotlinx.serialization.json.JsonElement
+import moe.nea.firmament.util.json.intoGson
+import moe.nea.firmament.util.json.intoKotlinJson
+
+data class ConfigEditor(
+ val roots: List<JsonPointer>,
+) {
+ fun transform(transform: (JsonElement) -> JsonElement) {
+ roots.forEach { root ->
+ root.set(transform(root.get().intoKotlinJson()).intoGson())
+ }
+ }
+
+ fun move(fromPath: String, toPath: String) {
+ if (fromPath == toPath) return
+ val fromSegments = fromPath.split(".").filter { it.isNotEmpty() }
+ val toSegments = toPath.split(".").filter { it.isNotEmpty() }
+ roots.forEach { root ->
+ var fp = root.get()
+ if (fromSegments.isEmpty()) {
+ root.set(JsonObject())
+ } else {
+ fromSegments.dropLast(1).forEach {
+ fp = (fp as JsonObject)[it] ?: return@forEach // todo warn if we dont find the object maybe
+ }
+ fp as JsonObject
+ fp = fp.remove(fromSegments.last())?.deepCopy() ?: return@forEach // in theory i don't need to deepcopy but fuck theory
+ }
+ if (toSegments.isEmpty()) {
+ root.set(fp)
+ } else {
+ var lp = root.get()
+ toSegments.dropLast(1).forEach { name ->
+ val parent = lp as JsonObject
+ var child = parent[name]
+ if (child == null) {
+ child = JsonObject()
+ parent.add(name, child)
+ }
+ lp = child
+ }
+ lp as JsonObject
+ if (lp.has(toSegments.last())) {
+ error("Cannot overwrite $lp.${toSegments.last()} with $fp")
+ }
+ lp.add(toSegments.last(), fp)
+ }
+ }
+ }
+
+ fun at(path: String, block: ConfigEditor.() -> Unit) {
+ block(at(path))
+ }
+
+ fun at(path: String): ConfigEditor {
+ var lastRoots = roots
+ for (segment in path.split(".")) {
+ if (segment.isEmpty()) {
+ continue
+ } else if (segment == "*") {
+ lastRoots = lastRoots.flatMap { root ->
+ when (val ele = root.get()) {
+ is JsonObject -> {
+ ele.entrySet().map {
+ (ObjectIndexedJsonPointer(ele, it.key))
+ }
+ }
+
+ is JsonArray -> {
+ (0..<ele.size()).map {
+ (ArrayIndexedJsonPointer(ele, it))
+ }
+ }
+
+ else -> {
+ error("Cannot expand a json primitive $ele at $path")
+ }
+ }
+ }
+ } else {
+ lastRoots = lastRoots.map { root ->
+ when (val ele = root.get()) {
+ is JsonObject -> {
+ ObjectIndexedJsonPointer(ele, segment)
+ }
+
+ is JsonArray -> {
+ ArrayIndexedJsonPointer(ele, segment.toInt())
+ }
+
+ else -> {
+ error("Cannot expand a json primitive $ele at $path")
+ }
+ }
+ }
+ }
+ }
+ return ConfigEditor(lastRoots)
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/gui/config/storage/ConfigFixEvent.kt b/src/main/java/moe/nea/firmament/gui/config/storage/ConfigFixEvent.kt
new file mode 100644
index 0000000..07148d5
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/gui/config/storage/ConfigFixEvent.kt
@@ -0,0 +1,38 @@
+package moe.nea.firmament.gui.config.storage
+
+import com.google.gson.JsonElement
+import com.google.gson.JsonObject
+import moe.nea.firmament.events.FirmamentEvent
+import moe.nea.firmament.events.FirmamentEventBus
+
+data class ConfigFixEvent(
+ val storageClass: ConfigStorageClass,
+ val toVersion: Int,
+ var data: JsonObject,
+) : FirmamentEvent() {
+ companion object : FirmamentEventBus<ConfigFixEvent>() {
+
+ }
+ fun on(
+ toVersion: Int,
+ storageClass: ConfigStorageClass,
+ block: ConfigEditor.() -> Unit
+ ) {
+ require(toVersion <= FirmamentConfigLoader.currentConfigVersion)
+ if (this.toVersion == toVersion && this.storageClass == storageClass) {
+ block(ConfigEditor(listOf(object : JsonPointer {
+ override fun get(): JsonObject {
+ return data
+ }
+
+ override fun set(value: JsonElement) {
+ data = value as JsonObject
+ }
+
+ override fun toString(): String {
+ return "ConfigRoot($storageClass)"
+ }
+ })))
+ }
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/gui/config/storage/JsonPointer.kt b/src/main/java/moe/nea/firmament/gui/config/storage/JsonPointer.kt
new file mode 100644
index 0000000..e34c312
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/gui/config/storage/JsonPointer.kt
@@ -0,0 +1,8 @@
+package moe.nea.firmament.gui.config.storage
+
+import com.google.gson.JsonElement
+
+interface JsonPointer {
+ fun get(): JsonElement
+ fun set(value: JsonElement)
+}
diff --git a/src/main/java/moe/nea/firmament/gui/config/storage/ObjectIndexedJsonPointer.kt b/src/main/java/moe/nea/firmament/gui/config/storage/ObjectIndexedJsonPointer.kt
new file mode 100644
index 0000000..091275d
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/gui/config/storage/ObjectIndexedJsonPointer.kt
@@ -0,0 +1,17 @@
+package moe.nea.firmament.gui.config.storage
+
+import com.google.gson.JsonElement
+import com.google.gson.JsonObject
+
+data class ObjectIndexedJsonPointer(
+ val owner: JsonObject,
+ val name: String
+) : JsonPointer {
+ override fun get(): JsonElement {
+ return owner.get(name)
+ }
+
+ override fun set(value: JsonElement) {
+ owner.add(name, value)
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/FirmKeybindsInVanillaControlsPatch.java b/src/main/java/moe/nea/firmament/mixins/FirmKeybindsInVanillaControlsPatch.java
index 699d5b7..4c9f925 100644
--- a/src/main/java/moe/nea/firmament/mixins/FirmKeybindsInVanillaControlsPatch.java
+++ b/src/main/java/moe/nea/firmament/mixins/FirmKeybindsInVanillaControlsPatch.java
@@ -3,7 +3,6 @@
package moe.nea.firmament.mixins;
import moe.nea.firmament.gui.config.KeyBindingHandler;
-import moe.nea.firmament.gui.config.ManagedConfig;
import moe.nea.firmament.keybindings.FirmamentKeyBindings;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.option.ControlsListWidget;
diff --git a/src/main/kotlin/gui/config/ManagedConfig.kt b/src/main/java/moe/nea/firmament/util/data/ManagedConfig.kt
index 90e58d0..169dad1 100644
--- a/src/main/kotlin/gui/config/ManagedConfig.kt
+++ b/src/main/java/moe/nea/firmament/util/data/ManagedConfig.kt
@@ -1,4 +1,4 @@
-package moe.nea.firmament.gui.config
+package moe.nea.firmament.util.data
import com.mojang.serialization.Codec
import io.github.notenoughupdates.moulconfig.ChromaColour
@@ -11,32 +11,42 @@ import io.github.notenoughupdates.moulconfig.gui.component.RowComponent
import io.github.notenoughupdates.moulconfig.gui.component.ScrollPanelComponent
import io.github.notenoughupdates.moulconfig.gui.component.TextComponent
import io.github.notenoughupdates.moulconfig.platform.MoulConfigScreenComponent
-import moe.nea.jarvis.api.Point
-import org.joml.Vector2i
-import org.lwjgl.glfw.GLFW
-import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
-import kotlin.io.path.createDirectories
-import kotlin.io.path.readText
-import kotlin.io.path.writeText
-import kotlin.time.Duration
-import net.minecraft.client.gui.screen.Screen
-import net.minecraft.text.Text
-import net.minecraft.util.StringIdentifiable
import moe.nea.firmament.Firmament
import moe.nea.firmament.gui.FirmButtonComponent
-import moe.nea.firmament.keybindings.GenericInputButton
-import moe.nea.firmament.keybindings.InputModifiers
+import moe.nea.firmament.gui.config.AllConfigsGui
+import moe.nea.firmament.gui.config.BooleanHandler
+import moe.nea.firmament.gui.config.ChoiceHandler
+import moe.nea.firmament.gui.config.ClickHandler
+import moe.nea.firmament.gui.config.ColourHandler
+import moe.nea.firmament.gui.config.DurationHandler
+import moe.nea.firmament.gui.config.GuiAppender
+import moe.nea.firmament.gui.config.HudMeta
+import moe.nea.firmament.gui.config.HudMetaHandler
+import moe.nea.firmament.gui.config.HudPosition
+import moe.nea.firmament.gui.config.IntegerHandler
+import moe.nea.firmament.gui.config.KeyBindingHandler
+import moe.nea.firmament.gui.config.ManagedOption
+import moe.nea.firmament.gui.config.StringHandler
import moe.nea.firmament.keybindings.SavedKeyBinding
-import moe.nea.firmament.util.ScreenUtil.setScreenLater
+import moe.nea.firmament.util.ScreenUtil
import moe.nea.firmament.util.collections.InstanceList
+import net.minecraft.client.gui.screen.Screen
+import net.minecraft.text.Text
+import net.minecraft.util.StringIdentifiable
+import org.joml.Vector2i
+import kotlinx.serialization.json.buildJsonObject
+import kotlin.io.path.createDirectories
+import kotlin.io.path.readText
+import kotlin.io.path.writeText
+import kotlin.time.Duration
+import moe.nea.firmament.gui.config.storage.ConfigStorageClass
abstract class ManagedConfig(
- override val name: String,
+ val name: String,
val category: Category,
- // TODO: allow vararg secondaryCategories: Category,
-) : ManagedConfigElement() {
+) : IDataHolder<Unit> {
enum class Category {
// Böse Kategorie, nicht benutzten lol
MISC,
@@ -75,29 +85,32 @@ abstract class ManagedConfig(
category.configs.add(this)
}
- // TODO: warn if two files use the same config file name :(
- 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())
+ override fun keys(): Collection<Unit> {
+ return listOf(Unit)
+ }
+
+ override fun clear() {
+ sortedOptions.forEach {
+ it._actualValue = null
}
}
- fun save() {
- val data = JsonObject(allOptions.mapNotNull { (key, value) ->
- value.toJson()?.let {
- key to it
+ override val storageClass: ConfigStorageClass
+ get() = ConfigStorageClass.CONFIG
+
+ override fun saveTo(key: Unit): JsonObject {
+ return buildJsonObject {
+ sortedOptions.forEach {
+ put(it.propertyName, it.toJson() ?: return@forEach)
}
- }.toMap())
- file.parent.createDirectories()
- file.writeText(Firmament.json.encodeToString(data))
+ }
}
+ override fun loadFrom(key: Unit, jsonObject: JsonObject) {
+ sortedOptions.forEach {
+ it.load(jsonObject)
+ }
+ }
val allOptions = mutableMapOf<String, ManagedOption<*>>()
val sortedOptions = mutableListOf<ManagedOption<*>>()
@@ -112,7 +125,6 @@ abstract class ManagedConfig(
if (propertyName in allOptions) error("Cannot register the same name twice")
return ManagedOption(this, propertyName, default, handler).also {
it.handler.initOption(it)
- it.load(data)
allOptions[propertyName] = it
sortedOptions.add(it)
}
@@ -188,7 +200,7 @@ abstract class ManagedConfig(
propertyName: String,
default: () -> Int,
): ManagedOption<SavedKeyBinding> = keyBindingWithOutDefaultModifiers(propertyName) {
- SavedKeyBinding.keyWithoutMods(default())
+ SavedKeyBinding.Companion.keyWithoutMods(default())
}
protected fun keyBindingWithOutDefaultModifiers(
@@ -201,7 +213,7 @@ abstract class ManagedConfig(
protected fun keyBindingWithDefaultUnbound(
propertyName: String,
): ManagedOption<SavedKeyBinding> {
- return keyBindingWithOutDefaultModifiers(propertyName) { SavedKeyBinding.unbound() }
+ return keyBindingWithOutDefaultModifiers(propertyName) { SavedKeyBinding.Companion.unbound() }
}
protected fun integer(
@@ -237,8 +249,8 @@ abstract class ManagedConfig(
RowComponent(
FirmButtonComponent(TextComponent("←")) {
if (parent != null) {
- save()
- setScreenLater(parent)
+ markDirty()
+ ScreenUtil.setScreenLater(parent)
} else {
AllConfigsGui.showAllGuis()
}
@@ -264,7 +276,7 @@ abstract class ManagedConfig(
}
fun showConfigEditor(parent: Screen? = null) {
- setScreenLater(getConfigEditor(parent))
+ ScreenUtil.setScreenLater(getConfigEditor(parent))
}
}
diff --git a/src/main/kotlin/Firmament.kt b/src/main/kotlin/Firmament.kt
index 83cc259..198defa 100644
--- a/src/main/kotlin/Firmament.kt
+++ b/src/main/kotlin/Firmament.kt
@@ -46,6 +46,7 @@ import moe.nea.firmament.events.ScreenRenderPostEvent
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.events.registration.registerFirmamentEvents
import moe.nea.firmament.features.FeatureManager
+import moe.nea.firmament.gui.config.storage.FirmamentConfigLoader
import moe.nea.firmament.repo.HypixelStaticData
import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.MC
@@ -137,10 +138,10 @@ object Firmament {
fun onClientInitialize() {
InitLevel.bump(InitLevel.MC_INIT)
FeatureManager.subscribeEvents()
+ FirmamentConfigLoader.loadConfig()
ClientTickEvents.END_CLIENT_TICK.register(ClientTickEvents.EndTick { instance ->
TickEvent.publish(TickEvent(MC.currentTick++))
})
- IDataHolder.registerEvents()
RepoManager.initialize()
SBData.init()
FeatureManager.autoload()
diff --git a/src/main/kotlin/commands/rome.kt b/src/main/kotlin/commands/rome.kt
index f808231..d12da44 100644
--- a/src/main/kotlin/commands/rome.kt
+++ b/src/main/kotlin/commands/rome.kt
@@ -20,7 +20,7 @@ import moe.nea.firmament.features.inventory.storageoverlay.StorageOverviewScreen
import moe.nea.firmament.features.mining.MiningBlockInfoUi
import moe.nea.firmament.gui.config.AllConfigsGui
import moe.nea.firmament.gui.config.BooleanHandler
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.gui.config.ManagedOption
import moe.nea.firmament.init.MixinPlugin
import moe.nea.firmament.repo.HypixelStaticData
@@ -90,7 +90,7 @@ fun firmamentCommand() = literal("firmament") {
}
propertyObj as ManagedOption<Boolean>
propertyObj.value = !propertyObj.value
- configObj.save()
+ configObj.markDirty()
source.sendFeedback(
Text.stringifiedTranslatable(
"firmament.command.toggle.toggled", configObj.labelText,
diff --git a/src/main/kotlin/features/FeatureManager.kt b/src/main/kotlin/features/FeatureManager.kt
index 183365b..3e235f5 100644
--- a/src/main/kotlin/features/FeatureManager.kt
+++ b/src/main/kotlin/features/FeatureManager.kt
@@ -35,6 +35,7 @@ import moe.nea.firmament.features.misc.CustomCapes
import moe.nea.firmament.features.misc.Hud
import moe.nea.firmament.features.world.FairySouls
import moe.nea.firmament.features.world.Waypoints
+import moe.nea.firmament.util.ErrorUtil
import moe.nea.firmament.util.compatloader.ICompatMeta
import moe.nea.firmament.util.data.DataHolder
@@ -91,16 +92,13 @@ object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "feature
fun subscribeEvents() {
SubscriptionList.allLists.forEach { list ->
if (ICompatMeta.shouldLoad(list.javaClass.name))
- runCatching {
+ ErrorUtil.catch("Error while loading events from $list") {
list.provideSubscriptions {
it.owner.javaClass.classes.forEach {
runCatching { it.getDeclaredField("INSTANCE").get(null) }
}
subscribeSingleEvent(it)
}
- }.getOrElse {
- // TODO: allow annotating source sets to specifically opt out of loading for mods, maybe automatically
- Firmament.logger.info("Ignoring events from $list, likely due to a missing compat mod.", it)
}
}
}
diff --git a/src/main/kotlin/features/FirmamentFeature.kt b/src/main/kotlin/features/FirmamentFeature.kt
index 2cfc4fd..08e7019 100644
--- a/src/main/kotlin/features/FirmamentFeature.kt
+++ b/src/main/kotlin/features/FirmamentFeature.kt
@@ -3,7 +3,7 @@
package moe.nea.firmament.features
import moe.nea.firmament.events.subscription.SubscriptionOwner
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
// TODO: remove this entire feature system and revamp config
interface FirmamentFeature : SubscriptionOwner {
diff --git a/src/main/kotlin/features/chat/AutoCompletions.kt b/src/main/kotlin/features/chat/AutoCompletions.kt
index 9e0de40..dac1daa 100644
--- a/src/main/kotlin/features/chat/AutoCompletions.kt
+++ b/src/main/kotlin/features/chat/AutoCompletions.kt
@@ -9,12 +9,14 @@ import moe.nea.firmament.commands.thenExecute
import moe.nea.firmament.events.CommandEvent
import moe.nea.firmament.events.MaskCommands
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.data.Config
object AutoCompletions : FirmamentFeature {
+ @Config
object TConfig : ManagedConfig(identifier, Category.CHAT) {
val provideWarpTabCompletion by toggle("warp-complete") { true }
val replaceWarpIsByWarpIsland by toggle("warp-is") { true }
diff --git a/src/main/kotlin/features/chat/ChatLinks.kt b/src/main/kotlin/features/chat/ChatLinks.kt
index 28c526f..6ea07d6 100644
--- a/src/main/kotlin/features/chat/ChatLinks.kt
+++ b/src/main/kotlin/features/chat/ChatLinks.kt
@@ -27,9 +27,10 @@ import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.ModifyChatEvent
import moe.nea.firmament.events.ScreenRenderPostEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.jarvis.JarvisIntegration
import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.render.drawTexture
import moe.nea.firmament.util.transformEachRecursively
import moe.nea.firmament.util.unformattedString
@@ -38,6 +39,7 @@ object ChatLinks : FirmamentFeature {
override val identifier: String
get() = "chat-links"
+ @Config
object TConfig : ManagedConfig(identifier, Category.CHAT) {
val enableLinks by toggle("links-enabled") { true }
val imageEnabled by toggle("image-enabled") { true }
diff --git a/src/main/kotlin/features/chat/CopyChat.kt b/src/main/kotlin/features/chat/CopyChat.kt
index 64f8734..5cd847a 100644
--- a/src/main/kotlin/features/chat/CopyChat.kt
+++ b/src/main/kotlin/features/chat/CopyChat.kt
@@ -4,7 +4,8 @@ import net.minecraft.text.OrderedText
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.ClientStartedEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.Config
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.reconstitute
@@ -12,6 +13,7 @@ object CopyChat : FirmamentFeature {
override val identifier: String
get() = "copy-chat"
+ @Config
object TConfig : ManagedConfig(identifier, Category.CHAT) {
val copyChat by toggle("copy-chat") { false }
}
diff --git a/src/main/kotlin/features/chat/PartyCommands.kt b/src/main/kotlin/features/chat/PartyCommands.kt
index de3a0d9..5a80013 100644
--- a/src/main/kotlin/features/chat/PartyCommands.kt
+++ b/src/main/kotlin/features/chat/PartyCommands.kt
@@ -12,10 +12,11 @@ import moe.nea.firmament.commands.thenExecute
import moe.nea.firmament.events.CommandEvent
import moe.nea.firmament.events.PartyMessageReceivedEvent
import moe.nea.firmament.events.ProcessChatEvent
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.ErrorUtil
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.TimeMark
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.tr
import moe.nea.firmament.util.useMatch
@@ -89,6 +90,7 @@ object PartyCommands {
// TODO: at TPS command
}
+ @Config
object TConfig : ManagedConfig("party-commands", Category.CHAT) {
val enable by toggle("enable") { false }
val cooldown by duration("cooldown", 0.seconds, 20.seconds) { 2.seconds }
diff --git a/src/main/kotlin/features/chat/QuickCommands.kt b/src/main/kotlin/features/chat/QuickCommands.kt
index 7963171..88218b4 100644
--- a/src/main/kotlin/features/chat/QuickCommands.kt
+++ b/src/main/kotlin/features/chat/QuickCommands.kt
@@ -16,7 +16,7 @@ import moe.nea.firmament.commands.thenArgument
import moe.nea.firmament.commands.thenExecute
import moe.nea.firmament.events.CommandEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.gui.config.ManagedOption
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SBData
diff --git a/src/main/kotlin/features/debug/DeveloperFeatures.kt b/src/main/kotlin/features/debug/DeveloperFeatures.kt
index fd236f9..cb9cf00 100644
--- a/src/main/kotlin/features/debug/DeveloperFeatures.kt
+++ b/src/main/kotlin/features/debug/DeveloperFeatures.kt
@@ -17,11 +17,12 @@ import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.DebugInstantiateEvent
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.init.MixinPlugin
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.TimeMark
import moe.nea.firmament.util.asm.AsmAnnotationUtil
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.iterate
object DeveloperFeatures : FirmamentFeature {
@@ -38,6 +39,7 @@ object DeveloperFeatures : FirmamentFeature {
.iterate { it.parent }
.find { it.resolve("settings.gradle.kts").exists() }
+ @Config
object TConfig : ManagedConfig("developer", Category.DEV) {
val autoRebuildResources by toggle("auto-rebuild") { false }
}
diff --git a/src/main/kotlin/features/debug/PowerUserTools.kt b/src/main/kotlin/features/debug/PowerUserTools.kt
index 0800a4f..90b73bb 100644
--- a/src/main/kotlin/features/debug/PowerUserTools.kt
+++ b/src/main/kotlin/features/debug/PowerUserTools.kt
@@ -28,10 +28,11 @@ import moe.nea.firmament.events.ScreenChangeEvent
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.events.WorldKeyboardEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.mixins.accessor.AccessorHandledScreen
import moe.nea.firmament.util.ClipboardUtils
import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.focusedItemStack
import moe.nea.firmament.util.mc.IntrospectableItemModelManager
import moe.nea.firmament.util.mc.SNbtFormatter
@@ -47,6 +48,7 @@ object PowerUserTools : FirmamentFeature {
override val identifier: String
get() = "power-user"
+ @Config
object TConfig : ManagedConfig(identifier, Category.DEV) {
val showItemIds by toggle("show-item-id") { false }
val copyItemId by keyBindingWithDefaultUnbound("copy-item-id")
diff --git a/src/main/kotlin/features/diana/DianaWaypoints.kt b/src/main/kotlin/features/diana/DianaWaypoints.kt
index 6d87262..68ee1ea 100644
--- a/src/main/kotlin/features/diana/DianaWaypoints.kt
+++ b/src/main/kotlin/features/diana/DianaWaypoints.kt
@@ -4,12 +4,14 @@ import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.AttackBlockEvent
import moe.nea.firmament.events.UseBlockEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.Config
+import moe.nea.firmament.util.data.ManagedConfig
object DianaWaypoints : FirmamentFeature {
override val identifier get() = "diana"
override val config get() = TConfig
+ @Config
object TConfig : ManagedConfig(identifier, Category.EVENTS) {
val ancestralSpadeSolver by toggle("ancestral-spade") { true }
val ancestralSpadeTeleport by keyBindingWithDefaultUnbound("ancestral-teleport")
diff --git a/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt b/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt
index c1900e9..e26b4c9 100644
--- a/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt
+++ b/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt
@@ -14,7 +14,7 @@ import moe.nea.firmament.events.ProcessChatEvent
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.events.WorldReadyEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.gui.hud.MoulConfigHud
import moe.nea.firmament.repo.ExpensiveItemCacheApi
import moe.nea.firmament.repo.ItemNameLookup
@@ -23,6 +23,7 @@ import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SHORT_NUMBER_FORMAT
import moe.nea.firmament.util.SkyblockId
import moe.nea.firmament.util.TimeMark
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.parseShortNumber
import moe.nea.firmament.util.useMatch
@@ -30,6 +31,7 @@ object AnniversaryFeatures : FirmamentFeature {
override val identifier: String
get() = "anniversary"
+ @Config
object TConfig : ManagedConfig(identifier, Category.EVENTS) {
val enableShinyPigTracker by toggle("shiny-pigs") {true}
val trackPigCooldown by position("pig-hud", 200, 300) { Vector2i(100, 200) }
diff --git a/src/main/kotlin/features/events/anniversity/CenturyRaffleFeatures.kt b/src/main/kotlin/features/events/anniversity/CenturyRaffleFeatures.kt
index 9935051..9eb098a 100644
--- a/src/main/kotlin/features/events/anniversity/CenturyRaffleFeatures.kt
+++ b/src/main/kotlin/features/events/anniversity/CenturyRaffleFeatures.kt
@@ -8,14 +8,16 @@ import net.minecraft.text.Style
import net.minecraft.util.Formatting
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.EntityRenderTintEvent
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SkyblockId
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.render.TintedOverlayTexture
import moe.nea.firmament.util.skyBlockId
import moe.nea.firmament.util.skyblock.SkyBlockItems
object CenturyRaffleFeatures {
+ @Config
object TConfig : ManagedConfig("centuryraffle", Category.EVENTS) {
val highlightPlayersForSlice by toggle("highlight-cake-players") { true }
// val highlightAllPlayers by toggle("highlight-all-cake-players") { true }
diff --git a/src/main/kotlin/features/events/carnival/CarnivalFeatures.kt b/src/main/kotlin/features/events/carnival/CarnivalFeatures.kt
index 840fb8c..877b54b 100644
--- a/src/main/kotlin/features/events/carnival/CarnivalFeatures.kt
+++ b/src/main/kotlin/features/events/carnival/CarnivalFeatures.kt
@@ -2,10 +2,12 @@
package moe.nea.firmament.features.events.carnival
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.Config
+import moe.nea.firmament.util.data.ManagedConfig
object CarnivalFeatures : FirmamentFeature {
- object TConfig : ManagedConfig(identifier, Category.EVENTS) {
+ @Config
+ object TConfig : ManagedConfig(identifier, Category.EVENTS) {
val enableBombSolver by toggle("bombs-solver") { true }
val displayTutorials by toggle("tutorials") { true }
}
diff --git a/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt b/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt
index 76f6ed4..1858e87 100644
--- a/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt
+++ b/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt
@@ -5,13 +5,15 @@ import net.minecraft.util.math.Vec3d
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.ParticleSpawnEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.compatloader.CompatLoader
+import moe.nea.firmament.util.data.Config
object CompatibliltyFeatures : FirmamentFeature {
override val identifier: String
get() = "compatibility"
+ @Config
object TConfig : ManagedConfig(identifier, Category.INTEGRATIONS) {
val enhancedExplosions by toggle("explosion-enabled") { false }
val explosionSize by integer("explosion-power", 10, 50) { 1 }
diff --git a/src/main/kotlin/features/fixes/Fixes.kt b/src/main/kotlin/features/fixes/Fixes.kt
index 0cb5a32..d3876a7 100644
--- a/src/main/kotlin/features/fixes/Fixes.kt
+++ b/src/main/kotlin/features/fixes/Fixes.kt
@@ -9,14 +9,16 @@ import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.HudRenderEvent
import moe.nea.firmament.events.WorldKeyboardEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.tr
object Fixes : FirmamentFeature {
override val identifier: String
get() = "fixes"
+ @Config
object TConfig : ManagedConfig(identifier, Category.MISC) { // TODO: split this config
val fixUnsignedPlayerSkins by toggle("player-skins") { true }
var autoSprint by toggle("auto-sprint") { false }
diff --git a/src/main/kotlin/features/garden/HideComposterNoises.kt b/src/main/kotlin/features/garden/HideComposterNoises.kt
index 69207a9..2e8eb76 100644
--- a/src/main/kotlin/features/garden/HideComposterNoises.kt
+++ b/src/main/kotlin/features/garden/HideComposterNoises.kt
@@ -5,11 +5,13 @@ import net.minecraft.sound.SoundEvent
import net.minecraft.sound.SoundEvents
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.SoundReceiveEvent
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.SBData
import moe.nea.firmament.util.SkyBlockIsland
+import moe.nea.firmament.util.data.Config
object HideComposterNoises {
+ @Config
object TConfig : ManagedConfig("composter", Category.GARDEN) {
val hideComposterNoises by toggle("no-more-noises") { false }
}
diff --git a/src/main/kotlin/features/inventory/ItemHotkeys.kt b/src/main/kotlin/features/inventory/ItemHotkeys.kt
index e826b31..c6b5ca6 100644
--- a/src/main/kotlin/features/inventory/ItemHotkeys.kt
+++ b/src/main/kotlin/features/inventory/ItemHotkeys.kt
@@ -2,7 +2,7 @@ package moe.nea.firmament.features.inventory
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.HandledScreenKeyPressedEvent
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.repo.ExpensiveItemCacheApi
import moe.nea.firmament.repo.HypixelStaticData
import moe.nea.firmament.repo.ItemCache
@@ -11,11 +11,13 @@ import moe.nea.firmament.repo.ItemCache.isBroken
import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.asBazaarStock
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.focusedItemStack
import moe.nea.firmament.util.skyBlockId
import moe.nea.firmament.util.skyblock.SBItemUtil.getSearchName
object ItemHotkeys {
+ @Config
object TConfig : ManagedConfig("item-hotkeys", Category.INVENTORY) {
val openGlobalTradeInterface by keyBindingWithDefaultUnbound("global-trade-interface")
}
diff --git a/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt b/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt
index 9dae118..196f948 100644
--- a/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt
+++ b/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt
@@ -11,9 +11,10 @@ import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.HotbarItemRenderEvent
import moe.nea.firmament.events.SlotRenderEvents
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.collections.lastNotNullOfOrNull
import moe.nea.firmament.util.collections.memoizeIdentity
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.mc.loreAccordingToNbt
import moe.nea.firmament.util.skyblock.Rarity
import moe.nea.firmament.util.unformattedString
@@ -22,6 +23,7 @@ object ItemRarityCosmetics : FirmamentFeature {
override val identifier: String
get() = "item-rarity-cosmetics"
+ @Config
object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val showItemRarityBackground by toggle("background") { false }
val showItemRarityInHotbar by toggle("background-hotbar") { false }
diff --git a/src/main/kotlin/features/inventory/JunkHighlighter.kt b/src/main/kotlin/features/inventory/JunkHighlighter.kt
index 80fd99d..e5ab036 100644
--- a/src/main/kotlin/features/inventory/JunkHighlighter.kt
+++ b/src/main/kotlin/features/inventory/JunkHighlighter.kt
@@ -4,7 +4,8 @@ import org.lwjgl.glfw.GLFW
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.SlotRenderEvents
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.Config
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.skyblock.SBItemUtil.getSearchName
import moe.nea.firmament.util.useMatch
@@ -12,6 +13,7 @@ object JunkHighlighter : FirmamentFeature {
override val identifier: String
get() = "junk-highlighter"
+ @Config
object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val junkRegex by string("regex") { "" }
val highlightBind by keyBinding("highlight") { GLFW.GLFW_KEY_LEFT_CONTROL }
diff --git a/src/main/kotlin/features/inventory/PetFeatures.kt b/src/main/kotlin/features/inventory/PetFeatures.kt
index 701d30c..5df4bc4 100644
--- a/src/main/kotlin/features/inventory/PetFeatures.kt
+++ b/src/main/kotlin/features/inventory/PetFeatures.kt
@@ -9,12 +9,13 @@ import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.HudRenderEvent
import moe.nea.firmament.events.SlotRenderEvents
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.jarvis.JarvisIntegration
import moe.nea.firmament.util.FirmFormatters.formatPercent
import moe.nea.firmament.util.FirmFormatters.shortFormat
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SBData
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.petData
import moe.nea.firmament.util.render.drawGuiTexture
import moe.nea.firmament.util.skyblock.Rarity
@@ -29,6 +30,7 @@ object PetFeatures : FirmamentFeature {
override val config: ManagedConfig?
get() = TConfig
+ @Config
object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val highlightEquippedPet by toggle("highlight-pet") { true }
var petOverlay by toggle("pet-overlay") { false }
diff --git a/src/main/kotlin/features/inventory/PriceData.kt b/src/main/kotlin/features/inventory/PriceData.kt
index 32e8a1f..ce5c7ea 100644
--- a/src/main/kotlin/features/inventory/PriceData.kt
+++ b/src/main/kotlin/features/inventory/PriceData.kt
@@ -6,12 +6,13 @@ import net.minecraft.util.StringIdentifiable
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.ItemTooltipEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.repo.HypixelStaticData
import moe.nea.firmament.util.FirmFormatters.formatCommas
import moe.nea.firmament.util.asBazaarStock
import moe.nea.firmament.util.bold
import moe.nea.firmament.util.darkGrey
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.getLogicalStackSize
import moe.nea.firmament.util.gold
import moe.nea.firmament.util.skyBlockId
@@ -22,6 +23,7 @@ object PriceData : FirmamentFeature {
override val identifier: String
get() = "price-data"
+ @Config
object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val tooltipEnabled by toggle("enable-always") { true }
val enableKeybinding by keyBindingWithDefaultUnbound("enable-keybind")
diff --git a/src/main/kotlin/features/inventory/REIDependencyWarner.kt b/src/main/kotlin/features/inventory/REIDependencyWarner.kt
index 6bf2928..4bb93ee 100644
--- a/src/main/kotlin/features/inventory/REIDependencyWarner.kt
+++ b/src/main/kotlin/features/inventory/REIDependencyWarner.kt
@@ -77,7 +77,7 @@ object REIDependencyWarner {
event.subcommand("disablereiwarning") {
thenExecute {
RepoManager.Config.warnForMissingItemListMod = false
- RepoManager.Config.save()
+ RepoManager.Config.markDirty()
MC.sendChat(Text.translatable("firmament.reiwarning.disabled").yellow())
}
}
diff --git a/src/main/kotlin/features/inventory/SaveCursorPosition.kt b/src/main/kotlin/features/inventory/SaveCursorPosition.kt
index bbd216c..2a08730 100644
--- a/src/main/kotlin/features/inventory/SaveCursorPosition.kt
+++ b/src/main/kotlin/features/inventory/SaveCursorPosition.kt
@@ -7,15 +7,17 @@ import kotlin.math.absoluteValue
import kotlin.time.Duration.Companion.milliseconds
import net.minecraft.client.util.InputUtil
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.TimeMark
import moe.nea.firmament.util.assertNotNullOr
+import moe.nea.firmament.util.data.Config
object SaveCursorPosition : FirmamentFeature {
override val identifier: String
get() = "save-cursor-position"
+ @Config
object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val enable by toggle("enable") { true }
val tolerance by duration("tolerance", 10.milliseconds, 5000.milliseconds) { 500.milliseconds }
diff --git a/src/main/kotlin/features/inventory/SlotLocking.kt b/src/main/kotlin/features/inventory/SlotLocking.kt
index b4cd535..8be7bdb 100644
--- a/src/main/kotlin/features/inventory/SlotLocking.kt
+++ b/src/main/kotlin/features/inventory/SlotLocking.kt
@@ -34,7 +34,7 @@ import moe.nea.firmament.events.IsSlotProtectedEvent
import moe.nea.firmament.events.ScreenChangeEvent
import moe.nea.firmament.events.SlotRenderEvents
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.keybindings.InputModifiers
import moe.nea.firmament.keybindings.SavedKeyBinding
import moe.nea.firmament.mixins.accessor.AccessorHandledScreen
@@ -42,6 +42,7 @@ import moe.nea.firmament.util.CommonSoundEffects
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SBData
import moe.nea.firmament.util.SkyBlockIsland
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.data.ProfileSpecificDataHolder
import moe.nea.firmament.util.extraAttributes
import moe.nea.firmament.util.json.DashlessUUIDSerializer
@@ -140,6 +141,7 @@ object SlotLocking : FirmamentFeature {
}
+ @Config
object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val lockSlot by keyBinding("lock") { GLFW.GLFW_KEY_L }
val lockUUID by keyBindingWithOutDefaultModifiers("lock-uuid") {
diff --git a/src/main/kotlin/features/inventory/TimerInLore.kt b/src/main/kotlin/features/inventory/TimerInLore.kt
index e939404..eb1463b 100644
--- a/src/main/kotlin/features/inventory/TimerInLore.kt
+++ b/src/main/kotlin/features/inventory/TimerInLore.kt
@@ -11,9 +11,10 @@ import net.minecraft.text.Text
import net.minecraft.util.StringIdentifiable
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.ItemTooltipEvent
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.SBData
import moe.nea.firmament.util.aqua
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.grey
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
import moe.nea.firmament.util.timestamp
@@ -21,6 +22,7 @@ import moe.nea.firmament.util.tr
import moe.nea.firmament.util.unformattedString
object TimerInLore {
+ @Config
object TConfig : ManagedConfig("lore-timers", Category.INVENTORY) {
val showTimers by toggle("show") { true }
val showCreationTimestamp by toggle("show-creation") { true }
diff --git a/src/main/kotlin/features/inventory/WardrobeKeybinds.kt b/src/main/kotlin/features/inventory/WardrobeKeybinds.kt
index 377afd3..ca5ff3a 100644
--- a/src/main/kotlin/features/inventory/WardrobeKeybinds.kt
+++ b/src/main/kotlin/features/inventory/WardrobeKeybinds.kt
@@ -5,11 +5,13 @@ import net.minecraft.item.Items
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.HandledScreenKeyPressedEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.mc.SlotUtils.clickLeftMouseButton
object WardrobeKeybinds {
+ @Config
object TConfig : ManagedConfig("wardrobe-keybinds", Category.INVENTORY) {
val wardrobeKeybinds by toggle("wardrobe-keybinds") { false }
val changePageKeybind by keyBinding("change-page") { GLFW.GLFW_KEY_ENTER }
diff --git a/src/main/kotlin/features/inventory/buttons/InventoryButtons.kt b/src/main/kotlin/features/inventory/buttons/InventoryButtons.kt
index 46e91b2..f49e6ab 100644
--- a/src/main/kotlin/features/inventory/buttons/InventoryButtons.kt
+++ b/src/main/kotlin/features/inventory/buttons/InventoryButtons.kt
@@ -13,16 +13,18 @@ import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.HandledScreenClickEvent
import moe.nea.firmament.events.HandledScreenForegroundEvent
import moe.nea.firmament.events.HandledScreenPushREIEvent
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.ScreenUtil
import moe.nea.firmament.util.TimeMark
import moe.nea.firmament.util.data.DataHolder
import moe.nea.firmament.util.accessors.getRectangle
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.gold
object InventoryButtons {
+ @Config
object TConfig : ManagedConfig("inventory-buttons-config", Category.INVENTORY) {
val _openEditor by button("open-editor") {
openEditor()
diff --git a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt
index f59b293..3734024 100644
--- a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt
+++ b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt
@@ -14,9 +14,10 @@ import moe.nea.firmament.events.SlotClickEvent
import moe.nea.firmament.events.SlotRenderEvents
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.customgui.customGui
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.data.ProfileSpecificDataHolder
object StorageOverlay : FirmamentFeature {
@@ -27,6 +28,7 @@ object StorageOverlay : FirmamentFeature {
override val identifier: String
get() = "storage-overlay"
+ @Config
object TConfig : ManagedConfig(identifier, Category.INVENTORY) {
val alwaysReplace by toggle("always-replace") { true }
val outlineActiveStoragePage by toggle("outline-active-page") { false }
diff --git a/src/main/kotlin/features/items/BlockZapperOverlay.kt b/src/main/kotlin/features/items/BlockZapperOverlay.kt
index c207d67..ad96b8e 100644
--- a/src/main/kotlin/features/items/BlockZapperOverlay.kt
+++ b/src/main/kotlin/features/items/BlockZapperOverlay.kt
@@ -13,8 +13,9 @@ import moe.nea.firmament.events.ClientStartedEvent
import moe.nea.firmament.events.WorldKeyboardEvent
import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.render.RenderInWorldContext
import moe.nea.firmament.util.skyBlockId
import moe.nea.firmament.util.skyblock.SkyBlockItems
@@ -23,6 +24,7 @@ object BlockZapperOverlay : FirmamentFeature {
override val identifier: String
get() = "block-zapper-overlay"
+ @Config
object TConfig : ManagedConfig(identifier, Category.ITEMS) {
var blockZapperOverlay by toggle("block-zapper-overlay") { false }
val color by colour("color") { ChromaColour.fromStaticRGB(160, 0, 0, 60) }
diff --git a/src/main/kotlin/features/items/BonemerangOverlay.kt b/src/main/kotlin/features/items/BonemerangOverlay.kt
index 6483b7a..80019c0 100644
--- a/src/main/kotlin/features/items/BonemerangOverlay.kt
+++ b/src/main/kotlin/features/items/BonemerangOverlay.kt
@@ -13,8 +13,9 @@ import moe.nea.firmament.events.ClientStartedEvent
import moe.nea.firmament.events.EntityRenderTintEvent
import moe.nea.firmament.events.HudRenderEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.render.TintedOverlayTexture
import moe.nea.firmament.util.skyBlockId
import moe.nea.firmament.util.skyblock.SkyBlockItems
@@ -24,6 +25,7 @@ object BonemerangOverlay : FirmamentFeature {
override val identifier: String
get() = "bonemerang-overlay"
+ @Config
object TConfig : ManagedConfig(identifier, Category.ITEMS) {
var bonemerangOverlay by toggle("bonemerang-overlay") { false }
val bonemerangOverlayHud by position("bonemerang-overlay-hud", 80, 10) { Vector2i() }
diff --git a/src/main/kotlin/features/items/EtherwarpOverlay.kt b/src/main/kotlin/features/items/EtherwarpOverlay.kt
index 8893339..640c8f5 100644
--- a/src/main/kotlin/features/items/EtherwarpOverlay.kt
+++ b/src/main/kotlin/features/items/EtherwarpOverlay.kt
@@ -14,9 +14,10 @@ import net.minecraft.world.BlockView
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SBData
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.extraAttributes
import moe.nea.firmament.util.render.RenderInWorldContext
import moe.nea.firmament.util.skyBlockId
@@ -27,6 +28,7 @@ object EtherwarpOverlay : FirmamentFeature {
override val identifier: String
get() = "etherwarp-overlay"
+ @Config
object TConfig : ManagedConfig(identifier, Category.ITEMS) {
var etherwarpOverlay by toggle("etherwarp-overlay") { false }
var onlyShowWhileSneaking by toggle("only-show-while-sneaking") { true }
diff --git a/src/main/kotlin/features/macros/ComboProcessor.kt b/src/main/kotlin/features/macros/ComboProcessor.kt
index 03e9238..2b979c3 100644
--- a/src/main/kotlin/features/macros/ComboProcessor.kt
+++ b/src/main/kotlin/features/macros/ComboProcessor.kt
@@ -24,12 +24,6 @@ object ComboProcessor {
var lastInput = TimeMark.farPast()
val breadCrumbs = mutableListOf<SavedKeyBinding>()
- init {
- setActions(
- MacroData.DConfig.data.comboActions
- )
- }
-
fun setActions(actions: List<ComboKeyAction>) {
rootTrie = KeyComboTrie.fromComboList(actions)
reset()
diff --git a/src/main/kotlin/features/macros/MacroData.kt b/src/main/kotlin/features/macros/MacroData.kt
index 91de423..447516e 100644
--- a/src/main/kotlin/features/macros/MacroData.kt
+++ b/src/main/kotlin/features/macros/MacroData.kt
@@ -8,5 +8,10 @@ data class MacroData(
var comboActions: List<ComboKeyAction> = listOf(),
var wheels: List<MacroWheel> = listOf(),
) {
- object DConfig : DataHolder<MacroData>(kotlinx.serialization.serializer(), "macros", ::MacroData)
+ object DConfig : DataHolder<MacroData>(kotlinx.serialization.serializer(), "macros", ::MacroData) {
+ override fun onLoad() {
+ ComboProcessor.setActions(data.comboActions)
+ RadialMacros.setWheels(data.wheels)
+ }
+ }
}
diff --git a/src/main/kotlin/features/macros/RadialMenu.kt b/src/main/kotlin/features/macros/RadialMenu.kt
index 3496d43..43e65a7 100644
--- a/src/main/kotlin/features/macros/RadialMenu.kt
+++ b/src/main/kotlin/features/macros/RadialMenu.kt
@@ -1,5 +1,6 @@
package moe.nea.firmament.features.macros
+import me.shedaniel.math.Color
import org.joml.Vector2f
import util.render.CustomRenderLayers
import kotlin.math.atan2
@@ -93,7 +94,7 @@ object RadialMenuViewer {
option.renderSlice(event.context)
mat.popMatrix()
}
- event.context.drawLine(1, 1, delta.x.toInt(), delta.y.toInt(), me.shedaniel.math.Color.ofOpaque(0x00FF00))
+ event.context.drawLine(1, 1, delta.x.toInt(), delta.y.toInt(), Color.ofOpaque(0x00FF00))
mat.popMatrix()
}
@@ -115,7 +116,7 @@ object RadialMenuViewer {
}
object RadialMacros {
- var wheels = MacroData.DConfig.data.wheels
+ lateinit var wheels: List<MacroWheel>
private set
fun setWheels(wheels: List<MacroWheel>) {
diff --git a/src/main/kotlin/features/mining/CommissionFeatures.kt b/src/main/kotlin/features/mining/CommissionFeatures.kt
index faba253..05658cc 100644
--- a/src/main/kotlin/features/mining/CommissionFeatures.kt
+++ b/src/main/kotlin/features/mining/CommissionFeatures.kt
@@ -3,20 +3,22 @@ package moe.nea.firmament.features.mining
import moe.nea.firmament.Firmament
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.SlotRenderEvents
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.mc.loreAccordingToNbt
import moe.nea.firmament.util.unformattedString
object CommissionFeatures {
- object Config : ManagedConfig("commissions", Category.MINING) {
+ @Config
+ object TConfig : ManagedConfig("commissions", Category.MINING) {
val highlightCompletedCommissions by toggle("highlight-completed") { true }
}
@Subscribe
fun onSlotRender(event: SlotRenderEvents.Before) {
- if (!Config.highlightCompletedCommissions) return
+ if (!TConfig.highlightCompletedCommissions) return
if (MC.screenName != "Commissions") return
val stack = event.slot.stack
if (stack.loreAccordingToNbt.any { it.unformattedString == "COMPLETED" }) {
diff --git a/src/main/kotlin/features/mining/HotmPresets.kt b/src/main/kotlin/features/mining/HotmPresets.kt
index 2241fee..763364e 100644
--- a/src/main/kotlin/features/mining/HotmPresets.kt
+++ b/src/main/kotlin/features/mining/HotmPresets.kt
@@ -18,7 +18,7 @@ import moe.nea.firmament.events.ChestInventoryUpdateEvent
import moe.nea.firmament.events.CommandEvent
import moe.nea.firmament.events.ScreenChangeEvent
import moe.nea.firmament.events.SlotRenderEvents
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.mixins.accessor.AccessorHandledScreen
import moe.nea.firmament.util.ClipboardUtils
import moe.nea.firmament.util.MC
diff --git a/src/main/kotlin/features/mining/PickaxeAbility.kt b/src/main/kotlin/features/mining/PickaxeAbility.kt
index de50217..3acdcc3 100644
--- a/src/main/kotlin/features/mining/PickaxeAbility.kt
+++ b/src/main/kotlin/features/mining/PickaxeAbility.kt
@@ -19,7 +19,7 @@ import moe.nea.firmament.events.SlotClickEvent
import moe.nea.firmament.events.UseItemEvent
import moe.nea.firmament.events.WorldReadyEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.DurabilityBarEvent
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SBData
@@ -27,6 +27,7 @@ import moe.nea.firmament.util.SHORT_NUMBER_FORMAT
import moe.nea.firmament.util.SkyBlockIsland
import moe.nea.firmament.util.TIME_PATTERN
import moe.nea.firmament.util.TimeMark
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.extraAttributes
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
import moe.nea.firmament.util.mc.loreAccordingToNbt
@@ -62,6 +63,7 @@ object PickaxeAbility : FirmamentFeature {
fun matches(type: ItemType) = items.contains(type)
}
+ @Config
object TConfig : ManagedConfig(identifier, Category.MINING) {
val cooldownEnabled by toggle("ability-cooldown") { false }
val disableInDungeons by toggle("disable-in-dungeons") { true }
diff --git a/src/main/kotlin/features/mining/PristineProfitTracker.kt b/src/main/kotlin/features/mining/PristineProfitTracker.kt
index eb3cba6..e63a107 100644
--- a/src/main/kotlin/features/mining/PristineProfitTracker.kt
+++ b/src/main/kotlin/features/mining/PristineProfitTracker.kt
@@ -10,12 +10,13 @@ import net.minecraft.text.Text
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.ProcessChatEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.gui.hud.MoulConfigHud
import moe.nea.firmament.util.BazaarPriceStrategy
import moe.nea.firmament.util.FirmFormatters.formatCommas
import moe.nea.firmament.util.SkyblockId
import moe.nea.firmament.util.StringUtil.parseIntWithComma
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.data.ProfileSpecificDataHolder
import moe.nea.firmament.util.formattedString
import moe.nea.firmament.util.useMatch
@@ -56,6 +57,7 @@ object PristineProfitTracker : FirmamentFeature {
override val config: ManagedConfig?
get() = TConfig
+ @Config
object TConfig : ManagedConfig(identifier, Category.MINING) {
val timeout by duration("timeout", 0.seconds, 120.seconds) { 30.seconds }
val gui by position("position", 100, 30) { Vector2i() }
diff --git a/src/main/kotlin/features/misc/CustomCapes.kt b/src/main/kotlin/features/misc/CustomCapes.kt
index a5bc52a..f59f715 100644
--- a/src/main/kotlin/features/misc/CustomCapes.kt
+++ b/src/main/kotlin/features/misc/CustomCapes.kt
@@ -23,15 +23,17 @@ import net.minecraft.client.util.math.MatrixStack
import net.minecraft.util.Identifier
import moe.nea.firmament.Firmament
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.TimeMark
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.mc.CustomRenderPassHelper
object CustomCapes : FirmamentFeature {
override val identifier: String
get() = "developer-capes"
+ @Config
object TConfig : ManagedConfig(identifier, Category.DEV) {
val showCapes by toggle("show-cape") { true }
}
diff --git a/src/main/kotlin/features/misc/Hud.kt b/src/main/kotlin/features/misc/Hud.kt
index 8c785ab..272c349 100644
--- a/src/main/kotlin/features/misc/Hud.kt
+++ b/src/main/kotlin/features/misc/Hud.kt
@@ -3,18 +3,20 @@ package moe.nea.firmament.features.misc
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.HudRenderEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.tr
import moe.nea.jarvis.api.Point
import org.joml.Vector2i
import net.minecraft.client.network.PlayerListEntry
import net.minecraft.text.Text
+import moe.nea.firmament.util.data.Config
object Hud : FirmamentFeature {
override val identifier: String
get() = "hud"
+ @Config
object TConfig : ManagedConfig(identifier, Category.MISC) {
var dayCount by toggle("day-count") { false }
val dayCountHud by position("day-count-hud", 80, 10) { Vector2i() }
diff --git a/src/main/kotlin/features/world/FairySouls.kt b/src/main/kotlin/features/world/FairySouls.kt
index 699aafc..477fbe6 100644
--- a/src/main/kotlin/features/world/FairySouls.kt
+++ b/src/main/kotlin/features/world/FairySouls.kt
@@ -14,12 +14,13 @@ import moe.nea.firmament.events.ProcessChatEvent
import moe.nea.firmament.events.SkyblockServerUpdateEvent
import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SBData
import moe.nea.firmament.util.SkyBlockIsland
import moe.nea.firmament.util.blockPos
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.data.ProfileSpecificDataHolder
import moe.nea.firmament.util.render.RenderInWorldContext
import moe.nea.firmament.util.render.RenderInWorldContext.Companion.renderInWorld
@@ -37,9 +38,10 @@ object FairySouls : FirmamentFeature {
override val config: ManagedConfig
get() = TConfig
+ @Config
object DConfig : ProfileSpecificDataHolder<Data>(serializer(), "found-fairysouls", ::Data)
-
+ @Config
object TConfig : ManagedConfig("fairy-souls", Category.MISC) {
val displaySouls by toggle("show") { false }
val resetSouls by button("reset") {
diff --git a/src/main/kotlin/features/world/Waypoints.kt b/src/main/kotlin/features/world/Waypoints.kt
index 205d5eb..72bd9e8 100644
--- a/src/main/kotlin/features/world/Waypoints.kt
+++ b/src/main/kotlin/features/world/Waypoints.kt
@@ -17,8 +17,9 @@ import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.events.WorldReadyEvent
import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.mc.asFakeServer
import moe.nea.firmament.util.render.RenderInWorldContext
import moe.nea.firmament.util.tr
@@ -27,6 +28,7 @@ object Waypoints : FirmamentFeature {
override val identifier: String
get() = "waypoints"
+ @Config
object TConfig : ManagedConfig(identifier, Category.MINING) { // TODO: add to misc
val tempWaypointDuration by duration("temp-waypoint-duration", 0.seconds, 1.hours) { 30.seconds }
val showIndex by toggle("show-index") { true }
diff --git a/src/main/kotlin/gui/config/AllConfigsGui.kt b/src/main/kotlin/gui/config/AllConfigsGui.kt
index f9ffd2d..0add10f 100644
--- a/src/main/kotlin/gui/config/AllConfigsGui.kt
+++ b/src/main/kotlin/gui/config/AllConfigsGui.kt
@@ -10,9 +10,11 @@ import moe.nea.firmament.commands.get
import moe.nea.firmament.commands.thenArgument
import moe.nea.firmament.commands.thenExecute
import moe.nea.firmament.events.CommandEvent
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.MoulConfigUtils
import moe.nea.firmament.util.ScreenUtil.setScreenLater
+import moe.nea.firmament.util.data.Config
object AllConfigsGui {
//
@@ -21,6 +23,7 @@ object AllConfigsGui {
// RepoManager.Config
// ) + FeatureManager.allFeatures.mapNotNull { it.config }
+ @Config
object ConfigConfig : ManagedConfig("configconfig", Category.META) {
val enableYacl by toggle("enable-yacl") { false }
val enableMoulConfig by toggle("enable-moulconfig") { true }
diff --git a/src/main/kotlin/gui/config/BooleanHandler.kt b/src/main/kotlin/gui/config/BooleanHandler.kt
index 8592777..b954401 100644
--- a/src/main/kotlin/gui/config/BooleanHandler.kt
+++ b/src/main/kotlin/gui/config/BooleanHandler.kt
@@ -9,6 +9,7 @@ import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.boolean
import kotlinx.serialization.json.jsonPrimitive
+import moe.nea.firmament.util.data.ManagedConfig
class BooleanHandler(val config: ManagedConfig) : ManagedConfig.OptionHandler<Boolean> {
override fun toJson(element: Boolean): JsonElement? {
@@ -29,7 +30,7 @@ class BooleanHandler(val config: ManagedConfig) : ManagedConfig.OptionHandler<Bo
override fun set(newValue: Boolean) {
opt.set(newValue)
- config.save()
+ config.markDirty()
}
}, 200)
))
diff --git a/src/main/kotlin/gui/config/ChoiceHandler.kt b/src/main/kotlin/gui/config/ChoiceHandler.kt
index 2ea3efc..9c3dda2 100644
--- a/src/main/kotlin/gui/config/ChoiceHandler.kt
+++ b/src/main/kotlin/gui/config/ChoiceHandler.kt
@@ -9,6 +9,7 @@ import kotlinx.serialization.json.JsonElement
import kotlin.jvm.optionals.getOrNull
import net.minecraft.util.StringIdentifiable
import moe.nea.firmament.gui.CheckboxComponent
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.ErrorUtil
import moe.nea.firmament.util.json.KJsonOps
diff --git a/src/main/kotlin/gui/config/ClickHandler.kt b/src/main/kotlin/gui/config/ClickHandler.kt
index fa1c621..9ea83aa 100644
--- a/src/main/kotlin/gui/config/ClickHandler.kt
+++ b/src/main/kotlin/gui/config/ClickHandler.kt
@@ -5,6 +5,7 @@ package moe.nea.firmament.gui.config
import io.github.notenoughupdates.moulconfig.gui.component.TextComponent
import kotlinx.serialization.json.JsonElement
import moe.nea.firmament.gui.FirmButtonComponent
+import moe.nea.firmament.util.data.ManagedConfig
class ClickHandler(val config: ManagedConfig, val runnable: () -> Unit) : ManagedConfig.OptionHandler<Unit> {
override fun toJson(element: Unit): JsonElement? {
diff --git a/src/main/kotlin/gui/config/ColourHandler.kt b/src/main/kotlin/gui/config/ColourHandler.kt
index 83ce8ac..33daa6d 100644
--- a/src/main/kotlin/gui/config/ColourHandler.kt
+++ b/src/main/kotlin/gui/config/ColourHandler.kt
@@ -10,6 +10,7 @@ import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
+import moe.nea.firmament.util.data.ManagedConfig
class ColourHandler(val config: ManagedConfig) :
ManagedConfig.OptionHandler<ChromaColour> {
@@ -73,7 +74,7 @@ class ColourHandler(val config: ManagedConfig) :
opt.value.toLegacyString(),
{
opt.value = ChromaColour.forLegacyString(it)
- config.save()
+ config.markDirty()
},
{ }
)
diff --git a/src/main/kotlin/gui/config/DurationHandler.kt b/src/main/kotlin/gui/config/DurationHandler.kt
index 32bec25..4800bf6 100644
--- a/src/main/kotlin/gui/config/DurationHandler.kt
+++ b/src/main/kotlin/gui/config/DurationHandler.kt
@@ -12,6 +12,7 @@ import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.long
+import moe.nea.firmament.util.data.ManagedConfig
import kotlin.time.Duration
import kotlin.time.DurationUnit
import kotlin.time.toDuration
diff --git a/src/main/kotlin/gui/config/HudMetaHandler.kt b/src/main/kotlin/gui/config/HudMetaHandler.kt
index 0637351..dcf5d8f 100644
--- a/src/main/kotlin/gui/config/HudMetaHandler.kt
+++ b/src/main/kotlin/gui/config/HudMetaHandler.kt
@@ -10,6 +10,7 @@ import net.minecraft.text.MutableText
import net.minecraft.text.Text
import moe.nea.firmament.Firmament
import moe.nea.firmament.gui.FirmButtonComponent
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.jarvis.JarvisIntegration
import moe.nea.firmament.util.MC
diff --git a/src/main/kotlin/gui/config/IntegerHandler.kt b/src/main/kotlin/gui/config/IntegerHandler.kt
index fd10447..3e7be57 100644
--- a/src/main/kotlin/gui/config/IntegerHandler.kt
+++ b/src/main/kotlin/gui/config/IntegerHandler.kt
@@ -12,6 +12,7 @@ import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonPrimitive
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.FirmFormatters
class IntegerHandler(val config: ManagedConfig, val min: Int, val max: Int) : ManagedConfig.OptionHandler<Int> {
diff --git a/src/main/kotlin/gui/config/KeyBindingHandler.kt b/src/main/kotlin/gui/config/KeyBindingHandler.kt
index 14a4b32..a5e626d 100644
--- a/src/main/kotlin/gui/config/KeyBindingHandler.kt
+++ b/src/main/kotlin/gui/config/KeyBindingHandler.kt
@@ -11,6 +11,7 @@ import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.json.encodeToJsonElement
import moe.nea.firmament.gui.FirmButtonComponent
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.keybindings.FirmamentKeyBindings
import moe.nea.firmament.keybindings.SavedKeyBinding
@@ -35,7 +36,7 @@ class KeyBindingHandler(val name: String, val managedConfig: ManagedConfig) :
{ opt.value },
{
opt.value = it
- opt.element.save()
+ opt.element.markDirty()
},
{ button.blur() },
{ button.requestFocus() }
diff --git a/src/main/kotlin/gui/config/ManagedConfigElement.kt b/src/main/kotlin/gui/config/ManagedConfigElement.kt
deleted file mode 100644
index 28cd6b8..0000000
--- a/src/main/kotlin/gui/config/ManagedConfigElement.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-package moe.nea.firmament.gui.config
-
-abstract class ManagedConfigElement {
- abstract val name: String
-
-}
diff --git a/src/main/kotlin/gui/config/ManagedOption.kt b/src/main/kotlin/gui/config/ManagedOption.kt
index 830086c..888b3f1 100644
--- a/src/main/kotlin/gui/config/ManagedOption.kt
+++ b/src/main/kotlin/gui/config/ManagedOption.kt
@@ -3,6 +3,7 @@ package moe.nea.firmament.gui.config
import io.github.notenoughupdates.moulconfig.observer.GetSetter
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
+import moe.nea.firmament.util.data.ManagedConfig
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
import net.minecraft.text.Text
@@ -27,11 +28,11 @@ class ManagedOption<T : Any>(
val descriptionTranslationKey = "firmament.config.${element.name}.${propertyName}.description"
val labelDescription: Text = Text.translatable(descriptionTranslationKey)
- private var actualValue: T? = null
+ var _actualValue: T? = null
var value: T
- get() = actualValue ?: error("Lateinit variable not initialized")
+ get() = _actualValue ?: error("Lateinit variable not initialized")
set(value) {
- actualValue = value
+ _actualValue = value
element.onChange(this)
}
diff --git a/src/main/kotlin/gui/config/StringHandler.kt b/src/main/kotlin/gui/config/StringHandler.kt
index a326abb..da14d4b 100644
--- a/src/main/kotlin/gui/config/StringHandler.kt
+++ b/src/main/kotlin/gui/config/StringHandler.kt
@@ -7,6 +7,7 @@ import io.github.notenoughupdates.moulconfig.observer.GetSetter
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.jsonPrimitive
+import moe.nea.firmament.util.data.ManagedConfig
import net.minecraft.text.Text
class StringHandler(val config: ManagedConfig) : ManagedConfig.OptionHandler<String> {
@@ -25,7 +26,7 @@ class StringHandler(val config: ManagedConfig) : ManagedConfig.OptionHandler<Str
object : GetSetter<String> by opt {
override fun set(newValue: String) {
opt.set(newValue)
- config.save()
+ config.markDirty()
}
},
130,
diff --git a/src/main/kotlin/gui/config/storage/ConfigLoadContext.kt b/src/main/kotlin/gui/config/storage/ConfigLoadContext.kt
new file mode 100644
index 0000000..59afaa1
--- /dev/null
+++ b/src/main/kotlin/gui/config/storage/ConfigLoadContext.kt
@@ -0,0 +1,65 @@
+package moe.nea.firmament.gui.config.storage
+
+import java.io.PrintWriter
+import java.nio.file.Path
+import org.apache.commons.io.output.StringBuilderWriter
+import kotlin.io.path.Path
+import kotlin.io.path.createParentDirectories
+import kotlin.io.path.writeText
+import moe.nea.firmament.Firmament
+
+data class ConfigLoadContext(
+ val loadId: String,
+) : AutoCloseable {
+ val logFile = Path("logs")
+ .resolve(Firmament.MOD_ID)
+ .resolve("config-$loadId.log")
+ .toAbsolutePath()
+ val logBuffer = StringBuilder()
+
+ var shouldSaveLogBuffer = false
+ fun markShouldSaveLogBuffer() {
+ shouldSaveLogBuffer = true
+ }
+
+ fun logDebug(message: String) {
+ logBuffer.append("[DEBUG] ").append(message).appendLine()
+ }
+
+ fun logInfo(message: String) {
+ Firmament.logger.info("[ConfigUpgrade] $message")
+ logBuffer.append("[INFO] ").append(message).appendLine()
+ }
+
+ fun logError(message: String, exception: Throwable) {
+ markShouldSaveLogBuffer()
+ Firmament.logger.error("[ConfigUpgrade] $message", exception)
+ logBuffer.append("[ERROR] ").append(message).appendLine()
+ PrintWriter(StringBuilderWriter(logBuffer)).use {
+ exception.printStackTrace(it)
+ }
+ logBuffer.appendLine()
+ }
+
+ fun logError(message: String) {
+ markShouldSaveLogBuffer()
+ Firmament.logger.error("[ConfigUpgrade] $message")
+ logBuffer.append("[ERROR] ").append(message).appendLine()
+ }
+
+ fun ensureWritable(path: Path) {
+ path.createParentDirectories()
+ }
+
+ override fun close() {
+ logInfo("Closing out config load.")
+ if (shouldSaveLogBuffer) {
+ try {
+ ensureWritable(logFile)
+ logFile.writeText(logBuffer.toString())
+ } catch (ex: Exception) {
+ logError("Could not save config load log", ex)
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/gui/config/storage/ConfigStorageClass.kt b/src/main/kotlin/gui/config/storage/ConfigStorageClass.kt
new file mode 100644
index 0000000..8258fe7
--- /dev/null
+++ b/src/main/kotlin/gui/config/storage/ConfigStorageClass.kt
@@ -0,0 +1,8 @@
+package moe.nea.firmament.gui.config.storage
+
+enum class ConfigStorageClass { // TODO: make this encode type info somehow
+ PROFILE,
+ STORAGE,
+ CONFIG,
+}
+
diff --git a/src/main/kotlin/gui/config/storage/FirmamentConfigLoader.kt b/src/main/kotlin/gui/config/storage/FirmamentConfigLoader.kt
new file mode 100644
index 0000000..22cba2c
--- /dev/null
+++ b/src/main/kotlin/gui/config/storage/FirmamentConfigLoader.kt
@@ -0,0 +1,204 @@
+package moe.nea.firmament.gui.config.storage
+
+import java.util.UUID
+import kotlinx.serialization.json.JsonElement
+import kotlinx.serialization.json.JsonObject
+import kotlinx.serialization.json.buildJsonObject
+import kotlinx.serialization.json.jsonObject
+import kotlin.io.path.Path
+import kotlin.io.path.exists
+import kotlin.io.path.forEachDirectoryEntry
+import kotlin.io.path.isDirectory
+import kotlin.io.path.listDirectoryEntries
+import kotlin.io.path.name
+import kotlin.io.path.readText
+import kotlin.io.path.writeText
+import moe.nea.firmament.util.data.IConfigProvider
+import moe.nea.firmament.util.data.IDataHolder
+import moe.nea.firmament.util.data.ProfileKeyedConfig
+import moe.nea.firmament.util.json.intoGson
+import moe.nea.firmament.util.json.intoKotlinJson
+
+object FirmamentConfigLoader {
+ val currentConfigVersion = 1000
+ val configFolder = Path("config/firmament")
+ .toAbsolutePath()
+ val storageFolder = configFolder.resolve("storage")
+ val profilePath = configFolder.resolve("profiles")
+ val tagLines = listOf(
+ "<- your config version here",
+ "I'm a teapot",
+ "mail.example.com ESMTP",
+ "Apples"
+ )
+ val configVersionFile = configFolder.resolve("config.version")
+
+ fun loadConfig() {
+ if (configFolder.exists()) {
+ if (!configVersionFile.exists()) {
+ LegacyImporter.importFromLegacy()
+ }
+ updateConfigs()
+ }
+
+ ConfigLoadContext("load-${System.currentTimeMillis()}").use { loadContext ->
+ val configData = FirstLevelSplitJsonFolder(loadContext, configFolder).load()
+ loadConfigFromData(configData, Unit, ConfigStorageClass.CONFIG)
+ val storageData = FirstLevelSplitJsonFolder(loadContext, storageFolder).load()
+ loadConfigFromData(storageData, Unit, ConfigStorageClass.STORAGE)
+ val profileData =
+ profilePath.listDirectoryEntries()
+ .filter { it.isDirectory() }
+ .associate {
+ UUID.fromString(it.name) to FirstLevelSplitJsonFolder(loadContext, it).load()
+ }
+ profileData.forEach { (key, value) ->
+ loadConfigFromData(value, key, ConfigStorageClass.PROFILE)
+ }
+ }
+ }
+
+ fun <T> loadConfigFromData(
+ configData: JsonObject,
+ key: T,
+ storageClass: ConfigStorageClass
+ ) {
+ for (holder in allConfigs) {
+ if (holder.storageClass == storageClass) {
+ (holder as IDataHolder<T>).loadFrom(key, configData)
+ }
+ }
+ }
+
+ fun <T> collectConfigFromData(
+ key: T,
+ storageClass: ConfigStorageClass,
+ ): JsonObject {
+ var json = JsonObject(mapOf())
+ for (holder in allConfigs) {
+ if (holder.storageClass == storageClass) {
+ json = mergeJson(json, (holder as IDataHolder<T>).saveTo(key))
+ }
+ }
+ return json
+ }
+
+ fun <T> saveStorage(
+ storageClass: ConfigStorageClass,
+ key: T,
+ firstLevelSplitJsonFolder: FirstLevelSplitJsonFolder,
+ ) {
+ firstLevelSplitJsonFolder.save(
+ collectConfigFromData(key, storageClass)
+ )
+ }
+
+ fun collectAllProfileIds(): Set<UUID> {
+ return allConfigs
+ .filter { it.storageClass == ConfigStorageClass.PROFILE }
+ .flatMapTo(mutableSetOf()) {
+ (it as ProfileKeyedConfig<*>).keys()
+ }
+ }
+
+ fun saveAll() {
+ ConfigLoadContext("load-${System.currentTimeMillis()}").use { context ->
+ saveStorage(
+ ConfigStorageClass.CONFIG,
+ Unit,
+ FirstLevelSplitJsonFolder(context, configFolder)
+ )
+ saveStorage(
+ ConfigStorageClass.STORAGE,
+ Unit,
+ FirstLevelSplitJsonFolder(context, storageFolder)
+ )
+ collectAllProfileIds().forEach { profileId ->
+ saveStorage(
+ ConfigStorageClass.PROFILE,
+ profileId,
+ FirstLevelSplitJsonFolder(context, profilePath.resolve(profileId.toString()))
+ )
+ }
+ }
+ }
+
+ fun mergeJson(a: JsonObject, b: JsonObject): JsonObject {
+ fun mergeInner(a: JsonElement?, b: JsonElement?): JsonElement {
+ if (a == null)
+ return b!!
+ if (b == null)
+ return a
+ a as JsonObject
+ b as JsonObject
+ return buildJsonObject {
+ (a.keys + b.keys)
+ .forEach {
+ put(it, mergeInner(a[it], b[it]))
+ }
+ }
+ }
+ return mergeInner(a, b) as JsonObject
+ }
+
+ val allConfigs: List<IDataHolder<*>> = IConfigProvider.providers.allValidInstances.flatMap { it.configs }
+
+ fun updateConfigs() {
+ val startVersion = configVersionFile.readText()
+ .substringBefore(' ')
+ .trim()
+ .toInt()
+ ConfigLoadContext("update-from-$startVersion-to-$currentConfigVersion-${System.currentTimeMillis()}")
+ .use { loadContext ->
+ updateOneConfig(
+ loadContext,
+ startVersion,
+ ConfigStorageClass.CONFIG,
+ FirstLevelSplitJsonFolder(loadContext, configFolder)
+ )
+ updateOneConfig(
+ loadContext,
+ startVersion,
+ ConfigStorageClass.STORAGE,
+ FirstLevelSplitJsonFolder(loadContext, storageFolder)
+ )
+ profilePath.forEachDirectoryEntry {
+ updateOneConfig(
+ loadContext,
+ startVersion,
+ ConfigStorageClass.PROFILE,
+ FirstLevelSplitJsonFolder(loadContext, it)
+ )
+ }
+ configVersionFile.writeText("$currentConfigVersion ${tagLines.random()}")
+ }
+ }
+
+ private fun updateOneConfig(
+ loadContext: ConfigLoadContext,
+ startVersion: Int,
+ storageClass: ConfigStorageClass,
+ firstLevelSplitJsonFolder: FirstLevelSplitJsonFolder
+ ) {
+ loadContext.logInfo("Starting upgrade from at ${firstLevelSplitJsonFolder.folder} ($storageClass) to $startVersion")
+ var data = firstLevelSplitJsonFolder.load()
+ for (nextVersion in (startVersion + 1)..currentConfigVersion) {
+ data = updateOneConfigOnce(nextVersion, storageClass, data)
+ }
+ firstLevelSplitJsonFolder.save(data)
+ }
+
+ private fun updateOneConfigOnce(
+ nextVersion: Int,
+ storageClass: ConfigStorageClass,
+ data: JsonObject
+ ): JsonObject {
+ return ConfigFixEvent.publish(ConfigFixEvent(storageClass, nextVersion, data.intoGson().asJsonObject))
+ .data.intoKotlinJson().jsonObject
+ }
+
+ fun markDirty(holder: IDataHolder<*>) {
+ TODO("Not yet implemented")
+ }
+
+}
diff --git a/src/main/kotlin/gui/config/storage/FirstLevelSplitJsonFolder.kt b/src/main/kotlin/gui/config/storage/FirstLevelSplitJsonFolder.kt
new file mode 100644
index 0000000..ff544d5
--- /dev/null
+++ b/src/main/kotlin/gui/config/storage/FirstLevelSplitJsonFolder.kt
@@ -0,0 +1,83 @@
+@file:OptIn(ExperimentalSerializationApi::class)
+
+package moe.nea.firmament.gui.config.storage
+
+import java.nio.file.Path
+import kotlinx.serialization.ExperimentalSerializationApi
+import kotlinx.serialization.json.JsonElement
+import kotlinx.serialization.json.JsonObject
+import kotlinx.serialization.json.decodeFromStream
+import kotlinx.serialization.json.encodeToStream
+import kotlin.io.path.deleteExisting
+import kotlin.io.path.inputStream
+import kotlin.io.path.listDirectoryEntries
+import kotlin.io.path.nameWithoutExtension
+import kotlin.io.path.outputStream
+import moe.nea.firmament.Firmament
+
+class FirstLevelSplitJsonFolder(
+ val context: ConfigLoadContext,
+ val folder: Path
+) {
+ fun load(): JsonObject {
+ context.logInfo("Loading FLSJF from $folder")
+ return folder.listDirectoryEntries("*.json")
+ .mapNotNull(::loadIndividualFile)
+ .toMap()
+ .let(::JsonObject)
+ .also { context.logInfo("FLSJF from $folder - Voller Erfolg!") }
+ }
+
+ fun loadIndividualFile(path: Path): Pair<String, JsonElement>? {
+ context.logInfo("Loading partial file from $path")
+ return try {
+ path.inputStream().use {
+ path.nameWithoutExtension to Firmament.json.decodeFromStream(JsonElement.serializer(), it)
+ }
+ } catch (ex: Exception) {
+ context.logError("Could not load file from $path", ex)
+ null
+ }
+ }
+
+ fun save(value: JsonObject) {
+ context.logInfo("Saving FLSJF to $folder")
+ context.logDebug("Current value:\n$value")
+ val entries = folder.listDirectoryEntries("*.json")
+ .toMutableList()
+ for ((name, element) in value) {
+ val path = saveIndividualFile(name, element)
+ if (path != null) {
+ entries.remove(path)
+ }
+ }
+ if (entries.isNotEmpty()) {
+ context.logInfo("Deleting additional files.")
+ for (path in entries) {
+ context.logInfo("Deleting $path")
+// context.backup(path)
+ try {
+ path.deleteExisting()
+ } catch (ex: Exception) {
+ context.logError("Could not delete $path", ex)
+ }
+ }
+ }
+ context.logInfo("FLSJF to $folder - Voller Erfolg!")
+ }
+
+ fun saveIndividualFile(name: String, element: JsonElement): Path? {
+ try {
+ context.logInfo("Saving partial file with name $name")
+ val path = folder.resolve("$name.json")
+ context.ensureWritable(path)
+ path.outputStream().use {
+ Firmament.json.encodeToStream(JsonElement.serializer(), element, it)
+ }
+ return path
+ } catch (ex: Exception) {
+ context.logError("Could not save $name with value $element", ex)
+ return null
+ }
+ }
+}
diff --git a/src/main/kotlin/gui/config/storage/LegacyImporter.kt b/src/main/kotlin/gui/config/storage/LegacyImporter.kt
new file mode 100644
index 0000000..8915c17
--- /dev/null
+++ b/src/main/kotlin/gui/config/storage/LegacyImporter.kt
@@ -0,0 +1,63 @@
+package moe.nea.firmament.gui.config.storage
+
+import java.nio.file.Path
+import javax.xml.namespace.QName
+import kotlin.io.path.Path
+import kotlin.io.path.copyTo
+import kotlin.io.path.copyToRecursively
+import kotlin.io.path.createDirectories
+import kotlin.io.path.createParentDirectories
+import kotlin.io.path.exists
+import kotlin.io.path.forEachDirectoryEntry
+import kotlin.io.path.listDirectoryEntries
+import kotlin.io.path.moveTo
+import kotlin.io.path.name
+import kotlin.io.path.nameWithoutExtension
+import kotlin.io.path.writeText
+import moe.nea.firmament.gui.config.storage.FirmamentConfigLoader.configFolder
+import moe.nea.firmament.gui.config.storage.FirmamentConfigLoader.configVersionFile
+import moe.nea.firmament.gui.config.storage.FirmamentConfigLoader.storageFolder
+
+object LegacyImporter {
+ val legacyConfigVersion = 995
+ val backupPath = configFolder.resolveSibling("firmament-legacy-config-${System.currentTimeMillis()}")
+
+ fun copyIf(from: Path, to: Path) {
+ if (from.exists()) {
+ to.createParentDirectories()
+ from.copyTo(to)
+ }
+ }
+
+ fun importFromLegacy() {
+ configFolder.moveTo(backupPath)
+ configFolder.createDirectories()
+
+ copyIf(
+ backupPath.resolve("inventory-buttons.json"),
+ storageFolder.resolve("inventory-buttons.json")
+ )
+
+ backupPath.listDirectoryEntries("*.json")
+ .forEach { path ->
+ val name = path.name
+ if (name == "inventory-buttons.json")
+ return@forEach
+ path.copyTo(configFolder.resolve(name))
+ }
+
+ backupPath.resolve("profiles")
+ .forEachDirectoryEntry { category ->
+ category.forEachDirectoryEntry { profile ->
+ copyIf(
+ profile,
+ FirmamentConfigLoader.profilePath
+ .resolve(profile.nameWithoutExtension)
+ .resolve(category.name + ".json")
+ )
+ }
+ }
+
+ configVersionFile.writeText(legacyConfigVersion.toString())
+ }
+}
diff --git a/src/main/kotlin/jarvis/JarvisIntegration.kt b/src/main/kotlin/jarvis/JarvisIntegration.kt
index 96f47f7..0dc75e4 100644
--- a/src/main/kotlin/jarvis/JarvisIntegration.kt
+++ b/src/main/kotlin/jarvis/JarvisIntegration.kt
@@ -39,7 +39,7 @@ class JarvisIntegration : JarvisPlugin {
}
override fun onHudEditorClosed() {
- configs.forEach { it.save() }
+ configs.forEach { it.markDirty() }
}
override fun getAllConfigOptions(): List<JarvisConfigOption> {
diff --git a/src/main/kotlin/repo/RepoManager.kt b/src/main/kotlin/repo/RepoManager.kt
index c3d1c52..d25494f 100644
--- a/src/main/kotlin/repo/RepoManager.kt
+++ b/src/main/kotlin/repo/RepoManager.kt
@@ -17,7 +17,7 @@ import net.minecraft.util.StringIdentifiable
import moe.nea.firmament.Firmament
import moe.nea.firmament.Firmament.logger
import moe.nea.firmament.events.ReloadRegistrationEvent
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.ErrorUtil
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.MinecraftDispatcher
@@ -35,18 +35,18 @@ object RepoManager {
username = "NotEnoughUpdates"
reponame = "NotEnoughUpdates-REPO"
branch = "master"
- save()
+ markDirty()
}
val enableREI by toggle("enable-rei") { true }
val disableItemGroups by toggle("disable-item-groups") { true }
val reload by button("reload") {
- save()
+ markDirty()
Firmament.coroutineScope.launch {
RepoManager.reload()
}
}
val redownload by button("redownload") {
- save()
+ markDirty()
RepoManager.launchAsyncUpdate(true)
}
val alwaysSuperCraft by toggle("enable-super-craft") { true }
diff --git a/src/main/kotlin/util/SBData.kt b/src/main/kotlin/util/SBData.kt
index 1a4734c..8675842 100644
--- a/src/main/kotlin/util/SBData.kt
+++ b/src/main/kotlin/util/SBData.kt
@@ -18,6 +18,10 @@ object SBData {
"CLICK THIS TO SUGGEST IT IN CHAT [DASHES]",
"CLICK THIS TO SUGGEST IT IN CHAT [NO DASHES]",
)
+
+ val NULL_UUID = UUID(0L, 0L)
+ val profileIdOrNil get() = profileId ?: NULL_UUID
+
var profileId: UUID? = null
get() {
// TODO: allow unfiltered access to this somehow
diff --git a/src/main/kotlin/util/data/Config.kt b/src/main/kotlin/util/data/Config.kt
new file mode 100644
index 0000000..41de039
--- /dev/null
+++ b/src/main/kotlin/util/data/Config.kt
@@ -0,0 +1,15 @@
+package moe.nea.firmament.util.data
+
+import moe.nea.firmament.util.compatloader.CompatLoader
+
+@Retention(AnnotationRetention.RUNTIME)
+@Target(AnnotationTarget.CLASS)
+annotation class Config(val prefix: String = "")
+
+
+interface IConfigProvider {
+ val configs: List<IDataHolder<*>>
+ companion object {
+ val providers = CompatLoader(IConfigProvider::class)
+ }
+}
diff --git a/src/main/kotlin/util/data/DataHolder.kt b/src/main/kotlin/util/data/DataHolder.kt
index 21a6014..9f21125 100644
--- a/src/main/kotlin/util/data/DataHolder.kt
+++ b/src/main/kotlin/util/data/DataHolder.kt
@@ -1,5 +1,3 @@
-
-
package moe.nea.firmament.util.data
import java.nio.file.Path
@@ -8,55 +6,13 @@ import kotlin.io.path.exists
import kotlin.io.path.readText
import kotlin.io.path.writeText
import moe.nea.firmament.Firmament
+import moe.nea.firmament.gui.config.storage.ConfigStorageClass
abstract class DataHolder<T>(
- val serializer: KSerializer<T>,
- val name: String,
- val default: () -> T
-) : IDataHolder<T> {
-
-
- final override var data: T
- private set
-
- init {
- data = readValueOrDefault()
- IDataHolder.putDataHolder(this::class, this)
- }
-
- private val file: Path get() = Firmament.CONFIG_DIR.resolve("$name.json")
-
- protected fun readValueOrDefault(): T {
- if (file.exists())
- try {
- return Firmament.json.decodeFromString(
- serializer,
- file.readText()
- )
- } catch (e: Exception) {/* Expecting IOException and SerializationException, but Kotlin doesn't allow multi catches*/
- IDataHolder.badLoads.add(name)
- Firmament.logger.error(
- "Exception during loading of config file $name. This will reset this config.",
- e
- )
- }
- return default()
- }
-
- private fun writeValue(t: T) {
- file.writeText(Firmament.json.encodeToString(serializer, t))
- }
-
- override fun save() {
- writeValue(data)
- }
-
- override fun load() {
- data = readValueOrDefault()
- }
-
- override fun markDirty() {
- IDataHolder.markDirty(this::class)
- }
-
+ serializer: KSerializer<T>,
+ name: String,
+ default: () -> T
+) : GenericConfig<T>(name, serializer, default) {
+ override val storageClass: ConfigStorageClass
+ get() = ConfigStorageClass.STORAGE
}
diff --git a/src/main/kotlin/util/data/IDataHolder.kt b/src/main/kotlin/util/data/IDataHolder.kt
index 1e9ba98..81198ee 100644
--- a/src/main/kotlin/util/data/IDataHolder.kt
+++ b/src/main/kotlin/util/data/IDataHolder.kt
@@ -1,71 +1,95 @@
package moe.nea.firmament.util.data
-import java.util.concurrent.CopyOnWriteArrayList
-import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents
-import kotlin.reflect.KClass
-import net.minecraft.text.Text
+import java.util.UUID
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.json.JsonObject
+import kotlinx.serialization.json.buildJsonObject
import moe.nea.firmament.Firmament
-import moe.nea.firmament.events.ScreenChangeEvent
-import moe.nea.firmament.util.MC
+import moe.nea.firmament.gui.config.storage.ConfigStorageClass
+import moe.nea.firmament.gui.config.storage.FirmamentConfigLoader
+import moe.nea.firmament.util.SBData
-interface IDataHolder<T> {
- companion object {
- internal var badLoads: MutableList<String> = CopyOnWriteArrayList()
- private val allConfigs: MutableMap<KClass<out IDataHolder<*>>, IDataHolder<*>> = mutableMapOf()
- private val dirty: MutableSet<KClass<out IDataHolder<*>>> = mutableSetOf()
+sealed interface IDataHolder<T> {
+ fun markDirty() {
+ FirmamentConfigLoader.markDirty(this)
+ }
- internal fun <T : IDataHolder<K>, K> putDataHolder(kClass: KClass<T>, inst: IDataHolder<K>) {
- allConfigs[kClass] = inst
- }
+ fun keys(): Collection<T>
+ fun saveTo(key: T): JsonObject
+ fun loadFrom(key: T, jsonObject: JsonObject)
+ fun clear()
+ val storageClass: ConfigStorageClass
+}
- fun <T : IDataHolder<K>, K> markDirty(kClass: KClass<T>) {
- if (kClass !in allConfigs) {
- Firmament.logger.error("Tried to markDirty '${kClass.qualifiedName}', which isn't registered as 'IConfigHolder'")
- return
- }
- dirty.add(kClass)
- }
+open class ProfileKeyedConfig<T>(
+ val prefix: String,
+ val serializer: KSerializer<T>,
+ val default: () -> T,
+) : IDataHolder<UUID> {
- private fun performSaves() {
- val toSave = dirty.toList().also {
- dirty.clear()
- }
- for (it in toSave) {
- val obj = allConfigs[it]
- if (obj == null) {
- Firmament.logger.error("Tried to save '${it}', which isn't registered as 'ConfigHolder'")
- continue
- }
- obj.save()
- }
- }
+ override val storageClass: ConfigStorageClass
+ get() = ConfigStorageClass.PROFILE
+ private var _data: MutableMap<UUID, T>? = null
+
+ val data
+ get() = _data!!.let { map ->
+ map[SBData.profileIdOrNil]
+ ?: default().also { map[SBData.profileIdOrNil] = it }
+ } ?: error("Config $this not loaded — forgot to register?")
- private fun warnForResetConfigs() {
- if (badLoads.isNotEmpty()) {
- MC.sendChat(
- Text.literal(
- "The following configs have been reset: ${badLoads.joinToString(", ")}. " +
- "This can be intentional, but probably isn't."
- )
- )
- badLoads.clear()
- }
+ override fun keys(): Collection<UUID> {
+ return _data!!.keys
+ }
+
+ override fun saveTo(key: UUID): JsonObject {
+ val d = _data!!
+ return buildJsonObject {
+ put(prefix, Firmament.json.encodeToJsonElement(serializer, d[key] ?: return@buildJsonObject))
}
+ }
- fun registerEvents() {
- ScreenChangeEvent.subscribe("IDataHolder:saveOnScreenChange") { event ->
- performSaves()
- warnForResetConfigs()
- }
- ClientLifecycleEvents.CLIENT_STOPPING.register(ClientLifecycleEvents.ClientStopping {
- performSaves()
- })
+ override fun loadFrom(key: UUID, jsonObject: JsonObject) {
+ (_data ?: mutableMapOf<UUID, T>().also { _data = it })[key] =
+ jsonObject[prefix]
+ ?.let {
+ Firmament.json.decodeFromJsonElement(serializer, it)
+ } ?: default()
+ }
+
+ override fun clear() {
+ _data = null
+ }
+}
+
+abstract class GenericConfig<T>(
+ val prefix: String,
+ val serializer: KSerializer<T>,
+ val default: () -> T,
+) : IDataHolder<Unit> {
+
+ private var _data: T? = null
+
+ val data get() = _data ?: error("Config $this not loaded — forgot to register?")
+
+ override fun keys(): Collection<Unit> {
+ return listOf(Unit)
+ }
+
+ open fun onLoad() {
+ }
+
+ override fun saveTo(key: Unit): JsonObject {
+ return buildJsonObject {
+ put(prefix, Firmament.json.encodeToJsonElement(serializer, data))
}
+ }
+ override fun loadFrom(key: Unit, jsonObject: JsonObject) {
+ _data = jsonObject[prefix]?.let { Firmament.json.decodeFromJsonElement(serializer, it) } ?: default()
+ onLoad()
}
- val data: T
- fun save()
- fun markDirty()
- fun load()
+ override fun clear() {
+ _data = null
+ }
}
diff --git a/src/main/kotlin/util/data/MultiFileDataHolder.kt b/src/main/kotlin/util/data/MultiFileDataHolder.kt
index 94c6f05..209f780 100644
--- a/src/main/kotlin/util/data/MultiFileDataHolder.kt
+++ b/src/main/kotlin/util/data/MultiFileDataHolder.kt
@@ -28,7 +28,6 @@ abstract class MultiFileDataHolder<T>(
try {
it.nameWithoutExtension to Firmament.json.decodeFromString(dataSerializer, it.readText())
} catch (e: Exception) { /* Expecting IOException and SerializationException, but Kotlin doesn't allow multi catches*/
- IDataHolder.badLoads.add(configName)
Firmament.logger.error(
"Exception during loading of multi file data holder $it ($configName). This will reset that profiles config.",
e
diff --git a/src/main/kotlin/util/data/ProfileSpecificDataHolder.kt b/src/main/kotlin/util/data/ProfileSpecificDataHolder.kt
index 1cd4f22..3922c34 100644
--- a/src/main/kotlin/util/data/ProfileSpecificDataHolder.kt
+++ b/src/main/kotlin/util/data/ProfileSpecificDataHolder.kt
@@ -1,84 +1,9 @@
-
-
package moe.nea.firmament.util.data
-import java.nio.file.Path
-import java.util.UUID
import kotlinx.serialization.KSerializer
-import kotlin.io.path.createDirectories
-import kotlin.io.path.deleteExisting
-import kotlin.io.path.exists
-import kotlin.io.path.extension
-import kotlin.io.path.listDirectoryEntries
-import kotlin.io.path.nameWithoutExtension
-import kotlin.io.path.readText
-import kotlin.io.path.writeText
-import moe.nea.firmament.Firmament
-import moe.nea.firmament.util.SBData
abstract class ProfileSpecificDataHolder<S>(
- private val dataSerializer: KSerializer<S>,
- val configName: String,
- private val configDefault: () -> S
-) : IDataHolder<S?> {
-
- var allConfigs: MutableMap<UUID, S>
-
- override val data: S?
- get() = SBData.profileId?.let {
- allConfigs.computeIfAbsent(it) { configDefault() }
- }
-
- init {
- allConfigs = readValues()
- IDataHolder.putDataHolder(this::class, this)
- }
-
- private val configDirectory: Path get() = Firmament.CONFIG_DIR.resolve("profiles").resolve(configName)
-
- private fun readValues(): MutableMap<UUID, S> {
- if (!configDirectory.exists()) {
- configDirectory.createDirectories()
- }
- val profileFiles = configDirectory.listDirectoryEntries()
- return profileFiles
- .filter { it.extension == "json" }
- .mapNotNull {
- try {
- UUID.fromString(it.nameWithoutExtension) to Firmament.json.decodeFromString(dataSerializer, it.readText())
- } catch (e: Exception) { /* Expecting IOException and SerializationException, but Kotlin doesn't allow multi catches*/
- IDataHolder.badLoads.add(configName)
- Firmament.logger.error(
- "Exception during loading of profile specific config file $it ($configName). This will reset that profiles config.",
- e
- )
- null
- }
- }.toMap().toMutableMap()
- }
-
- override fun save() {
- if (!configDirectory.exists()) {
- configDirectory.createDirectories()
- }
- val c = allConfigs
- configDirectory.listDirectoryEntries().forEach {
- if (it.nameWithoutExtension !in c.mapKeys { it.toString() }) {
- it.deleteExisting()
- }
- }
- c.forEach { (name, value) ->
- val f = configDirectory.resolve("$name.json")
- f.writeText(Firmament.json.encodeToString(dataSerializer, value))
- }
- }
-
- override fun markDirty() {
- IDataHolder.markDirty(this::class)
- }
-
- override fun load() {
- allConfigs = readValues()
- }
-
-}
+ dataSerializer: KSerializer<S>,
+ configName: String,
+ configDefault: () -> S
+) : ProfileKeyedConfig<S>(configName, dataSerializer, configDefault)
diff --git a/src/main/kotlin/util/json/jsonConversion.kt b/src/main/kotlin/util/json/jsonConversion.kt
new file mode 100644
index 0000000..899ae11
--- /dev/null
+++ b/src/main/kotlin/util/json/jsonConversion.kt
@@ -0,0 +1,66 @@
+package moe.nea.firmament.util.json
+
+import com.google.gson.JsonArray
+import com.google.gson.JsonElement
+import com.google.gson.JsonNull
+import com.google.gson.JsonObject
+import com.google.gson.JsonPrimitive
+import com.google.gson.internal.LazilyParsedNumber
+import kotlin.collections.map
+
+
+fun JsonElement.intoKotlinJson(): kotlinx.serialization.json.JsonElement {
+ when (this) {
+ is JsonNull -> return kotlinx.serialization.json.JsonNull
+ is JsonObject -> {
+ return kotlinx.serialization.json.JsonObject(
+ this.entrySet()
+ .associate { it.key to it.value.intoKotlinJson() })
+ }
+
+ is JsonArray -> {
+ return kotlinx.serialization.json.JsonArray(this.map { it.intoKotlinJson() })
+ }
+
+ is JsonPrimitive -> {
+ if (this.isString)
+ return kotlinx.serialization.json.JsonPrimitive(this.asString)
+ if (this.isBoolean)
+ return kotlinx.serialization.json.JsonPrimitive(this.asBoolean)
+ return kotlinx.serialization.json.JsonPrimitive(this.asNumber)
+ }
+
+ else -> error("Unknown json variant $this")
+ }
+}
+
+fun kotlinx.serialization.json.JsonElement.intoGson(): JsonElement {
+ when (this) {
+ is kotlinx.serialization.json.JsonNull -> return JsonNull.INSTANCE
+ is kotlinx.serialization.json.JsonPrimitive -> {
+ if (this.isString)
+ return JsonPrimitive(this.content)
+ if (this.content == "true")
+ return JsonPrimitive(true)
+ if (this.content == "false")
+ return JsonPrimitive(false)
+ return JsonPrimitive(LazilyParsedNumber(this.content))
+ }
+
+ is kotlinx.serialization.json.JsonObject -> {
+ val obj = JsonObject()
+ for ((k, v) in this) {
+ obj.add(k, v.intoGson())
+ }
+ return obj
+ }
+
+ is kotlinx.serialization.json.JsonArray -> {
+ val arr = JsonArray()
+ for (v in this) {
+ arr.add(v.intoGson())
+ }
+ return arr
+ }
+ }
+}
diff --git a/src/main/kotlin/util/skyblock/SackUtil.kt b/src/main/kotlin/util/skyblock/SackUtil.kt
index c46542e..8c82022 100644
--- a/src/main/kotlin/util/skyblock/SackUtil.kt
+++ b/src/main/kotlin/util/skyblock/SackUtil.kt
@@ -8,6 +8,8 @@ import net.minecraft.text.Text
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.ChestInventoryUpdateEvent
import moe.nea.firmament.events.ProcessChatEvent
+import moe.nea.firmament.gui.config.storage.ConfigFixEvent
+import moe.nea.firmament.gui.config.storage.ConfigStorageClass
import moe.nea.firmament.repo.ItemNameLookup
import moe.nea.firmament.util.SHORT_NUMBER_FORMAT
import moe.nea.firmament.util.SkyblockId
@@ -28,7 +30,14 @@ object SackUtil {
// val sackTypes:
)
- object Store : ProfileSpecificDataHolder<SackContents>(serializer(), "Sacks", ::SackContents)
+ object Store : ProfileSpecificDataHolder<SackContents>(serializer(), "sacks", ::SackContents)
+
+ @Subscribe
+ fun onConfigFix(event: ConfigFixEvent) {
+ event.on(996, ConfigStorageClass.PROFILE) {
+ move("Sacks", "sacks")
+ }
+ }
val items get() = Store.data?.contents ?: mutableMapOf()
val storedRegex = "^Stored: (?<stored>$SHORT_NUMBER_FORMAT)/(?<max>$SHORT_NUMBER_FORMAT)$".toPattern()
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt
index 18949ff..1f911dc 100644
--- a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt
@@ -16,8 +16,9 @@ import moe.nea.firmament.events.FinalizeResourceManagerEvent
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.features.debug.PowerUserTools
-import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.collections.WeakCache
+import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.mc.decodeProfileTextureProperty
import moe.nea.firmament.util.skyBlockId
@@ -25,6 +26,7 @@ object CustomSkyBlockTextures : FirmamentFeature {
override val identifier: String
get() = "custom-skyblock-textures"
+ @Config
object TConfig : ManagedConfig(identifier, Category.INTEGRATIONS) { // TODO: should this be its own thing?
val enabled by toggle("enabled") { true }
val skullsEnabled by toggle("skulls-enabled") { true }
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentRootPredicateSerializer.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentRootPredicateSerializer.kt
index 0b8ae8e..39e1fc3 100644
--- a/src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentRootPredicateSerializer.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentRootPredicateSerializer.kt
@@ -6,6 +6,7 @@ import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import moe.nea.firmament.features.texturepack.predicates.AndPredicate
+import moe.nea.firmament.util.json.intoGson
object FirmamentRootPredicateSerializer : KSerializer<FirmamentModelPredicate> {
val delegateSerializer = kotlinx.serialization.json.JsonObject.serializer()
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/StringMatcher.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/StringMatcher.kt
index 863ca3b..446bf07 100644
--- a/src/texturePacks/java/moe/nea/firmament/features/texturepack/StringMatcher.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/StringMatcher.kt
@@ -14,6 +14,8 @@ import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import net.minecraft.nbt.NbtString
import net.minecraft.text.Text
+import moe.nea.firmament.util.json.intoGson
+import moe.nea.firmament.util.json.intoKotlinJson
import moe.nea.firmament.util.removeColorCodes
@Serializable(with = StringMatcher.Serializer::class)
@@ -144,59 +146,3 @@ interface StringMatcher {
}
}
}
-
-fun JsonElement.intoKotlinJson(): kotlinx.serialization.json.JsonElement {
- when (this) {
- is JsonNull -> return kotlinx.serialization.json.JsonNull
- is JsonObject -> {
- return kotlinx.serialization.json.JsonObject(
- this.entrySet()
- .associate { it.key to it.value.intoKotlinJson() })
- }
-
- is JsonArray -> {
- return kotlinx.serialization.json.JsonArray(this.map { it.intoKotlinJson() })
- }
-
- is JsonPrimitive -> {
- if (this.isString)
- return kotlinx.serialization.json.JsonPrimitive(this.asString)
- if (this.isBoolean)
- return kotlinx.serialization.json.JsonPrimitive(this.asBoolean)
- return kotlinx.serialization.json.JsonPrimitive(this.asNumber)
- }
-
- else -> error("Unknown json variant $this")
- }
-}
-
-fun kotlinx.serialization.json.JsonElement.intoGson(): JsonElement {
- when (this) {
- is kotlinx.serialization.json.JsonNull -> return JsonNull.INSTANCE
- is kotlinx.serialization.json.JsonPrimitive -> {
- if (this.isString)
- return JsonPrimitive(this.content)
- if (this.content == "true")
- return JsonPrimitive(true)
- if (this.content == "false")
- return JsonPrimitive(false)
- return JsonPrimitive(LazilyParsedNumber(this.content))
- }
-
- is kotlinx.serialization.json.JsonObject -> {
- val obj = JsonObject()
- for ((k, v) in this) {
- obj.add(k, v.intoGson())
- }
- return obj
- }
-
- is kotlinx.serialization.json.JsonArray -> {
- val arr = JsonArray()
- for (v in this) {
- arr.add(v.intoGson())
- }
- return arr
- }
- }
-}