/* Copyright (C) 2008, 2009 TitanFiesta Dev Team * Licensed under GNU GPL v3 * For license details, see LICENCE in the root folder. */ #include #include #include typedef unsigned __int8 byte; typedef unsigned __int16 word; typedef unsigned __int32 dword; #include "CTitanFile.hpp" std::string ReplaceCharInString( const std::string & source, char charToReplace, const std::string replaceString ) { std::string result; // For each character in source string: const char * pch = source.c_str(); while ( *pch != '\0' ) { // Found character to be replaced? if ( *pch == charToReplace ) { result += replaceString; } else { // Just copy original character result += (*pch); } // Move to next character ++pch; } return result; } class CSHNReader { public: struct SSHNColumn { char name[0x30]; dword type; dword columnSize; }; CSHNReader(){} ~CSHNReader(){} void Open(char* path, char* tablename){ CTitanFile fh(path, "rb"); fh.Skip(0x28); rows = fh.Read(); fh.Skip(4); dword cols = fh.Read(); printf("CREATE TABLE `%s` (\n", tablename); for(dword i = 0; i < cols; i++){ SSHNColumn* curCol = reinterpret_cast(fh.ReadBytes(0x38)); printf("`%s`", curCol->name); switch(curCol->type){ case 1: printf(" tinyint(1) NOT NULL"); break; case 2: printf(" smallint(2) UNSIGNED NOT NULL"); break; case 3: printf(" int(4) NOT NULL"); break; case 9: printf(" char(%d) NOT NULL", curCol->columnSize); break; case 11: printf(" int(4) NOT NULL"); break; case 18: printf(" int(4) NOT NULL"); break; case 26: printf(" varchar(255) NOT NULL"); break; case 27: printf(" int(4) NOT NULL"); break; } if(i < cols - 1) printf(",\n"); else printf("\n"); columns.push_back(curCol); } printf(") ENGINE=MyISAM DEFAULT CHARSET=utf8 ;\n\n"); const int rowLimit = 100; for(dword i = 0; i < rows; i++){ word rowSize = fh.Read(); if(i % rowLimit == 0) printf("INSERT INTO `%s` VALUES ", tablename); printf(" (", tablename); for(dword j = 0; j < columns.size(); j++){ SSHNColumn* curCol = columns[j]; switch(curCol->type){ case 1: printf("%d", fh.Read()); break; case 2: printf("%d", fh.Read()); break; case 3: printf("%d", fh.Read()); break; case 9: { char* tmp = fh.ReadString(curCol->columnSize); std::string curStr; curStr.assign(tmp); curStr = ReplaceCharInString(curStr, '\'', "\\'"); printf("'%s'", curStr.c_str()); delete [] tmp; } break; case 11: printf("%d", fh.Read()); break; case 18: printf("%d", fh.Read()); break; case 26: { char* tmp = fh.ReadNullString(); std::string curStr; curStr.assign(tmp); curStr = ReplaceCharInString(curStr, '\'', "\\'"); printf("'%s'", curStr.c_str()); delete [] tmp; } break; case 27: printf("%d", fh.Read()); break; default: fh.Skip(curCol->columnSize); } if(j < cols - 1) printf(", "); else printf(" "); } if(i >= rows - 1 || (i % rowLimit) >= rowLimit - 1) printf(");\n\n"); else printf("),\n"); } fh.Close(); } private: dword rows; std::vector columns; }; unsigned char* ShnDecrypt(unsigned char* data, long int filesize) { byte key = filesize & 0xFF; for(long int i = filesize - 1; i > 0; --i){ data[i] ^= key; byte tmp1 = ( 0x0b * (byte)i ); byte tmp2 = ( i & 0x0f ) + 0x55; key ^= (tmp1 ^ tmp2) ^ 0xaa; } return data; } int main(int argc, char** argv){ if(argc < 3){ return 0; } FILE* fh; fopen_s(&fh, argv[1], "rb"); if(fh == NULL){ printf("Could not open file\n"); return 0; } fseek(fh, 0, SEEK_END); long int filesize = ftell(fh); fseek(fh, 0, SEEK_SET); unsigned char* data = new unsigned char[filesize]; fread(data, filesize, 1, fh); fclose(fh); ShnDecrypt(data + 0x24, filesize - 0x24); { char tempPath[256]; sprintf_s(tempPath, 256, "%s.dec", argv[1]); FILE* fh; fopen_s(&fh, tempPath, "wb"); if(fh == NULL){ printf("Could not open file\n"); return 0; } fwrite(data, filesize, 1, fh); fclose(fh); CSHNReader reader; reader.Open(tempPath, argv[2]); } return 0; }