
Все уже наверно в курсе о такой замечательной веб-игре, как agar.io.
В очередной раз проиграв в ней более везучему сопернику, я тихо выругался про себя и решил как-то взломать эту игрушку, чтобы получить наконец в ней преимущество! В итоге мне удалось создать себе отряд игровых ботов, которые стремятся найти меня на карте, чтобы влиться в мою игровую клетку.
Влезаем в клиент игры
Сначала надо было понять, как все работает.
Игра написана на javascript и общается с игровым сервером через веб-сокет.
Основной игровой скрипт лежит в файле main_out.js.
Код там конечно же обфусцирован и всячески пытается не давать себя запускать откуда не следует:
if ("agar.io" != h.location.hostname && "localhost" != h.location.hostname && "10.10.2.13" != h.location.hostname) h.location = "http://agar.io/";
Развернув файл в читаемый вид через дебаггер Хрома, встал вопрос: каким образом вклиниться в логику игры?
Вначале я решил создать локальную копию файлов и соединяться с сервером, отключив в браузере проверку на кроссдомен:
#файлы игры
/css/bootstrap.min.css
/js/jquery.js
/index.html
/main_out.js
/quadtree.js
#запуск Хрома без same origin policy
chrome.exe --disable-web-security
Это заработало для AJAX запросов игровых регионов, но дальнейшие попытки соединиться по веб-сокету были отклонены. Нужен был другой подход.
Подменяем файлы по урлу
Рабочим решением стала загрузка реального игрового клиента, но подмена для браузера нужных файлов на ��вои. Для этого устанавливаем замечательную программу Fiddler Web Debugger и указываем нужные пути в табе AutoResponder:

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

Казалось бы все пути закрыты: сервер не доверяет клиентам никакой важной информации и всё просчитывает самостоятельно.
Но тогда можно обмануть сервер в рамках его правил: создать стаю ботов, которые постоянно будут жертвовать собой, увеличивая мою массу. Но как же ботам находить мою клетку на карте? Выручило само API сервера: если постоянно отправлять ему например координаты (0, 0), то игровая клетка будет всегда следовать в эту часть карты без остановки, пока не достигнет цели. Вместо нулей надо всего лишь отправлять ботам мои текущие координаты и они сами будут приходить ко мне на ужин!
Пишем ботов в текущем окне
Код клиента одновременно получает данные и перерисовывает объекты на экране. Можно было бы открыть 20 табов, управляемых ботами и один мой игровой таб. Но тогда надо было бы как-то передавать мои координаты в соседние табы. Плюс рисование каждого таба тормозило бы весь браузер (я пробовал — так и есть). Поэтому было решено создавать новые игровые сессии прямо в текущем табе, но выключить для них связь с отображением:
//запускаем новые копии игры
var isBot = true;
for (i = 0; i < botsCount; i++) {
//нужно делать паузу перед новым ботом,
//чтобы сервер не отклонил слишком частые соединения
setTimeout(function(){
game(window, r, isBot, botsUrl, M);
}, 500);
}
//не даем эти копиям рисовать на экране
function paint() {
if(bot) return;
//...
}
Так же нужно было дописать код, чтобы при смерти бота, он автоматически начинал новую сессию.
Результаты работы
Боты создаются. И находят меня на карте!

Однако, все не так радужно.
Во-первых, сервер раскидывает игроков по игровым комнатам. Поэтому со мной на карту из 50 ботов попадают 2-3. Остальные «играют» в других комнатах, следуя по координатам из соседней Вселенной.
Во-вторых, ботов может съесть кто-то другой! Поэтому им удается придти ко мне где-то пару раз в минуту.
И, наконец, в-третьих, боты маленькие. Идя ко мне, они не набирают особой массы. Поэтому, с определенного этапа, их вклад в мою победу становится минимальным.
Выводы
Авторам игры удалось создать замечательный сетевой код, который не ломается от банального хакинга. Однако игра не защищена от ботоводства и немного разобравшись в коде клиента, можно создать себе небольшое техническое преимущество перед остальными.
Если же решить вопрос с тем, чтобы боты подключались на нужную карту, то тогда есть возможность серьезно потеснить своих менее технически-подкованных соперников.
Я же своей маленькой цели достиг:

Может быть благодаря ботам, может быть мне повезло самому.
[ Итоговый код клиента ]
Спасибо за внимание и удачи в игре!
