Яндекс.Метрика

gdev

Бот для браузерной игры, сетевой подход

Прочитав статьи о ботах решил поделится своим скромным опытом создания бота с помощью Java и использованием сетевого протокола (то есть никаких макросов или внедрений в AS).

Введение

Где-то пол года назад я встретил одну довольно популярную игру ВКонтакте — Zonk, сама игра представляет собой вариацию на игру в кости Zilch, и заключается в том, что вам необходимо набрать 10000 очков быстрей своего противника выкидывая на костях различные комбинации.
Подготовка

Перед тем как приступить к написанию бота я решил изучить каким образом игра связывается с сервером и обменивается с ним данными. Для этого был использован довольно популярный сниффер — Wireshark.

После запуска Wireshark, надо запустить саму игру и сыграть пару игр. Потом найти сообщения между браузером и сервером в Wireshark и открыть всю историю переговоров.



В итоге было выявлено, что игра связывается с сервером по 9337/9338 порту и обменивается с ним с помощью JSON запросов. Аутентификация же происходит в виде обмена XML сообщениями содержащими вашу информацию ВКонтакте (как я понял, эта информация вынимается посредством API ВКонтакте).

Написание бота

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

Так как я не желал тратить время на парсинг XML, обмен сообщениями для аутентификации был реализован довольно грубо и в лоб:
socket = new Socket(serverIP, port);
out = new PrintWriter(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.print("<msg t='sys'><body action='verChk' r='0'><ver v='161' /></body></msg>" + END_CHAR);
out.flush();
while (!ZonkBotApp.getMessage(in).contains("apiOK")) {}
out.print("XMLMESSAGE" + END_CHAR); //Ваши данные
out.flush();

Для передачи сообщений с помощью JSON, был использован Jackson Java JSON-processor.
Затем создавался экземпляр бота, конструктору которого передавались Input и OutputStreams (открытые через сокет):
public Bot(BufferedReader in, PrintWriter out) {
        inputStream = in;
        outputStream = out;
}

Bot имел всего один метод, который создает комнату и отыгрывает один матч:
public void playGame(JTextArea outConsole, int gameType, int aiType)

Вторым компонентом бота, был его мозг, представляющий собой класс с публичным методом:
public BotAction actionToDo(DiceThrow diceThrow, int aiType);

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

Бот имел довольно аскетичный интерфейс который позволял соединятся с сервером, производить базовые настройки и запускать бота.



Дальнейшее исследование

После написания бота я решил заняться механизмами его доводки, для этого было реализовано несколько вариантов «мозгов» бота, нацеленных на различную игру, агрессивную, пассивную или же достижение определенного порога. Как я не старался, но мне не удавалось вывести бота в плюс по очкам, лучшее чего я смог достичь это потеря 5% очков в течении 2000 игр.

Исходные коты находятся в очень плачевном состоянии (бот писался год назад), но если есть желание я попробую привести их в порядок и выложить на github.