Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Intro

I have been fiddling around with the spectator system for LoL in hopes of eventually scraping data from the streams and building a dataset with it for analysis. I understand that there are already some unofficial APIs and techniques, but I am looking for really specific game events (champion kills, turret kills, item puchases, jungle mob kills, champion co-ords for particular events, etc).

What I have figured out so far

When you begin spectating a game (in NA), your client connects to the following host:

spectator.na.lol.riotgames.com:8088

I assume this host is backed by Amazon AWS or similar. Anyways, the next thing that happens is the client sends a version request to the spectate server:

GET /observer-mode/rest/consumer/version

This returns whatever the current spectator server version is. Ex: '1.80.54'

Next, the client sends a request for the game metadata:

GET /observer-mode/rest/consumer/getGameMetaData/NA1/[gameid]/[some random nonce]/token

This returns metadata about the game. An example of this data: http://pastebin.com/3N4qs0hx

The client now knows the parameters by which the spectate session should progress. It tries to locate the latest data chunk by calling:

GET /observer-mode/rest/consumer/getLastChunkInfo/NA1/[gameid]/30000/token

Sample of this data: http://pastebin.com/Cj7dEAr9

Once the data chunks have been identified, they are requested:

GET /observer-mode/rest/consumer/getGameDataChunk/NA1/[gameid]/[token#]/token

Sample of a token's data (binary converted to hex): http:// pastebin.com /GyqPRP5J

The game cycles between calling getLastChunkInfo and getGameDataChunk as data becomes available from the replay stream. There is also a call which occurs after about 5 chunks are grabbed to the following:

GET /observer-mode/rest/consumer/getKeyFrame/NA1/[gameid]/[somechunkid]/token

I believe this call only occurs at the replay start up and whenever the user seeks to a different time.

I know the game uses encryption at some level. I believe it to be Blowfish ECB, with the actual key specified on the command line. I have attempted to decrypt these tokens using the session's key, but they still look pretty random.

Edit 3/23/2013

  • I have determined that the tokens are most likely not encrypted by modifying the command line argument containing the key and re-launching the game from debugger (it loaded the replay correctly).
  • The tokens seem to be compressed. There is a call to a subroutine which if returns non-zero integer will trigger the following:

    if ( sub_B71120(v21, v15, (int *)&Size, *(_DWORD *)(v6 + 108)) )
    {
    sub_BAD700(
    (int)"!\"Error Decompressing data chunk.\"",
    (int)"D:\\jenkins\\workspace\\Code-CI-Releases-Public\\code\\HeroWars_clientServer\\Sources\\ReplaySystem\\ReplayServerConnection.cpp",
    6,
    (int)"Riot::Replay::ReplayServerConnection::GetChunk",
    (int)"Assert occurred, game may crash.");
    sub_9BB750("ReplayServerConnection GetChunk error. Error decompressing chunk data. Error: %d\n");
    }
    
  • Upon investigation of sub_B71120 I have located a call which eventually enters a fairly large function. This function contains strings like:

    • "incorrect header check"
    • "unknown compression method"
    • "invalid window size"
  • A quick Google search of these strings reveals the following: http://www.opensource.apple.com/source/zlib/zlib-22/zlib/inflate.c

  • I have also found the string reference "1.2.3" in a function call just before the call to inflate.c method, as well as another reference "inflate 1.2.3 Copyright 1995-2005 Mark Adler". It definitely looks like they are using Zlib version 1.2.3 for the decompression of the tokens. I just can't get them to decompress regardless of what file offset I start at.

My question(s)

Does anyone know how these 'tokens' might be formatted or if there is some type of compression/encryption I am unaware of? I have a suspicion that they are some compressed or packed form of the ethernet packets used during live play which are simply played back internally to the client.

Alternatively, can anyone think of some other method by which to scrape this data without running the actual game client? Keep in mind I would like to grab data from many streams simultaneously.

share|improve this question
1  
The way I thought to go about it was to grab as many replay files from LOLReplay as possible and just crunch those. There is, I think, an open archive where people can upload their own games, and I think the new spectator mode lets the Replay client grab more information than it did before. –  Robert S. Feb 26 '13 at 5:10
    
What other APIs and Techniques are there? Why do you think there is encryption? I found this in the GetGameMetaData: "encryptionKey":"" and "decodedEncryptionKey":"" –  Nathan Goings Mar 4 '13 at 0:43
    
As an FYI for the people who keep landing on this question from various LoL forums, seeing my name on the post under "edited by," and emailing me to ask about the topic... I don't know anything about LoL or the format of its streams. Please don't email me about it. –  Josh Petrie Jun 13 at 2:45

1 Answer 1

up vote 5 down vote accepted

I've been researching the same thing and I found this repo to be extremely helpful. The file decrypt.rb decrypts both chunks and keyframes.

Edit: check out this reddit thread too.

share|improve this answer
    
Excellent. The first link answers my question precisely. The second link is also really helpful. Thanks a ton! –  Bob Mar 25 '13 at 1:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.