I'm using runelites FlatStorage cache format (https://github.com/runelite/runelite...atStorage.java) which does not have a concept of index 255 or also known as the "ref table".
In order to use the FlatStorage format with my js5 update server, I'll need to generate the entire reference table (index 255 archive 255) and all of its children reference tables (index 255 archives 0-20) from scratch. Is this possible using only the indices/archives?
Here's what the FlatStorage cache looks like on disk:
Here's what I got so far for generating the sub reference tables (index 255 and archives 0-20 or how ever many indices your cache has) but the data it gives me does not align with the data I have in the original binary cache (.dat2 file) (I assume because it does not include the main reference file 255/255 and the sectors are wrong). Does anyone have examples of generating these tables completely from scratch using the data only?
Thanks.
Code:
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
}
Entire code can be found here:
https://gist.github.com/Jonatino/9bb...38c45acf143be3
You can use any osrs cache, here's the tool to convert the binary format to runelites FlatStorage format.
Code:
package com.pvphero.cache.packing.extractor
import net.runelite.cache.fs.Store
import net.runelite.cache.fs.flat.FlatStorage
import java.io.File
object CacheExtractor {
@JvmStatic
fun main(args: Array<String>) {
val diskStore = Store(File("./osrs-cache"))
diskStore.load()
val out = File("./test-cache")
val flatStorage = FlatStorage(out)
flatStorage.save(diskStore)
}
}