diff --git a/addons/geary-prefabs/src/jvmMain/kotlin/com/mineinabyss/geary/prefabs/PrefabsDSLExtensions.kt b/addons/geary-prefabs/src/jvmMain/kotlin/com/mineinabyss/geary/prefabs/PrefabsDSLExtensions.kt index 14d6d2b3..7b6ca85f 100644 --- a/addons/geary-prefabs/src/jvmMain/kotlin/com/mineinabyss/geary/prefabs/PrefabsDSLExtensions.kt +++ b/addons/geary-prefabs/src/jvmMain/kotlin/com/mineinabyss/geary/prefabs/PrefabsDSLExtensions.kt @@ -5,6 +5,7 @@ import kotlinx.io.buffered import kotlinx.io.files.Path import java.io.File import java.io.InputStream +import java.util.jar.JarFile import kotlin.io.path.* import kotlin.reflect.KClass @@ -47,20 +48,57 @@ object PrefabsDSLExtensions { fun walkJarResources( classLoader: ClassLoader, directory: String, - ): Sequence { - val directoryPath = File(classLoader.getResource(directory)?.toURI() ?: return emptySequence()).toPath() - return directoryPath.walk().filter { it.isRegularFile() } + ): Sequence = sequence { + val resources = classLoader.getResources(directory) + while (resources.hasMoreElements()) { + val resource = resources.nextElement() + val protocol = resource.protocol + if (protocol == "jar") { + val jarPath = resource.path.substringBefore("!").removePrefix("file:") + val jarFile = JarFile(jarPath) + val entries = jarFile.entries() + while (entries.hasMoreElements()) { + val entry = entries.nextElement() + if (entry.name.startsWith(directory) && !entry.isDirectory) { + yield(JarResource( + nameWithoutExt = entry.name.substringAfterLast("/").substringBeforeLast("."), + ext = entry.name.substringAfterLast("."), + stream = jarFile.getInputStream(entry) + )) + } + } + } else if (protocol == "file") { + val directoryPath = File(classLoader.getResource(directory)?.toURI() ?: return@sequence).toPath() + yieldAll(directoryPath.walk().filter { it.isRegularFile() }.map { + JarResource( + nameWithoutExt = it.nameWithoutExtension, + ext = it.extension, + stream = it.inputStream() + ) + }) + } + } } - fun getResource(classLoader: ClassLoader, path: String): java.nio.file.Path? { - return File(classLoader.getResource(path)?.toURI() ?: return null).toPath() + fun getResource(classLoader: ClassLoader, path: String): JarResource? { + return classLoader.getResourceAsStream(path)?.let { stream -> + JarResource( + nameWithoutExt = path.substringAfterLast("/").substringBeforeLast("."), + ext = path.substringAfterLast("."), + stream = stream + ) + } } - private fun java.nio.file.Path.asPrefabSource(namespace: String) = PrefabSource( - source = inputStream().asSource().buffered(), - key = PrefabKey.of(namespace, nameWithoutExtension), - formatExt = extension + private fun JarResource.asPrefabSource(namespace: String) = PrefabSource( + source = stream.asSource().buffered(), + key = PrefabKey.of(namespace, nameWithoutExt), + formatExt = ext ) - data class NameToStream(val name: String, val stream: InputStream) + data class JarResource( + val nameWithoutExt: String, + val ext: String, + val stream: InputStream, + ) } diff --git a/addons/geary-prefabs/src/jvmTest/kotlin/com/mineinabyss/geary/prefabs/PrefabFromResourcesTest.kt b/addons/geary-prefabs/src/jvmTest/kotlin/com/mineinabyss/geary/prefabs/PrefabFromResourcesTest.kt index eed508a4..fdfe220f 100644 --- a/addons/geary-prefabs/src/jvmTest/kotlin/com/mineinabyss/geary/prefabs/PrefabFromResourcesTest.kt +++ b/addons/geary-prefabs/src/jvmTest/kotlin/com/mineinabyss/geary/prefabs/PrefabFromResourcesTest.kt @@ -2,7 +2,6 @@ package com.mineinabyss.geary.prefabs import com.mineinabyss.geary.modules.TestEngineModule import com.mineinabyss.geary.modules.geary -import com.mineinabyss.geary.prefabs.PrefabsDSLExtensions.fromFiles import com.mineinabyss.geary.prefabs.PrefabsDSLExtensions.fromJarResourceDirectory import com.mineinabyss.geary.prefabs.PrefabsDSLExtensions.fromJarResources import com.mineinabyss.geary.serialization.formats.YamlFormat @@ -48,23 +47,4 @@ class PrefabFromResourcesTest { entityOfOrNull(PrefabKey.of("test:prefabB")) shouldNotBe null } } - - @Test - fun `should load prefabs from path source`() { - val world = world().configure { - namespace("test") { - prefabs { - fromFiles( - PrefabsDSLExtensions.getResource( - PrefabFromResourcesTest::class.java.classLoader, - "prefabs/prefabA.yml" - )!! - ) - } - } - }.start() - with(world) { - entityOfOrNull(PrefabKey.of("test:prefabA")) shouldNotBe null - } - } }