Intro
J'ai bidouillé avec le système de spectateurs pour LoL dans l'espoir de finalement gratter les données des flux et de créer un ensemble de données avec pour analyse. Je comprends qu'il existe déjà des API et des techniques non officielles, mais je recherche des événements de jeu vraiment spécifiques (champion kills, turret kills, item puchases, jungle mob kills, champion coordonnés pour des événements particuliers, etc.).
Ce que j'ai compris jusqu'à présent
Lorsque vous commencez à observer un jeu (en NA), votre client se connecte à l'hôte suivant:
spectator.na.lol.riotgames.com:8088
Je suppose que cet hôte est soutenu par Amazon AWS ou similaire. Quoi qu'il en soit, la prochaine chose qui se passe est que le client envoie une demande de version au serveur spectate:
GET / mode observateur / repos / consommateur / version
Cela renvoie quelle que soit la version actuelle du serveur spectateur. Ex: '1.80.54'
Ensuite, le client envoie une demande pour les métadonnées du jeu:
GET / mode observateur / rest / consumer / getGameMetaData / NA1 / [gameid] / [some random nonce] / token
Cela renvoie des métadonnées sur le jeu. Un exemple de ces données: http://pastebin.com/3N4qs0hx
Le client connaît maintenant les paramètres selon lesquels la session de spectateur doit progresser. Il essaie de localiser le dernier bloc de données en appelant:
GET / mode observateur / repos / consommateur / getLastChunkInfo / NA1 / [gameid] / 30000 / token
Exemple de ces données: http://pastebin.com/Cj7dEAr9
Une fois les blocs de données identifiés, il leur est demandé:
GET / mode observateur / repos / consommateur / getGameDataChunk / NA1 / [gameid] / [token #] / token
Exemple de données d'un jeton (binaire converti en hexadécimal): http: // pastebin.com / GyqPRP5J
Le jeu alterne entre l'appel de getLastChunkInfo et getGameDataChunk à mesure que les données deviennent disponibles à partir du flux de relecture. Il existe également un appel qui se produit après avoir récupéré environ 5 morceaux:
GET / mode observateur / repos / consommateur / getKeyFrame / NA1 / [gameid] / [somechunkid] / token
Je crois que cet appel ne se produit qu'au démarrage de la relecture et chaque fois que l'utilisateur cherche à une heure différente.
Je sais que le jeu utilise le cryptage à un certain niveau. Je pense que c'est Blowfish ECB, avec la clé réelle spécifiée sur la ligne de commande. J'ai tenté de décrypter ces jetons à l'aide de la clé de la session, mais ils semblent toujours assez aléatoires.
Modifier 23/03/2013
- J'ai déterminé que les jetons ne sont probablement pas chiffrés en modifiant l'argument de ligne de commande contenant la clé et en relançant le jeu à partir du débogueur (il a chargé la relecture correctement).
Les jetons semblent être compressés. Il y a un appel à un sous-programme qui, s'il retourne un entier non nul, déclenchera ce qui suit:
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"); }
Après enquête sur sub_B71120, j'ai localisé un appel qui finit par entrer dans une fonction assez importante. Cette fonction contient des chaînes comme:
- "vérification d'en-tête incorrecte"
- "méthode de compression inconnue"
- "taille de fenêtre non valide"
Une recherche rapide sur Google de ces chaînes révèle ce qui suit: http://www.opensource.apple.com/source/zlib/zlib-22/zlib/inflate.c
J'ai également trouvé la référence de chaîne "1.2.3" dans un appel de fonction juste avant l'appel à la méthode inflate.c, ainsi qu'une autre référence "inflate 1.2.3 Copyright 1995-2005 Mark Adler". Il semble définitivement qu'ils utilisent la version 1.2.3 de Zlib pour la décompression des jetons. Je n'arrive tout simplement pas à les décompresser, quel que soit le décalage de fichier auquel je commence.
Mes questions)
Quelqu'un sait-il comment ces «jetons» peuvent être formatés ou s'il existe un type de compression / cryptage que je ne connais pas? Je soupçonne qu'il s'agit d'une forme compressée ou compressée des paquets Ethernet utilisés pendant la lecture en direct qui sont simplement lus en interne pour le client.
Alternativement, quelqu'un peut-il penser à une autre méthode pour supprimer ces données sans exécuter le client de jeu réel? Gardez à l'esprit que je voudrais récupérer simultanément les données de nombreux flux.