Định dạng luồng Liên minh huyền thoại


12

Giới thiệu

Tôi đã loay hoay với hệ thống khán giả cho LoL với hy vọng cuối cùng sẽ lấy dữ liệu từ các luồng và xây dựng một bộ dữ liệu với nó để phân tích. Tôi hiểu rằng đã có một số API và kỹ thuật không chính thức, nhưng tôi đang tìm kiếm các sự kiện trò chơi thực sự cụ thể (giết người vô địch, giết tháp pháo, puchase vật phẩm, giết người đi rừng, đồng đội vô địch cho các sự kiện cụ thể, v.v.).

Những gì tôi đã tìm ra cho đến nay

Khi bạn bắt đầu xem một trò chơi (bằng NA), ứng dụng khách của bạn sẽ kết nối với máy chủ sau:

khán giả.na.lol.riotgames.com: 8088

Tôi cho rằng máy chủ này được hỗ trợ bởi Amazon AWS hoặc tương tự. Dù sao, điều tiếp theo xảy ra là máy khách gửi yêu cầu phiên bản đến máy chủ phổ biến:

GET / observer-mode / rest / Consumer / phiên bản

Điều này trả về bất cứ phiên bản máy chủ khán giả hiện tại là gì. Vd: '1.80.54'

Tiếp theo, khách hàng gửi yêu cầu cho siêu dữ liệu trò chơi:

GET / observer-mode / rest / Consumer / getGameMetaData / NA1 / [gameid] / [một số nonce ngẫu nhiên] / mã thông báo

Điều này trả về siêu dữ liệu về trò chơi. Một ví dụ về dữ liệu này: http://pastebin.com/3N4qs0hx

Bây giờ khách hàng biết các tham số mà phiên khán giả sẽ tiến triển. Nó cố gắng xác định vị trí dữ liệu mới nhất bằng cách gọi:

GET / observer-mode / rest / Consumer / getLastChunkInfo / NA1 / [gameid] / 30000 / mã thông báo

Mẫu dữ liệu này: http://pastebin.com/Cj7dEAr9

Khi các khối dữ liệu đã được xác định, chúng được yêu cầu:

GET / observer-mode / rest / Consumer / getGameDataChunk / NA1 / [gameid] / [token #] / token

Mẫu dữ liệu của mã thông báo (nhị phân được chuyển đổi thành hex): http: // pastebin.com / GyqPRP5J

Trò chơi xoay vòng giữa việc gọi getLastChunkInfo và getGameDataChunk khi dữ liệu có sẵn từ luồng phát lại. Ngoài ra còn có một cuộc gọi xảy ra sau khi khoảng 5 khối được thực hiện như sau:

GET / observer-mode / rest / Consumer / getKeyFrame / NA1 / [gameid] / [somechunkid] / token

Tôi tin rằng cuộc gọi này chỉ xảy ra khi bắt đầu phát lại và bất cứ khi nào người dùng tìm đến một thời điểm khác.

Tôi biết trò chơi sử dụng mã hóa ở một số cấp độ. Tôi tin rằng đó là Blowfish ECB, với khóa thực tế được chỉ định trên dòng lệnh. Tôi đã cố gắng giải mã các mã thông báo này bằng khóa của phiên, nhưng chúng vẫn trông khá ngẫu nhiên.

Chỉnh sửa 23/03/2013

  • Tôi đã xác định rằng các mã thông báo rất có thể không được mã hóa bằng cách sửa đổi đối số dòng lệnh chứa khóa và khởi chạy lại trò chơi từ trình gỡ lỗi (nó đã tải lại phát lại chính xác).
  • Các mã thông báo dường như bị nén. Có một cuộc gọi đến chương trình con mà nếu trả về số nguyên khác không sẽ kích hoạt như sau:

    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");
    }
  • Khi điều tra sub_B71120, tôi đã tìm thấy một cuộc gọi cuối cùng có chức năng khá lớn. Hàm này chứa các chuỗi như:

    • "kiểm tra tiêu đề không chính xác"
    • "phương pháp nén không xác định"
    • "kích thước cửa sổ không hợp lệ"
  • Một tìm kiếm nhanh của Google về các chuỗi này cho thấy những điều sau đây: http://www.opensource.apple.com/source/zlib/zlib-22/zlib/inflate.c

  • Tôi cũng đã tìm thấy tham chiếu chuỗi "1.2.3" trong một lệnh gọi hàm ngay trước khi gọi phương thức Inflate.c, cũng như một tham chiếu khác "thổi phồng 1.2.3 Bản quyền 1995-2005 Mark Adler". Có vẻ như họ đang sử dụng Zlib phiên bản 1.2.3 để giải nén mã thông báo. Tôi chỉ không thể khiến họ giải nén bất kể tôi bắt đầu bù vào tập tin nào.

Những câu hỏi của tôi)

Có ai biết làm thế nào các 'mã thông báo' này có thể được định dạng hoặc nếu có một số loại nén / mã hóa mà tôi không biết? Tôi có một nghi ngờ rằng chúng là một số dạng gói ethernet được nén hoặc đóng gói được sử dụng trong khi phát trực tiếp, đơn giản là được phát lại nội bộ cho máy khách.

Ngoài ra, bất cứ ai cũng có thể nghĩ ra một số phương pháp khác để cạo dữ liệu này mà không cần chạy ứng dụng khách thực tế? Hãy nhớ rằng tôi muốn lấy dữ liệu từ nhiều luồng đồng thời.


1
Cách tôi nghĩ về nó là lấy càng nhiều tệp phát lại từ LOLReplay càng tốt và chỉ cần bẻ khóa chúng. Tôi nghĩ, có một kho lưu trữ mở, nơi mọi người có thể tải lên các trò chơi của riêng họ và tôi nghĩ chế độ khán giả mới cho phép ứng dụng khách Phát lại lấy nhiều thông tin hơn trước đây.
Robert S.

Có những API và Kỹ thuật nào khác? Tại sao bạn nghĩ rằng có mã hóa? Tôi đã tìm thấy điều này trong GetGameMetaData: "mã hóa": "" và "decodingEncodingKey": ""
Nathan Goings

Là một FYI cho những người tiếp tục đặt câu hỏi này từ các diễn đàn LoL khác nhau, nhìn thấy tên của tôi trên bài đăng dưới "được chỉnh sửa bởi" và gửi email cho tôi để hỏi về chủ đề này ... Tôi không biết gì về LoL hoặc định dạng của luồng. Xin đừng gửi email cho tôi về nó.

Câu trả lời:


4

Tôi đã nghiên cứu điều tương tự và tôi thấy repo này cực kỳ hữu ích. Tệp decrypt.rb giải mã cả khối và khung hình chính.

Chỉnh sửa: kiểm tra chủ đề reddit này quá.


Thông minh. Liên kết đầu tiên trả lời chính xác câu hỏi của tôi. Liên kết thứ hai cũng thực sự hữu ích. Cảm ơn rất nhiều!
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.