Server Emulator

Warning

Server emulator is not fully functional. It’s just a proof of concept. Lots of WorldServer events are only triggerable from python InteractiveConsole.

Requirements

In order to run the differents scripts, you must have installed:

MythLoginServiceConfig

WAR.exe at launch will extract XML data from the file data/MythLoginServiceConfig.xml (data.myp ; Hash name : 0x3FE03665349E2A8C).

XML data contains address and port used for the LoginServer, if you want to run your own server, you will have to replace this configuration file.

MythLoginServiceConfig.xml file entry informations in data.myp:

  • offset = 12463784
  • size_header = 136
  • sizez = 306
  • size = 810
  • name = 4602738627475024524
  • crc = 1840099700
  • flag = 1
Get original content of MythLoginServiceConfig.xml from data.myp
>>> import hashlib
>>> import zlib
>>> hashlib.md5(open("data.myp", "rb").read()).hexdigest()
'fc0cac05ba416e920b3a6dd7defa8fc1'
>>> fd = open("data.myp", "rb")
>>> fd.seek(12463784 + 136, 0)          # seek to (offset + size_header)
>>> print zlib.decompress(fd.read(306)) # read sizez
<?xml version="1.0" encoding="utf-8"?>
<RootElementOfAnyName>
<MythLoginServiceConfig>
    <Settings>
    <ProductId>2</ProductId>
    <MessageTimeoutSecs>20</MessageTimeoutSecs>
    </Settings>
    <RegionList>
    <Region regionName="WAR Live">
        <PingServer serverName="None">
        <Address>0.0.0.0</Address>
        <Port>0</Port>
        </PingServer>
        <LoginServerList>
        <LoginServer serverName="login 1">
            <Address>107.23.232.189</Address>
            <Port>8046</Port>
        </LoginServer>
        <LoginServer serverName="login 2">
            <Address>107.23.135.143</Address>
            <Port>8046</Port>
        </LoginServer>
        </LoginServerList>
    </Region>
    </RegionList>
</MythLoginServiceConfig>
</RootElementOfAnyName>

Loading of this file is done in sub at 0x004ACE41.

.text:004ACF1E 68 AC 98 A7 00          push    offset aMythloginservi ; "MythLoginServiceConfig.xml"
.text:004ACF23 68 58 24 A7 00          push    offset aData    ; "data"

...

.text:004ACF6A E8 C5 06 3E 00          call    sub_88D634
.text:004ACF6F 8B 08                   mov     ecx, [eax]

The call to 0x0088D634 will get the content of file MythLoginServiceConfig.xml from data.myp archive.

In order to not alter the data.myp file, we can insert a Hook just after the call 0x0088D634 and we will be able to replace the content of the file.

The DLL replace_xml will setup an hook for replacing the content at runtime when injected inside WAR.exe.

Replace XML

You can create a file server_ip.txt inside warhammer online folder that will be load by replace_xml.dll for the server address.

Example server_ip.txt
E:\Game\Warhammer Online>type server_ip.txt
192.168.1.42

If server_ip.txt is not found, the default ip address value is: 127.0.0.1

Inject DLL

You can use the project injector for injecting the DLL in WAR.exe.

Warning

acctname and sesstoken arguments for WAR.exe are hardcoded inside the injector

Example
E:\Game\Warhammer Online>war_injector.exe replace_xml.dll

You can create a shortcut (.lnk) or a script (.bat) for next launch

Now warhammer online will connect to the LoginServer at IP address you specified or default one.

LoginServer

Before running WAR_LoginServer.py, you must have installed correctly all the requirements (see Requirements.).

Open a window cmd shell, navigate to server folder, and launch WAR_LoginServer.py.

Any authentication token is accepted, there is no check/validation.

If the WorldServer is not running on localhost, edit in the function handle_GetClusterList() in WAR_LoginServer.py the following line:

cluster_info.lobby_host = "127.0.0.1" # IP TO REPLACE

WorldServer

Before running WAR_WorldServer.py, you must have installed correctly all the requirements (see Requirements.).

Open a window cmd shell, navigate to server folder, and launch WAR_WorldServer.py.

Only one character is sent to the client for character list, but you can edit the dict CHARACTER in premaidcharacter().

Once your character choosed, you can edit the packet PACKET_S_PLAYER_INITTED in response_S_PLAYER_INITTED() for all infos regarding the positioning of your character.

object_id of player is hardcoded to value 0x4242.

Interactive Console

TODO