Вступ
Я розмовляв із системою глядачів для LoL, сподіваючись врешті-решт викреслити дані з потоків та створити набір даних для аналізу. Я розумію, що вже є деякі неофіційні API та методи, але я шукаю дійсно конкретні ігрові події (чемпіонські вбивства, баштові вбивства, предметні закупівлі, вбивства в джунглях, вручення чемпіонів для конкретних подій тощо).
Що я з’ясував поки що
Коли ви починаєте переглядати гру (в NA), ваш клієнт підключається до наступного хоста:
глядач.na.lol.riotgames.com:8088
Я припускаю, що цей хост підтримується Amazon AWS або подібним. У будь-якому разі, наступне, що трапляється - клієнт надсилає запит на версію на сервер spetepe:
GET / режим спостерігача / відпочинок / споживач / версія
Це повертає незалежно від поточної версії сервера для глядача. Наприклад: '1,80,54'
Далі клієнт надсилає запит на метадані гри:
GET / режим спостерігача / відпочинок / споживач / getGameMetaData / NA1 / [gameid] / [деякий випадковий не] / токен
Це повертає метадані про гру. Приклад цих даних: http://pastebin.com/3N4qs0hx
Клієнт тепер знає параметри, за якими повинен прогресувати виступ сеансу. Він намагається знайти останній фрагмент даних, зателефонувавши:
GET / режим спостерігачів / відпочинок / споживач / getLastChunkInfo / NA1 / [gameid] / 30000 / токен
Зразок цих даних: http://pastebin.com/Cj7dEAr9
Після виявлення фрагментів даних їх запитують:
GET / режим спостерігачів / відпочинок / споживач / getGameDataChunk / NA1 / [gameid] / [token #] / token
Зразок даних маркера (бінарний перетворений у шістнадцятковий): http: // pastebin.com / GyqPRP5J
Ігрові цикли між викликом getLastChunkInfo та getGameDataChunk, оскільки дані стають доступними з потоку повтору. Існує також дзвінок, який відбувається після того, як приблизно 5 шматочків схоплені до наступного:
GET / режим спостерігачів / відпочинок / споживач / getKeyFrame / NA1 / [gameid] / [somechunkid] / токен
Я вважаю, що цей виклик відбувається лише під час запуску повтору та кожного разу, коли користувач прагне до іншого часу.
Я знаю, що гра використовує шифрування на якомусь рівні. Я вважаю, що це Blowfish ECB, фактичний ключ вказаний у командному рядку. Я намагався розшифрувати ці маркери за допомогою ключа сеансу, але вони все ще виглядають досить випадковими.
Редагувати 23.03.2013
- Я визначив, що лексеми, швидше за все, не шифруються, змінивши аргумент командного рядка, що містить ключ, і повторно запустити гру з налагоджувача (вона правильно завантажила повтор).
Жетони, здається, стиснуті. Існує виклик до підпрограми, який у випадку повернення ненульового цілого числа викликає наступне:
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"); }
Після розслідування sub_B71120 я виявив дзвінок, який з часом переходить у досить велику функцію. Ця функція містить рядки, такі як:
- "неправильна перевірка заголовка"
- "невідомий метод стиснення"
- "недійсний розмір вікна"
Швидкий пошук цих рядків Google виявляє таке: http://www.opensource.apple.com/source/zlib/zlib-22/zlib/inflate.c
Я також знайшов посилання рядка "1.2.3" у виклику функції безпосередньо перед викликом методу inflate.c, а також іншу посилання "надути 1.2.3. Напевно виглядає так, що вони використовують Zlib версії 1.2.3 для декомпресії лексем. Я просто не можу їх розпакувати, незалежно від того, з якого зміщення файлу я починаю.
Мої питання
Хто-небудь знає, як можуть бути відформатовані ці "жетони" чи є якийсь тип стиснення / шифрування, про який я не знаю? У мене є підозра, що вони представляють собою певну стиснуту або запаковану форму пакетів Ethernet, використовуваних під час прямої гри, які просто відтворюються внутрішньо для клієнта.
Як альтернатива, чи може хтось придумати якийсь інший метод, за допомогою якого можна скребти ці дані, не запускаючи фактичного клієнта ігор? Майте на увазі, я хотів би одночасно збирати дані з багатьох потоків.