• We have updated our Community Code of Conduct. Please read through the new rules for the forum that are an integral part of Paradox Interactive’s User Agreement.

Shn

Private
51 Badges
Dec 19, 2009
21
0
  • Crusader Kings II: Charlemagne
  • Europa Universalis IV: Pre-order
  • Crusader Kings II
  • Europa Universalis IV: Res Publica
  • Heir to the Throne
  • Europa Universalis IV: Call to arms event
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Art of War
  • Europa Universalis IV
  • Europa Universalis III: Chronicles
  • Europa Universalis III
  • Crusader Kings II: Sword of Islam
  • Crusader Kings II: Sons of Abraham
  • Crusader Kings II: The Republic
  • Crusader Kings II: Rajas of India
  • Crusader Kings II: The Old Gods
  • Crusader Kings II: Legacy of Rome
  • Divine Wind
  • Stellaris: Leviathans Story Pack
  • Crusader Kings II: Monks and Mystics
  • Stellaris - Path to Destruction bundle
  • Europa Universalis IV: Mandate of Heaven
  • Stellaris: Synthetic Dawn
  • Europa Universalis IV: Cradle of Civilization
  • Stellaris: Humanoids Species Pack
  • Stellaris: Apocalypse
  • Stellaris: Distant Stars
  • Stellaris: Federations
  • Stellaris: Megacorp
  • Crusader Kings II: Holy Fury
  • Prison Architect
  • Stellaris: Ancient Relics
  • Stellaris: Lithoids
  • Crusader Kings II: Horse Lords
  • Victoria 2
  • 500k Club
  • Cities: Skylines Deluxe Edition
  • Crusader Kings II: Holy Knight (pre-order)
  • Europa Universalis IV: El Dorado
  • Crusader Kings II: Way of Life
  • Europa Universalis IV: Common Sense
  • Stellaris: Digital Anniversary Edition
  • Europa Universalis IV: Cossacks
  • Crusader Kings II: Conclave
  • Stellaris
  • Crusader Kings II: Reapers Due
  • Europa Universalis IV: Rights of Man
  • Crusader Kings II: Jade Dragon
  • Europa Universalis IV: Mare Nostrum
I've written a little patch to modify the EXE to remove the hard-coded restriction on selecting non-Christians, Republics and Theocracies. I know you can already play those characters using the console, but I prefer to be able to select them on the normal selection screen. I have written this as a patch to the EXE this time instead of using DLL injection like I used for my duchy limit mod because I play the game on Mac OS X under Crossover and it doesn't seem to support the Windows APIs I used, so I ended up having to patch the EXE anyway. I've only tested it on the GamersGate 1.03b version, it's quite possible it won't work on the Steam version, though I wrote it in a more flexible way than the duchy limit mod so there's a chance it will work. If it doesn't work and you have a copy of the Steam version and you don't mind doing some testing, please PM me.

To create a patched version of the EXE, run it like this from cmd.exe:
Code:
PlayEveryonePatch.exe "C:\Program Files\Paradox Interactive\Crusader Kings II\ck2.exe" ck2_patched.exe

It will output a patched version in the working directory, which you can copy/paste/rename to replace the original EXE (back it up first!). If you want to output directly to your game dir in Program Files you will need to run cmd.exe as administrator in Windows Vista and Windows 7 unless you have disabled UAC (I think).

Here's a pre-compiled binary:
View attachment PlayEveryonePatch.exe

Here is the source code (from some reason I can't upload a file with a .cpp extension):
View attachment playeveryone.txt
Code:
#include <iostream>
#include <fstream>
#include <cstring>

struct Patch
{
    char *orig;
    char *patch;
    int size;
};

char * memmem(char *src, int src_size, char *pattern, int pattern_size);

int main(int argc, char **argv)
{
    const static Patch PATCHES[] = {
                                     //Patches for map tooltip

                                     //Is unplayable religion
                                     {
                                       {
                                         "\x80\x78\x71\x00" //CMP [EAX+71], 0
                                         "\x0F\x85\xD7\x00\x00\x00" //JNE +0xD7
                                       },
                                       {
                                         "\x80\x78\x71\x00" //CMP [EAX+71], 0
                                         "\xE9\xD8\x00\x00\x00" //JMP +0xD8
                                         "\x90" //NOP
                                       },
                                       10
                                     },
                                     //Is a republic
                                     {
                                       {
                                         "\x83\xFE\x01" //CMP ESI, 1
                                         "\x0F\x85\x36\x01\x00\x00" //JNE +0x136
                                       },
                                       {
                                         "\x83\xFE\x01" //CMP ESI, 1
                                         "\xE9\x37\x01\x00\x00" //JMP +0x137
                                         "\x90" //NOP
                                       },
                                       9
                                     },
                                     //Is a theocracy
                                     {
                                       {
                                         "\x83\xFE\x02" //CMP ESI, 2
                                         "\x74\x33" //JE +0x33
                                       },
                                       {
                                         "\x83\xFE\x02" //CMP ESI, 2
                                         "\x90" //NOP
                                         "\x90" //NOP
                                       },
                                       5
                                     },
                                     //Playable test? - jumps to RETN
                                     {
                                       {
                                         "\x80\xB8\xF8\x02\x00\x00\x00" //CMP [EAX+2F8], 0
                                         "\x0F\x84\x23\xFD\xFF\xFF" //JE -0x2DD
                                       },
                                       {
                                         "\x80\xB8\xF8\x02\x00\x00\x00" //CMP [EAX+2F8], 0
                                         "\xE9\x24\xFD\xFF\xFF" //JMP -0x2DC
                                         "\x90" //NOP
                                       },
                                       13
                                     },

                                     //Patches for "Play" button

                                     //Is a theocracy
                                     {
                                       {
                                         "\x38\x98\xF8\x02\x00\x00" //CMP [EAX+2F8], BL
                                         "\x0F\x85\x15\x01\x00\x00" //JNE +0x115
                                       },
                                       {
                                         "\x38\x98\xF8\x02\x00\x00" //CMP [EAX+2F8], BL
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                       },
                                       12
                                     },
                                     //Is unplayable religion
                                     //Is a republic
                                     {
                                       {
                                         "\x0F\x84\xAD\x00\x00\x00" //JE +0xAD
                                         "\x39\x5D\xE8" //CMP [EBP-18], BL
                                         "\x0F\x85\xA4\x00\x00\x00" //JNE +0xA4
                                       },
                                       {
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x39\x5D\xE8" //CMP [EBP-18], BL
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                         "\x90" //NOP
                                       },
                                       15
                                     },
                                     //Unplayable tooltip on button hover
                                     {
                                       {                                           
                                         "\x3B\xF3" //CMP ESI, EBX
                                         "\x0F\x84\x87\x07\x00\x00" //JE +0x787
                                       },
                                       {
                                         "\x3B\xF3"  //CMP ESI, EBX
                                         "\xE9\x88\x07\x00\x00"  //JMP +0x788
                                         "\x90" //NOP
                                       },
                                       8
                                     },
                                   };

    const static int NUM_PATCHES = 7;

    if (argc != 3)
    {
        std::cerr << "Invalid arguments" << std::endl;
        std::cerr << "Usage: " << argv[0] << " " << "<input file> <output file>" << std::endl;
        return 1;
    }

    std::fstream in_file;

    in_file.open(argv[1], std::ios::in | std::ios::binary | std::ios::ate);

    if (!in_file.is_open())
    {
        std::cerr << "Unable to open " << argv[1] << " for reading" << std::endl;
        return 1;
    }

    int file_size = in_file.tellg();
    char *buf = new char[file_size];

    in_file.seekg(0, std::ios::beg);
    in_file.read(buf, file_size);

    in_file.close();

    char *patch_point;

    for (int i = 0; i < NUM_PATCHES; i++)
    {
        const Patch *p = &PATCHES[i];
        patch_point = memmem(buf, file_size, p->orig, p->size);
        if (patch_point != NULL)
        {
            std::cout << "Patching " << p->size << " bytes at offset " << (int) patch_point - (int) buf << std::endl;
            std::memcpy(patch_point, p->patch, p->size);
        }
        else 
        {
            std::cerr << "Failed to find patch location " << i << ", dying" << std::endl;
            return 1;
        }
    }

    std::fstream out_file;

    out_file.open(argv[2], std::ios::out | std::ios::binary | std::ios::trunc);

    if (!out_file.is_open())
    {
        std::cerr << "Unable to open " << argv[2] << " for writing" << std::endl;
        return 1;
    }

    out_file.write(buf, file_size);

    out_file.close();

    delete[] buf;

	return 0;
}

char * memmem(char *src, int src_size, char *pattern, int pattern_size) 
{
    char *pos = src;

    do 
    {

        pos = (char *) std::memchr(pos, pattern[0], src + src_size - pos);
        if (pos != NULL)
        {
            if (pos + pattern_size < src + src_size)
            {
                if (std::memcmp(pos, pattern, pattern_size) == 0)
                {
                    break;
                } else
                {
                    pos++;
                }
            }
            else
            {
                pos = NULL;
            }
        }
    } while (pos != NULL);

    return pos;
}
 
Quick question, does the game still work when you play as a Republic or Theocracy? I would guess that at the very least, their laws and character views don't work the same way.
 
I haven't actually tested them, I really just wanted to play as Muslims and it was simple enough to disable the checks for the others too.

Edit: Oops, I just checked and it seems if you try to start a game as a theocracy or republic you get an instant game over screen. I'll see what I can do about that tomorrow, I'm going to bed now. I don't know how well the mechanics of the game will work if you try to play as the pope or a republic though.