Skip to content

Instantly share code, notes, and snippets.

@jonatino
Created January 15, 2021 02:46
Show Gist options
  • Save jonatino/9bb6649873fafa213d38c45acf143be3 to your computer and use it in GitHub Desktop.
Save jonatino/9bb6649873fafa213d38c45acf143be3 to your computer and use it in GitHub Desktop.
package net.runelite.cache
import io.netty.buffer.ByteBuf
import io.netty.buffer.Unpooled
import net.runelite.cache.fs.Container
import net.runelite.cache.fs.Store
import net.runelite.cache.fs.flat.FlatStorage
import net.runelite.cache.fs.jagex.DataFileWriteResult
import net.runelite.cache.fs.jagex.DiskStorage
import net.runelite.cache.fs.jagex.IndexEntry
import java.io.File
import java.io.IOException
import java.io.RandomAccessFile
import java.nio.ByteBuffer
import java.util.LinkedList
object ReferenceTableGenerator {
data class Result(val indexId: Int, val sector: Int, val length: Int)
@JvmStatic
fun main(args: Array<String>) {
val flats = flat()
val disks = disk()
val index255s = index255()
flats.forEachIndexed { index, flat ->
val disk = disks.get(index)
val index255 = index255s.get(index)
println("Flat: $flat")
println("Disk: $disk")
println("Index255: $index255")
println("Equal: flat==disk: ${flat == disk} flat==255: ${flat == index255}\n")
}
}
fun disk(): LinkedList<Result> {
val store = Store(File("E:\\Sync\\Insignia\\game-server\\osrs-cache"))
store.load()
return encode(store)
}
fun index255(): LinkedList<Result> {
val store = Store(File("E:\\Sync\\Insignia\\game-server\\osrs-cache"))
store.load()
val out = LinkedList<Result>()
val storage = (store.storage as DiskStorage)
store.indexes.sortBy { it.id }
store.indexes.forEach {
val entry: IndexEntry = storage.index255.read(it.id)
out.add(Result(it.id, entry.sector, entry.length))
}
return out
}
fun flat(): LinkedList<Result> {
val store = Store(FlatStorage(File("E:\\Sync\\Insignia\\game-server\\test-cache")))
store.load()
return encode(store)
}
private fun encode(store: Store): LinkedList<Result> {
val out = LinkedList<Result>()
val refTable = Unpooled.buffer(1024 * 1024)
store.indexes.sortBy { it.id }
store.indexes.forEach { index ->
val indexData = index.toIndexData()
val data = indexData.writeIndexData()
val container = Container(index.compression, -1) // index data revision is always -1
container.compress(data, null)
val startSector = buildChildRefTables(255, index.id, container.data, refTable)
out.add(Result(index.id, startSector, container.data.size))
}
return out
}
private const val SECTOR_SIZE = 520
fun buildChildRefTables(indexId: Int, archiveId: Int, compressedData: ByteArray, refTable: ByteBuf): Int {
val writeBuffer = ByteArray(SECTOR_SIZE)
val data = ByteBuffer.wrap(compressedData)
var sector: Int = ((refTable.readableBytes() + (SECTOR_SIZE - 1).toLong()) / SECTOR_SIZE.toLong()).toInt()
if (sector == 0) {
sector = 1
}
val startSector: Int = sector
println("Starting sector is $sector")
var part = 0
while (data.hasRemaining()) {
var nextSector = sector + 1 // we always just append sectors
var dataToWrite: Int
if (0xFFFF < archiveId) {
if (data.remaining() <= 510) {
nextSector = 0
}
writeBuffer[0] = (archiveId shr 24).toByte()
writeBuffer[1] = (archiveId shr 16).toByte()
writeBuffer[2] = (archiveId shr 8).toByte()
writeBuffer[3] = archiveId.toByte()
writeBuffer[4] = (part shr 8).toByte()
writeBuffer[5] = part.toByte()
writeBuffer[6] = (nextSector shr 16).toByte()
writeBuffer[7] = (nextSector shr 8).toByte()
writeBuffer[8] = nextSector.toByte()
writeBuffer[9] = indexId.toByte()
println(
"1. Seeking to ${SECTOR_SIZE * sector} $archiveId $part $nextSector $indexId ${
writeBuffer.copyOf(
10
).contentToString()
}"
)
refTable.writerIndex(SECTOR_SIZE * sector)
refTable.writeBytes(writeBuffer, 0, 10)
dataToWrite = data.remaining()
if (dataToWrite > 510) {
dataToWrite = 510
}
} else {
if (data.remaining() <= 512) {
nextSector = 0
}
writeBuffer[0] = (archiveId shr 8).toByte()
writeBuffer[1] = archiveId.toByte()
writeBuffer[2] = (part shr 8).toByte()
writeBuffer[3] = part.toByte()
writeBuffer[4] = (nextSector shr 16).toByte()
writeBuffer[5] = (nextSector shr 8).toByte()
writeBuffer[6] = nextSector.toByte()
writeBuffer[7] = indexId.toByte()
refTable.writerIndex(SECTOR_SIZE * sector)
println(
"2. Seeking to ${SECTOR_SIZE * sector} $archiveId $part $nextSector $indexId ${
writeBuffer.copyOf(
8
).contentToString()
}"
)
refTable.writeBytes(writeBuffer, 0, 8)
dataToWrite = data.remaining()
if (dataToWrite > 512) {
dataToWrite = 512
}
}
data[writeBuffer, 0, dataToWrite] //println("3. We're at ${SECTOR_SIZE * sector} ${data.remaining()}")
refTable.writeBytes(writeBuffer, 0, dataToWrite)
sector = nextSector
++part
}
return startSector
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment