Пишем бота для браузерной игры agar. io

Все уже наверно в курсе о такой замечательной веб-игре, как agar. io .

В очередной раз проиграв в ней более везучему сопернику, я тихо выругался про себя и решил как-то взломать эту игрушку, чтобы получить наконец в ней преимущество! В итоге мне удалось создать себе отряд игровых ботов, которые стремятся найти меня на карте, чтобы влиться в мою игровую клетку.

Влезаем в клиент игры

Сначала надо было понять, как все работает.

Игра написана на javascript и общается с игровым сервером через веб-сокет.

Основной игровой скрипт лежит в файле main_out. js .

Код там конечно же обфусцирован и всячески пытается не давать себя запускать откуда не следует:

Развернув файл в читаемый вид через дебаггер Хрома, встал вопрос: каким образом вклиниться в логику игры?

Вначале я решил создать локальную копию файлов и соединяться с сервером, отключив в браузере проверку на кроссдомен:

Это заработало для AJAX запросов игровых регионов, но дальнейшие попытки соединиться по веб-сокету были отклонены. Нужен был другой подход.

Подменяем файлы по урлу

Рабочим решением стала загрузка реального игрового клиента, но подмена для браузера нужных файлов на свои. Для этого устанавливаем замечательную программу Fiddler Web Debugger и указываем нужные пути в табе AutoResponder:

Такой подход очевидно требует держать Fiddler запущенным во время игровой сессии.

Пытаемся обмануть сервер

Хочу похвалить авторов игры — на сервер не отправляется ничего такого, что можно было бы поменять в свою пользу (например: свой размер :)). Клиент шлет лишь координаты мыши, куда бы он хотел передвинуть свою клетку и сообщает о желаемых действиях (например: разделиться).

Сервер в свою очередь не присылает клиенту «лишних» для него данных. Например, когда я увеличил масштаб игровой карты, то сервер все равно присылал лишь то окно объектов, которое я должен был видеть в рамках своей клетки:

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

Но тогда можно обмануть сервер в рамках его правил: создать стаю ботов, которые постоянно будут жертвовать собой, увеличивая мою массу. Но как же ботам находить мою клетку на карте? Выручило само API сервера: если постоянно отправлять ему например координаты (0, 0), то игровая клетка будет всегда следовать в эту часть карты без остановки, пока не достигнет цели. Вместо нулей надо всего лишь отправлять ботам мои текущие координаты и они сами будут приходить ко мне на ужин!

Пишем ботов в текущем окне

Код клиента одновременно получает данные и перерисовывает объекты на экране. Можно было бы открыть 20 табов, управляемых ботами и один мой игровой таб. Но тогда надо было бы как-то передавать мои координаты в соседние табы. Плюс рисование каждого таба тормозило бы весь браузер (я пробовал — так и есть). Поэтому было решено создавать новые игровые сессии прямо в текущем табе, но выключить для них связь с отображением:

Так же нужно было дописать код, чтобы при смерти бота, он автоматически начинал новую сессию.

Результаты работы

Боты создаются. И находят меня на карте!

Однако, все не так радужно.

Во-первых, сервер раскидывает игроков по игровым комнатам. Поэтому со мной на карту из 50 ботов попадают 2-3. Остальные «играют» в других комнатах, следуя по координатам из соседней Вселенной.

Во-вторых, ботов может съесть кто-то другой! Поэтому им удается придти ко мне где-то пару раз в минуту.

И, наконец, в-третьих, боты маленькие. Идя ко мне, они не набирают особой массы. Поэтому, с определенного этапа, их вклад в мою победу становится минимальным.

Выводы

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

Если же решить вопрос с тем, чтобы боты подключались на нужную карту, то тогда есть возможность серьезно потеснить своих менее технически-подкованных соперников.

Я же своей маленькой цели достиг:

Может быть благодаря ботам, может быть мне повезло самому.