I'm almost done building the equipment system. Equipping items, unequipping items, and updating the player graphic is completed. All that is left is to implement examining other players. The whole item list had to be uploaded into the server database to do checks like if a item has been max-stacked or what type of item it is. Sadly graphical data is not stored on the client (unlike 2.0) and requires me inputting every model id. Luckily these match pretty well with 2.0 as the whole db was imported when they transitioned. Here are some tests I did:



I also took a look at the original login and updater exes to see if I could get them working, instead of using SU (for that authentic effect). First I had to figure out the updater's version check request. This turned out easy at first and became very difficult. This updater and it's server is the same one used to update 2.0's launcher (the version check/download that happens in the grey box before the launcher appears). Using Wireshark and Fiddler I saw the HTTP GET request the program makes. The API works like this:

A request is made to "<website>/vercheck/ffxiv/win32/release/game(or boot)/<patchnumber>". If the version is up to date, the server responds with

header("HTTP/1.0 204 No Content");
header("Content-Location: ffxiv/2d2a390f/vercheck.dat");
header("X-Repository: ffxiv/win32/release/boot");
header("X-Patch-Module: ZiPatch");
header("X-Protocol: torrent");
header("X-Info-Url: http://www.example.com");
header("X-Latest-Version: 2012.09.19.0000");

If there is an update, it responds with

header("HTTP/1.0 200 OK");
header("Content-Location: ffxiv/48eca647/vercheck.dat");
header("Content-Type: multipart/mixed; boundary=477D80B1_38BC_41d4_8B48_5273ADB89CAC");
header("X-Repository: ffxiv/win32/release/boot");
header("X-Patch-Module: ZiPatch");
header("X-Protocol: torrent");
header("X-Info-Url: http://example.com");
header("X-Latest-Version: 2012.05.20.0000.0001");
header("Connection: keep-alive")

Content-Type: application/octet-stream
Content-Location: ffxiv/48eca647/metainfo/D2012.05.20.0000.0001.torrent
X-Patch-Length: 20874726
X-Signature: jqxmt9WQH1aXptNju6CmCdztFdaKbyOAVjdGw_DJvRiBJhnQL6UlDUcqxg2DeiIKhVzkjUm3hFXOVUFjygxCoPUmCwnbCaryNqVk_oTk_aZE4HGWNOEcAdBwf0Gb2SzwAtk69zs_5dLAtZ0mPpMuxWJiaNSvWjEmQ925BFwd7Vk=


These are both HTTP responses. They are technically copy/pastes of some PHP code on my server. First; in the header is the patch format (ZiPatch), the protocol to download (can by HTTP or Torrent), latest version info, and some general HTTP stuff. If there is a patch, a body entity is also added, with the content location, patch length, a signature, and then either the HTTP file or Torrent file.

About the content-location; both define a directory in your downloads folder under /My Documents/My Games/Final Fantasy XIV/downloads. The header version is to store the vercheck.dat file... this is basically the response saved into a file. The one in the entity body is where to download the http or torrent file to.

In 1.0, all patches were signed and the "X-Signature" gives the signature to verify the patch with. Strangely this was no longer done in 2.0. After these headers, the torrent or http file is appended. All of the patch stuff in 1.0 was done through torrents. However in 2.0 the patches are downloaded using http, and a simple file is sent, consisting of a bunch space-seperated-values including the url to download the patch at.

After a bunch of debugging and trial and error I was able to get the updater to work. To by-pass the signature issue, I found the "RSA_verify" function (part of the OpenSSL library) in ffxivboot.exe and forced it to always return 1 (return true; it's verified). Sadly there seems to be some limitations with the torrent client. I think the client will only talk to certain trackers or peers, and explains why the official updater was so slow compared to normal torrent clients. I shelved work on the updater till a later time.


Regardless, even if I couldn't patch, I could at least inform the updater it was up to date and start the login client. It's a very simply program that shows a Internet Explorer Frame. If a downloaded HTML page has this tag:

<x-sqexauth sid="$sessionId" lang="en-us" region="2" utc="11231131" />

It will start ffxivgame.exe with the given arguments. Now to get the official login client to work... I had to finish one of the last missing core components of the lobby server: the blowfish key generation. All of the lobby traffic is encrypted using Blowfish encryption. The client grabs the current computer time at launch and send that to the server unencrypted. Along with a phrase "Test Ticket Data" to help generate the key. It combines these two pieces of info and some other constant numbers, it then MD5 hashes this into a 128bit key for Blowfish.

With Seventh Umbral (and my server as well until now), the SU launcher was forcing the time to a constant value. On the server side it used the same key at all times. With the original login client, it would send a new time value to the server at each launch so key generation had to be completed. Well, now it is and you can login using either clients!

I got a friend who is way better at webdev than me to write a look-a-like of the original login page: