Format strumienia League of Legends Spectator

12

Wprowadzenie

Bawiłem się z systemem obserwacyjnym LoL w nadziei, że w końcu skrobię dane ze strumieni i zbuduję z nich zestaw danych do analizy. Rozumiem, że istnieją już pewne nieoficjalne interfejsy API i techniki, ale szukam naprawdę konkretnych wydarzeń w grze (zabójstwa bohaterów, zabójstwa z wieżyczek, puchazy przedmiotów, zabójstwa w dżungli, koledzy mistrzów dla określonych wydarzeń itp.).

Co do tej pory wymyśliłem

Kiedy zaczynasz obserwować grę (w NA), twój klient łączy się z następującym hostem:

spectator.na.lol.riotgames.com:8088

Zakładam, że ten host jest wspierany przez Amazon AWS lub podobny. W każdym razie następną rzeczą, która się dzieje, jest wysłanie przez klienta żądania wersji do serwera Spectate:

GET / tryb obserwatora / rest / konsument / wersja

Zwraca to niezależnie od bieżącej wersji serwera widza. Np .: „1,80,54”

Następnie klient wysyła żądanie metadanych gry:

GET / tryb obserwatora / rest / Consumer / getGameMetaData / NA1 / [gameid] / [some random nonce] / token

Zwraca metadane dotyczące gry. Przykład tych danych: http://pastebin.com/3N4qs0hx

Klient zna teraz parametry, według których sesja obserwacyjna powinna się rozwijać. Próbuje zlokalizować najnowszą porcję danych, wywołując:

GET / tryb obserwatora / rest / Consumer / getLastChunkInfo / NA1 / [gameid] / 30000 / token

Próbka tych danych: http://pastebin.com/Cj7dEAr9

Po zidentyfikowaniu fragmentów danych są one proszone:

GET / tryb obserwatora / rest / Consumer / getGameDataChunk / NA1 / [gameid] / [token #] / token

Próbka danych tokena (plik binarny przekonwertowany na heksadecymalny): http: // pastebin.com / GyqPRP5J

Gra przełącza się między wywołaniem getLastChunkInfo i getGameDataChunk, gdy dane stają się dostępne ze strumienia powtórek. Istnieje również połączenie, które występuje po przechwyceniu około 5 części do następujących elementów:

GET / tryb obserwatora / rest / Consumer / getKeyFrame / NA1 / [gameid] / [somechunkid] / token

Uważam, że to połączenie występuje tylko przy uruchomieniu powtórki i za każdym razem, gdy użytkownik szuka innej godziny.

Wiem, że gra używa szyfrowania na pewnym poziomie. Uważam, że jest to Blowfish ECB z faktycznym kluczem określonym w wierszu poleceń. Próbowałem odszyfrować te tokeny za pomocą klucza sesji, ale nadal wyglądają dość losowo.

Edytuj 23.03.2013

  • Stwierdziłem, że tokeny najprawdopodobniej nie są szyfrowane przez modyfikację argumentu wiersza poleceń zawierającego klucz i ponowne uruchomienie gry z debuggera (poprawnie załadował powtórkę).
  • Żetony wydają się być skompresowane. Istnieje wywołanie podprogramu, który jeśli zwróci liczbę całkowitą niezerową, wywoła następujące czynności:

    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");
    }
  • Po zbadaniu sub_B71120 zlokalizowałem wywołanie, które ostatecznie wchodzi w dość dużą funkcję. Ta funkcja zawiera ciągi znaków takie jak:

    • „nieprawidłowe sprawdzenie nagłówka”
    • „nieznana metoda kompresji”
    • „nieprawidłowy rozmiar okna”
  • Szybkie wyszukiwanie tych ciągów w Google ujawnia: http://www.opensource.apple.com/source/zlib/zlib-22/zlib/inflate.c

  • Znalazłem również odwołanie do łańcucha „1.2.3” w wywołaniu funkcji tuż przed wywołaniem metody inflate.c, a także inne odwołanie „inflate 1.2.3 Copyright 1995-2005 Mark Adler”. Wygląda na to, że używają Zlib w wersji 1.2.3 do dekompresji tokenów. Po prostu nie mogę ich zdekompresować, niezależnie od tego, od jakiego przesunięcia pliku zacznę.

Moje pytania)

Czy ktoś wie, jak te „tokeny” mogą zostać sformatowane lub czy istnieje jakiś rodzaj kompresji / szyfrowania, o którym nie wiem? Podejrzewam, że są to niektóre skompresowane lub spakowane pakiety ethernetowe używane podczas gry na żywo, które są po prostu odtwarzane wewnętrznie klientowi.

Alternatywnie, czy ktoś może pomyśleć o innej metodzie skrobania tych danych bez uruchamiania rzeczywistego klienta gry? Pamiętaj, że chciałbym pobierać dane z wielu strumieni jednocześnie.


źródło
1
Myślałem o tym, aby pobrać jak najwięcej plików LOLReplay i po prostu je zgnieść. Wydaje mi się, że istnieje otwarte archiwum, w którym ludzie mogą przesyłać własne gry, i myślę, że nowy tryb obserwatora pozwala klientowi Replay uzyskać więcej informacji niż wcześniej.
Robert S.
Jakie są inne interfejsy API i techniki? Jak myślisz, dlaczego jest szyfrowanie? Znalazłem to w GetGameMetaData: „encryptionKey”: „” i „decodedEncryptionKey”: „”
Nathan Goings
Jako informacja dla osób, które wciąż lądują na tym pytaniu z różnych forów LoL, widząc moje imię w poście pod nagłówkiem „edytowane przez” i wysyłając mi e-maile z pytaniem o temat ... Nie wiem nic o LoL ani format jego strumieni. Proszę nie pisz mi o tym e-mailem.

Odpowiedzi:

4

Badam to samo i uważam, że to repozytorium jest niezwykle pomocne. Plik decrypt.rb odszyfrowuje zarówno fragmenty, jak i klatki kluczowe.

Edycja: sprawdź też ten wątek reddit .

tyscorp
źródło
Doskonały. Pierwszy link odpowiada dokładnie na moje pytanie. Drugi link jest również bardzo pomocny. Wielkie dzięki!