Add command-line tools for headerless compression

These are useful for manipulating the files used by the loader, some of
which are compressed with DEFLATE or headerless gzip.

Signed-off-by: Graham <gpe@openrs2.dev>
Graham 5 years ago
parent 892d21df10
commit c849c5ad46
  1. 1
      all/build.gradle.kts
  2. 2
      all/src/main/java/dev/openrs2/Command.kt
  3. 24
      cli/build.gradle.kts
  4. 40
      cli/src/main/java/dev/openrs2/cli/OptionExtensions.kt
  5. 32
      compress-cli/build.gradle.kts
  6. 29
      compress-cli/src/main/java/dev/openrs2/compress/cli/CompressCommand.kt
  7. 22
      compress-cli/src/main/java/dev/openrs2/compress/cli/bzip2/Bunzip2Command.kt
  8. 22
      compress-cli/src/main/java/dev/openrs2/compress/cli/bzip2/Bzip2Command.kt
  9. 31
      compress-cli/src/main/java/dev/openrs2/compress/cli/deflate/DeflateCommand.kt
  10. 23
      compress-cli/src/main/java/dev/openrs2/compress/cli/deflate/InflateCommand.kt
  11. 22
      compress-cli/src/main/java/dev/openrs2/compress/cli/gzip/GunzipCommand.kt
  12. 31
      compress-cli/src/main/java/dev/openrs2/compress/cli/gzip/GzipCommand.kt
  13. 2
      settings.gradle.kts

@ -16,6 +16,7 @@ application {
dependencies {
implementation(project(":bundler"))
implementation(project(":compress-cli"))
implementation(project(":decompiler"))
implementation(project(":deob"))
implementation(project(":deob-ast"))

@ -3,6 +3,7 @@ package dev.openrs2
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.subcommands
import dev.openrs2.bundler.BundleCommand
import dev.openrs2.compress.cli.CompressCommand
import dev.openrs2.decompiler.DecompileCommand
import dev.openrs2.deob.DeobfuscateCommand
import dev.openrs2.deob.ast.AstDeobfuscateCommand
@ -10,6 +11,7 @@ import dev.openrs2.game.GameCommand
fun main(args: Array<String>) = Command().subcommands(
BundleCommand(),
CompressCommand(),
DecompileCommand(),
DeobfuscateCommand(),
AstDeobfuscateCommand(),

@ -0,0 +1,24 @@
plugins {
`maven-publish`
kotlin("jvm")
}
dependencies {
api("com.github.ajalt:clikt:${Versions.clikt}")
}
publishing {
publications.create<MavenPublication>("maven") {
from(components["java"])
pom {
packaging = "jar"
name.set("OpenRS2 CLI")
description.set(
"""
Clikt extensions.
""".trimIndent()
)
}
}
}

@ -0,0 +1,40 @@
package dev.openrs2.cli
import com.github.ajalt.clikt.parameters.options.NullableOption
import com.github.ajalt.clikt.parameters.options.OptionWithValues
import com.github.ajalt.clikt.parameters.options.RawOption
import com.github.ajalt.clikt.parameters.options.convert
import com.github.ajalt.clikt.parameters.options.default
import java.io.InputStream
import java.io.OutputStream
import java.nio.file.Files
fun RawOption.inputStream(): NullableOption<InputStream, InputStream> {
return convert("FILE") {
return@convert if (it == "-") {
System.`in`
} else {
Files.newInputStream(java.nio.file.Paths.get(it))
}
}
}
fun NullableOption<InputStream, InputStream>.defaultStdin(): OptionWithValues<InputStream, InputStream, InputStream> {
return default(System.`in`, "-")
}
fun RawOption.outputStream(): NullableOption<OutputStream, OutputStream> {
return convert("FILE") {
return@convert if (it == "-") {
System.out
} else {
Files.newOutputStream(java.nio.file.Paths.get(it))
}
}
}
fun NullableOption<OutputStream, OutputStream>.defaultStdout(): OptionWithValues<OutputStream, OutputStream,
OutputStream> {
return default(System.out, "-")
}

@ -0,0 +1,32 @@
plugins {
`maven-publish`
application
kotlin("jvm")
}
application {
mainClassName = "dev.openrs2.compress.cli.CompressCommandKt"
}
dependencies {
api(project(":cli"))
implementation(project(":compress"))
}
publishing {
publications.create<MavenPublication>("maven") {
from(components["java"])
pom {
packaging = "jar"
name.set("OpenRS2 Compression CLI")
description.set(
"""
Tools for compressing and uncompressing headerless bzip2,
DEFLATE and gzip files.
""".trimIndent()
)
}
}
}

@ -0,0 +1,29 @@
package dev.openrs2.compress.cli
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.subcommands
import dev.openrs2.compress.cli.bzip2.Bunzip2Command
import dev.openrs2.compress.cli.bzip2.Bzip2Command
import dev.openrs2.compress.cli.deflate.DeflateCommand
import dev.openrs2.compress.cli.deflate.InflateCommand
import dev.openrs2.compress.cli.gzip.GunzipCommand
import dev.openrs2.compress.cli.gzip.GzipCommand
fun main(args: Array<String>) = CompressCommand().main(args)
class CompressCommand : CliktCommand(name = "compress") {
init {
subcommands(
Bzip2Command(),
Bunzip2Command(),
DeflateCommand(),
InflateCommand(),
GzipCommand(),
GunzipCommand()
)
}
override fun run() {
// empty
}
}

@ -0,0 +1,22 @@
package dev.openrs2.compress.cli.bzip2
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.options.option
import dev.openrs2.cli.defaultStdin
import dev.openrs2.cli.defaultStdout
import dev.openrs2.cli.inputStream
import dev.openrs2.cli.outputStream
import dev.openrs2.compress.bzip2.Bzip2
class Bunzip2Command : CliktCommand(name = "bunzip2") {
private val input by option().inputStream().defaultStdin()
private val output by option().outputStream().defaultStdout()
override fun run() {
Bzip2.createHeaderlessInputStream(input).use { input ->
output.use { output ->
input.copyTo(output)
}
}
}
}

@ -0,0 +1,22 @@
package dev.openrs2.compress.cli.bzip2
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.options.option
import dev.openrs2.cli.defaultStdin
import dev.openrs2.cli.defaultStdout
import dev.openrs2.cli.inputStream
import dev.openrs2.cli.outputStream
import dev.openrs2.compress.bzip2.Bzip2
class Bzip2Command : CliktCommand(name = "bzip2") {
private val input by option().inputStream().defaultStdin()
private val output by option().outputStream().defaultStdout()
override fun run() {
input.use { input ->
Bzip2.createHeaderlessOutputStream(output).use { output ->
input.copyTo(output)
}
}
}
}

@ -0,0 +1,31 @@
package dev.openrs2.compress.cli.deflate
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.validate
import com.github.ajalt.clikt.parameters.types.int
import dev.openrs2.cli.defaultStdin
import dev.openrs2.cli.defaultStdout
import dev.openrs2.cli.inputStream
import dev.openrs2.cli.outputStream
import java.util.zip.Deflater
import java.util.zip.DeflaterOutputStream
class DeflateCommand : CliktCommand(name = "deflate") {
private val input by option().inputStream().defaultStdin()
private val output by option().outputStream().defaultStdout()
private val level by option().int().default(Deflater.BEST_COMPRESSION).validate {
require(it >= Deflater.NO_COMPRESSION && it <= Deflater.BEST_COMPRESSION) {
"--level must be between ${Deflater.NO_COMPRESSION} and ${Deflater.BEST_COMPRESSION} inclusive"
}
}
override fun run() {
input.use { input ->
DeflaterOutputStream(output, Deflater(level, true)).use { output ->
input.copyTo(output)
}
}
}
}

@ -0,0 +1,23 @@
package dev.openrs2.compress.cli.deflate
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.options.option
import dev.openrs2.cli.defaultStdin
import dev.openrs2.cli.defaultStdout
import dev.openrs2.cli.inputStream
import dev.openrs2.cli.outputStream
import java.util.zip.Inflater
import java.util.zip.InflaterInputStream
class InflateCommand : CliktCommand(name = "inflate") {
private val input by option().inputStream().defaultStdin()
private val output by option().outputStream().defaultStdout()
override fun run() {
InflaterInputStream(input, Inflater(true)).use { input ->
output.use { output ->
input.copyTo(output)
}
}
}
}

@ -0,0 +1,22 @@
package dev.openrs2.compress.cli.gzip
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.options.option
import dev.openrs2.cli.defaultStdin
import dev.openrs2.cli.defaultStdout
import dev.openrs2.cli.inputStream
import dev.openrs2.cli.outputStream
import dev.openrs2.compress.gzip.Gzip
class GunzipCommand : CliktCommand(name = "gunzip") {
private val input by option().inputStream().defaultStdin()
private val output by option().outputStream().defaultStdout()
override fun run() {
Gzip.createHeaderlessInputStream(input).use { input ->
output.use { output ->
input.copyTo(output)
}
}
}
}

@ -0,0 +1,31 @@
package dev.openrs2.compress.cli.gzip
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.validate
import com.github.ajalt.clikt.parameters.types.int
import dev.openrs2.cli.defaultStdin
import dev.openrs2.cli.defaultStdout
import dev.openrs2.cli.inputStream
import dev.openrs2.cli.outputStream
import dev.openrs2.compress.gzip.Gzip
import java.util.zip.Deflater
class GzipCommand : CliktCommand(name = "gzip") {
private val input by option().inputStream().defaultStdin()
private val output by option().outputStream().defaultStdout()
private val level by option().int().default(Deflater.BEST_COMPRESSION).validate {
require(it >= Deflater.NO_COMPRESSION && it <= Deflater.BEST_COMPRESSION) {
"--level must be between ${Deflater.NO_COMPRESSION} and ${Deflater.BEST_COMPRESSION} inclusive"
}
}
override fun run() {
input.use { input ->
Gzip.createHeaderlessOutputStream(output, level).use { output ->
input.copyTo(output)
}
}
}
}

@ -6,8 +6,10 @@ include(
"all",
"asm",
"bundler",
"cli",
"common",
"compress",
"compress-cli",
"decompiler",
"deob",
"deob-annotations",

Loading…
Cancel
Save