IDLE на запросах.
Данная статья носит исключительно образовательный характер. Автор не несёт ответственности за любой ущерб, причинённый читателями третьим лицам или сервисам при использовании полученных знаний.
Любые упоминания сторонних лиц и сервисов в статье используются исключительно в контексте изложения материала и не несут рекламного характера.
Вступление
Хола бола, у микрофона Флопа.
В данной статье будет рассмотрен способ IDLE-фарма без окон.
Наверняка каждый олд помнит, как прекрасно было фармить кейсы без прайма. Для этого необходимо было приобрести специальный сервер.
Сервер состоял из минималистичной карты и ключевого элемента – плагина "Drop Summoner". Этот плагин был создан разработчиками кастомных серверов Steam исключительно для развлечения. Однако авторы не осознавали истинный потенциал своего творения, чего не скажешь о фермерах, которые быстро поняли его практическую ценность.
Суть фарма заключалась в следующем: нужно было одновременно подключить к серверу не менее двух аккаунтов(максимум 64) и удерживать их на сервере в течение 4 часов. Плагин каждые 5 минут пытался призвать выпадение дропа для каждого подключенного аккаунта. Если аккаунт успешно получал дроп, плагин автоматически исключал его из списка активных участников.
Самым известным поставщиком серверов был Rexto, который, в том числе, использовал плагин от разработчика под ником Феникс.
В конечном итоге данный плагин инициировал запрос k_EMsgGCCStrike15_v2_MatchEndRunRewardDrops, это единственное для чего он нужен был, в версиях дороже была отправка о дропе в ТГ канал.
Безопасность
На самом деле IDLE-фарм был самым безопасным методом из всех существовавших и существующих на текущий момент. Ни клиент, ни сервер не передавали никакой информации о действиях игроков на сервере. Steam воспринимал одинаково, бегаете ли вы или стоите без движения. Единственной информацией, передаваемой в систему, были количество убийств и текущий опыт.
Скорее всего, именно из-за этого Valve приняли решение изменить систему дропа, так как определить и заблокировать аккаунты по паттерну "афк на сервере" было невозможно, ведь Steam не имел данных о реальном поведении игроков.
Немного о Tedon
На просторах GitHub появился проект tiny-csgo-client. Именно на его базе и был создан известный фарм без окон, когда множество процессов Steam запускались через песочницу, и к каждому подключался Tiny Client.
В конечном итоге Tedon взял этот проект без каких-либо модификаций и нагло выдал его за свою разработку. Изначально всё было понятно, когда софт для фарма на запросах работает, а обыкновенная программа для запуска аккаунтов в авасте постоянно вылетает. Что было своровано, а что разработано)
До сих пор у этих ребят осталась своя фишка в виде бесконечного обилия багов.
К большому удивлению, Tedon не воспользовался смежным проектом — tiny-csgo-server, который позволял запускать IDLE-сервер без возможности прямого подключения игроков, но при этом корректно выполнял все запросы, необходимые для выпадения кейсов.
Данная часть написана не с целью кого-либо оскорбить, а для того, чтобы отдать должное настоящим разработчикам, заслуживающим внимания и признания, чьи проекты были использованы без упоминания авторства.
Техническая реализация Tiny Client
Поскольку Steam Client написан на C++ это даёт возможность вызывать методы через публичные интерфейсы, они были разработаны для внутриигрового взаимодействия. Старые версии этих интерфейсов имели скрытые возможности по авторизации, получения TICKET для игр Valve с помощью вызова метода, этим и воспользовался разработчик. Он подключался к уже существующему Steam клиенту и вызывал методы, как это делает игра.
Информация о них расположена тут: https://github.com/alliedmodders/hl2sdk/tree/csgo
Техническая реализация нашей версии
Проект для фарма без окон и без использования Steam-клиентов был реализован на .NET с помощью библиотеки SteamKit2.
Основой сетевого клиентского обмена информацией в Steam является протокол Protobuf.
В самой библиотеке SteamKit2 уже присутствует множество примеров авторизации, доступных в официальном репозитории, поэтому здесь мы сразу перейдём к сути процесса.
Система работы была следующей:
Клиент:
- Подключение к игровому координатору (EGCBaseClientMsg.k_EMsgGCClientHello).
- Инициализация подключения к серверу матчмейкинга (ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingGC2ClientHello).
- Запрос на подключение к эмулированному IDLE-серверу (ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientRequestJoinServerData).
- Далее необходимо было создать так называемый TICKET, подтверждающий прохождение проверки VAC. Одним из ключевых условий была защита сервера с помощью VAC, поэтому требовалось формировать подпись, подтверждающую успешную верификацию модуля VAC. Это являлось наиболее сложной частью программы, так как малейшая ошибка приводила к отказу подключения с соответствующей VAC-ошибкой, аналогичной той, которая периодически возникает и в официальном клиенте CS.
Созданный TICKET отправлялся в Steam и передавался серверу, который также должен был отправить его в Steam для подтверждения корректности подключения.
После успешной верификации тикета у аккаунта появлялось 15 минут, в течение которых время нахождения на сервере засчитывалось Steam. По истечении этого времени тикет необходимо было обновлять и заново проходить процедуру верификации.
Сервер:
- Авторизация через анонимного пользователя, что доступно для игровых серверов.
- Отправка базовой информации сервера (порт, название и т.д.) с помощью сообщения (EMsg.GSServerType).
- Инициализация подключения осуществлялась отправкой информации о текущих подключённых клиентах, их пинге и других параметрах (EMsg.AMGameServerUpdate).
- При каждом новом подключении клиента сервер должен был отправлять обновления (EMsg.AMGameServerUpdate) с актуальной информацией о подключённых клиентах и сетевой статистикой.
- Каждые 3 минуты отправлялся запрос (ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingServerReservationResponse), подтверждающий, что клиент провёл необходимое время на сервере для засчитывания игрового времени Steam.
- Каждые 5 минут отправлялся запрос (ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchEndRunRewardDrops), инициирующий процесс выпадения дропа на аккаунтах.
Благодаря эмуляции, серверу и клиенту не надо было иметь постоянное соединение через сокет, как это реализовано в Tiny Server и официальном сервере Steam. Надо было лишь уведомить Steam с помощью клиента и сервера, что аккаунт успешно авторизовался.
Также важной необходимо было поддерживать так называемый HeartBeat, специальные системные сообщения, которые говорят Steam сети, что клиент активен. Это надо делать со стороны сервера и клиента.