#include <algorithm> // std::copy, std::copy_n
#include <iterator> // std::istreambuf_iterator, std::ostreambuf_iterator, std::back_inserter
#include <vector> // std::vector
#include <fstream> // std::ifstream, std::ofstream
template <typename T, typename CharT>
T IStreamRead(std::basic_istream<CharT>& stream)
{
return T
(
std::istreambuf_iterator<CharT>(stream),
std::istreambuf_iterator<CharT>()
);
}
template <typename CharT>
std::vector<CharT> BufferRead_N(std::basic_istream<CharT>& stream, std::size_t read)
{
std::vector<CharT> out;
std::copy_n(std::istreambuf_iterator<CharT>(stream), read, std::back_inserter(out));
return out;
}
template <typename T, typename CharT>
void IStreamWrite(std::basic_ostream<CharT>& stream, T& write)
{
std::copy(write.begin(), write.end(), std::ostreambuf_iterator<CharT>(stream));
};
#include <iostream>
#include <string>
#include <Windows.h>
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<BYTE> bytes = IStreamRead<std::vector<BYTE>>
(
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 <array>
int main()
{
view();
return 0;
//std::vector<char> fileBytes = IStreamRead<std::vector<char>>
//(
// std::ifstream("SETUPDATA.bin", std::ifstream::binary)
//);
//WORD* entryCount = (WORD*)(fileBytes.data() + 0);
std::vector<char> fileBytes;
std::vector<std::array<std::string, 2>> 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<char> bytes = std::vector<char>(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;
}
Comments
0 B
|👍
/👎