Intro
Mi sono armeggiato con il sistema di spettatori per LoL nella speranza di alla fine raccogliere dati dai flussi e costruire un set di dati con esso per l'analisi. Comprendo che ci sono già alcune API e tecniche non ufficiali, ma sto cercando eventi di gioco davvero specifici (uccisioni di campioni, uccisioni di torrette, uccisioni di mob della giungla, uccisioni di mafia della giungla, combinazioni di campioni per eventi particolari, ecc.).
Quello che ho capito finora
Quando inizi a guardare un gioco (in NA), il tuo client si connette al seguente host:
spectator.na.lol.riotgames.com:8088
Presumo che questo host sia supportato da Amazon AWS o simili. Comunque, la prossima cosa che succede è che il client invia una richiesta di versione al server spectate:
OTTIENI / modalità osservatore / resto / consumatore / versione
Ciò restituisce qualunque sia la versione corrente del server spettatore. Es .: "1.80.54"
Successivamente, il client invia una richiesta per i metadati del gioco:
GET / modalità osservatore / resto / consumatore / getGameMetaData / NA1 / [gameid] / [alcuni nonce casuali] / token
Questo restituisce metadati sul gioco. Un esempio di questi dati: http://pastebin.com/3N4qs0hx
Il client ora conosce i parametri in base ai quali la sessione di spettatori dovrebbe progredire. Cerca di individuare l'ultimo blocco di dati chiamando:
GET / modalità osservatore / resto / consumatore / getLastChunkInfo / NA1 / [gameid] / 30000 / token
Esempio di questi dati: http://pastebin.com/Cj7dEAr9
Una volta identificati i blocchi di dati, vengono richiesti:
GET / modalità osservatore / resto / consumatore / getGameDataChunk / NA1 / [gameid] / [token #] / token
Esempio di dati di un token (binario convertito in esadecimale): http: // pastebin.com / GyqPRP5J
Il gioco scorre tra la chiamata di getLastChunkInfo e getGameDataChunk quando i dati diventano disponibili dal flusso di riproduzione. C'è anche una chiamata che si verifica dopo che sono stati catturati circa 5 blocchi:
GET / modalità osservatore / resto / consumatore / getKeyFrame / NA1 / [gameid] / [somechunkid] / token
Credo che questa chiamata si verifichi solo all'avvio del replay e ogni volta che l'utente cerca un orario diverso.
So che il gioco utilizza la crittografia a un certo livello. Credo che sia BlowB ECB, con la chiave effettiva specificata nella riga di comando. Ho tentato di decrittografare questi token usando la chiave della sessione, ma sembrano comunque abbastanza casuali.
Modifica il 23/03/2013
- Ho determinato che i token molto probabilmente non sono crittografati modificando l'argomento della riga di comando contenente la chiave e rilanciando il gioco dal debugger (ha caricato correttamente il replay).
I token sembrano essere compressi. Esiste una chiamata a una subroutine che, se restituisce un numero intero diverso da zero, attiverà quanto segue:
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"); }
All'indagine di sub_B71120 ho individuato una chiamata che alla fine entra in una funzione abbastanza grande. Questa funzione contiene stringhe come:
- "controllo intestazione errato"
- "metodo di compressione sconosciuto"
- "dimensione della finestra non valida"
Una rapida ricerca su Google di queste stringhe rivela quanto segue: http://www.opensource.apple.com/source/zlib/zlib-22/zlib/inflate.c
Ho anche trovato il riferimento alla stringa "1.2.3" in una chiamata di funzione appena prima della chiamata al metodo inflate.c, nonché un altro riferimento "infllate 1.2.3 Copyright 1995-2005 Mark Adler". Sembra che stiano usando Zlib versione 1.2.3 per la decompressione dei token. Non riesco proprio a farli decomprimere indipendentemente dall'offset del file da cui inizio.
Le mie domande)
Qualcuno sa come questi "token" potrebbero essere formattati o se esiste un tipo di compressione / crittografia di cui non sono a conoscenza? Ho il sospetto che si tratti di una forma compressa o compressa dei pacchetti Ethernet utilizzati durante la riproduzione dal vivo che vengono semplicemente riprodotti internamente al client.
In alternativa, qualcuno può pensare a qualche altro metodo con cui raschiare questi dati senza eseguire l'effettivo client di gioco? Tieni presente che vorrei acquisire dati da molti stream contemporaneamente.