Как сделать клиент браузерной игры
Пишем бота для браузерной игры agar.io
Все уже наверно в курсе о такой замечательной веб-игре, как agar.io.
В очередной раз проиграв в ней более везучему сопернику, я тихо выругался про себя и решил как-то взломать эту игрушку, чтобы получить наконец в ней преимущество! В итоге мне удалось создать себе отряд игровых ботов, которые стремятся найти меня на карте, чтобы влиться в мою игровую клетку.
Влезаем в клиент игры
Сначала надо было понять, как все работает.
Игра написана на javascript и общается с игровым сервером через веб-сокет.
Основной игровой скрипт лежит в файле main_out.js.
Код там конечно же обфусцирован и всячески пытается не давать себя запускать откуда не следует:
Развернув файл в читаемый вид через дебаггер Хрома, встал вопрос: каким образом вклиниться в логику игры?
Вначале я решил создать локальную копию файлов и соединяться с сервером, отключив в браузере проверку на кроссдомен:
Это заработало для AJAX запросов игровых регионов, но дальнейшие попытки соединиться по веб-сокету были отклонены. Нужен был другой подход.
Подменяем файлы по урлу
Рабочим решением стала загрузка реального игрового клиента, но подмена для браузера нужных файлов на свои. Для этого устанавливаем замечательную программу Fiddler Web Debugger и указываем нужные пути в табе AutoResponder:
Такой подход очевидно требует держать Fiddler запущенным во время игровой сессии.
Пытаемся обмануть сервер
Хочу похвалить авторов игры — на сервер не отправляется ничего такого, что можно было бы поменять в свою пользу (например: свой размер :)). Клиент шлет лишь координаты мыши, куда бы он хотел передвинуть свою клетку и сообщает о желаемых действиях (например: разделиться).
Сервер в свою очередь не присылает клиенту «лишних» для него данных. Например, когда я увеличил масштаб игровой карты, то сервер все равно присылал лишь то окно объектов, которое я должен был видеть в рамках своей клетки:
Казалось бы все пути закрыты: сервер не доверяет клиентам никакой важной информации и всё просчитывает самостоятельно.
Но тогда можно обмануть сервер в рамках его правил: создать стаю ботов, которые постоянно будут жертвовать собой, увеличивая мою массу. Но как же ботам находить мою клетку на карте? Выручило само API сервера: если постоянно отправлять ему например координаты (0, 0), то игровая клетка будет всегда следовать в эту часть карты без остановки, пока не достигнет цели. Вместо нулей надо всего лишь отправлять ботам мои текущие координаты и они сами будут приходить ко мне на ужин!
Пишем ботов в текущем окне
Код клиента одновременно получает данные и перерисовывает объекты на экране. Можно было бы открыть 20 табов, управляемых ботами и один мой игровой таб. Но тогда надо было бы как-то передавать мои координаты в соседние табы. Плюс рисование каждого таба тормозило бы весь браузер (я пробовал — так и есть). Поэтому было решено создавать новые игровые сессии прямо в текущем табе, но выключить для них связь с отображением:
Так же нужно было дописать код, чтобы при смерти бота, он автоматически начинал новую сессию.
Результаты работы
Боты создаются. И находят меня на карте!
Однако, все не так радужно.
Во-первых, сервер раскидывает игроков по игровым комнатам. Поэтому со мной на карту из 50 ботов попадают 2-3. Остальные «играют» в других комнатах, следуя по координатам из соседней Вселенной.
Во-вторых, ботов может съесть кто-то другой! Поэтому им удается придти ко мне где-то пару раз в минуту.
И, наконец, в-третьих, боты маленькие. Идя ко мне, они не набирают особой массы. Поэтому, с определенного этапа, их вклад в мою победу становится минимальным.
Выводы
Авторам игры удалось создать замечательный сетевой код, который не ломается от банального хакинга. Однако игра не защищена от ботоводства и немного разобравшись в коде клиента, можно создать себе небольшое техническое преимущество перед остальными.
Если же решить вопрос с тем, чтобы боты подключались на нужную карту, то тогда есть возможность серьезно потеснить своих менее технически-подкованных соперников.
Я же своей маленькой цели достиг:
Может быть благодаря ботам, может быть мне повезло самому.
Спасибо за внимание и удачи в игре!
Ой, у вас баннер убежал!
Читают сейчас
Редакторский дайджест
Присылаем лучшие статьи раз в месяц
Скоро на этот адрес придет письмо. Подтвердите подписку, если всё в силе.
Похожие публикации
Еженедельник io.js, 6 марта 2015
IO.js или старые грабли под новым соусом
WebSocket RPC или как написать живое WEB приложение для браузера
Курсы
AdBlock похитил этот баннер, но баннеры не зубы — отрастут
Минуточку внимания
Комментарии 35
Да. На самом деле, успех в игре зависит прежде всего от умений игрока, а уже потом от удачи.
Для того, чтобы стабильно выбиваться в лидеры нежно освоить несколько приемов:
1) рассчитывать свою массу и массу противника, чтобы при делении не оказаться в патовой ситуации и не быть съеденным;
2) разбивать лидеров в с помощью зубастых клеток;
3) обмениваться массой между поделившимися клетками;
4) ретироваться делением в случае угрозы со стороны лидеров;
Во-первых, сервер раскидывает игроков по игровым комнатам. Поэтому со мной на карту из 50 ботов попадают 2-3. Остальные «играют» в других комнатах, следуя по координатам из соседней Вселенной.
В треде на reddit уже всё давно обсудили, и даже разработчик ответил: www.reddit.com/r/Agario/comments/34z3zp
Да и на youtube, к слову, такие же боты-кормильцы 8 дней как выложены: www.youtube.com/watch?v=XyLWCdnff2A
Я пошёл дальше и вообще исключил игрока оставив лишь ботов, которые кооперируются для выживания.
Свой код я инъектирую с помощью отладчика. Достаточно остановить его в любой внутренней функции и мы имеем полный доступ ко внутренним переменным. Так что можно через консоль создать замыкание, вызывающееся по таймеру, и можно творить что угодно.
Инфа о своих клетках находится в хэше «m». Инфа обо всех остальных клетках лежит в словаре «v». Этого уже достаточно для игры. Пробегаемся в цикле по своим клеткам и по чужим и складываем вычисленные для пар «я — не я» ускорения. Потом дёргаем onmousemove, чтобы сообщить движку в какую сторону мы хотим ускориться.
Все чужие клетки делятся на следующие группы:
2. Друзья — дружеские боты, действующие всоседних вкладках. Их определяем по префиксу в имени. К ним притягиваемся с константной силой. Это позволяет им находить друг друга даже если отреспаунились в разных конца карты.
3. Враги — клетки, которые больше максимального размера, что мы можем съесть. От них отталкиваемся как отвирусов, но с другим коэффициентом.
4. Еда — все остальные клетки, существенно меньше нашей. К ним притягиваемся по обратно квадратичному закону.
Кроме того, чтобы бота не зажимали к стенке, добавляем отталкивание от них в перпендирулярних к ним направляниях по тому же закону обратных квадратов.
Итого это позволяет убегать от группы врагов поедая попадающуюся по пути еду и сливаться с друзьями образуя более крупную особь. Однако люди всё ещё могут хитростью зажать нашего бота в тиски или порвать его простреливая через вирус.
Чтобы отреспауниться, достаточно вызвать функцию setNick(string). Я её вызываю просто всегда при вызове моего замыкания.
Фото рекорда:
Видео с четырьмя ботами:
Создаем многопользовательскую браузерную игру. Часть первая. Клиент-серверная архитектура
Рассказывает Алвин Лин, разработчик программного обеспечения из Нью-Йорка
В 2014 году я впервые побывал на CodeDay в Нью-Йорке. И хотя CodeDay не совсем хакатон, это было моё первое знакомство с подобными мероприятиями. Там мы с моим другом Кеннетом Ли написали многопользовательскую игру в танчики. Так как несколько моих друзей спрашивали меня о том, как я её написал, я решил описать процесс её создания.
В этом посте я вкратце опишу ход своих рассуждений и покажу, как воссоздать архитектуру, а также дам некоторые советы, если вы захотите сделать игру сами. Этот пост рассчитан на тех, кто владеет основами JavaScript и Node.js. Если вы с ними не знакомы, то есть много замечательных онлайн-ресурсов, где можно их изучить.
Прим. перев. На нашем сайте есть много познавательных материалов как по JavaScript, так и по Node.js — обязательно найдёте что-нибудь подходящее.
Прим. перев. Если вы не знакомы с веб-сокетами, рекомендуем прочитать наш вводный материал.
Создание проекта
Для начала установите зависимости. Создайте папку проекта, перейдите в неё и запустите следующий код:
Для быстрой настройки сервера целесообразно использовать фреймворк Express, а для обработки веб-сокетов на сервере — пакет socket.io. В файл server.js поместите следующий код:
Теперь нужно настроить веб-сокеты на сервере. В конец файла server.js добавьте:
Пока что в игре нет никаких функций, поэтому в обработчик веб-сокетов ничего добавлять не нужно. Для тестирования допишите следующие строки в конец файла server.js :
Эта функция будет отправлять сообщение с именем message и содержимым hi всем подключенным веб-сокетам. Позже не забудьте удалить эту часть кода, так как она предназначена только для тестирования.
24 февраля в 11:00, Киев, От 500 до 8000 ₴
Запустите сервер командой node server.js и в любом браузере перейдите по ссылке http://localhost:5000. Если вы откроете окно разработчика (нажать правую кнопку мыши → Проверить (Inspect)), то увидите, как каждую секунду приходит новое сообщение:
Как правило, socket.emit(name, data) отправляет сообщение с заданным именем и данными серверу, если запрос идет от клиента, и наоборот, если запрос идет от сервера. Для получения сообщений по конкретному имени используется следующая команда:
С помощью socket.emit() вы можете отправить любое сообщение. Можно также передавать объекты JSON, что для нас очень удобно. Это позволяет мгновенно передавать информацию в игре от сервера к клиенту и обратно, что является основой многопользовательской игры.
Теперь пусть клиент отправляет некоторые состояния клавиатуры. Поместите следующий код в конец файла static/game.js :
Эта часть кода позволит отправлять на сервер информацию о состоянии клавиатуры клиента 60 раз в секунду. Теперь необходимо прописать эту ситуацию со стороны сервера. В конец файла server.js добавьте следующие строки:
Когда сервер получит сообщение о том, что присоединился новый игрок, он добавит новый вход в объект игроков при помощи id сокета, который будет в этом сообщении. Когда сервер получит сообщение о движении, то обновит информацию об игроке, который связан с этим сокетом, если он существует.
io.sockets.emit() — это запрос, который будет отправлять сообщение и данные ВСЕМ подключённым сокетам. Сервер будет отправлять это состояние всем подключённым клиентам 60 раз в секунду.
Этот код обращается к id Canvas ( #canvas ) и рисует там. Каждый раз, когда от сервера будет поступать сообщение о состоянии, данные в Canvas будут обнуляться, и на нём в виде зеленых кружков будут заново отображаться все игроки.
Вот и всё! Если у вас возникли проблемы, посмотрите архив с исходным кодом.
Некоторые тонкости
Когда будете разрабатывать более функциональную игру, целесообразно разделить код на несколько файлов.
Такие многопользовательские игры — отличный пример архитектуры MVC (модель-представление-контроллер). Вся логическая часть должна обрабатываться на сервере, а всё, что должен делать клиент — это отправлять входные пользовательские данные на сервер и отображать информацию, которую получает от сервера.
Однако в этом демо-проекте есть несколько недостатков. Обновление игры связано со слушателем сокета. Если бы я хотел повлиять на ход игры, то мог бы написать в консоли браузера следующее:
Теперь данные о движении будут отправляться на сервер в зависимости от характеристик компьютера более 60 раз в секунду. Это приведёт к тому, что игрок будет передвигаться невероятно быстро. Так мы переходим к концепции определения полномочного сервера.
Ни на каком этапе клиент не должен контролировать какие-либо данные на сервере. Например, никогда не нужно размещать на сервере код, который позволит клиенту определять своё положение/здоровье на основе данных, которые передаются через сокет, так как пользователь сможет легко подделать сообщение, исходящее из сокета, как показано выше.
Лучшая аналогия, которую я могу привести, заключается в том, что клиенты должны посылать на сервер только информацию о своих намерениях, которые затем будут обрабатываться и использоваться для изменения состояния игроков, если они валидны.
Кроме того, старайтесь избегать такого кода:
В этом отрезке кода обновление координаты х для игрока связано с частотой смены кадров в игре. SetInterval() не всегда гарантирует соблюдение интервала, вместо этого напишите нечто подобное:
Это не так изящно, зато обеспечит более плавную и последовательную работу. Усложните демо-проект и попробуйте сделать так, чтобы обновление осуществлялось согласно времени, а не частоте смены кадров. Если не захотите на этом останавливаться, попытайтесь создать на сервере физический движок, который будет управлять движениями игроков.
Также можно сделать так, чтобы из игры удалялись отключенные игроки. Когда сокет отключается, автоматически отправляется сообщение о разъединении. Это можно прописать так:
Также попытайтесь создать собственный физический движок. Это сложно, но весело. Если захотите попробовать, то рекомендую прочитать книгу «The Nature of Code», в которой есть много полезных идей.
Если хотите посмотреть на гораздо более продвинутый пример, вот игра, которую я сделал, а также исходный код, если вы хотите узнать, как это было написано. На этом всё. Спасибо, что прочитали!
Написание/редактирование клиента для браузерной игры
Бот для браузерной игры на С++
Привет! Хотелось бы узнать, можно ли на С++/Qt написать бота для браузерной игры, например.
Бот для браузерной игры
Решил написать бота для браузерной игры, и задался вопрос как это сделать, знаю что иногда боты.
Бот для браузерной флеш-игры
ребят, понадобилась помощь! никогда не работал из с++ с флешь и браузером. это для меня в.
Можно ли написать плагин для браузерной игры
Доброе время суток,под ночь озадачился вопросом «а можно ли написать своеобразный плагин для.
Хочу изменить клиент под похожую игру
telepat, а вот вас и спрашивают, что именно вы хотите изменить? Как, например, вы определили, что игры похожи?
Пока что вопрос звучит слишком общим, а еще и при неизвестном уровне вашей подготовки, советовать вам что-то затруднительно.
Ну и исходник-то на C#, а тут раздел по C++. Почему вы написали именно сюда?
XLAT, я спросил «как», а не «похожи ли».
Если автор сравнил этот код с кодом какой-то другой игры, то ему так и следовало написать. Это во-первых. Во-вторых, если у него достаточно квалификации, чтобы сделать такое сравнение, то не понятно в чем его вопрос заключается. В этом случае он сам способен все сделать и без форума.
XLAT, вам поговорить не с кем? 🙂
так не цепляйтесь на крючок и будете свободны 🙂
мне вот ясно как автор определил схожесть,
ваш вопрос у меня вызвал удивление,
поэтому я решил вам помочь, но вы сильно надутый, чтобы принять помощь. 😀
подготовка нулевая. Игра слеплена из исходников основы. Либо как написать самый примитивный клиент, чтобы интерфейс просто был и скажем навигатор сделать для перемещений по карте? Какие навыки для этого нужны?)
Добавлено через 14 секунд
И возможно ли вообще новичку такое сотворить?
Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.
Бот для браузерной игры
Подскажите что-нибудь по сетевому С/С+ Моя задача написать бота для браузерной игры:)
Написание клиента/сервера для обмена сообщениями и файлами
Всем привет. Возникла задача: Написать клиент/сервер, для обмена сообщениями и файлами. Клиентов.
Написание бота для игры
Уже задавал этот вопрос, только в другой категории, а ответить по делу мне так и не смогли. Ищу.
Бот для браузерной игры
Добрый день, только начинаю изучать C#. До этого писал бота на Autoit, очень нравилась простота. Но.