-
Notifications
You must be signed in to change notification settings - Fork 13
Block Type 1
The 0x01 file block contains instructions for how to take the current file and rebuild it to the newest version.
There are many different ways that you can parse this block. It all depends on how much memory you want to consume. Nexon's patcher uses a 0x10000 byte cache for everything. This is why Nexon's patcher runs so terribly slow. The cache is way too small.
The header for this file block is quite simple:
struct RebuildBlock
{
unsigned int oldFileChecksum;
unsigned int newFileChecksum;
};
So verify the checksum of the old file, then proceed to read the series of build blocks that give you directions on how to rebuild the file. The build blocks are parsed like this:
for(Command = GetInt(&zlibBlock); Command != 0x00000000; Command = GetInt(&zlibBlock))
{
if((Command & 0xC0000000) == 0xC0000000)
{
//This is a repeat block. It's essentially run length encoding.
repeatedByte = Command & 0x000000FF
lengthOfBlock = (Command & 0x3FFFFF00) >> 8;
//use memset in C to write to a buffer containing the repeatedByte for lengthOfBlock number of bytes, then write it to the file.
}
else if((Command & 0x80000000) == 0x80000000)
{
// This is a direct write block. The bytes to be written are contained directly in the zlib stream. Simply write these bytes out to the file.
lengthOfBlock = Command & 0x7FFFFFFF;
}
else
{
//This means we take from the old file and write to the new file.
lengthOfBlock = Command
oldFileOffset = GetInt(&zlibBlock);
//So open the old file, seek to the oldFileOffset, read lengthOfBlock number of bytes, then write those bytes to the new file.
}
}
As defined in the for loop, you stop reading blocks once a build block definition reads 0x00000000.
It is STRONGLY recommended to calculate the new checksum while you have the bytes for the new file in memory. It's hundreds of times faster than writing to the hard disk and then calculating the new checksum from the disk.