From 8680abd105df41539a1d194b080eec50534577f3 Mon Sep 17 00:00:00 2001 From: Seggan Date: Wed, 11 Feb 2026 09:59:31 -0500 Subject: [PATCH 1/4] Add context file to config error --- .../io/github/pylonmc/rebar/config/Config.kt | 12 ++++++++ .../pylonmc/rebar/config/ConfigSection.kt | 30 ++++++++++++------- .../github/pylonmc/rebar/fluid/RebarFluid.kt | 2 +- .../io/github/pylonmc/rebar/item/RebarItem.kt | 2 +- rebar/src/main/resources/config.yml | 1 - 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/Config.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/Config.kt index c2b40f78b..073a54325 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/Config.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/Config.kt @@ -27,4 +27,16 @@ class Config( fun save() { internalConfig.save(file) } + + override fun modifyException(exception: Exception): Exception = when (exception) { + is KeyNotFoundException -> KeyNotFoundException( + exception.key, + "Key '${exception.key}' not found in config file ${file.absolutePath}" + ) + + else -> RuntimeException( + "An error occurred while reading config file ${file.absolutePath} (CHECK THE SUB-EXCEPTION BEFORE REPORTING)", + exception + ) + } } \ No newline at end of file diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/ConfigSection.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/ConfigSection.kt index 294482643..b5c20af9d 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/ConfigSection.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/ConfigSection.kt @@ -49,7 +49,7 @@ open class ConfigSection(val internalSection: ConfigurationSection) { } fun getSectionOrThrow(key: String): ConfigSection = - getSection(key) ?: throw KeyNotFoundException(internalSection.currentPath, key) + getSection(key) ?: throw modifyException(KeyNotFoundException(getKeyPath(key))) /** * Returns null if the key does not exist or if the value cannot be converted to the desired type. @@ -70,13 +70,15 @@ open class ConfigSection(val internalSection: ConfigurationSection) { */ fun getOrThrow(key: String, adapter: ConfigAdapter): T { val value = cache.getOrPut(key) { - val value = internalSection.get(key) ?: throw KeyNotFoundException(internalSection.currentPath, key) + val value = internalSection.get(key) ?: throw modifyException(KeyNotFoundException(getKeyPath(key))) try { adapter.convert(value) } catch (e: Exception) { - throw IllegalArgumentException( - "Failed to convert value '$value' to type ${adapter.type} for key '$key' in section '${internalSection.currentPath}'", - e + throw modifyException( + IllegalArgumentException( + "Failed to convert value '$value' to type ${adapter.type} for key '${getKeyPath(key)}'", + e + ) ) } } @@ -84,7 +86,7 @@ open class ConfigSection(val internalSection: ConfigurationSection) { fun getClass(type: Type): Class<*> = when (type) { is Class<*> -> type is ParameterizedType -> getClass(type.rawType) - else -> throw IllegalArgumentException("Unsupported type: $type") + else -> throw modifyException(IllegalArgumentException("Unsupported type: $type")) } @Suppress("UNCHECKED_CAST") @@ -97,8 +99,8 @@ open class ConfigSection(val internalSection: ConfigurationSection) { cache.remove(key) } - fun createSection(key: String): ConfigSection - = ConfigSection(internalSection.createSection(key)).also { sectionCache[key] = it } + fun createSection(key: String): ConfigSection = + ConfigSection(internalSection.createSection(key)).also { sectionCache[key] = it } /** * 'Merges' [other] with this ConfigSection by copying all of its keys into this ConfigSection. @@ -120,9 +122,17 @@ open class ConfigSection(val internalSection: ConfigurationSection) { } } + private fun getKeyPath(key: String): String = + if (internalSection.currentPath.isNullOrEmpty()) key else "${internalSection.currentPath}.$key" + + /** + * This exists so that [Config] can add more context to exceptions thrown by this class without having to override every method. + * The default implementation is just `throw exception`. + */ + protected open fun modifyException(exception: Exception): Exception = exception + /** * Thrown when a key is not found. */ - class KeyNotFoundException(path: String?, key: String) : - Exception(if (!path.isNullOrEmpty()) "Config key not found: $path.$key" else "Config key not found: $key") + class KeyNotFoundException(val key: String, message: String = "Config key not found: $key") : RuntimeException(message) } \ No newline at end of file diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/fluid/RebarFluid.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/fluid/RebarFluid.kt index b43309eff..561117093 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/fluid/RebarFluid.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/fluid/RebarFluid.kt @@ -60,7 +60,7 @@ open class RebarFluid( for (locale in addon.languages) { val translationKey = "${key.namespace}.fluid.${key.key}" if (!addon.translator.canTranslate(translationKey, locale)) { - Rebar.logger.warning("${key.namespace} is missing a translation key for fluid ${key.key} (locale: ${locale.displayName} | expected translation key: $translationKey") + Rebar.logger.warning("${key.namespace} is missing a translation key for fluid ${key.key} (locale: ${locale.displayName} | expected translation key: $translationKey)") } } } diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/item/RebarItem.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/item/RebarItem.kt index 4452a488a..2b6689a60 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/item/RebarItem.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/item/RebarItem.kt @@ -95,7 +95,7 @@ open class RebarItem(val stack: ItemStack) : Keyed { ItemStackBuilder.nameKey( schema.key ) - }" + })" ) } } diff --git a/rebar/src/main/resources/config.yml b/rebar/src/main/resources/config.yml index 7a0bde628..d04cf42df 100644 --- a/rebar/src/main/resources/config.yml +++ b/rebar/src/main/resources/config.yml @@ -173,7 +173,6 @@ custom-block-textures: presets: # No culling, all entities are sent to the client, do NOT remove this preset disabled: - index: 0 id: "disabled" material: "minecraft:gray_concrete" update-interval: 10 From b6589aa3719b07af9821fc0d1b44110e20439aed Mon Sep 17 00:00:00 2001 From: Seggan Date: Wed, 11 Feb 2026 10:39:00 -0500 Subject: [PATCH 2/4] Improve adapter error messages --- .../pylonmc/rebar/config/ConfigSection.kt | 4 ++ .../rebar/config/adapter/ConfigAdapter.kt | 1 + .../adapter/ConfigSectionConfigAdapter.kt | 23 +++++++++ .../adapter/CullingPresetConfigAdapter.kt | 20 ++++---- .../adapter/RandomizedSoundConfigAdapter.kt | 47 +++++++++---------- .../config/adapter/SoundConfigAdapter.kt | 13 +++-- .../adapter/WailaDisplayConfigAdapter.kt | 13 ++--- .../adapter/WeightedSetConfigAdapter.kt | 6 +-- rebar/src/main/resources/config.yml | 1 + 9 files changed, 77 insertions(+), 51 deletions(-) create mode 100644 rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/ConfigSectionConfigAdapter.kt diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/ConfigSection.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/ConfigSection.kt index b5c20af9d..6ca113c9d 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/ConfigSection.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/ConfigSection.kt @@ -73,6 +73,10 @@ open class ConfigSection(val internalSection: ConfigurationSection) { val value = internalSection.get(key) ?: throw modifyException(KeyNotFoundException(getKeyPath(key))) try { adapter.convert(value) + } catch (e: KeyNotFoundException) { + val exception = modifyException(KeyNotFoundException("$key.${e.key.removePrefix("$key.")}")) + exception.stackTrace = e.stackTrace + throw exception } catch (e: Exception) { throw modifyException( IllegalArgumentException( diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/ConfigAdapter.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/ConfigAdapter.kt index 7c57f66ac..264c4c3f3 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/ConfigAdapter.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/ConfigAdapter.kt @@ -96,6 +96,7 @@ interface ConfigAdapter { @JvmField val WEIGHTED_SET = WeightedSetConfigAdapter @JvmField val CULLING_PRESET = CullingPresetConfigAdapter @JvmField val WAILA_DISPLAY = WailaDisplayConfigAdapter + @JvmField val CONFIG_SECTION = ConfigSectionConfigAdapter // @formatter:on } } diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/ConfigSectionConfigAdapter.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/ConfigSectionConfigAdapter.kt new file mode 100644 index 000000000..c9356ee47 --- /dev/null +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/ConfigSectionConfigAdapter.kt @@ -0,0 +1,23 @@ +package io.github.pylonmc.rebar.config.adapter + +import io.github.pylonmc.rebar.config.ConfigSection +import org.bukkit.configuration.ConfigurationSection +import org.bukkit.configuration.MemoryConfiguration + +object ConfigSectionConfigAdapter : ConfigAdapter { + + override val type = ConfigSection::class.java + + override fun convert(value: Any): ConfigSection { + val section = if (value is ConfigurationSection) { + value + } else { + val memoryConfig = MemoryConfiguration() + for ((key, value) in MapConfigAdapter.STRING_TO_ANY.convert(value)) { + memoryConfig.set(key, value) + } + memoryConfig + } + return ConfigSection(section) + } +} \ No newline at end of file diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/CullingPresetConfigAdapter.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/CullingPresetConfigAdapter.kt index f58489ff3..6599821e6 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/CullingPresetConfigAdapter.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/CullingPresetConfigAdapter.kt @@ -7,17 +7,17 @@ object CullingPresetConfigAdapter : ConfigAdapter { override val type: Type = CullingPreset::class.java override fun convert(value: Any): CullingPreset { - val map = MapConfigAdapter.STRING_TO_ANY.convert(value) + val section = ConfigAdapter.CONFIG_SECTION.convert(value) return CullingPreset( - index = ConfigAdapter.INT.convert(map["index"] ?: throw IllegalArgumentException("Culling preset is missing 'index' field")), - id = ConfigAdapter.STRING.convert(map["id"] ?: throw IllegalArgumentException("Culling preset is missing 'id' field")), - material = ConfigAdapter.MATERIAL.convert(map["material"] ?: throw IllegalArgumentException("Culling preset is missing 'material' field")), - updateInterval = ConfigAdapter.INT.convert(map["update-interval"] ?: throw IllegalArgumentException("Culling preset is missing 'update-interval' field")), - hiddenInterval = map["hidden-interval"]?.let { ConfigAdapter.INT.convert(it) } ?: 1, - visibleInterval = map["visible-interval"]?.let { ConfigAdapter.INT.convert(it) } ?: 20, - alwaysShowRadius = map["always-show-radius"]?.let { ConfigAdapter.INT.convert(it) } ?: 16, - cullRadius = map["cull-radius"]?.let { ConfigAdapter.INT.convert(it) } ?: 64, - maxOccludingCount = map["max-occluding-count"]?.let { ConfigAdapter.INT.convert(it) } ?: 3 + index = section.getOrThrow("index", ConfigAdapter.INT), + id = section.getOrThrow("id", ConfigAdapter.STRING), + material = section.getOrThrow("material", ConfigAdapter.MATERIAL), + updateInterval = section.getOrThrow("update-interval", ConfigAdapter.INT), + hiddenInterval = section.get("hidden-interval", ConfigAdapter.INT, 1), + visibleInterval = section.get("visible-interval", ConfigAdapter.INT, 20), + alwaysShowRadius = section.get("always-show-radius", ConfigAdapter.INT, 16), + cullRadius = section.get("cull-radius", ConfigAdapter.INT, 64), + maxOccludingCount = section.get("max-occluding-count", ConfigAdapter.INT, 3) ) } } \ No newline at end of file diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/RandomizedSoundConfigAdapter.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/RandomizedSoundConfigAdapter.kt index ddc8eaec4..13207a095 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/RandomizedSoundConfigAdapter.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/RandomizedSoundConfigAdapter.kt @@ -1,5 +1,6 @@ package io.github.pylonmc.rebar.config.adapter +import io.github.pylonmc.rebar.config.ConfigSection import io.github.pylonmc.rebar.util.RandomizedSound import net.kyori.adventure.key.Key import net.kyori.adventure.sound.Sound @@ -10,40 +11,36 @@ object RandomizedSoundConfigAdapter : ConfigAdapter { override val type: Type = RandomizedSound::class.java override fun convert(value: Any): RandomizedSound { - val map = MapConfigAdapter.STRING_TO_ANY.convert(value) + val section = ConfigAdapter.CONFIG_SECTION.convert(value) val keys = mutableListOf() - if (map.containsKey("sound")) { - keys.add(Key.key(map["sound"]!! as String)) - } else if (map.containsKey("sounds")) { - for (element in map["sounds"] as List<*>) { - keys.add(Key.key(element as String) ) - } - } else { - throw IllegalArgumentException("No 'sound' or 'sounds' field found in section: $value") + section.get("sound", ConfigAdapter.NAMESPACED_KEY)?.let(keys::add) + section.get("sounds", ConfigAdapter.LIST.from(ConfigAdapter.NAMESPACED_KEY))?.let(keys::addAll) + + if (keys.isEmpty()) { + section.get("sound", ConfigAdapter.STRING) // will report the error + throw AssertionError() } return RandomizedSound( keys, - ConfigAdapter.ENUM.from().convert(map["source"] ?: throw IllegalArgumentException("Sound is missing 'source' field")), - getRange(map, "volume"), - getRange(map, "pitch") + section.getOrThrow("source", ConfigAdapter.ENUM.from()), + getRange(section, "volume"), + getRange(section, "pitch") ) } - private fun getRange(section: Map, key: String): Pair { - val range = section[key] ?: throw IllegalArgumentException("Sound is missing '$key' field") - if (range is ConfigurationSection || range is Map<*, *>) { - val range = MapConfigAdapter.STRING_TO_ANY.convert(range) - return Pair( - ConfigAdapter.DOUBLE.convert(range["min"] ?: throw IllegalArgumentException("Sound is missing '$key.min' field")), - ConfigAdapter.DOUBLE.convert(range["max"] ?: throw IllegalArgumentException("Sound is missing '$key.max' field")) - ) - } else if (range is List<*>) { - return Pair(ConfigAdapter.DOUBLE.convert(range[0]!!), ConfigAdapter.DOUBLE.convert(range[1]!!)) - } else { - try { + private fun getRange(section: ConfigSection, key: String): Pair { + return when (val range = section.getOrThrow(key, ConfigAdapter.ANY)) { + is ConfigurationSection, is Map<*, *> -> { + val range = ConfigAdapter.CONFIG_SECTION.convert(range) + range.getOrThrow("min", ConfigAdapter.DOUBLE) to range.getOrThrow("max", ConfigAdapter.DOUBLE) + } + + is List<*> -> ConfigAdapter.DOUBLE.convert(range[0]!!) to ConfigAdapter.DOUBLE.convert(range[1]!!) + + else -> try { val value = range.toString().toDouble() - return Pair(value, value) + Pair(value, value) } catch (_: Throwable) { throw IllegalArgumentException("Sound '$key' field is not a valid number or range: $range") } diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/SoundConfigAdapter.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/SoundConfigAdapter.kt index f9444abc9..3c22f5278 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/SoundConfigAdapter.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/SoundConfigAdapter.kt @@ -1,19 +1,18 @@ package io.github.pylonmc.rebar.config.adapter -import net.kyori.adventure.key.Key -import net.kyori.adventure.sound.Sound +import net.kyori.adventure.sound.Sound import java.lang.reflect.Type object SoundConfigAdapter : ConfigAdapter { override val type: Type = Sound::class.java override fun convert(value: Any): Sound { - val map = MapConfigAdapter.STRING_TO_ANY.convert(value) + val section = ConfigAdapter.CONFIG_SECTION.convert(value) return Sound.sound( - Key.key(map["name"] as String), - ConfigAdapter.ENUM.from().convert(map["source"] ?: throw IllegalArgumentException("Sound is missing 'source' field")), - ConfigAdapter.FLOAT.convert(map["volume"] ?: throw IllegalArgumentException("Sound is missing 'volume' field")), - ConfigAdapter.FLOAT.convert(map["pitch"] ?: throw IllegalArgumentException("Sound is missing 'pitch' field")) + section.getOrThrow("name", ConfigAdapter.NAMESPACED_KEY), + section.getOrThrow("source", ConfigAdapter.ENUM.from()), + section.getOrThrow("volume", ConfigAdapter.FLOAT), + section.getOrThrow("pitch", ConfigAdapter.FLOAT) ) } } \ No newline at end of file diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WailaDisplayConfigAdapter.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WailaDisplayConfigAdapter.kt index 926557ace..b842f8ca4 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WailaDisplayConfigAdapter.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WailaDisplayConfigAdapter.kt @@ -8,11 +8,12 @@ object WailaDisplayConfigAdapter : ConfigAdapter { override val type = WailaDisplay::class.java override fun convert(value: Any): WailaDisplay { - val map = MapConfigAdapter.STRING_TO_ANY.convert(value) - val text = Component.translatable(ConfigAdapter.STRING.convert(map["text"] ?: throw IllegalArgumentException("WailaDisplay is missing 'text' field"))) - val color = ConfigAdapter.ENUM.from().convert(map["color"] ?: throw IllegalArgumentException("WailaDisplay is missing 'color' field")) - val overlay = ConfigAdapter.ENUM.from().convert(map["overlay"] ?: throw IllegalArgumentException("WailaDisplay is missing 'overlay' field")) - val progress = ConfigAdapter.FLOAT.convert(map["progress"] ?: throw IllegalArgumentException("WailaDisplay is missing 'progress' field")) - return WailaDisplay(text, color, overlay, progress) + val section = ConfigAdapter.CONFIG_SECTION.convert(value) + return WailaDisplay( + text = Component.translatable(section.getOrThrow("text", ConfigAdapter.STRING)), + color = section.getOrThrow("color", ConfigAdapter.ENUM.from()), + overlay = section.getOrThrow("overlay", ConfigAdapter.ENUM.from()), + progress = section.getOrThrow("progress", ConfigAdapter.FLOAT) + ) } } \ No newline at end of file diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WeightedSetConfigAdapter.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WeightedSetConfigAdapter.kt index d8026811a..e065a3dce 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WeightedSetConfigAdapter.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WeightedSetConfigAdapter.kt @@ -11,9 +11,9 @@ class WeightedSetConfigAdapter(private val elementAdapter: ConfigAdapter) override fun convert(value: Any): WeightedSet { return if (value is List<*>) { value.mapTo(WeightedSet()) { - val map = MapConfigAdapter.STRING_TO_ANY.convert(it!!) - val element = elementAdapter.convert(map["value"] ?: throw IllegalArgumentException("Missing 'value' key in weighted set element")) - val weight = ConfigAdapter.FLOAT.convert(map["weight"] ?: 1f) + val section = ConfigAdapter.CONFIG_SECTION.convert(value) + val element = section.getOrThrow("value", elementAdapter) + val weight = section.get("weight", ConfigAdapter.FLOAT, 1f) WeightedSet.Element(element, weight) } } else { diff --git a/rebar/src/main/resources/config.yml b/rebar/src/main/resources/config.yml index d04cf42df..7a0bde628 100644 --- a/rebar/src/main/resources/config.yml +++ b/rebar/src/main/resources/config.yml @@ -173,6 +173,7 @@ custom-block-textures: presets: # No culling, all entities are sent to the client, do NOT remove this preset disabled: + index: 0 id: "disabled" material: "minecraft:gray_concrete" update-interval: 10 From 98307a1fb5daec61c0a88dc1c0686580b88801ac Mon Sep 17 00:00:00 2001 From: Seggan Date: Wed, 11 Feb 2026 10:43:17 -0500 Subject: [PATCH 3/4] Improve message --- .../src/main/kotlin/io/github/pylonmc/rebar/addon/RebarAddon.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/addon/RebarAddon.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/addon/RebarAddon.kt index b74955762..05aad638d 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/addon/RebarAddon.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/addon/RebarAddon.kt @@ -66,7 +66,7 @@ interface RebarAddon : Keyed { @ApiStatus.NonExtendable fun registerWithRebar() { if (!Bukkit.getPluginManager().isPluginEnabled("Rebar")) { - throw IllegalStateException("Rebar is not installed or not enabled") + throw IllegalStateException("Rebar is not installed or not enabled (if Rebar is installed, has it errored?)") } RebarRegistry.ADDONS.register(this) From 0179cf88b5ffef9bbed590de153c184c81563c9c Mon Sep 17 00:00:00 2001 From: Seggan Date: Wed, 11 Feb 2026 10:55:10 -0500 Subject: [PATCH 4/4] Woops --- .../pylonmc/rebar/config/adapter/WeightedSetConfigAdapter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WeightedSetConfigAdapter.kt b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WeightedSetConfigAdapter.kt index e065a3dce..360af742b 100644 --- a/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WeightedSetConfigAdapter.kt +++ b/rebar/src/main/kotlin/io/github/pylonmc/rebar/config/adapter/WeightedSetConfigAdapter.kt @@ -11,7 +11,7 @@ class WeightedSetConfigAdapter(private val elementAdapter: ConfigAdapter) override fun convert(value: Any): WeightedSet { return if (value is List<*>) { value.mapTo(WeightedSet()) { - val section = ConfigAdapter.CONFIG_SECTION.convert(value) + val section = ConfigAdapter.CONFIG_SECTION.convert(it!!) val element = section.getOrThrow("value", elementAdapter) val weight = section.get("weight", ConfigAdapter.FLOAT, 1f) WeightedSet.Element(element, weight)