Add support for OSRS beta caches and server_version param

Signed-off-by: Graham <gpe@openrs2.org>
Graham 1 year ago
parent 8052561dcf
commit f6324198ef
  1. 40
      archive/src/main/kotlin/org/openrs2/archive/cache/CacheDownloader.kt
  2. 31
      archive/src/main/kotlin/org/openrs2/archive/world/World.kt
  3. 22
      archive/src/main/kotlin/org/openrs2/archive/world/WorldList.kt

@ -5,11 +5,15 @@ import jakarta.inject.Singleton
import org.openrs2.archive.cache.nxt.MusicStreamClient import org.openrs2.archive.cache.nxt.MusicStreamClient
import org.openrs2.archive.game.GameDatabase import org.openrs2.archive.game.GameDatabase
import org.openrs2.archive.jav.JavConfig import org.openrs2.archive.jav.JavConfig
import org.openrs2.archive.world.World
import org.openrs2.archive.world.WorldList
import org.openrs2.buffer.ByteBufBodyHandler import org.openrs2.buffer.ByteBufBodyHandler
import org.openrs2.buffer.use
import org.openrs2.net.BootstrapFactory import org.openrs2.net.BootstrapFactory
import org.openrs2.net.awaitSuspend import org.openrs2.net.awaitSuspend
import java.net.URI import java.net.URI
import java.net.http.HttpClient import java.net.http.HttpClient
import java.net.http.HttpRequest
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
@Singleton @Singleton
@ -22,23 +26,25 @@ public class CacheDownloader @Inject constructor(
) { ) {
public suspend fun download(gameName: String, environment: String, language: String) { public suspend fun download(gameName: String, environment: String, language: String) {
val game = gameDatabase.getGame(gameName, environment, language) ?: throw Exception("Game not found") val game = gameDatabase.getGame(gameName, environment, language) ?: throw Exception("Game not found")
val url = game.url ?: throw Exception("URL not set") val url = game.url ?: throw Exception("URL not set")
var buildMajor = game.buildMajor ?: throw Exception("Current major build not set")
val config = JavConfig.download(client, url) val config = JavConfig.download(client, url)
val group = bootstrapFactory.createEventLoopGroup() val group = bootstrapFactory.createEventLoopGroup()
try { try {
suspendCoroutine { continuation -> suspendCoroutine { continuation ->
val bootstrap = bootstrapFactory.createBootstrap(group) val bootstrap = bootstrapFactory.createBootstrap(group)
val hostname: String val hostname: String
val initializer = when (gameName) { val initializer = when (gameName) {
"oldschool" -> { "oldschool" -> {
var buildMajor = game.buildMajor
hostname = if (environment == "beta") {
findOsrsWorld(config, World::isBeta) ?: throw Exception("Failed to find beta world")
} else {
val codebase = config.config[CODEBASE] ?: throw Exception("Codebase missing") val codebase = config.config[CODEBASE] ?: throw Exception("Codebase missing")
hostname = URI(codebase).host ?: throw Exception("Hostname missing") URI(codebase).host ?: throw Exception("Hostname missing")
}
val serverVersion = config.params[OSRS_SERVER_VERSION] val serverVersion = config.params[OSRS_SERVER_VERSION]
if (serverVersion != null) { if (serverVersion != null) {
@ -52,7 +58,7 @@ public class CacheDownloader @Inject constructor(
game.id, game.id,
hostname, hostname,
PORT, PORT,
buildMajor, buildMajor ?: throw Exception("Current major build not set"),
game.lastMasterIndexId, game.lastMasterIndexId,
continuation, continuation,
importer importer
@ -61,7 +67,8 @@ public class CacheDownloader @Inject constructor(
} }
"runescape" -> { "runescape" -> {
var buildMinor = game.buildMinor ?: throw Exception("Current minor build not set") var buildMajor = game.buildMajor
var buildMinor = game.buildMinor
val serverVersion = config.config[NXT_SERVER_VERSION] val serverVersion = config.config[NXT_SERVER_VERSION]
if (serverVersion != null) { if (serverVersion != null) {
@ -95,8 +102,8 @@ public class CacheDownloader @Inject constructor(
game.id, game.id,
hostname, hostname,
PORT, PORT,
buildMajor, buildMajor ?: throw Exception("Current major build not set"),
buildMinor, buildMinor ?: throw Exception("Current minor build not set"),
game.lastMasterIndexId, game.lastMasterIndexId,
continuation, continuation,
importer, importer,
@ -118,8 +125,23 @@ public class CacheDownloader @Inject constructor(
} }
} }
private fun findOsrsWorld(config: JavConfig, predicate: (World) -> Boolean): String? {
val url = config.params[OSRS_WORLD_LIST_URL] ?: throw Exception("World list URL missing")
val list = client.send(HttpRequest.newBuilder(URI(url)).build(), byteBufBodyHandler).body().use { buf ->
WorldList.read(buf)
}
return list.worlds
.filter(predicate)
.map(World::hostname)
.shuffled()
.firstOrNull()
}
private companion object { private companion object {
private const val CODEBASE = "codebase" private const val CODEBASE = "codebase"
private const val OSRS_WORLD_LIST_URL = "17"
private const val OSRS_SERVER_VERSION = "25" private const val OSRS_SERVER_VERSION = "25"
private const val NXT_SERVER_VERSION = "server_version" private const val NXT_SERVER_VERSION = "server_version"
private const val NXT_LIVE_HOSTNAME = "content.runescape.com" private const val NXT_LIVE_HOSTNAME = "content.runescape.com"

@ -0,0 +1,31 @@
package org.openrs2.archive.world
import io.netty.buffer.ByteBuf
import org.openrs2.buffer.readString
public data class World(
public val id: Int,
public val flags: Int,
public val hostname: String,
public val activity: String,
public val country: Int,
public val players: Int
) {
public val isBeta: Boolean
get() = (flags and FLAG_BETA) != 0
public companion object {
private const val FLAG_BETA = 0x10000
public fun read(buf: ByteBuf): World {
val id = buf.readUnsignedShort()
val flags = buf.readInt()
val hostname = buf.readString()
val activity = buf.readString()
val country = buf.readUnsignedByte().toInt()
val players = buf.readShort().toInt()
return World(id, flags, hostname, activity, country, players)
}
}
}

@ -0,0 +1,22 @@
package org.openrs2.archive.world
import io.netty.buffer.ByteBuf
public data class WorldList(
public val worlds: List<World>
) {
public companion object {
public fun read(buf: ByteBuf): WorldList {
buf.skipBytes(4)
val count = buf.readUnsignedShort()
val worlds = buildList(count) {
for (i in 0 until count) {
add(World.read(buf))
}
}
return WorldList(worlds)
}
}
}
Loading…
Cancel
Save