diff --git a/archive/src/main/kotlin/org/openrs2/archive/web/CachesController.kt b/archive/src/main/kotlin/org/openrs2/archive/web/CachesController.kt index 33a0c05834..39bf334a97 100644 --- a/archive/src/main/kotlin/org/openrs2/archive/web/CachesController.kt +++ b/archive/src/main/kotlin/org/openrs2/archive/web/CachesController.kt @@ -12,6 +12,7 @@ import io.ktor.thymeleaf.ThymeleafContent import io.netty.buffer.ByteBufAllocator import org.openrs2.archive.cache.CacheExporter import org.openrs2.cache.DiskStoreZipWriter +import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream import javax.inject.Inject import javax.inject.Singleton @@ -63,7 +64,7 @@ public class CachesController @Inject constructor( } } - public suspend fun exportKeys(call: ApplicationCall) { + public suspend fun exportKeysJson(call: ApplicationCall) { val id = call.parameters["id"]?.toIntOrNull() if (id == null) { call.respond(HttpStatusCode.NotFound) @@ -72,4 +73,47 @@ public class CachesController @Inject constructor( call.respond(exporter.exportKeys(id)) } + + public suspend fun exportKeysZip(call: ApplicationCall) { + val id = call.parameters["id"]?.toIntOrNull() + if (id == null) { + call.respond(HttpStatusCode.NotFound) + return + } + + call.response.header( + HttpHeaders.ContentDisposition, + ContentDisposition.Attachment + .withParameter(ContentDisposition.Parameters.FileName, "keys.zip") + .toString() + ) + + call.respondOutputStream(contentType = ContentType.Application.Zip) { + ZipOutputStream(this).use { output -> + output.bufferedWriter().use { writer -> + for (key in exporter.exportKeys(id)) { + if (key.mapSquare == null) { + continue + } + + output.putNextEntry(ZipEntry("keys/${key.mapSquare}.txt")) + + writer.write(key.key.k0.toString()) + writer.write('\n'.toInt()) + + writer.write(key.key.k1.toString()) + writer.write('\n'.toInt()) + + writer.write(key.key.k2.toString()) + writer.write('\n'.toInt()) + + writer.write(key.key.k3.toString()) + writer.write('\n'.toInt()) + + writer.flush() + } + } + } + } + } } diff --git a/archive/src/main/kotlin/org/openrs2/archive/web/WebServer.kt b/archive/src/main/kotlin/org/openrs2/archive/web/WebServer.kt index d5b16e9ea7..870430654e 100644 --- a/archive/src/main/kotlin/org/openrs2/archive/web/WebServer.kt +++ b/archive/src/main/kotlin/org/openrs2/archive/web/WebServer.kt @@ -5,10 +5,12 @@ import io.ktor.application.call import io.ktor.application.install import io.ktor.features.ContentNegotiation import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode import io.ktor.http.content.resources import io.ktor.http.content.static import io.ktor.jackson.JacksonConverter import io.ktor.response.respond +import io.ktor.response.respondRedirect import io.ktor.routing.get import io.ktor.routing.routing import io.ktor.server.engine.embeddedServer @@ -50,7 +52,19 @@ public class WebServer @Inject constructor( get("/caches") { cachesController.index(call) } get("/caches/{id}") { cachesController.show(call) } get("/caches/{id}.zip") { cachesController.export(call) } - get("/caches/{id}.json") { cachesController.exportKeys(call) } + get("/caches/{id}.json") { + val id = call.parameters["id"] + if (id == null) { + call.respond(HttpStatusCode.NotFound) + return@get + } + + call.respondRedirect(permanent = true) { + path("caches", id, "keys.json") + } + } + get("/caches/{id}/keys.json") { cachesController.exportKeysJson(call) } + get("/caches/{id}/keys.zip") { cachesController.exportKeysZip(call) } static("/static") { resources("/org/openrs2/archive/static") } } }.start(wait = true) diff --git a/archive/src/main/resources/org/openrs2/archive/templates/caches/index.html b/archive/src/main/resources/org/openrs2/archive/templates/caches/index.html index 52f509ea76..d37d533f35 100644 --- a/archive/src/main/resources/org/openrs2/archive/templates/caches/index.html +++ b/archive/src/main/resources/org/openrs2/archive/templates/caches/index.html @@ -67,7 +67,7 @@