Intro
Saya telah mengutak-atik sistem penonton untuk LoL dengan harapan pada akhirnya mengambil data dari aliran dan membangun dataset dengan itu untuk analisis. Saya mengerti bahwa sudah ada beberapa API dan teknik tidak resmi, tetapi saya sedang mencari acara game yang sangat spesifik (membunuh juara, pembunuhan menara, puchase item, pembunuhan gerombolan hutan, juara bersama untuk acara tertentu, dll).
Apa yang saya ketahui sejauh ini
Saat Anda mulai menonton pertandingan (dalam NA), klien Anda terhubung ke host berikut:
spectator.na.lol.riotgames.com:8088
Saya menganggap host ini didukung oleh Amazon AWS atau serupa. Bagaimanapun, hal berikutnya yang terjadi adalah klien mengirimkan permintaan versi ke server spectate:
GET / mode pengamat / istirahat / konsumen / versi
Ini mengembalikan apa pun versi server penonton saat ini. Contoh: '1.80.54'
Selanjutnya, klien mengirim permintaan untuk metadata game:
DAPATKAN / mode-pengamat / istirahat / konsumen / getGameMetaData / NA1 / [gameid] / [beberapa angka acak] / token
Ini mengembalikan metadata tentang permainan. Contoh data ini: http://pastebin.com/3N4qs0hx
Klien sekarang tahu parameter di mana sesi tontonan harus maju. Mencoba untuk menemukan potongan data terbaru dengan memanggil:
DAPATKAN / mode pengamat / istirahat / konsumen / getLastChunkInfo / NA1 / [gameid] / 30000 / token
Contoh data ini: http://pastebin.com/Cj7dEAr9
Setelah potongan data diidentifikasi, mereka diminta:
GET / mode pengamat / istirahat / konsumen / getGameDataChunk / NA1 / [gameid] / [token #] / token
Contoh data token (biner dikonversi ke hex): http: // pastebin.com / GyqPRP5J
Gim ini siklus antara memanggil getLastChunkInfo dan getGameDataChunk saat data tersedia dari aliran replay. Ada juga panggilan yang terjadi setelah sekitar 5 chunk diambil sebagai berikut:
GET / mode pengamat / istirahat / konsumen / getKeyFrame / NA1 / [gameid] / [somechunkid] / token
Saya percaya panggilan ini hanya terjadi pada saat pemutaran ulang dimulai dan setiap kali pengguna mencari waktu yang berbeda.
Saya tahu permainan menggunakan enkripsi pada tingkat tertentu. Saya percaya itu adalah Blowfish ECB, dengan kunci aktual yang ditentukan pada baris perintah. Saya telah mencoba mendekripsi token ini menggunakan kunci sesi, tetapi masih terlihat acak.
Edit 3/23/2013
- Saya telah menentukan bahwa token kemungkinan besar tidak dienkripsi dengan memodifikasi argumen baris perintah yang berisi kunci dan meluncurkan kembali game dari debugger (ini memuat replay dengan benar).
Token tampaknya dikompresi. Ada panggilan ke subrutin yang jika mengembalikan bilangan bulat nol akan memicu yang berikut:
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"); }
Setelah menyelidiki sub_B71120 saya telah menemukan panggilan yang akhirnya memasuki fungsi yang cukup besar. Fungsi ini berisi string seperti:
- "pemeriksaan header salah"
- "metode kompresi yang tidak diketahui"
- "ukuran jendela tidak valid"
Pencarian cepat Google string ini mengungkapkan yang berikut: http://www.opensource.apple.com/source/zlib/zlib-22/zlib/inflate.c
Saya juga telah menemukan referensi string "1.2.3" dalam pemanggilan fungsi tepat sebelum pemanggilan metode inflate.c, dan juga referensi lain "mengembang 1.2.3. Hak Cipta 1995-2005 Mark Adler". Tampaknya mereka menggunakan Zlib versi 1.2.3 untuk dekompresi token. Saya tidak bisa membuat mereka melakukan dekompresi terlepas dari file offset apa yang saya mulai.
Pertanyaan saya)
Adakah yang tahu bagaimana 'token' ini dapat diformat atau jika ada beberapa jenis kompresi / enkripsi yang tidak saya sadari? Saya memiliki kecurigaan bahwa mereka adalah bentuk paket ethernet yang dipadatkan atau dikemas yang digunakan selama live play yang hanya diputar ulang secara internal kepada klien.
Atau, adakah yang bisa memikirkan metode lain untuk mengikis data ini tanpa menjalankan klien game sebenarnya? Ingat saya ingin mengambil data dari banyak aliran secara bersamaan.