python

Вычисляем персонажей гейммастеров в World of Warcraft с помощью Python

  • четверг, 4 июня 2015 г. в 02:10:57
http://habrahabr.ru/post/259463/

Был у меня как-то сайт по поиску твинков в World of Warcraft. Любой мог ввести ник и получить список персонажей, находящихся на той же записи (если данные имелись в базе сайта, конечно).

И вот однажды ко мне зашел посетитель из Blizzard:

image

99% людей во время первого посещения ищут себя и своих друзей. Посетитель из Франции не стал исключением и оставил в логе просмотров несколько персонажей, скорее всего принадлежащих работникам близзард (что было
видно по активности на форуме и другим признакам). Конечно, мне стало интересно, чем же отличаются персонажи гейммастеров от персонажей обычных смертных и отличаются ли вообще.

После просмотра ачивок этих персонажей стало ясно, что при поступлении на службу новоиспеченному ГМу выдают набор коллекционных изданий всех игр близзард. После более пристального изучения вскрылась одна деталь: все коллекционки получены в один день (видимо, примерная дата поступления на работу).

image

Используем API Battle.net


Гмы получают все существующие (на дату получения) коллекционки — а значит, и самую первую, «ванильную». Она была выпущена больше 10 лет назад и сегодня достать ее можно разве что на ebay за 2-3 тысячи евро. Её-то и будем использовать для поиска других персонажей.

Искать будем персонажей, у которых есть такой пет (его дают бонусом за активацию ванильной коллекционки):

image

Так как прямого доступа к спискам персонажей API не предоставляет, будем искать персонажей через аукцион.

realm = "гордунни"  # реалм, на котором будем искать персонажей

# Получаем ссылку на дамп аукциона
r = requests.get("http://eu.battle.net/api/wow/auction/data/%s" % realm)
auction_dump_url = json.loads(r.text)["files"][0]["url"]

# Загружаем данные по лотам на аукционе
auc_data = json.loads(requests.get(auction_dump_url).text)

# Составляем список имен/реалмов персонажей
chars = {(lot["owner"], lot["ownerRealm"]) for lot in auc_data["auctions"]["auctions"]}

В этой функции определяем, является ли персонаж потенциальным гмом:

def is_gm(name, realm):
    r = requests.get(CHAR_API_URL.format(name=name, realm=realm))
    if r.text.find("Panda Cub") != -1:
        return True

Запускаем проверку:

for name, realm in chars:
    if is_gm(name, realm):
        print("Возможно ГМ: %s %s" % (name, realm))
    time.sleep(1)

Код скрипта целиком
import json
import requests
import time


CHAR_API_URL = "http://eu.battle.net/api/wow/character/{realm}/{name}?fields=pets,guild"

# В этой функции определяем, является ли персонаж потенциальным гмом
def is_gm(name, realm):
    r = requests.get(CHAR_API_URL.format(name=name, realm=realm))
    if r.text.find("Panda Cub") != -1:
        return True


realm = "гордунни"  # реалм, на котором будем искать персонажей

# Получаем ссылку на дамп аукциона
r = requests.get("http://eu.battle.net/api/wow/auction/data/%s" % realm)
auction_dump_url = json.loads(r.text)["files"][0]["url"]

# Загружаем данные по лотам на аукционе
auc_data = json.loads(requests.get(auction_dump_url).text)

# Составляем список имен/реалмов персонажей
chars = {(lot["owner"], lot["ownerRealm"]) for lot in auc_data["auctions"]["auctions"]}

# Запускаем проверку
for name, realm in chars:
    if is_gm(name, realm):
        print("Возможно ГМ: %s %s" % (name, realm))
    time.sleep(1)


Примечание: скрипт ищет только персонажей, выставляющих лоты на аукционе. Для более широкого охвата можно также сканировать согильдийцев каждого владельца лота.

Дальше нужно смотреть другие признаки — сколько получено коллекционок за один день, их общее кол-во и так далее.
Конечно, не каждый персонаж, который соответствует критериям, принадлежит ГМу. Это может быть и просто коллекционер, например.

Для отображения результатов скрипта создал простенький сайт: http://wow-gm-track.website

Из интересностей: в процессе сканирования выявились целые гнезда — гильдии, в которых сразу несколько разных аккаунтов, принадлежащих (предположительно) ГМам. Например: Зов древних (6 штук, в том числе глава гильдии).

И немного статистики: на сегодняшний день просканировано 1,7 миллиона персонажей на русскоязычных реалмах, ванильную коллекционку имеют 1306 персонажей (0,07%), из них только 380 персонажей получили хотя бы 4 коллекционки в один день (0,02% от общего числа).