giriş
Sonunda akışlardan veri kazıma ve analiz için onunla bir veri kümesi oluşturma umuduyla LoL için seyirci sistemi ile uğraşıyorum. Zaten bazı gayri resmi API'ler ve teknikler olduğunu anlıyorum, ancak gerçekten özel oyun etkinlikleri arıyorum (şampiyon öldürmeleri, taret öldürmeleri, eşya satın alımları, orman çete öldürmeleri, belirli etkinlikler için şampiyon eş-kurumları, vb.).
Şimdiye kadar ne buldum
Bir oyunu izlemeye başladığınızda (NA), istemciniz aşağıdaki ana bilgisayara bağlanır:
spectator.na.lol.riotgames.com:8088
Bu ev sahibinin Amazon AWS veya benzeri tarafından desteklendiğini varsayıyorum. Her neyse, gerçekleşen bir sonraki şey, istemci spectate sunucusuna bir sürüm isteği gönderir:
GET / gözlemci modu / dinlenme / tüketici / sürüm
Bu, geçerli izleyici sunucusu sürümü ne olursa olsun döndürür. Örn: '1.80.54'
Ardından, müşteri oyun meta verileri için bir istek gönderir:
GET / gözlemci modu / dinlenme / tüketici / getGameMetaData / NA1 / [gameid] / [bazı rasgele nonce] / belirteç
Bu, oyun hakkındaki meta verileri döndürür. Bu verilere bir örnek: http://pastebin.com/3N4qs0hx
İstemci artık spectate oturumunun ilerlemesi gereken parametreleri biliyor. Arayarak en son veri yığınını bulmaya çalışır:
GET / gözlemci modu / dinlenme / tüketici / getLastChunkInfo / NA1 / [gameid] / 30000 / jeton
Bu verilerin örneği: http://pastebin.com/Cj7dEAr9
Veri parçaları tanımlandıktan sonra, bunlar istenir:
GET / gözlemci modu / dinlenme / tüketici / getGameDataChunk / NA1 / [gameid] / [belirteç #] / belirteç
Bir belirteç verisi örneği (ikili kod onaltılık biçime dönüştürülür): http: // pastebin.com / GyqPRP5J
Oyun, veri tekrar akışından alındığında getLastChunkInfo ve getGameDataChunk öğelerini çağırmak arasında geçiş yapar. Aşağıdakilere yaklaşık 5 parça alındıktan sonra gerçekleşen bir çağrı da vardır:
GET / gözlemci modu / dinlenme / tüketici / getKeyFrame / NA1 / [gameid] / [somechunkid] / belirteç
Bu çağrının yalnızca tekrar başlatma sırasında ve kullanıcı farklı bir zaman aradığında gerçekleştiğine inanıyorum.
Oyunun bir düzeyde şifreleme kullandığını biliyorum. Komut satırında belirtilen gerçek anahtarla Blowfish ECB olduğuna inanıyorum. Oturumun anahtarını kullanarak bu belirteçlerin şifresini çözmeyi denedim, ancak yine de oldukça rastgele görünüyorlar.
Düzenle 3/23/2013
- Jetonların büyük olasılıkla anahtarı içeren komut satırı argümanını değiştirip oyunu hata ayıklayıcıdan yeniden başlatarak şifrelenmediğini belirledim (tekrarlamayı doğru yükledi).
Jetonlar sıkıştırılmış gibi görünüyor. Sıfır olmayan tamsayı döndürürse aşağıdakileri tetikleyecek bir alt yordama çağrı vardır:
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 araştırması üzerine, sonunda oldukça büyük bir işleve giren bir çağrı buldum. Bu işlev aşağıdaki dizeleri içerir:
- "yanlış başlık kontrolü"
- "bilinmeyen sıkıştırma yöntemi"
- "geçersiz pencere boyutu"
Bu dizelerde hızlı bir Google araması aşağıdakileri gösterir: http://www.opensource.apple.com/source/zlib/zlib-22/zlib/inflate.c
Ben de inflate.c yöntemi çağrısından hemen önce bir işlev çağrısında "1.2.3" dize başvurusunu ve ayrıca başka bir başvuru "şişirmek 1.2.3 Copyright 1995-2005 Mark Adler" bulduk. Kesinlikle jetonların dekompresyonu için Zlib 1.2.3 sürümünü kullanıyor gibi görünüyor. Hangi dosya ofsetinden başladığımdan bağımsız olarak sıkıştırmasını açamıyorum.
Sorularım)
Herkes bu 'belirteçleri' nasıl biçimlendirilmiş biliyor olabilir veya farkında olmayan bir tür sıkıştırma / şifreleme varsa? Sadece canlı oyun sırasında kullanılan ve sadece müşteriye dahili olarak oynanan ethernet paketlerinin bazı sıkıştırılmış veya paketlenmiş şekli olduğundan şüphe duyuyorum.
Alternatif olarak, herkes gerçek oyun istemcisini çalıştırmadan bu verileri kazımak için başka bir yöntem düşünebilir mi? Aynı anda birçok akıştan veri almak istiyorum.