RUEN
Обсудить проект

Инженерный кейс

Автоматизация игрового клиента

Связка из панели, агента и клиентского модуля: выполняет игровые действия без человека и скрывает от клиента признаки того, что машина ему уже знакома.

части и общий слой
3
бита обязательно
32
описание протокола
1

Три части: панель, агент-загрузчик на машине и модуль внутри игрового процесса с наложенным интерфейсом. Модуль выполняет игровые действия без человека; идентификаторы оборудования при этом подменяются на уровне системных запросов — без этого клиент узнаёт машину.

Три части, одно описание протокола

Панель, агент и клиентский модуль — разные исполняемые файлы с разным жизненным циклом. Всё общее вынесено в отдельный слой заголовков: протокол запуска, работа с окружением, журнал, обработчик падений.

Так описание живёт в одном месте на три части. Три собственные реализации разъехались бы на первом же изменённом поле — и разъезд обнаружился бы не при сборке, а во время работы, когда одна часть уже не понимает другую.

Запуск — это рукопожатие, а не ожидание вслепую

Пути, каталог журналов, адрес прокси и признаки подмены передаются модулю через переменные окружения, а готовность сторон — через именованные события: агент говорит «я готов», клиентский модуль — «я загрузился».

Очевидный путь — подождать секунду и продолжить — ломается на медленной машине и на быстрой: в первом случае рано, во втором зря потеряно время. Событие снимает вопрос: ждём ровно до готовности.

Сборка принудительно 32-битная, и об этом предупреждает сама сборка

Игровой клиент 32-битный, значит и модуль обязан быть таким же. В настройках сборки стоит проверка: если выбрана другая разрядность, выдаётся предупреждение прямо при конфигурации.

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

Свой обработчик падений

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

Без него единственным свидетельством сбоя было бы «у меня всё закрылось».

Интерфейс живёт внутри игры

Наложенный интерфейс собран на Dear ImGui и рисуется прямо в окне игры, а перехват точек входа сделан через MinHook. Обе библиотеки подтягиваются сборкой по фиксированной версии — не «последняя из сети», а конкретный тег.

Для проекта, который живёт годами и собирается редко, это разница между «собралось как тогда» и «собралось неизвестно из чего».

Трафик каждой копии идёт своим маршрутом

В общем слое есть клиент прокси, SOCKS5 и запуск туннеля: каждая копия выходит в сеть своим путём. Это часть той же задачи — машины должны выглядеть независимыми, а не одной.

Что сделано на скорую руку

Имена переменных окружения для подмены продублированы в двух заголовках, чтобы разорвать циклическое включение, и синхронизируются руками. В коде на это стоит прямая пометка — но проверки, что они не разъехались, нет.

C++20 · CMake · MSVC · Dear ImGui · MinHook · Windows API