rendered paste body#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char statname[256];
unsigned long keys[256] = {
0x697A5, 0x6045C, 0xAB4E2, 0x409E4, 0x71209, 0x32392, 0xA7292, 0xB09FC, 0x4B658, 0xAAAD5, 0x9B9CF, 0xA326A, 0x8DD12, 0x38150, 0x8E14D, 0x2EB7F,
0xE0A56, 0x7E6FA, 0xDFC27, 0xB1301, 0x8B4F7, 0xA7F70, 0xAA713, 0x6CC0F, 0x6FEDF, 0x2EC87, 0xC0F1C, 0x45CA4, 0x30DF8, 0x60E99, 0xBC13E, 0x4E0B5,
0x6318B, 0x82679, 0x26EF2, 0x79C95, 0x86DDC, 0x99BC0, 0xB7167, 0x72532, 0x68765, 0xC7446, 0xDA70D, 0x9D132, 0xE5038, 0x2F755, 0x9171F, 0xCB49E,
0x6F925, 0x601D3, 0x5BD8A, 0x2A4F4, 0x9B022, 0x706C3, 0x28C10, 0x2B24B, 0x7CD55, 0xCA355, 0xD95F4, 0x727BC, 0xB1138, 0x9AD21, 0xC0ACA, 0xCD928,
0x953E5, 0x97A20, 0x345F3, 0xBDC03, 0x7E157, 0x96C99, 0x968EF, 0x92AA9, 0xC2276, 0xA695D, 0x6743B, 0x2723B, 0x58980, 0x66E08, 0x51D1B, 0xB97D2,
0x6CAEE, 0xCC80F, 0x3BA6C, 0xB0BF5, 0x9E27B, 0xD122C, 0x48611, 0x8C326, 0xD2AF8, 0xBB3B7, 0xDED7F, 0x4B236, 0xD298F, 0xBE912, 0xDC926, 0xC873F,
0xD0716, 0x9E1D3, 0x48D94, 0x9BD91, 0x5825D, 0x55637, 0xB2057, 0xBCC6C, 0x460DE, 0xAE7FB, 0x81B03, 0x34D8F, 0xC0528, 0xC9B59, 0x3D260, 0x6051D,
0x93757, 0x8027F, 0xB7C34, 0x4A14E, 0xB12B8, 0xE4945, 0x28203, 0xA1C0F, 0xAA382, 0x46ABB, 0x330B9, 0x5A114, 0xA754B, 0xC68D0, 0x9040E, 0x6C955,
0xBB1EF, 0x51E6B, 0x9FF21, 0x51BCA, 0x4C879, 0xDFF70, 0x5B5EE, 0x29936, 0xB9247, 0x42611, 0x2E353, 0x26F3A, 0x683A3, 0xA1082, 0x67333, 0x74EB7,
0x754BA, 0x369D5, 0x8E0BC, 0xABAFD, 0x6630B, 0xA3A7E, 0xCDBB1, 0x8C2DE, 0x92D32, 0x2F8ED, 0x7EC54, 0x572F5, 0x77461, 0xCB3F5, 0x82C64, 0x35FE0,
0x9203B, 0xADA2D, 0xBAEBD, 0xCB6AF, 0xC8C9A, 0x5D897, 0xCB727, 0xA13B3, 0xB4D6D, 0xC4929, 0xB8732, 0xCCE5A, 0xD3E69, 0xD4B60, 0x89941, 0x79D85,
0x39E0F, 0x6945B, 0xC37F8, 0x77733, 0x45D7D, 0x25565, 0xA3A4E, 0xB9F9E, 0x316E4, 0x36734, 0x6F5C3, 0xA8BA6, 0xC0871, 0x42D05, 0x40A74, 0x2E7ED,
0x67C1F, 0x28BE0, 0xE162B, 0xA1C0F, 0x2F7E5, 0xD505A, 0x9FCC8, 0x78381, 0x29394, 0x53D6B, 0x7091D, 0xA2FB1, 0xBB942, 0x29906, 0xC412D, 0x3FCD5,
0x9F2EB, 0x8F0CC, 0xE25C3, 0x7E519, 0x4E7D9, 0x5F043, 0xBBA1B, 0x6710A, 0x819FB, 0x9A223, 0x38E47, 0xE28AD, 0xB690B, 0x42328, 0x7CF7E, 0xAE108,
0xE54BA, 0xBA5A1, 0xA09A6, 0x9CAB7, 0xDB2B3, 0xA98CC, 0x5CEBA, 0x9245D, 0x5D083, 0x8EA21, 0xAE349, 0x54940, 0x8E557, 0x83EFD, 0xDC504, 0xA6059,
0xB85C9, 0x9D162, 0x7AEB6, 0xBED34, 0xB4963, 0xE367B, 0x4C891, 0x9E42C, 0xD4304, 0x96EAA, 0xD5D69, 0x866B8, 0x83508, 0x7BAEC, 0xD03FD, 0xDA122
};
unsigned long MakeStrHash(const char *str){
register unsigned long result = 0xDEADC0DE;
register unsigned long tkey = 0x7FED7FED;
register char c = 0;
while (*(str)){
c = (*str<'a'||*str>'z')?*str:*str-32;
result += tkey;
tkey *= 0x21;
result ^= keys[c];
tkey += result + c + 3;
str++;
}
return result;
}
FILE* logfile;
void bprintf( char* format, ... )
{
va_list args;
va_start( args, format );
//vprintf( format, args );
vfprintf( logfile, format, args );
va_end( args );
};
struct qsdentry
{
unsigned conditioncount;
unsigned rewardcount;
char name[128];
void* data;
};
struct qsdblock
{
unsigned entrycount;
char name[128];
qsdentry* entries;
};
char* GetStatName( unsigned statid )
{
switch( statid )
{
{
case 2: return "Gender";
case 3: return "Union";
case 10: return "Strength";
case 11: return "Dexterity";
case 12: return "Intelligence";
case 13: return "Concentration";
case 14: return "Charm";
case 15: return "Sensibility";
case 16: return "HP";
case 17: return "MP";
case 18: return "Attack Power";
case 19: return "Defence Power";
case 20: return "Hit Rate";
case 21: return "Magic Resistance";
case 22: return "Dodge Rate";
case 23: return "MSpeed";
case 31: return "Level";
case 40: return "Money";
default:
{
sprintf_s( statname, 256, "STAT: %u", statid );
return statname;
}
};
}
}
char* GetOperator( unsigned operatorid )
{
switch( operatorid )
{
case 0: return "==";
case 1: return "<=";
case 2: return ">=";
case 3: return "<";
case 4: return ">";
case 5: return "=";
case 6: return "+=";
case 7: return "-=";
default: return "???";
}
}
int ReadQSD( char* filename )
{
FILE* myqsd;
unsigned fileversion;
unsigned blockcount;
unsigned tmp;
unsigned short strreadlen;
unsigned questhash;
char buffer[2048];
qsdblock* blocks;
fopen_s( &myqsd, filename, "rb" );
if( !myqsd )
{
printf( "Could not open the qsd file '%s'", filename );
system( "pause" );
return 0;
}
fread( &fileversion, 4, 1, myqsd );
fread( &blockcount, 4, 1, myqsd );
fread( &strreadlen, 2, 1, myqsd );
fread( &buffer[0], 1, strreadlen, myqsd );
blocks = new qsdblock[blockcount];
for( unsigned i = 0; i < blockcount; i++ )
{
fread( &blocks[i].entrycount, 4, 1, myqsd );
fread( &strreadlen, 2, 1, myqsd );
fread( &blocks[i].name[0], 1, strreadlen, myqsd );
bprintf( "|-Block %u - Name: %s\n", i, blocks[i].name );
blocks[i].entries = new qsdentry[blocks[i].entrycount];
for( unsigned j = 0; j < blocks[i].entrycount; j++ )
{
fseek( myqsd, 1, SEEK_CUR );
fread( &blocks[i].entries[j].conditioncount, 4, 1, myqsd );
fread( &blocks[i].entries[j].rewardcount, 4, 1, myqsd );
fread( &strreadlen, 2, 1, myqsd );
fread( &blocks[i].entries[j].name, 1, strreadlen, myqsd );
bprintf( "| |-Entry %u - Name: %s\n", j, blocks[i].entries[j].name );
questhash = MakeStrHash( blocks[i].entries[j].name );
bprintf( "| | |-Hash: %08x\n", questhash );
bprintf( "| | |-%c730 3 0 %02x %02x %02x %02x\n", '%', questhash & 0xFF, ( questhash >> 8 ) & 0xFF, ( questhash >> 16 ) & 0xFF, ( questhash >> 24 ) & 0xFF );
for( unsigned k = 0; k < blocks[i].entries[j].conditioncount + blocks[i].entries[j].rewardcount; k++ )
{
if( k == 0 && blocks[i].entries[j].conditioncount > 0 )
{
bprintf( "| | |-Conditions\n" );
}
if( k == blocks[i].entries[j].conditioncount )
{
bprintf( "| | |-Rewards\n" );
}
fread( &tmp, 4, 1, myqsd );
fread( &buffer[0], 1, tmp - 4, myqsd );
switch( *((unsigned*)&buffer[0]) )
{
case 0x00000000:
{
bprintf( "| | | |- Must have quest id: %u\n", *((unsigned*)&buffer[4]) );
break;
}
case 0x00000003:
{
// Check Stat
bprintf( "| | | |- %s MUST BE %s %u\n", GetStatName( *((unsigned*)&buffer[8]) ), GetOperator( buffer[16] ), *((unsigned*)&buffer[12]) );
break;
}
case 0x00000004:
{
// Check for item
bprintf( "| | | |- MUST HAVE ITEM - TYPE:%u ID:%u COUNT:%u\n", *((unsigned*)&buffer[8])/1000, *((unsigned*)&buffer[8])%1000, *((unsigned*)&buffer[16]) );
break;
}
case 0x00000009:
{
// Check for Skill
bprintf( "| | | |- MUST HAVE SKILL %u\n", *((unsigned*)&buffer[4]) );
break;
}
case 0x0000000E:
{
// Check Quest Flag
bprintf( "| | | |- Flag ID: %u MUST BE %u\n", *((unsigned short*)&buffer[4]), *((unsigned short*)&buffer[6]) );
break;
}
case 0x01000000:
{
// Activate quest??
bprintf( "| | | |- Quest %u activated\n", *((unsigned short*)&buffer[4]) );
break;
}
case 0x01000001:
{
// Remove item??
bprintf( "| | | |- Remove item - TYPE:%u ID:%u\n", *((unsigned*)&buffer[4])/1000, *((unsigned*)&buffer[4])%1000 );
break;
}
case 0x01000003:
{
// Set Stat
bprintf( "| | | |- SET %s %s %u\n", GetStatName( *((unsigned*)&buffer[8]) ), GetOperator( buffer[16] ), *((unsigned*)&buffer[12]) );
break;
}
case 0x01000005:
{
if( *((unsigned short*)&buffer[4]) == 0x502 ) {
bprintf( "| | | |- Give Item - TYPE:%u ID:%u COUNT:%u\n", *((unsigned*)&buffer[12])/1000, *((unsigned*)&buffer[12])%1000,*((unsigned*)&buffer[8]) );
}else if( *((unsigned short*)&buffer[4]) == 0 ) {
bprintf( "| | | |- Give EXP: %u\n", *((unsigned*)&buffer[8]) );
}else{
bprintf( "| | | |- Unknown Item Opcode\n" );
}
break;
}
case 0x01000007:
{
float telex = (float)*((unsigned*)&buffer[8]) / 100;
float teley = (float)*((unsigned*)&buffer[12]) / 100;
bprintf( "| | | |- Teleport to: %u %.2f,%.2f\n", *((unsigned short*)&buffer[4]), telex, teley );
break;
}
case 0x01000009:
{
bprintf( "| | | |- Activate quest trigger: '%s'\n", &buffer[6] );
break;
}
case 0x0100000E:
{
// Learn Skill?
bprintf( "| | | |- Learn skill %u\n", *((unsigned*)&buffer[8]) );
break;
}
case 0x0100000F:
{
// Set Quest Flag
bprintf( "| | | |- Flag ID: %u SET TO %u\n", *((unsigned short*)&buffer[4]), *((unsigned short*)&buffer[6]) );
break;
}
case 0x0100001D:
{
// Activate external function?
bprintf( "| | | |- Activate External function: '%s'\n", &buffer[6] );
break;
}
default:
{
bprintf( "| | | |- Unknown Opcode: %08x\n", *((unsigned*)&buffer[0]) );
break;
}
}
}
}
}
fclose( myqsd );
return 1;
}
int main( int argc, char* argv[] )
{
FILE* mylist;
unsigned curbyte = 0;
char buffer[200];
fopen_s( &logfile, "C:\\qsddec.log", "wt" );
if( !logfile )
{
printf( "Could not open the log file..." );
system( "pause" );
return 0;
}
fopen_s( &mylist, "qsdlist.txt", "rb" );
while( !feof( mylist ) )
{
fread( &buffer[curbyte], 1, 1, mylist );
if( buffer[curbyte] == 0x0A )
{
buffer[curbyte] = 0;
ReadQSD( &buffer[0] );
curbyte = 0;
}else{
curbyte++;
}
}
fclose( mylist );
fclose( logfile );
system( "pause" );
return 0;
}