#include // std::copy, std::copy_n #include // std::istreambuf_iterator, std::ostreambuf_iterator, std::back_inserter #include // std::vector #include // std::ifstream, std::ofstream template T IStreamRead(std::basic_istream& stream) { return T ( std::istreambuf_iterator(stream), std::istreambuf_iterator() ); } template std::vector BufferRead_N(std::basic_istream& stream, std::size_t read) { std::vector out; std::copy_n(std::istreambuf_iterator(stream), read, std::back_inserter(out)); return out; } template void IStreamWrite(std::basic_ostream& stream, T& write) { std::copy(write.begin(), write.end(), std::ostreambuf_iterator(stream)); }; #include #include #include struct MM2FileHeader { WORD entryCount; WORD word02; DWORD dword4; DWORD dword8; DWORD dwordC; DWORD firstEntryOffset; }; struct MM2FileStruct { DWORD dword00; DWORD dword04; DWORD dword08; DWORD dword0C; DWORD dword10; FILETIME fileTime; DWORD dword1C; WORD firstStringLength; }; struct MM2InstallerEntry { WORD entryType; // 10 WORD field02; DWORD field04; DWORD dword8; // 11 DWORD dwordC; // 0 WORD word10; // 19 WORD word12; DWORD entrySize; DWORD dword18; // 1 DWORD dword1C; DWORD dword20; // 4294967295 BYTE byte24; BYTE gap25; WORD field26; DWORD fileSize; DWORD field2C; DWORD field30; DWORD lpUnkString; MM2InstallerEntry* lpNextEntry2; MM2InstallerEntry* lpNextEntry; WORD gap40; WORD field_42; WORD field_44; WORD field_46; MM2FileStruct fileStruct; }; const char* months[ ] = { "January", "Februray", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; void view() { std::vector bytes = IStreamRead> ( std::ifstream("SETUPDATA.bin", std::ifstream::binary) ); MM2FileHeader* header = (MM2FileHeader*)(bytes.data()); WORD itemCount = header->entryCount; MM2InstallerEntry* currentEntry = (MM2InstallerEntry*)((char*)(&header->dwordC) + header->firstEntryOffset); while (itemCount-- > 0) { DebugBreak(); switch (currentEntry->entryType) { case 3: { } break; case 2: case 11: { } break; case 10: { char* from = (char*)(¤tEntry->fileStruct.firstStringLength) + 2; char* to = from + currentEntry->fileStruct.firstStringLength; char* copyType = to + strlen(to) + 1; // 1 = Always, 2 = Only in full version char* unkNumber2 = copyType + strlen(copyType) + 1; // Always -1; SYSTEMTIME systemTime; FileTimeToSystemTime(¤tEntry->fileStruct.fileTime, &systemTime); printf_s("Copy File %24s to %24s | %s, %s - %hu %s %hu \n", from, to, copyType, unkNumber2, systemTime.wDay, months[systemTime.wMonth], systemTime.wYear); } break; case 13: { // Set some global variable to true } break; }; currentEntry = (MM2InstallerEntry*)((char*)currentEntry + currentEntry->entrySize + 0x48); }; std::cin.get(); } #include int main() { view(); return 0; //std::vector fileBytes = IStreamRead> //( // std::ifstream("SETUPDATA.bin", std::ifstream::binary) //); //WORD* entryCount = (WORD*)(fileBytes.data() + 0); std::vector fileBytes; std::vector> mods = { { "mods\\! !rv5_audio.ar", "! !rv5_audio.ar" }, { "mods\\! !rv5_buckNeye.ar", "! !rv5_buckNeye.ar" }, { "mods\\! !rv5_graphics.ar", "! !rv5_graphics.ar" }, { "mods\\! !rv5_groover.ar", "! !rv5_groover.ar" }, { "mods\\! !rv5_LOD.ar", "! !rv5_LOD.ar" }, { "mods\\! !rv5_maincars.ar", "! !rv5_maincars.ar" }, { "mods\\! !rv5_maincity.ar", "! !rv5_maincity.ar" }, { "mods\\! !rv5_materials.ar", "! !rv5_materials.ar" }, { "mods\\! !rv5_mirrordist.ar", "! !rv5_mirrordist.ar" }, { "mods\\! !rv5_pickupNvan.ar", "! !rv5_pickupNvan.ar" }, { "mods\\! !rv5_seagulls.ar", "! !rv5_seagulls.ar" }, { "mods\\! !rv5_trafficweight.ar", "! !rv5_trafficweight.ar" }, { "mods\\!!mod_riva_refl_3.1.ar", "!!mod_riva_refl_3.1.ar" }, { "mods\\!!sm2.ar", "!!sm2.ar" }, { "mods\\Fire and Smoke mod-3.2.ar", "Fire and Smoke mod-3.2.ar" }, { "patch\\Midtown2.exe", "Midtown2Patched.exe" }, }; fileBytes.push_back(BYTE(mods.size())); for (auto mod : mods) { std::vector bytes = std::vector(106, NULL); MM2InstallerEntry* entry = (MM2InstallerEntry*)(bytes.data()); std::string from = "game\\" + mod[0]; std::string to = mod[1]; std::string copyType = "1"; // 2 std::string unkNum2 = "-1"; // 3 entry->entryType = 10; entry->dword8 = 11; entry->word10 = 19; entry->entrySize = 34 + // MM2FileStruct (without end padding) WORD(from.size()) + 1 + // from + 1 WORD(to.size()) + 1 + // to + 1 WORD(copyType.size()) + 1 + // copy type + 1 WORD(unkNum2.size()) + 1 + // unkNnum2 + 1 4; // FF FF FF FF entry->dword18 = 1; entry->dword20 = 4294967295; entry->fileSize = 0; entry->fileStruct.dword1C = 80; entry->fileStruct.firstStringLength = WORD(from.size() + 1); bytes.insert(bytes.end(), from.begin(), from.end()); bytes.push_back('\0'); bytes.insert(bytes.end(), to.begin(), to.end()); bytes.push_back('\0'); bytes.insert(bytes.end(), copyType.begin(), copyType.end()); bytes.push_back('\0'); bytes.insert(bytes.end(), unkNum2.begin(), unkNum2.end()); bytes.push_back('\0'); bytes.push_back('\xFF'); bytes.push_back('\xFF'); bytes.push_back('\xFF'); bytes.push_back('\xFF'); fileBytes.insert(fileBytes.end(), bytes.begin(), bytes.end()); } IStreamWrite(std::ofstream("SETUPDATA2.bin", std::ofstream::binary), fileBytes); std::cin.get(); return 0; }