Brick icon

Midtown Madness 2 Installer Patcher

Brick | PRO | 09/22/16 07:47:58 PM UTC | 0 ⭐ | 243 👁️ | Never ⏰ | []
C++ |

7.03 KB

|

None

|

0 👍

/

0 👎

#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*)(&currentEntry->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(&currentEntry->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

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎