|
21 | 21 |
|
22 | 22 | package icu.h2l.api.util |
23 | 23 |
|
| 24 | +import icu.h2l.api.log.warn |
24 | 25 | import org.spongepowered.configurate.CommentedConfigurationNode |
25 | 26 | import org.spongepowered.configurate.ConfigurationNode |
26 | 27 | import org.spongepowered.configurate.ConfigurationOptions |
@@ -63,6 +64,29 @@ object ConfigLoader { |
63 | 64 |
|
64 | 65 | val loaded = runCatching { targetNode.get(T::class.java) }.getOrNull() ?: defaultProvider() |
65 | 66 |
|
| 67 | + // Detect schema mismatch: compare actual file keys with expected keys from a freshly serialised default instance |
| 68 | + if (!targetNode.virtual() && targetNode.isMap) { |
| 69 | + runCatching { |
| 70 | + val tempNode = loader.createNode() |
| 71 | + tempNode.set(T::class.java, loaded) |
| 72 | + val expectedKeys = tempNode.childrenMap().keys.map { it.toString() }.toSet() |
| 73 | + val actualKeys = targetNode.childrenMap().keys.map { it.toString() }.toSet() |
| 74 | + val extraKeys = actualKeys - expectedKeys |
| 75 | + val missingKeys = expectedKeys - actualKeys |
| 76 | + if (extraKeys.isNotEmpty() || missingKeys.isNotEmpty()) { |
| 77 | + warn { |
| 78 | + buildString { |
| 79 | + append("[ConfigLoader] Schema mismatch detected in \"$fileName\"") |
| 80 | + if (nodePath.isNotEmpty()) append(" (node: ${nodePath.joinToString(".")})") |
| 81 | + append(". It is recommended to delete the file and let it regenerate.") |
| 82 | + if (extraKeys.isNotEmpty()) append(" Extra keys (no longer used): $extraKeys.") |
| 83 | + if (missingKeys.isNotEmpty()) append(" Missing keys (new defaults will be used): $missingKeys.") |
| 84 | + } |
| 85 | + } |
| 86 | + } |
| 87 | + } |
| 88 | + } |
| 89 | + |
66 | 90 | val finalConfig = postLoadHook?.invoke(targetNode, loaded, firstCreation) ?: loaded |
67 | 91 | val shouldSave = forceSaveHook(targetNode, firstCreation) |
68 | 92 |
|
|
0 commit comments