Introducción
He estado jugando con el sistema de espectadores para LoL con la esperanza de eventualmente extraer datos de las transmisiones y construir un conjunto de datos con ellos para su análisis. Entiendo que ya hay algunas API y técnicas no oficiales, pero estoy buscando eventos de juego realmente específicos (asesinatos de campeones, asesinatos de torretas, compras de artículos, asesinatos de la mafia de la jungla, coordinaciones de campeones para eventos particulares, etc.).
Lo que he descubierto hasta ahora
Cuando comienzas a ver un juego (en NA), tu cliente se conecta al siguiente host:
spectator.na.lol.riotgames.com:8088
Supongo que este host está respaldado por Amazon AWS o similar. De todos modos, lo siguiente que sucede es que el cliente envía una solicitud de versión al servidor de espectate:
GET / observador-modo / descanso / consumidor / versión
Esto devuelve cualquiera que sea la versión actual del servidor espectador. Ej: '1.80.54'
A continuación, el cliente envía una solicitud de metadatos del juego:
GET / observer-mode / rest / consumer / getGameMetaData / NA1 / [gameid] / [some nonce aleatorio] / token
Esto devuelve metadatos sobre el juego. Un ejemplo de estos datos: http://pastebin.com/3N4qs0hx
El cliente ahora conoce los parámetros por los cuales la sesión de espectadores debería progresar. Intenta localizar el último fragmento de datos llamando a:
GET / observer-mode / rest / consumer / getLastChunkInfo / NA1 / [gameid] / 30000 / token
Muestra de estos datos: http://pastebin.com/Cj7dEAr9
Una vez que se han identificado los fragmentos de datos, se solicitan:
GET / observer-mode / rest / consumer / getGameDataChunk / NA1 / [gameid] / [token #] / token
Muestra de datos de un token (binario convertido a hexadecimal): http: // pastebin.com / GyqPRP5J
El juego cambia entre las llamadas getLastChunkInfo y getGameDataChunk a medida que los datos están disponibles desde la secuencia de reproducción. También hay una llamada que se produce después de que se toman alrededor de 5 fragmentos de lo siguiente:
GET / observer-mode / rest / consumer / getKeyFrame / NA1 / [gameid] / [somechunkid] / token
Creo que esta llamada solo ocurre en el inicio de la reproducción y siempre que el usuario busque un momento diferente.
Sé que el juego usa encriptación en algún nivel. Creo que es Blowfish ECB, con la clave real especificada en la línea de comando. Intenté descifrar estos tokens usando la clave de la sesión, pero todavía se ven bastante al azar.
Editar 23/03/2013
- He determinado que los tokens probablemente no estén encriptados modificando el argumento de la línea de comando que contiene la clave y reiniciando el juego desde el depurador (cargó la reproducción correctamente).
Las fichas parecen estar comprimidas. Hay una llamada a una subrutina que, si devuelve un entero distinto de cero, activará lo siguiente:
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"); }
Tras la investigación de sub_B71120, he localizado una llamada que finalmente entra en una función bastante grande. Esta función contiene cadenas como:
- "verificación de encabezado incorrecta"
- "método de compresión desconocido"
- "tamaño de ventana no válido"
Una búsqueda rápida en Google de estas cadenas revela lo siguiente: http://www.opensource.apple.com/source/zlib/zlib-22/zlib/inflate.c
También he encontrado la referencia de cadena "1.2.3" en una llamada de función justo antes de la llamada al método inflate.c, así como otra referencia "inflar 1.2.3 Copyright 1995-2005 Mark Adler". Definitivamente parece que están usando Zlib versión 1.2.3 para la descompresión de los tokens. Simplemente no puedo hacer que se descompriman sin importar en qué desplazamiento de archivo empiezo.
Mis preguntas)
¿Alguien sabe cómo se pueden formatear estos 'tokens' o si hay algún tipo de compresión / cifrado que desconozco? Tengo la sospecha de que son una forma comprimida o empaquetada de los paquetes de Ethernet utilizados durante la reproducción en vivo que simplemente se reproducen internamente en el cliente.
Alternativamente, ¿alguien puede pensar en algún otro método para raspar estos datos sin ejecutar el cliente del juego real? Tenga en cuenta que me gustaría obtener datos de muchas transmisiones simultáneamente.