Add ChecksumTable and VersionList classes

Signed-off-by: Graham <gpe@openrs2.org>
Graham 3 years ago
parent 007f7d68ef
commit 8448f74b3c
  1. 62
      cache/src/main/kotlin/org/openrs2/cache/ChecksumTable.kt
  2. 68
      cache/src/main/kotlin/org/openrs2/cache/VersionList.kt

@ -0,0 +1,62 @@
package org.openrs2.cache
import io.netty.buffer.ByteBuf
import org.openrs2.buffer.crc32
import org.openrs2.buffer.use
public class ChecksumTable(
public val entries: MutableList<Int> = mutableListOf()
) {
public fun write(buf: ByteBuf) {
for (entry in entries) {
buf.writeInt(entry)
}
var checksum = 1234
for (entry in entries) {
checksum = (checksum shl 1) + entry
}
buf.writeInt(checksum)
}
public companion object {
public fun create(store: Store): ChecksumTable {
val table = ChecksumTable()
var nextArchive = 0
for (archive in store.list(0)) {
val entry = store.read(0, archive).use { buf ->
buf.crc32()
}
for (i in nextArchive until archive) {
table.entries += 0
}
table.entries += entry
nextArchive = archive + 1
}
return table
}
public fun read(buf: ByteBuf): ChecksumTable {
val table = ChecksumTable()
var expectedChecksum = 1234
while (buf.readableBytes() >= 8) {
val entry = buf.readInt()
table.entries += entry
expectedChecksum = (expectedChecksum shl 1) + entry
}
val actualChecksum = buf.readInt()
require(expectedChecksum == actualChecksum)
return table
}
}
}

@ -0,0 +1,68 @@
package org.openrs2.cache
import org.openrs2.buffer.use
public class VersionList(
public val files: List<List<File>>,
public val maps: Map<Int, MapSquare>,
) {
public data class File(
val version: Int,
val checksum: Int
)
public data class MapSquare(
val mapFile: Int,
val locFile: Int,
val freeToPlay: Boolean
)
public companion object {
private val NAMES = listOf("model", "anim", "midi", "map")
public fun read(archive: JagArchive): VersionList {
val files = mutableListOf<List<File>>()
for (name in NAMES) {
val versions = archive.read("${name}_version".uppercase()).use { buf ->
IntArray(buf.readableBytes() / 2) {
buf.readUnsignedShort()
}
}
val checksums = archive.read("${name}_crc".uppercase()).use { buf ->
IntArray(buf.readableBytes() / 4) {
buf.readInt()
}
}
require(versions.size == checksums.size)
files += versions.zip(checksums, ::File)
}
val maps = mutableMapOf<Int, MapSquare>()
archive.read("map_index".uppercase()).use { buf ->
while (buf.readableBytes() >= 7) {
val mapSquare = buf.readUnsignedShort()
val mapFile = buf.readUnsignedShort()
val locFile = buf.readUnsignedShort()
val freeToPlay = buf.readBoolean()
if (maps.containsKey(mapSquare)) {
/*
* If there's a map square collision, pick the first
* entry for compatibility with the client.
*/
continue
}
maps[mapSquare] = MapSquare(mapFile, locFile, freeToPlay)
}
}
return VersionList(files, maps)
}
}
}
Loading…
Cancel
Save