@@ -24,15 +24,18 @@ import io.leangen.geantyref.TypeToken
2424import net.kyori.adventure.text.Component
2525import java.io.File
2626import java.lang.reflect.Type
27- import java.net.JarURLConnection
27+ import java.net.URLConnection
2828import java.net.URLDecoder
2929import java.nio.file.Files
3030import java.nio.file.Path
3131import java.util.*
3232import java.util.concurrent.TimeUnit
3333import java.util.jar.JarFile
3434import java.util.zip.ZipException
35+ import kotlin.io.bufferedReader
36+ import kotlin.io.copyTo
3537import kotlin.io.path.*
38+ import kotlin.jvm.java
3639import kotlin.jvm.optionals.getOrNull
3740
3841object ConfigLoader {
@@ -94,15 +97,33 @@ object ConfigLoader {
9497 if (dataClass.isInstance(EmptyConfiguration )) {
9598 return configClass.getConstructor(Map ::class .java).newInstance(emptyMap<String , D >())
9699 }
97- if (MultiLocaleConfiguration ::class .java.isAssignableFrom(configClass) && path.notExists()) {
98- EsuConfig .get().localeSoftLinkPath.getOrNull()?.let { linkTo ->
99- val relativize = EsuCore .instance.baseConfigPath().relativize(path)
100- val source = linkTo.resolve(relativize)
101- if (! source.isDirectory()) {
102- source.createDirectories()
100+ if (MultiLocaleConfiguration ::class .java.isAssignableFrom(configClass)) {
101+ if (path.notExists()) {
102+ EsuConfig .get().localeSoftLinkPath.getOrNull()?.let { linkTo ->
103+ val relativize = EsuCore .instance.baseConfigPath().relativize(path)
104+ val source = linkTo.resolve(relativize)
105+ if (! source.isDirectory()) {
106+ source.createDirectories()
107+ }
108+ Files .createSymbolicLink(path, source)
109+ EsuCore .instance.info(" Created symbolic link: [$path ] -> [$source ]" )
110+ } ? : path.createDirectories()
111+ }
112+ if (settings.findResource) {
113+ val p = settings.basePath.relativize(path)
114+ val lang = getLangCache(dataClass.classLoader, p.pathString)
115+ for (resource in lang) {
116+ val resolve = path.resolve(resource.name)
117+ if (resolve.notExists()) {
118+ resource.save(dataClass, resolve)
119+ } else {
120+ val loader = createBuilder(null ).let (settings.yamlLoader).path(path).build()
121+ val config = loader.load()
122+ val read = resource.readConfig(dataClass, settings)
123+ config.mergeFrom(read)
124+ loader.save(config)
125+ }
103126 }
104- Files .createSymbolicLink(path, source)
105- EsuCore .instance.info(" Created symbolic link: [$path ] -> [$source ]" )
106127 }
107128 }
108129 return configClass.getConstructor(Map ::class .java).newInstance(
@@ -162,15 +183,9 @@ object ConfigLoader {
162183 val locale = if (EsuConfig .initialized) EsuConfig .get().locale else Locale .getDefault().language + ' _' + Locale .getDefault().country.lowercase()
163184 val resource = lang.find { it.nameWithoutExtension == locale }
164185 ? : lang.firstOrNull { it.nameWithoutExtension.substringBefore(' _' ) == locale.substringBefore(' _' ) }
165- resource?.let {
166- val conn = clazz.classLoader.getResource(it.resourcePath)!! .openConnection() as JarURLConnection
167- conn.useCaches = false
168- conn.connect()
169- val reader = conn.getInputStream().bufferedReader()
170- createBuilder(null ).source { reader }.let (settings.yamlLoader).build().load()
171- }
186+ resource?.readConfig(clazz, settings)
172187 } else null
173- val loader = createBuilder(resourceNode).path(path). let (settings.yamlLoader).build()
188+ val loader = createBuilder(resourceNode).let (settings.yamlLoader).path(path ).build()
174189 val node = settings.nodeMapper(loader.load())
175190 val t = settings.modifier.invoke(node.require(clazz), path)
176191 node.set(clazz, t)
@@ -379,8 +394,36 @@ object ConfigLoader {
379394 val name : String ,
380395 path : String ,
381396 ) {
382- val nameWithoutExtension = name.substringBeforeLast (' .' )
397+ val nameWithoutExtension = name.substringBefore (' .' )
383398 val resourcePath = " lang/$path$name "
399+
400+ fun save (clazz : Class <* >, path : Path ) {
401+ save(clazz.classLoader, path)
402+ }
403+
404+ fun save (classLoader : ClassLoader , path : Path ) {
405+ getConnection(classLoader).getInputStream().use { input ->
406+ path.outputStream().use { output ->
407+ input.copyTo(output)
408+ }
409+ }
410+ }
411+
412+ fun readConfig (clazz : Class <* >, settings : LoaderSettings <* >): ConfigurationNode {
413+ return readConfig(clazz.classLoader, createBuilder(null ).let (settings.yamlLoader))
414+ }
415+
416+ fun readConfig (classLoader : ClassLoader , yamlBuilder : YamlConfigurationLoader .Builder ): ConfigurationNode {
417+ val reader = getConnection(classLoader).getInputStream().bufferedReader()
418+ return yamlBuilder.source { reader }.build().load()
419+ }
420+
421+ private fun getConnection (classLoader : ClassLoader ): URLConnection {
422+ val conn = classLoader.getResource(resourcePath)!! .openConnection()
423+ conn.useCaches = false
424+ conn.connect()
425+ return conn
426+ }
384427 }
385428
386429 open class LoaderSettings <T >(
0 commit comments