All pastes #292886 Raw Edit

Someone

public text v1 · immutable
#292886 ·published 2006-12-27 00:33 UTC
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;
}