diff options
author | CalMWolfs <94038482+CalMWolfs@users.noreply.github.com> | 2024-06-04 04:16:22 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-03 20:16:22 +0200 |
commit | aa66334dba2c2c086b94eab1767abd4765e006f7 (patch) | |
tree | 42c9cc1d76f1d331a42c0bee2e55830168e6f85a | |
parent | fde5544ca7a49f8315318a249607769aee87661c (diff) | |
download | skyhanni-aa66334dba2c2c086b94eab1767abd4765e006f7.tar.gz skyhanni-aa66334dba2c2c086b94eab1767abd4765e006f7.tar.bz2 skyhanni-aa66334dba2c2c086b94eab1767abd4765e006f7.zip |
Fix: Config resetting on wrong value (#1979)
Co-authored-by: Brady <brady@thatgravyboat.tech>
21 files changed, 214 insertions, 166 deletions
diff --git a/.idea/dictionaries/default_user.xml b/.idea/dictionaries/default_user.xml index 62935a97c..1cc3cc669 100644 --- a/.idea/dictionaries/default_user.xml +++ b/.idea/dictionaries/default_user.xml @@ -77,6 +77,7 @@ <w>inquis</w> <w>inquistiors</w> <w>interp</w> + <w>itemstack</w> <w>jawbus</w> <w>jerries</w> <w>jerrypocalypse</w> diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt index 16b0fcfa3..fc654983c 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt @@ -2,42 +2,28 @@ package at.hannibal2.skyhanni.config import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.core.config.Position -import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.jsonobjects.local.FriendsJson import at.hannibal2.skyhanni.data.jsonobjects.local.JacobContestsJson import at.hannibal2.skyhanni.data.jsonobjects.local.KnownFeaturesJson import at.hannibal2.skyhanni.data.jsonobjects.local.VisualWordsJson import at.hannibal2.skyhanni.events.LorenzEvent -import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity import at.hannibal2.skyhanni.features.misc.update.UpdateManager import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.ChatUtils import at.hannibal2.skyhanni.utils.DelayedRun import at.hannibal2.skyhanni.utils.IdentityCharacteristics -import at.hannibal2.skyhanni.utils.KotlinTypeAdapterFactory import at.hannibal2.skyhanni.utils.LorenzLogger -import at.hannibal2.skyhanni.utils.LorenzRarity import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzVec -import at.hannibal2.skyhanni.utils.NEUInternalName -import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName -import at.hannibal2.skyhanni.utils.NEUItems import at.hannibal2.skyhanni.utils.SimpleTimeMark -import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark -import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker +import at.hannibal2.skyhanni.utils.json.BaseGsonBuilder import com.google.gson.Gson import com.google.gson.GsonBuilder import com.google.gson.JsonObject -import com.google.gson.TypeAdapter import com.google.gson.TypeAdapterFactory -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter import io.github.notenoughupdates.moulconfig.annotations.ConfigLink -import io.github.notenoughupdates.moulconfig.observer.PropertyTypeAdapterFactory import io.github.notenoughupdates.moulconfig.processor.BuiltinMoulConfigGuis import io.github.notenoughupdates.moulconfig.processor.ConfigProcessorDriver import io.github.notenoughupdates.moulconfig.processor.MoulConfigProcessor -import net.minecraft.item.ItemStack import java.io.BufferedReader import java.io.BufferedWriter import java.io.File @@ -49,12 +35,9 @@ import java.io.OutputStreamWriter import java.nio.charset.StandardCharsets import java.nio.file.Files import java.nio.file.StandardCopyOption -import java.util.UUID import kotlin.concurrent.fixedRateTimer -typealias TrackerDisplayMode = SkyHanniTracker.DefaultDisplayMode - -private fun GsonBuilder.reigsterIfBeta(create: TypeAdapterFactory): GsonBuilder { +private fun GsonBuilder.registerIfBeta(create: TypeAdapterFactory): GsonBuilder { return if (LorenzUtils.isBetaVersion()) { registerTypeAdapterFactory(create) } else this @@ -62,114 +45,12 @@ private fun GsonBuilder.reigsterIfBeta(create: TypeAdapterFactory): GsonBuilder class ConfigManager { companion object { - fun createBaseGsonBuilder(): GsonBuilder { - return GsonBuilder().setPrettyPrinting() - .excludeFieldsWithoutExposeAnnotation() - .serializeSpecialFloatingPointValues() - .registerTypeAdapterFactory(PropertyTypeAdapterFactory()) - .registerTypeAdapterFactory(KotlinTypeAdapterFactory()) - .registerTypeAdapter(UUID::class.java, object : TypeAdapter<UUID>() { - override fun write(out: JsonWriter, value: UUID) { - out.value(value.toString()) - } - - override fun read(reader: JsonReader): UUID { - return UUID.fromString(reader.nextString()) - } - }.nullSafe()) - .registerTypeAdapter(LorenzVec::class.java, object : TypeAdapter<LorenzVec>() { - override fun write(out: JsonWriter, value: LorenzVec) { - value.run { out.value("$x:$y:$z") } - } - - override fun read(reader: JsonReader): LorenzVec { - return LorenzVec.decodeFromString(reader.nextString()) - } - }.nullSafe()) - .registerTypeAdapter(TrophyRarity::class.java, object : TypeAdapter<TrophyRarity>() { - override fun write(out: JsonWriter, value: TrophyRarity) { - value.run { out.value(value.name) } - } - override fun read(reader: JsonReader): TrophyRarity { - val text = reader.nextString() - return TrophyRarity.getByName(text) ?: error("Could not parse TrophyRarity from '$text'") - } - }.nullSafe()) - .registerTypeAdapter(ItemStack::class.java, object : TypeAdapter<ItemStack>() { - override fun write(out: JsonWriter, value: ItemStack) { - out.value(NEUItems.saveNBTData(value)) - } - - override fun read(reader: JsonReader): ItemStack { - return NEUItems.loadNBTData(reader.nextString()) - } - }.nullSafe()) - .registerTypeAdapter(NEUInternalName::class.java, object : TypeAdapter<NEUInternalName>() { - override fun write(out: JsonWriter, value: NEUInternalName) { - out.value(value.asString()) - } - - override fun read(reader: JsonReader): NEUInternalName { - return reader.nextString().asInternalName() - } - }.nullSafe()) - .registerTypeAdapter(LorenzRarity::class.java, object : TypeAdapter<LorenzRarity>() { - override fun write(out: JsonWriter, value: LorenzRarity) { - out.value(value.name) - } - - override fun read(reader: JsonReader): LorenzRarity { - return LorenzRarity.valueOf(reader.nextString().uppercase().replace(" ", "_")) - } - }.nullSafe()) - .registerTypeAdapter(IslandType::class.java, object : TypeAdapter<IslandType>() { - override fun write(out: JsonWriter, value: IslandType) { - out.value(value.name) - } - - override fun read(reader: JsonReader): IslandType { - return IslandType.valueOf(reader.nextString().uppercase()) - } - }.nullSafe()) - .registerTypeAdapter(TrackerDisplayMode::class.java, object : TypeAdapter<TrackerDisplayMode>() { - override fun write(out: JsonWriter, value: TrackerDisplayMode) { - out.value(value.name) - } - - override fun read(reader: JsonReader): TrackerDisplayMode { - return TrackerDisplayMode.valueOf(reader.nextString()) - } - }.nullSafe()) - .registerTypeAdapter(SimpleTimeMark::class.java, object : TypeAdapter<SimpleTimeMark>() { - override fun write(out: JsonWriter, value: SimpleTimeMark) { - out.value(value.toMillis()) - } - - override fun read(reader: JsonReader): SimpleTimeMark { - return reader.nextString().toLong().asTimeMark() - } - }.nullSafe()) - .enableComplexMapKeySerialization() - } - - val gson: Gson = createBaseGsonBuilder() - // TODO reenable with toggle that is default disabled -// .reigsterIfBeta(FeatureTogglesByDefaultAdapter) + val gson: Gson = BaseGsonBuilder.gson() +// .registerIfBeta(FeatureTogglesByDefaultAdapter) .create() var configDirectory = File("config/skyhanni") - - inline fun <reified T> GsonBuilder.registerTypeAdapter( - crossinline write: (JsonWriter, T) -> Unit, - crossinline read: (JsonReader) -> T, - ): GsonBuilder { - this.registerTypeAdapter(T::class.java, object : TypeAdapter<T>() { - override fun write(out: JsonWriter, value: T) = write(out, value) - override fun read(reader: JsonReader) = read(reader) - }.nullSafe()) - return this - } } val features get() = jsonHolder[ConfigFileType.FEATURES] as Features @@ -281,13 +162,14 @@ class ConfigManager { try { val inputStreamReader = InputStreamReader(FileInputStream(file), StandardCharsets.UTF_8) val bufferedReader = BufferedReader(inputStreamReader) + val lenientGson = BaseGsonBuilder.lenientGson().create() logger.log("load-$fileName-now") output = if (fileType == ConfigFileType.FEATURES) { - val jsonObject = gson.fromJson(bufferedReader.readText(), JsonObject::class.java) + val jsonObject = lenientGson.fromJson(bufferedReader.readText(), JsonObject::class.java) val newJsonObject = ConfigUpdaterMigrator.fixConfig(jsonObject) - val run = { gson.fromJson(newJsonObject, defaultValue.javaClass) } + val run = { lenientGson.fromJson(newJsonObject, defaultValue.javaClass) } if (LorenzUtils.isInDevEnvironment()) { try { run() @@ -299,7 +181,7 @@ class ConfigManager { run() } } else { - gson.fromJson(bufferedReader.readText(), defaultValue.javaClass) + lenientGson.fromJson(bufferedReader.readText(), defaultValue.javaClass) } logger.log("Loaded $fileName from file") diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt index 56118f4db..b7fd4838b 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt @@ -4,7 +4,7 @@ import at.hannibal2.skyhanni.events.LorenzEvent import at.hannibal2.skyhanni.features.misc.limbo.LimboTimeTracker import at.hannibal2.skyhanni.utils.LorenzLogger import at.hannibal2.skyhanni.utils.LorenzUtils.asIntOrNull -import at.hannibal2.skyhanni.utils.shDeepCopy +import at.hannibal2.skyhanni.utils.json.shDeepCopy import com.google.gson.JsonElement import com.google.gson.JsonObject import com.google.gson.JsonPrimitive @@ -110,7 +110,8 @@ object ConfigUpdaterMigrator { fun fixConfig(config: JsonObject): JsonObject { val lastVersion = (config["lastVersion"] as? JsonPrimitive)?.asIntOrNull ?: -1 if (lastVersion > CONFIG_VERSION) { - error("Cannot downgrade config") + logger.log("Attempted to downgrade config version") + return config } if (lastVersion == CONFIG_VERSION) return config return (lastVersion until CONFIG_VERSION).fold(config) { accumulator, i -> diff --git a/src/main/java/at/hannibal2/skyhanni/data/MayorAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/MayorAPI.kt index 666713c70..584d2291f 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/MayorAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/MayorAPI.kt @@ -19,7 +19,7 @@ import at.hannibal2.skyhanni.utils.RegexUtils.matches import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark import at.hannibal2.skyhanni.utils.SkyBlockTime -import at.hannibal2.skyhanni.utils.fromJson +import at.hannibal2.skyhanni.utils.json.fromJson import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/src/main/java/at/hannibal2/skyhanni/data/bazaar/HypixelBazaarFetcher.kt b/src/main/java/at/hannibal2/skyhanni/data/bazaar/HypixelBazaarFetcher.kt index db39e98c5..6ed9b8e6a 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/bazaar/HypixelBazaarFetcher.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/bazaar/HypixelBazaarFetcher.kt @@ -13,7 +13,7 @@ import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.NEUItems import at.hannibal2.skyhanni.utils.NEUItems.getItemStackOrNull import at.hannibal2.skyhanni.utils.SimpleTimeMark -import at.hannibal2.skyhanni.utils.fromJson +import at.hannibal2.skyhanni.utils.json.fromJson import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext diff --git a/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/HotmTree.kt b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/HotmTree.kt index b9fba9ca0..3c0118089 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/HotmTree.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/HotmTree.kt @@ -1,6 +1,6 @@ package at.hannibal2.skyhanni.data.jsonobjects.local; -import at.hannibal2.skyhanni.utils.fromJson +import at.hannibal2.skyhanni.utils.json.fromJson import com.google.gson.Gson import com.google.gson.annotations.Expose diff --git a/src/main/java/at/hannibal2/skyhanni/data/model/Graph.kt b/src/main/java/at/hannibal2/skyhanni/data/model/Graph.kt index b6e6f7b8e..c25a567fb 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/model/Graph.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/model/Graph.kt @@ -1,8 +1,8 @@ package at.hannibal2.skyhanni.data.model -import at.hannibal2.skyhanni.config.ConfigManager.Companion.registerTypeAdapter import at.hannibal2.skyhanni.utils.LorenzVec -import at.hannibal2.skyhanni.utils.fromJson +import at.hannibal2.skyhanni.utils.json.SkyHanniTypeAdapters.registerTypeAdapter +import at.hannibal2.skyhanni.utils.json.fromJson import com.google.gson.GsonBuilder import com.google.gson.JsonElement import com.google.gson.annotations.Expose @@ -36,8 +36,7 @@ value class Graph( override fun lastIndexOf(element: GraphNode) = graph.lastIndexOf(element) companion object { - val gson = GsonBuilder().setPrettyPrinting() - /* ConfigManager.createBaseGsonBuilder() */.registerTypeAdapter<Graph>({ out, value -> + val gson = GsonBuilder().setPrettyPrinting().registerTypeAdapter<Graph>({ out, value -> out.beginObject() value.forEach { out.name(it.id.toString()).beginObject() diff --git a/src/main/java/at/hannibal2/skyhanni/events/NeuRepositoryReloadEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/NeuRepositoryReloadEvent.kt index bb741ae80..a02cb308f 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/NeuRepositoryReloadEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/NeuRepositoryReloadEvent.kt @@ -3,7 +3,7 @@ package at.hannibal2.skyhanni.events import at.hannibal2.skyhanni.config.ConfigManager import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.NEUItems.manager -import at.hannibal2.skyhanni.utils.fromJson +import at.hannibal2.skyhanni.utils.json.fromJson import com.google.gson.JsonObject import com.google.gson.JsonSyntaxException import java.io.File diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt index 3025ae7d1..6f8523c34 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt @@ -1,7 +1,6 @@ package at.hannibal2.skyhanni.features.garden.farming import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.config.ConfigManager import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.config.enums.OutsideSbFeature import at.hannibal2.skyhanni.data.HypixelData @@ -30,12 +29,11 @@ import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.StringUtils import at.hannibal2.skyhanni.utils.TimeUtils -import at.hannibal2.skyhanni.utils.fromJson +import at.hannibal2.skyhanni.utils.json.BaseGsonBuilder +import at.hannibal2.skyhanni.utils.json.SkyHanniTypeAdapters +import at.hannibal2.skyhanni.utils.json.fromJson import at.hannibal2.skyhanni.utils.renderables.Renderable import com.google.gson.JsonObject -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter import kotlinx.coroutines.launch import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.time.Duration.Companion.minutes @@ -132,21 +130,9 @@ class FarmingWeightDisplay { } private val eliteWeightApiGson by lazy { - ConfigManager.createBaseGsonBuilder() - .registerTypeAdapter(CropType::class.java, object : TypeAdapter<CropType>() { - override fun write(out: JsonWriter, value: CropType) {} - - override fun read(reader: JsonReader): CropType { - return CropType.getByName(reader.nextString()) - } - }.nullSafe()) - .registerTypeAdapter(PestType::class.java, object : TypeAdapter<PestType>() { - override fun write(out: JsonWriter, value: PestType) {} - - override fun read(reader: JsonReader): PestType { - return PestType.getByName(reader.nextString()) - } - }.nullSafe()) + BaseGsonBuilder.gson() + .registerTypeAdapter(CropType::class.java, SkyHanniTypeAdapters.CROP_TYPE.nullSafe()) + .registerTypeAdapter(PestType::class.java, SkyHanniTypeAdapters.PEST_TYPE.nullSafe()) .create() } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/bazaar/BazaarDataHolder.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/bazaar/BazaarDataHolder.kt index 8911e1e2b..3d7867ad9 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/bazaar/BazaarDataHolder.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/bazaar/BazaarDataHolder.kt @@ -8,7 +8,7 @@ import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.APIUtil import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.NEUItems -import at.hannibal2.skyhanni.utils.fromJson +import at.hannibal2.skyhanni.utils.json.fromJson import kotlinx.coroutines.launch class BazaarDataHolder { diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventTracker.kt index 6fa28a83b..698335f27 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventTracker.kt @@ -19,7 +19,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.TimeUtils -import at.hannibal2.skyhanni.utils.fromJson +import at.hannibal2.skyhanni.utils.json.fromJson import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import com.google.gson.JsonPrimitive import kotlinx.coroutines.launch diff --git a/src/main/java/at/hannibal2/skyhanni/test/TestExportTools.kt b/src/main/java/at/hannibal2/skyhanni/test/TestExportTools.kt index 44a147c07..303c41bbe 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/TestExportTools.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/TestExportTools.kt @@ -5,13 +5,13 @@ import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.GuiKeyPressEvent import at.hannibal2.skyhanni.test.command.CopyItemCommand.copyItemToClipboard import at.hannibal2.skyhanni.utils.ChatUtils -import at.hannibal2.skyhanni.utils.ItemStackTypeAdapterFactory import at.hannibal2.skyhanni.utils.KSerializable import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyHeld import at.hannibal2.skyhanni.utils.KotlinTypeAdapterFactory -import at.hannibal2.skyhanni.utils.NBTTypeAdapter import at.hannibal2.skyhanni.utils.OSUtils -import at.hannibal2.skyhanni.utils.fromJson +import at.hannibal2.skyhanni.utils.json.ItemStackTypeAdapterFactory +import at.hannibal2.skyhanni.utils.json.NBTTypeAdapter +import at.hannibal2.skyhanni.utils.json.fromJson import com.google.gson.GsonBuilder import com.google.gson.JsonElement import net.minecraft.item.ItemStack diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt index b3d92e68f..297a40585 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt @@ -15,6 +15,8 @@ import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName import at.hannibal2.skyhanni.utils.NumberUtil.isInt import at.hannibal2.skyhanni.utils.PrimitiveItemStack.Companion.makePrimitiveStack +import at.hannibal2.skyhanni.utils.json.BaseGsonBuilder +import at.hannibal2.skyhanni.utils.json.fromJson import com.google.gson.JsonObject import com.google.gson.JsonPrimitive import com.google.gson.TypeAdapter @@ -51,7 +53,7 @@ object NEUItems { private val ingredientsCache = mutableMapOf<NeuRecipe, Set<Ingredient>>() private val hypixelApiGson by lazy { - ConfigManager.createBaseGsonBuilder() + BaseGsonBuilder.gson() .registerTypeAdapter(HypixelApiTrophyFish::class.java, object : TypeAdapter<HypixelApiTrophyFish>() { override fun write(out: JsonWriter, value: HypixelApiTrophyFish) {} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/json/BaseGsonBuilder.kt b/src/main/java/at/hannibal2/skyhanni/utils/json/BaseGsonBuilder.kt new file mode 100644 index 000000000..d73edc0b0 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/json/BaseGsonBuilder.kt @@ -0,0 +1,37 @@ +package at.hannibal2.skyhanni.utils.json + +import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity +import at.hannibal2.skyhanni.utils.KotlinTypeAdapterFactory +import at.hannibal2.skyhanni.utils.LorenzRarity +import at.hannibal2.skyhanni.utils.LorenzVec +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker +import com.google.gson.GsonBuilder +import io.github.notenoughupdates.moulconfig.observer.PropertyTypeAdapterFactory +import net.minecraft.item.ItemStack +import java.util.UUID + +object BaseGsonBuilder { + fun gson(): GsonBuilder = GsonBuilder().setPrettyPrinting() + .excludeFieldsWithoutExposeAnnotation() + .serializeSpecialFloatingPointValues() + .registerTypeAdapterFactory(PropertyTypeAdapterFactory()) + .registerTypeAdapterFactory(KotlinTypeAdapterFactory()) + .registerTypeAdapter(UUID::class.java, SkyHanniTypeAdapters.UUID.nullSafe()) + .registerTypeAdapter(LorenzVec::class.java, SkyHanniTypeAdapters.VEC_STRING.nullSafe()) + .registerTypeAdapter(TrophyRarity::class.java, SkyHanniTypeAdapters.TROPHY_RARITY.nullSafe()) + .registerTypeAdapter(ItemStack::class.java, SkyHanniTypeAdapters.NEU_ITEMSTACK.nullSafe()) + .registerTypeAdapter(NEUInternalName::class.java, SkyHanniTypeAdapters.INTERNAL_NAME.nullSafe()) + .registerTypeAdapter(LorenzRarity::class.java, SkyHanniTypeAdapters.RARITY.nullSafe()) + .registerTypeAdapter(IslandType::class.java, SkyHanniTypeAdapters.ISLAND_TYPE.nullSafe()) + .registerTypeAdapter( + SkyHanniTracker.DefaultDisplayMode::class.java, + SkyHanniTypeAdapters.TRACKER_DISPLAY_MODE.nullSafe() + ) + .registerTypeAdapter(SimpleTimeMark::class.java, SkyHanniTypeAdapters.TIME_MARK.nullSafe()) + .enableComplexMapKeySerialization() + + fun lenientGson(): GsonBuilder = gson().registerTypeAdapterFactory(SkippingTypeAdapterFactory) +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/FeatureTogglesByDefaultAdapter.kt b/src/main/java/at/hannibal2/skyhanni/utils/json/FeatureTogglesByDefaultAdapter.kt index f78a0c4dc..bcc9c2edf 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/FeatureTogglesByDefaultAdapter.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/json/FeatureTogglesByDefaultAdapter.kt @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils +package at.hannibal2.skyhanni.utils.json import at.hannibal2.skyhanni.config.FeatureToggle import at.hannibal2.skyhanni.utils.ReflectionUtils.getDeclaredFieldOrNull diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemStackTypeAdapter.kt b/src/main/java/at/hannibal2/skyhanni/utils/json/ItemStackTypeAdapter.kt index 602bffa2d..1940b03c0 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ItemStackTypeAdapter.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/json/ItemStackTypeAdapter.kt @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils +package at.hannibal2.skyhanni.utils.json import com.google.gson.Gson import com.google.gson.TypeAdapter diff --git a/src/main/java/at/hannibal2/skyhanni/utils/JsonUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/json/JsonUtils.kt index cc3dda044..750bd96aa 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/JsonUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/json/JsonUtils.kt @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils +package at.hannibal2.skyhanni.utils.json import com.google.gson.Gson import com.google.gson.JsonArray diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NBTTypeAdapter.kt b/src/main/java/at/hannibal2/skyhanni/utils/json/NBTTypeAdapter.kt index 4e0762895..e2e782636 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NBTTypeAdapter.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/json/NBTTypeAdapter.kt @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils +package at.hannibal2.skyhanni.utils.json import com.google.gson.TypeAdapter import com.google.gson.stream.JsonReader diff --git a/src/main/java/at/hannibal2/skyhanni/utils/json/SimpleStringTypeAdapter.kt b/src/main/java/at/hannibal2/skyhanni/utils/json/SimpleStringTypeAdapter.kt new file mode 100644 index 000000000..21f601932 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/json/SimpleStringTypeAdapter.kt @@ -0,0 +1,29 @@ +package at.hannibal2.skyhanni.utils.json + +import com.google.gson.TypeAdapter +import com.google.gson.stream.JsonReader +import com.google.gson.stream.JsonWriter + +class SimpleStringTypeAdapter<T>( + val serializer: T.() -> String, + val deserializer: String.() -> T +) : TypeAdapter<T>() { + + override fun write(writer: JsonWriter, value: T) { + writer.value(serializer(value)) + } + + override fun read(reader: JsonReader): T { + return deserializer(reader.nextString()) + } + + companion object { + + inline fun <reified T : Enum<T>> forEnum(): SimpleStringTypeAdapter<T> { + return SimpleStringTypeAdapter( + { name }, + { enumValueOf(this.replace(" ", "_").uppercase()) } + ) + } + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/json/SkippingTypeAdapterFactory.kt b/src/main/java/at/hannibal2/skyhanni/utils/json/SkippingTypeAdapterFactory.kt new file mode 100644 index 000000000..a926976ca --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/json/SkippingTypeAdapterFactory.kt @@ -0,0 +1,32 @@ +package at.hannibal2.skyhanni.utils.json + +import at.hannibal2.skyhanni.SkyHanniMod +import com.google.gson.Gson +import com.google.gson.TypeAdapter +import com.google.gson.TypeAdapterFactory +import com.google.gson.reflect.TypeToken +import com.google.gson.stream.JsonReader +import com.google.gson.stream.JsonWriter + +object SkippingTypeAdapterFactory : TypeAdapterFactory { + + override fun <T : Any?> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T> { + return SafeTypeAdapter(gson.getDelegateAdapter(this, type)) + } + + private class SafeTypeAdapter<T>(val parent: TypeAdapter<T>) : TypeAdapter<T>() { + override fun write(writer: JsonWriter, value: T) { + parent.write(writer, value) + } + + override fun read(reader: JsonReader): T? { + return try { + parent.read(reader) + } catch (e: Exception) { + SkyHanniMod.logger.warn("Failed to read value from JSON, skipping", e) + reader.skipValue() + null + } + } + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/json/SkyHanniTypeAdapters.kt b/src/main/java/at/hannibal2/skyhanni/utils/json/SkyHanniTypeAdapters.kt new file mode 100644 index 000000000..dc50eef74 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/json/SkyHanniTypeAdapters.kt @@ -0,0 +1,79 @@ +package at.hannibal2.skyhanni.utils.json + +import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity +import at.hannibal2.skyhanni.features.garden.CropType +import at.hannibal2.skyhanni.features.garden.pests.PestType +import at.hannibal2.skyhanni.utils.LorenzRarity +import at.hannibal2.skyhanni.utils.LorenzVec +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.NEUItems +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark +import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker +import com.google.gson.GsonBuilder +import com.google.gson.TypeAdapter +import com.google.gson.stream.JsonReader +import com.google.gson.stream.JsonWriter +import net.minecraft.item.ItemStack +import java.util.UUID + +object SkyHanniTypeAdapters { + val NEU_ITEMSTACK: TypeAdapter<ItemStack> = SimpleStringTypeAdapter(NEUItems::saveNBTData, NEUItems::loadNBTData) + + val UUID: TypeAdapter<UUID> = SimpleStringTypeAdapter( + { this.toString() }, + { java.util.UUID.fromString(this) } + ) + + val INTERNAL_NAME: TypeAdapter<NEUInternalName> = SimpleStringTypeAdapter( + { this.asString() }, + { this.asInternalName() } + ) + + val VEC_STRING: TypeAdapter<LorenzVec> = SimpleStringTypeAdapter( + { "$x:$y:$z" }, + { LorenzVec.decodeFromString(this) } + ) + + val TROPHY_RARITY: TypeAdapter<TrophyRarity> = SimpleStringTypeAdapter( + { name }, + { TrophyRarity.getByName(this) ?: error("Could not parse TrophyRarity from '$this'") } + ) + + val TIME_MARK: TypeAdapter<SimpleTimeMark> = object : TypeAdapter<SimpleTimeMark>() { + override fun write(out: JsonWriter, value: SimpleTimeMark) { + out.value(value.toMillis()) + } + + override fun read(reader: JsonReader): SimpleTimeMark { + return reader.nextString().toLong().asTimeMark() + } + } + + val CROP_TYPE: TypeAdapter<CropType> = SimpleStringTypeAdapter( + { name }, + { CropType.getByName(this) } + ) + + val PEST_TYPE: TypeAdapter<PestType> = SimpleStringTypeAdapter( + { name }, + { PestType.getByName(this) } + ) + + val TRACKER_DISPLAY_MODE = SimpleStringTypeAdapter.forEnum<SkyHanniTracker.DefaultDisplayMode>() + val ISLAND_TYPE = SimpleStringTypeAdapter.forEnum<IslandType>() + val RARITY = SimpleStringTypeAdapter.forEnum<LorenzRarity>() + + inline fun <reified T> GsonBuilder.registerTypeAdapter( + crossinline write: (JsonWriter, T) -> Unit, + crossinline read: (JsonReader) -> T, + ): GsonBuilder { + this.registerTypeAdapter(T::class.java, object : TypeAdapter<T>() { + override fun write(out: JsonWriter, value: T) = write(out, value) + override fun read(reader: JsonReader) = read(reader) + }.nullSafe()) + return this + } +} |