Как я узнал данные 70 тысяч игроков MMORPG

Мне нравится рубить дерево в Minecraft’е. Я рубил дерево целый год и мне стало интересно сколько дерева срубаю каждый день. Так получилось сделать сервис по сбору статистики https://foragingupdate.com.

страница статистики срубленного дерева

страница статистики срубленного дерева

Уже более года я играю на сервере Hypixel в MMORPG режим Skyblock. Любопытно, что там есть таблица лидеров для самых разных абсурдных действий. Так сформировалось сообщество «элитных фермеров», где игроки каждый час соревнуются в скорости сбора различных растений. И все лидеры серьёзно настроены. Поэтому kaeso сделал сайт https://elitebot.dev, где элитные фермеры могут посмотреть любую информацию о себе и своих конкурентах. Это проект с открытым исходным кодом, так что предварительно изучил его и решил один issue:)

Но всё равно, хотелось создать сайт, где можно посмотреть историю за продолжительный период времени, чтобы понимать свою эффективность.

Реверс инжиниринг протокола

Первый вопрос, который надо было решить — если человек заходит на сервис со статистикой о его игре, оно ожидает увидеть какую-то статистику. Значит, я должен узнать список всех активных игроков до того, как сервис откроется. У Hypixel эта база данных есть, и есть Hypixel API, но буквально пару лет назад они отключили возможность узнать список текущих игроков сервера. Причина — защита частной жизни, приватность.

Но есть и другой способ узнать список всех игроков. Можно самому заходить в игру и записывать на бумагу имена всех игроков, которых встречаю. Это не противоречит правилам, с точки зрения законов физики мне нельзя это запретить. Может найти способ автоматически узнавать всех, кто со мной в игре и записывать это в базу данных?

Да, тема моей научно-исследовательской работы «Методика Анализа Защищенности Мобильных Приложений». Перед тем как попасть на мой экран, информация о каждом игроке приходит на мой компьютер с серверов Hypixel’я. Можно написать небольшой прокси, который будет перехватывать все интересующие пакеты, доставать из них имена игроков и сохранять в sqlite.

пример пакета с именем игрока

пример пакета с именем игрока

Для начала надо определить какие пакеты меня интересуют. Есть проект pakkit, который позволяет посмотреть пакеты Minecraft’а в удобном интерфейсе на electron. Воспользовавшись этим инструментом, нашёл интересующий меня тип пакетов «scoreboard_team». Далее пошёл в исходный код pakkit, и нашёл пример создания собственного прокси, который скопировал, добавил фильтрацию и сохранение в хранилище.

Этот шаг проекта выложил на github: https://github.com/notTGY/minecraft-sniffing.

Так я за 4 дня собрал две тысячи игроков. Но это лишь первая проблема, с которой пришлось столкнуться. Суммарно этот способ сбора информации принёс более десяти тысяч игроков.

Культ лесорубов

Приложение решил написать на языке Go, потому что. Сначала спроектировал сервис, оценил нагрузку и требования к памяти, построил архитектуру хранилища. На тот момент оценивал максимальное число пользователей в 43 тысячи, как видно из моих расчётов.

архитектура сервиса

архитектура сервиса

Оценка сроков: до 1 декабря собираю список пользователей, 1 декабря запускаю сервис и набираю статистику до 25 декабря пока решаю рождественский advent of code.

Всё написаное было точно, но ошибка закралась там, где её не должно было быть. API Limit выглядит странно: мне дадут делать запросы к Hypixel API каждую секунду каждый день без ограничений? Как оказалось, это неправда. На самом деле есть более жёсткое ограничение на восемь тысяч запросов к API ежедневно, после чего аккаунт блокируется до следущего дня.

За пару дней написал сервер на Go, добавил туда модуль для сниффера, чтобы можно было из прокси сразу писать в настоящую базу данных на сервер. Добавил модуль для обращения к Mojang API, чтобы узнавать уникальные идентификаторы игроков (имя может поменяться в будущем, а идентификатор останется). Позже оказалось, что библиотеки для Mojang API все устарели или неудобны в использовании, поэтому вынес этот модуль в отдельную библиотеку: https://github.com/notTGY/mojango.

Ключевая функция сервера — взаимодействие с Hypixel API для получения информации о количестве срубленного дерева. Тут тоже самое — существующие решения не понравились — сделал свою библиотеку https://github.com/notTGY/gopixel. Удивительно, как гоферы хотят добавить go в название всего, что движется.

Другая функция, которую подсмотрел у elitebot.dev — авторизация и привязка аккаунта при помощи discord. Прямо внутри игры можно связать свои соц. сети с профилем игрока, и потом эти данные доступны через Hypixel API. В России не получилось воспользоваться Discord API, так что для этого пришлось написать микросервис. Прокси сервер (только для авторизации): https://github.com/notTGY/discord-oauth-proxy.

Социальное дерево

Дело в том, что я выбрал этот проект своим проектом по курсу «Компьютерные системы поддержки принятия решений», и поэтому нужно было удивить преподавателя каким-нибудь нетривиальным экспериментом. Придумал систему получения дополнительных игроков.

В Hypixel Skyblock геймеры могут объединяться в коллективные хозяйства, чтобы вместе развиваться и получать наслаждение от игры с друзьями. И информация о друзьях лежит прямо там же, где и количество срубленного дерева. Более того, я уже получал информацию о всех друзьях пользователя, просто выкидывал за ненадобностью. Теперь стал добавлять друзей в базу данных.

Любопытно, что максимальная глубина дерева, которая получилась — 7; 6 если не учитывать меня (потому что я не общался с людьми, которых собирал в базу — их 10000!). То есть теория шести рукопожатий работает! Это довольно неожиданный результат для такой предметной области.

главная страница

главная страница

Наконец, я попросил https://v0.dev нагенерить главную страницу, добавил туда статистику лучших 25ти игроков и сделал страницы статистики отдельных людей на основе дизайна https://dribbble.com/shots/24512667-Home-fitness-app.

Ограничения Hypixel API

Всё это время я пользовался ключом для разработчика. Этот ключ меняется каждые 24 часа, и на него есть серьёзные ограничения по количеству использований. Максимальное число запросов в день — 8000, а у меня в базе 70000 логинов, о которых нужно обновлять информацию ежедневно.

В качестве временного решения добавил на сервер функционал обновления токена каждые 24 часа при помощи сообщения в телеграм боте. Сервер видит, что таймер прошёл, посылает мне уведомление и ссылку на получение токена, после чего я могу в 3 клика ответить ему токеном. Такое решение оказалось довольно эффективным, использовал его 25 дней подряд и не испытывал дискомфорт.

Уже в период интенсивного сбора информации наткнулся на ещё один похожий проект — https://tem.cx — где команда разработчиков собирает информацию о миллионах игровых предметов. Их проект закрылся, после долгих переговоров с командой Hypixel, авторы не смогли получить разрешение на постоянное приложение. Этот пример заставил меня поглубже задуматься о пользе моего проекта по сравнению с создаваемой нагрузкой на API. И как результат, думаю, оставить проект ради личного пользования звучит максимально этично.

После осознания уменьшил ежедневный лимит на использование API. Подумав, я решил, что собирать огромное количество персональных данных, это не тот путь, по которому я хочу пойти.

Вывод

Если человек хорошо организован, у него стойкий и неутомимый характер, и он использует все технологические достижения… Этот проект — всего лишь статистика срубленного дерева в видеоигре для детей. Но я всегда буду делать что-то, что принесёт мне удовольствие. Каждый биместр хочу делать новый удивительный проект и эволюционировать. Весь мой прогресс можно наблюдать здесь: https://t.me/fearorlove7734.

© Habrahabr.ru