codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
// ObjectMergerFixer.cpp // VERSION 4.1.0 [2016_10_30] // ^ = MAJOR REBUILDS // ^ = NEW STUFF // ^ = FIXES // BY SourceSeeker / EdwardElric (hiveworkshop.com) / MasterOfSickness (wc3c.net) // THANKS TO: // - Vexorian (AUTHOR OF JASSHELPER) FOR EVERYTHING :D // - PitzerMike (AUTHOR OF GRIMEX) FOR PUBLISHING HIS SOURCE CODE // - WaterKnight (http://www.hiveworkshop.com/members/waterknight.178519/) FOR HELPFUL TIPS VIA CHAT (http://www.hiveworkshop.com/chat/) & BEING PATIENT WITH ME & MY QUESTIONS ;p // - Barade (http://www.hiveworkshop.com/members/barade.125524/) FOR HELPFUL TIPS ABOUT MPQ API // - Aniki (http://www.hiveworkshop.com/members/aniki.241724/) FOR HINT TO ADD FIX FOR UNIT OBJECT FIELD (utco) #include "sfmpq/SFmpqapi_no-lib.h" // HEADER FOR: MpqOpenArchiveForUpdate, ... #include <iostream> // SYSTEM HEADER FOR: std::cout #include <vector> // SYSTEM HEADER FOR: std::vector #include <algorithm> // SYSTEM HEADER FOR: sst::search std::vector<char> getFixedW3U( std::vector<char> &v_input, const char * c_wrongBytes, const char * c_rightBytes ) { std::vector<char> v_output; std::vector<char>::iterator it_counter; int i_distance; int i_distance2 = 0; // SEARCH FOR OBJECT FIELD ID [4 BYTES] & TYPE [4 BYTES] (EXAMPLE: "uaen" & STRING) IN BINARY STREAM AS HEX SEQUENCE: { 0x75, 0x61, 0x65, 0x6E, 0x03, 0x00, 0x00, 0x00 } // OBJECT MERGER ERROR 1: // THOSE LAST 4 BYTES SHOULD BE { 0x00, 0x00, 0x00, 0x00 } // FOR EACH MATCH RETRIEVE THE FOLLOWING BYTES UNTIL NULL BYTE // OBJECT MERGER ERROR 2: // FOR "uaen" THIS BYTE SHOULD BE 0x00, 0x01, 0x02 OR 0x03, FOLLOWED BY 3 NULL BYTES, // INSTEAD THE BYTE IS 0x48, 0x49, 0x50 OR 0x51, FOLLOWED BY 1 NULL BYTE! // PUT CORRECT BYTES INTO OUTPUT VECTOR it_counter = std::search( v_input.begin(), v_input.end(), c_wrongBytes, c_wrongBytes +8 ); // IF W3U CONTAINS WRONG BYTES LIKE "uaen....": if ( it_counter != v_input.end() ) { while ( it_counter != v_input.end() ) { i_distance = it_counter - v_input.begin(); // APPEND PART OF INPUT VECTOR v_buffer TO OUTPUT VECTOR v_output: v_output.insert( v_output.end(), v_input.begin() +i_distance2, v_input.begin() +i_distance +4 ); i_distance2 = i_distance +4; // = EVERYTHING UNTIL (INLCUDING) ...uaen OR ...utco // SAVE NUMBER FOLLOWED BY WRONG BYTES UNTIL NEXT NULL BYTE: // SAVE UP TO TWO-PLACE (-9...99), BECAUSE: // FIELD (utco) RANGE: -1 - 12 // FIELD (uaen) RANGE: 0 - 3 // - 0 = NOTHING // - 1 = ONLY ATTACK 1 // - 2 = ONLY ATTACK 2 // - 3 = BOTH // EXAMPLES: // WRONG BYTES FOR uaen = 0: // BYTE: 1 2 3 4 5 6 7 8 9 10 // CHAR: u a e n . . . . 0 . // HEX: 0x75 0x61 0x65 0x6E 0x03 0x00 0x00 0x00 0x30 0x00 // RIGHT BYTES FOR uaen = 0: // BYTE: 1 2 3 4 5 6 7 8 9 10 11 12 // CHAR: u a e n . . . . . . . . // HEX: 0x75 0x61 0x65 0x6E 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 // WRONG BYTES FOR utco = 12: // BYTE: 1 2 3 4 5 6 7 8 9 10 11 // CHAR: u t c o . . . . 1 2 . // HEX: 0x75 0x74 0x63 0x6F 0x03 0x00 0x00 0x00 0x31 0x32 0x00 // RIGHT BYTES FOR utco = 12: // BYTE: 1 2 3 4 5 6 7 8 9 10 11 12 // CHAR: u t c o . . . . . . . . // HEX: 0x75 0x74 0x63 0x6F 0x00 0x00 0x00 0x00 0x0C 0x00 0x00 0x00 // WRONG BYTES FOR utco = -1: // BYTE: 1 2 3 4 5 6 7 8 9 10 11 // CHAR: u t c o . . . . - 1 . // HEX: 0x75 0x74 0x63 0x6F 0x03 0x00 0x00 0x00 0x2D 0x31 0x00 // RIGHT BYTES FOR utco = -1: // BYTE: 1 2 3 4 5 6 7 8 9 10 11 12 // CHAR: u t c o . . . . ÿ ÿ ÿ ÿ // HEX: 0x75 0x74 0x63 0x6F 0x00 0x00 0x00 0x00 0x255 0x255 0x255 0x255 int i_byteValue; int i_byteCount = 0; int i_matches = 0; int i_sign = 1; int i_result = 0; // GET CHAR VALUE AT INDEX OF VECTOR: while ( (i_byteValue = (int)v_input[i_distance +8 +i_byteCount]) != 0 ) { // CHECK FOR MINUS: if ( (i_byteValue == '-') && (i_matches == 0) ) { i_sign = -1; i_matches++; } // CHECK FOR DIGIT: if ( (i_byteValue >= '0') && (i_byteValue <= '9') && (i_matches <= 2) ) { i_result *= 10; i_result += i_byteValue - '0'; i_matches++; } i_byteCount++; } i_result *= i_sign; // ADD FIX: if (i_result < 0) { // CONVERT DECIMAL TO HEXADECIMAL: // ONLY TESTED FOR -1!! DON'T KNOW IF ANYTHING LOWER WORKS AS IT SHOULD!! STILL HAS TO BE TESTED IF ANOTHER OBJECT FIELD WITH SUCH A RANGE < -1 SHOULD BE FIXED... unsigned char bytes[4]; unsigned long n = i_result; bytes[0] = (n >> 24) & 0xFF; bytes[1] = (n >> 16) & 0xFF; bytes[2] = (n >> 8) & 0xFF; bytes[3] = n & 0xFF; int dataArray[8] = { 0, 0, 0, 0, bytes[0], bytes[1], bytes[2], bytes[3] }; v_output.insert( v_output.end(), &dataArray[0], &dataArray[8] ); } else { int dataArray[8] = { c_rightBytes[4], c_rightBytes[5], c_rightBytes[6], c_rightBytes[7], i_result, 0, 0, 0 }; v_output.insert( v_output.end(), &dataArray[0], &dataArray[8] ); } i_distance2 = i_distance2 +4 +i_byteCount +1; // i_distance2 +4 +i_byteCount +1 BECAUSE: // u, t, c, o, 0x03, 0x00, 0x00, 0x00, \, 0, 0x00, // ^ = distance2 ^ = +4 ^ = +i_byteCount // CONTINUE SEARCH: it_counter = std::search( v_input.begin() +i_distance +4, v_input.end(), c_wrongBytes, c_wrongBytes +8 ); } // APPEND END OF INPUT VECTOR buffer TO OUTPUT VECTOR v_output: v_output.insert( v_output.end(), v_input.begin() +i_distance2, v_input.end() ); return v_output; } return std::vector<char>(); } int main(int argc, char **argv) { funcMpqOpenArchiveForUpdate MpqOpenArchiveForUpdate = 0; funcMpqCloseUpdatedArchive MpqCloseUpdatedArchive = 0; funcMpqAddFileFromBufferEx MpqAddFileFromBufferEx = 0; funcMpqAddFileFromBuffer MpqAddFileFromBuffer = 0; funcSFileOpenFileEx SFileOpenFileEx = 0; funcSFileGetFileSize SFileGetFileSize = 0; funcSFileReadFile SFileReadFile = 0; funcSFileCloseFile SFileCloseFile = 0; HINSTANCE hSFMpq = 0; hSFMpq = LoadLibrary("SFMpq.dll"); // "SFMpq.dll" FROM PitzerMike WAS BUILD AS 32-BIT DLL! // IF YOU WANT TO USE THIS DLL, YOUR PROJECT HAS TO BE COMPILED AS 32-BIT TOO, OTHERWISE THE DLL ISN'T LOADED! // IF DLL 'SFMpq.dll' WAS LOADED, CONTINUE: if (hSFMpq!=0) { MpqOpenArchiveForUpdate = (funcMpqOpenArchiveForUpdate)GetProcAddress(hSFMpq,"MpqOpenArchiveForUpdate"); MpqCloseUpdatedArchive = (funcMpqCloseUpdatedArchive)GetProcAddress(hSFMpq,"MpqCloseUpdatedArchive"); MpqAddFileFromBufferEx = (funcMpqAddFileFromBufferEx)GetProcAddress(hSFMpq,"MpqAddFileFromBufferEx"); MpqAddFileFromBuffer = (funcMpqAddFileFromBuffer)GetProcAddress(hSFMpq,"MpqAddFileFromBuffer"); SFileOpenFileEx = (funcSFileOpenFileEx)GetProcAddress(hSFMpq,"SFileOpenFileEx"); SFileGetFileSize = (funcSFileGetFileSize)GetProcAddress(hSFMpq,"SFileGetFileSize"); SFileReadFile = (funcSFileReadFile)GetProcAddress(hSFMpq,"SFileReadFile"); SFileCloseFile = (funcSFileCloseFile)GetProcAddress(hSFMpq,"SFileCloseFile"); HANDLE mpq = MpqOpenArchiveForUpdate(argv[1], MOAU_OPEN_EXISTING | MOAU_MAINTAIN_LISTFILE, 1024); HANDLE file; if(!SFileOpenFileEx(mpq, "war3map.w3u", 0, &file)) { // DEBUG: MessageBox(0, "fail: could not open 'war3map.w3u'", "ObjectMergerFixer: error", MB_OK); std::cout << "fail: could not open 'war3map.w3u'\n" << "HIT ENTER TO CONTINUE!\n"; getchar(); return 0; } DWORD size = SFileGetFileSize(file, 0); // Retrieves a size of the file within archive // http://www.zezula.net/en/mpq/stormlib.html char * c_buf = new char[size]; SFileReadFile(file, c_buf, size, &size, NULL); // Reads data from the file // http://www.zezula.net/en/mpq/stormlib.html // CONTENT FROM FILE file IS SAVED TO buf.buf SFileCloseFile(file); // W3U FIXES: // COPY INPUT W3U DATA INTO BUFFER: std::vector<char> v_input( c_buf, c_buf +size ); // uaen: const char c_uaen_wrong[9] = { 0x75, 0x61, 0x65, 0x6E, 0x03, 0x00, 0x00, 0x00 }; // { 0x75, 0x61, 0x65, 0x6E, ... } = { u, a, e, n, ... } const char c_uaen_right[9] = { 0x75, 0x61, 0x65, 0x6E, 0x00, 0x00, 0x00, 0x00 }; // { 0x75, 0x61, 0x65, 0x6E, ... } = { u, a, e, n, ... } std::vector<char> v_output = getFixedW3U( v_input, c_uaen_wrong, c_uaen_right ); // utco: const char c_utco_wrong[9] = { 0x75, 0x74, 0x63, 0x6F, 0x03, 0x00, 0x00, 0x00 }; // { 0x75, 0x74, 0x63, 0x6F, ... } = { u, t, c, o, ... } const char c_utco_right[9] = { 0x75, 0x74, 0x63, 0x6F, 0x00, 0x00, 0x00, 0x00 }; // { 0x75, 0x74, 0x63, 0x6F, ... } = { u, t, c, o, ... } if ( v_output.empty() ) { v_output = getFixedW3U( v_input, c_utco_wrong, c_utco_right ); } else { v_output = getFixedW3U( v_output, c_utco_wrong, c_utco_right ); } // EXIT IF NO FIXES NEED TO BE APPLIED: if ( v_output.empty() ) { MpqCloseUpdatedArchive(mpq, 0); return 0; } // ADD FIXED W3U BACK TO W3M/W3X: if ( !MpqAddFileFromBufferEx(mpq, (LPVOID)v_output.data(), v_output.size(), "war3map.w3u", MAFA_REPLACE_EXISTING | MAFA_COMPRESS, MAFA_COMPRESS_DEFLATE, Z_BEST_COMPRESSION) ) { // DEBUG: MessageBox(0, "fail: could not write 'war3map.w3u'", "ObjectMergerFixer: error", MB_OK); std::cout << "fail: could not write 'war3map.w3u'\n" << "HIT ENTER TO CONTINUE!\n"; getchar(); } if ( !MpqCloseUpdatedArchive(mpq, 0) ) { // DEBUG: MessageBox(0, "fail: could not update MPQ", "ObjectMergerFixer: error", MB_OK); std::cout << "fail: could not update MPQ\n" << "HIT ENTER TO CONTINUE!\n"; getchar(); } // IF DLL 'SFMpq.dll' WAS NOT LOADED, EXIT: } else { // DEBUG: MessageBox(0, "fail: could not load 'SFMpq.dll'", "ObjectMergerFixer: error", MB_OK); std::cout << "fail: could not load 'SFMpq.dll'\n" << "HIT ENTER TO CONTINUE!\n"; getchar(); } return 0; }
Private
[
?
]
Run code
Submit