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

    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.