From 158eb7b63f9fd33481630c04cf47f82d290ec2e5 Mon Sep 17 00:00:00 2001 From: woahscam <elkin.austin@hotmail.com> Date: Fri, 7 May 2021 02:37:36 -0400 Subject: [PATCH 1/3] Update constants to support texture dumper paths --- src/main/kotlin/com/opennxt/Constants.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/kotlin/com/opennxt/Constants.kt b/src/main/kotlin/com/opennxt/Constants.kt index ab9faf9..e14122a 100644 --- a/src/main/kotlin/com/opennxt/Constants.kt +++ b/src/main/kotlin/com/opennxt/Constants.kt @@ -10,4 +10,8 @@ object Constants { val CACHE_PATH = DATA_PATH.resolve("cache") val PROT_PATH = DATA_PATH.resolve("prot") val RESOURCE_PATH = DATA_PATH.resolve("resources") + val TEXTURES_PATH_DXT = DATA_PATH.resolve("textures/dxt") + val TEXTURES_PATH_PNG = DATA_PATH.resolve("textures/png") + val TEXTURES_PATH_MIP = DATA_PATH.resolve("textures/mipmap") + val TEXTURES_PATH_ETC = DATA_PATH.resolve("textures/etc") } \ No newline at end of file From dca4cdecf25552ddb680a6e00ec4ab4a24d53bc8 Mon Sep 17 00:00:00 2001 From: woahscam <elkin.austin@hotmail.com> Date: Fri, 7 May 2021 02:38:33 -0400 Subject: [PATCH 2/3] Added ability to dump textures --- .../opennxt/tools/impl/other/TextureDumper.kt | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/main/kotlin/com/opennxt/tools/impl/other/TextureDumper.kt diff --git a/src/main/kotlin/com/opennxt/tools/impl/other/TextureDumper.kt b/src/main/kotlin/com/opennxt/tools/impl/other/TextureDumper.kt new file mode 100644 index 0000000..77fb328 --- /dev/null +++ b/src/main/kotlin/com/opennxt/tools/impl/other/TextureDumper.kt @@ -0,0 +1,127 @@ +package com.opennxt.tools.impl.other + +import com.github.ajalt.clikt.parameters.options.default +import com.github.ajalt.clikt.parameters.options.option +import com.github.ajalt.clikt.parameters.types.choice +import com.github.ajalt.clikt.parameters.types.int +import com.opennxt.Constants +import com.opennxt.filesystem.Container +import com.opennxt.tools.Tool +import io.netty.buffer.Unpooled +import java.io.ByteArrayInputStream +import java.io.File +import javax.imageio.ImageIO +import kotlin.system.exitProcess + + +class TextureDumper : Tool(name = "texture-dump", help = "This tool dumps textures from a user selected index.") { + private val idx: Int by option(help = "The index to dump from (default = -1 | all)").choice("dxt" to 52, "png" to 53, "mip" to 54, "etc" to 55, "all" to -1).default(-1) + private val textureId: Int by option("--tex", help = "The texture to dump (default = -1 | all)").int().default(-1) + override fun runTool() { + verifyTextureDirectories() + + when { + (idx == -1 && textureId == -1) -> { + + for (texIndex in 52..55) { + val table = filesystem.getReferenceTable(texIndex)!! + table.archives.forEach { + decodeTexture(texIndex, it.value.id) + } + } + } + + (idx != -1 && textureId == -1) -> { + + val table = filesystem.getReferenceTable(idx)!! + table.archives.forEach { + decodeTexture(idx, it.value.id) + } + } + + (idx == -1 && textureId != -1) -> { + + val texture = textureId + for (texIndex in 52..55) { + decodeTexture(texIndex, texture) + } + } + + (idx != -1 && textureId != -1) -> { + + val texture = textureId + decodeTexture(idx, texture) + } + + else -> { + logger.error { "Invalid option found! | Index: $idx | Texture: $textureId" } + exitProcess(901) + } + } + } + + private fun decodeTexture(index: Int, textureId: Int) { + if (!filesystem.exists(index, textureId)) { + logger.error { "No texture found! | Index: $index - Texture: $textureId | " + + "RANGE: ${filesystem.getReferenceTable(index)?.archives?.firstKey()} - " + + "${filesystem.getReferenceTable(index)?.archives?.lastKey()}" } + exitProcess(902) + } + + val data = Unpooled.wrappedBuffer(Container.decode(filesystem.read(index, textureId)!!).data) + var raw = ByteArray(data.readableBytes()) + + if (index == 54 || index == 55) { + data.skipBytes(1) + } else { + data.skipBytes(5) + raw = ByteArray(data.readableBytes()) + data.readBytes(raw) + } + + when (index) { + 52 -> { + File("${Constants.TEXTURES_PATH_DXT}/${textureId}.dds").writeBytes(raw) + } + 53 -> { + val image = ImageIO.read(ByteArrayInputStream(raw)) + ImageIO.write(image, "png", File("${Constants.TEXTURES_PATH_PNG}/${textureId}.png")) + } + 54 -> { + for (level in 0 until data.readUnsignedByte().toInt()) { + val size = data.readInt() + raw = ByteArray(size) + data.readBytes(raw) + + val image = ImageIO.read(ByteArrayInputStream(raw)) + val file = File("${Constants.TEXTURES_PATH_MIP}/${textureId}/${image.width}x${image.height}.png").also { + it.parentFile.mkdirs() + } + ImageIO.write(image, "png", file) + } + } + 55 -> { + val size = data.readInt() + raw = ByteArray(size) + data.readBytes(raw) + File("${Constants.TEXTURES_PATH_ETC}/${textureId}.ktx").writeBytes(raw) + } + else -> { + logger.error { "Invalid index found! | Index: $index | Texture: $textureId" } + exitProcess(903) + } + } + } + + private fun verifyTextureDirectories() { + try { + File("${Constants.TEXTURES_PATH_DXT}").mkdirs() + File("${Constants.TEXTURES_PATH_PNG}").mkdirs() + File("${Constants.TEXTURES_PATH_MIP}").mkdirs() + File("${Constants.TEXTURES_PATH_ETC}").mkdirs() + } catch (e: SecurityException) { + logger.error { "Unable to create required directories!" } + exitProcess(900) + } + } +} \ No newline at end of file From 84b1cf53bce4955ebd72c77fc7a2700703b876ad Mon Sep 17 00:00:00 2001 From: woahscam <woahscam@hotmail.com> Date: Fri, 7 May 2021 11:07:11 -0400 Subject: [PATCH 3/3] Minor compliance correction --- .../com/opennxt/tools/impl/other/TextureDumper.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/opennxt/tools/impl/other/TextureDumper.kt b/src/main/kotlin/com/opennxt/tools/impl/other/TextureDumper.kt index 77fb328..cffdf5e 100644 --- a/src/main/kotlin/com/opennxt/tools/impl/other/TextureDumper.kt +++ b/src/main/kotlin/com/opennxt/tools/impl/other/TextureDumper.kt @@ -55,7 +55,7 @@ class TextureDumper : Tool(name = "texture-dump", help = "This tool dumps textur else -> { logger.error { "Invalid option found! | Index: $idx | Texture: $textureId" } - exitProcess(901) + exitProcess(1) } } } @@ -65,7 +65,7 @@ class TextureDumper : Tool(name = "texture-dump", help = "This tool dumps textur logger.error { "No texture found! | Index: $index - Texture: $textureId | " + "RANGE: ${filesystem.getReferenceTable(index)?.archives?.firstKey()} - " + "${filesystem.getReferenceTable(index)?.archives?.lastKey()}" } - exitProcess(902) + exitProcess(1) } val data = Unpooled.wrappedBuffer(Container.decode(filesystem.read(index, textureId)!!).data) @@ -108,7 +108,7 @@ class TextureDumper : Tool(name = "texture-dump", help = "This tool dumps textur } else -> { logger.error { "Invalid index found! | Index: $index | Texture: $textureId" } - exitProcess(903) + exitProcess(1) } } } @@ -121,7 +121,7 @@ class TextureDumper : Tool(name = "texture-dump", help = "This tool dumps textur File("${Constants.TEXTURES_PATH_ETC}").mkdirs() } catch (e: SecurityException) { logger.error { "Unable to create required directories!" } - exitProcess(900) + exitProcess(1) } } -} \ No newline at end of file +}