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

Все попытки применения — исключительно на свой страх и риск.

Реализация приведена для Windows десктопов.

Итак, создадим простой бот, целью которого будет:

1) зайти в игру;
2) зайти в аккаунт;
3) зайти в игровой мир;
4) открыть почтовый ящик;
5) сформировать и отправить письмо другому игроку;

1) Зайти в игру


Для того чтобы зайти в игру, нам нужно собственно иметь заранее скачанный клиент игры.
В работе мы используем exe файл Wow.exe. Запишем его путь следующим образом:

String WowPatch="D:/Wow/Wow.exe";

Здесь мы записали путь к исполняющему файлу Wow. У Вас этот путь вероятно будет отличаться.

Путь — это конечно хорошо, но этого мало, для того чтобы запустить игру.

Для запуска нам потребуется вот такой код:

String WowPatch="D:/Wow/Wow.exe";
File file =new File(WowPatch);
try {
      Desktop.getDesktop().open(file);
      } 
	catch (IOException e1) 
	{
		e1.printStackTrace();
	}

В результате применения вышеуказанного кода, у вас на компьютере должен запуститься WoW.

WoW мы запустили и тут же столкнулись с новой проблемой — Как сделать так чтобы бот автоматически ввел логин и пароль от аккаунта?

2) Зайти в аккаунт


Теперь? нам нужно записать еще две текстовых переменных.

String Login="YourLogin";
String Password="YourPassword";

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

Чтобы логин и пароль не «ввелись» раньше времени, мы сделаем паузу в нашем коде:

String WowPatch="D:/Wow/Wow.exe";
File file =new File(WowPatch);
try {
      Desktop.getDesktop().open(file);
      } 
	catch (IOException e1) 
	{
		e1.printStackTrace();
	}
Thread.sleep(20000);
String Login="YourLogin";
String Password="YourPassword";

Здесь мы сделали паузу на 20 сек. У меня этого времени хватает более чем, чтобы загрузился WoW. Стоит отметить, что сразу после загрузки WoW мы уже имеем по умолчанию выбранным поле для логина. Все что нам теперь нужно сделать — скопировать логин из нашей переменной в буфер обмена и вставить в поле для логина:

Robot rb= new Robot();

StringSelection stringSelection = new StringSelection(Login);
Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard();
clpbrd.setContents(stringSelection, null);

rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);

Здесь мы скопировали наш Логин в буфер обмена и сымитировав нажатие комбинации Ctrl+V, вставили логин в соответствующее окно.

Теперь нам нужно переключится на окошко для ввода пароля. Это можно сделать двумя путями:

— Мы можем сымитировать движение мыши и клик по второму окошку.
— Мы можем переключиться, сымитировав нажатие на кнопку Tab.

Мы воспользуемся вторым вариантом, так как он проще:

rb.keyPress(KeyEvent.VK_TAB);
rb.keyRelease(KeyEvent.VK_TAB);

Далее скопируем в буфер обмена наш пароль и вставим его:

StringSelection stringSelection2 = new StringSelection(Password);
Clipboard clpbrd2 = Toolkit.getDefaultToolkit().getSystemClipboard();
clpbrd2.setContents(stringSelection2, null);
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);

Ура!!! Мы вошли в меню выбора персонажа. Теперь нужно войти в игровой мир.

3) Зайти в игровой мир


Теперь мы видим на экране меню выбора персонажа. Мы пожалуй не будем особо перебирать и зайдем на первого попавшегося персонажа.

Для того, чтобы войти, мы можем использовать два разных варианта:

— Переместить курсор мыши на кнопку «Войти» и сымитировать клик;
— Сымитировать нажатие на кнопку Enter;

Второй вариант проще, но если мы допишем нажатие сразу после функции входа, то снова будут неприятности, потому снова сделаем паузу, давая игре спокойно зайти в меню выбора персонажа:

Thread.sleep(5000);
rb.keyPress(KeyEvent.VK_ENTER);
rb.keyRelease(KeyEvent.VK_ENTER);

Мне 5 сек. хватает с головой.

О чудо, пошла загрузка игрового мира!

4) Открыть почтовый ящик


Здесь нам снова придется сделать паузу, дабы WoW успел загрузить игровой мир. Так же желательно предварительно подготовить персонажа:

— Максимально приблизить камеру;
— Стать лбом в почтовый ящик;

Для того чтобы открыть почтовый ящик, нужно крикнуть по нему правой кнопкой мыши. Для этого мы переместим курсор мыши и сымитируем клик:


Thread.sleep(30000);
rb.mouseMove(700, 350);
rb.mousePress(InputEvent.BUTTON3_MASK);
rb.mouseRelease(InputEvent.BUTTON3_MASK);

Учитывайте, что позиция мыши указанная мной, рассчитана на разрешение экрана 1366х768.
BUTTON3 — это именно правая кнопка мыши.

Почтовый ящик открыли, теперь перейдем в вкладку «Отправить»:

rb.mouseMove(200, 550);
rb.mousePress(InputEvent.BUTTON1_MASK);
rb.mouseRelease(InputEvent.BUTTON1_MASK);

Здесь мы не только имитировали перемещение мыши по экрану, но и сделали клик левой кнопкой мыши.

Теперь самое время заполнить и отправить письмо!

5) Сформировать и отправить письмо другому игроку


Теперь нам нужно заполнить пункты:

— Имя получателя;
— Тема сообщения;
— Текст сообщения;

String Name="Name";
String Theme="Theme";
String Text="Text";

Для начала поместим в буфер обмена, имя персонажа и вставим его в соответствующую графу:

StringSelection stringSelection3 = new StringSelection(Name);
Clipboard clpbrd3 = Toolkit.getDefaultToolkit().getSystemClipboard();
clpbrd3.setContents(stringSelection3, null);

rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);

rb.keyPress(KeyEvent.VK_TAB);
rb.keyRelease(KeyEvent.VK_TAB);

Мы вставили имя получателя и переключились на другую графу. Теперь нужно вставить тему сообщения:

StringSelection stringSelection4 = new StringSelection(Theme);
Clipboard clpbrd4 = Toolkit.getDefaultToolkit().getSystemClipboard();
clpbrd4.setContents(stringSelection4, null);

rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);

rb.keyPress(KeyEvent.VK_TAB);
rb.keyRelease(KeyEvent.VK_TAB);

Вставили тему сообщения и переключились на третью графу — текст сообщения:

StringSelection stringSelection5 = new StringSelection(Text);
Clipboard clpbrd5 = Toolkit.getDefaultToolkit().getSystemClipboard();
clpbrd5.setContents(stringSelection5, null);

rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);

Вставили текст сообщения. Теперь только осталось нажать на кнопку «Отправить»:

rb.mouseMove(200, 520);
rb.mousePress(InputEvent.BUTTON1_MASK);
rb.mouseRelease(InputEvent.BUTTON1_MASK);

Переместили курсор и нажали левой кнопкой мыши на «Отправить».

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

Комментарии (12)


  1. Daar
    24.12.2018 22:03

    Эхх… подобным занимался лет так… 20 назад :))) когда начал играть в свою первую онлайн игру… Ultima Online… по модему :))) и уже тогда пытался анализировать картинку, многие предметы имели определенную цветовую гамму, ввиду этого была кучка скриптов, например один для поисков ресурсов в пещерах, пробегался по экрану с определенным шагом, находил интересующую палитру и туда кликал мышкой для перемещения персонажа. Даже помню писал что-то типа своего автобоя… эхххх… есть что вспомнить.


    1. CrazyDeveloperZz Автор
      24.12.2018 22:08

      Моей первой онлайн игрой и был WOW :) потому он и «попал под раздачу» ) дань памяти, так сказать


  1. argamidon
    24.12.2018 22:31

    А откуда используемые классы в частности Desktop, StringSelection, Clipboard, Toolkit? Какая библиотека(и)?


    1. CrazyDeveloperZz Автор
      24.12.2018 22:40

      java.awt.AWTException;
      java.awt.Robot;
      java.awt.Toolkit;
      java.awt.datatransfer.Clipboard;
      java.awt.datatransfer.StringSelection;
      java.awt.event.InputEvent;
      java.awt.event.KeyEvent;
      java.awt.Desktop;


  1. Lertmind
    25.12.2018 04:48

    Ботом это сложно назвать, скорее обычным макросом, который можно написать в AutoHotkey.
    Боты на официальном сервере запрещены и караются, что там с макросами не знаю.
    В пунктах 2) и 5) так и просится устранение дублирования через «Извлечение метода» или использование готового класса. Ну и форматирование кода не помешало бы, умудрились перебрать все варианты с присваиванием: "=", " =", "= ", " = ". IDE может расставить всё автоматически.


  1. GennPen
    25.12.2018 08:41
    +1

    потому его работоспособность на официальных серверах не гарантирована
    Мало того, крайне не желательна.

    Для того чтобы открыть почтовый ящик, нужно крикнуть по нему правой кнопкой мыши. Для этого мы переместим курсор мыши и сымитируем клик:

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


    1. CrazyDeveloperZz Автор
      25.12.2018 10:16

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


      Именно потому я написал:

      Здесь нам снова придется сделать паузу, дабы WoW успел загрузить игровой мир. Так же желательно предварительно подготовить персонажа:

      — Максимально приблизить камеру;
      — Стать лбом в почтовый ящик;


  1. Anshi85
    25.12.2018 08:46
    -1

    Ну на пиратке можно итак себе сделать любой шмот и уровень, особенно если ты админ сервера. Я как то поднимал в 2007 году на работе сервер и играли с коллегами иногда вечером. На официальных серверах банят, сам использовал бота для рыбалки и получил бан на полгода. А вообще лично мое мнение если уже пытаешься автоматизировать игру то значит игра уже тебе не интересна. Игра должна приносить удовольствие от самого процесса игры в нее. Я обычно в WOW возвращаюсь раз в год — два на пару месяцев проплачиваю аккаунт, если нужно покупаю аддон, потом как игра наскучивает удаляю.


  1. vinty
    25.12.2018 10:18

    Крайне интересно было бы прочесть с точки зрения подключения OpenCV, не пробовали так? У вас указаны координаты мыши на экране, но ведь это гарантированная ошибка, если персонаж не прямо стоит упершись в ящик, не? Хоть какой-то анализ картинки с ящиком на «ящик это или нет» — было бы очень интересно.
    И что за классы, которые нажимают на клавиши? mvnrepository.com/artifact/org.robotframework/robotframework — это оно?


    1. CrazyDeveloperZz Автор
      25.12.2018 10:20

      Это Java AWT. Анализ картинки и работа с масками, это совсем другой уровень бота.


  1. Slav2
    25.12.2018 10:21

    Написание и продажа ботов для игр это хороший бизнес без начальных затрат. Сам этим занимаюсь уже седьмой год. Продаваемого бота можно написать не для любой игры. Нужно чтобы выполнялось несколько условий. Между персонажами можно передавать предметы/валюту. Тогда появляется класс ботоводов, которые обеспечивают остальных нужными ресурсами продавая их за реал. В процессе игры персонаж может терять какие то вещи в результате боев, т.е. это не песочница где все только накапливают состояние. Иначе бот не требуется. Игра должна вам нравиться, тогда работа превращается в хобби. Ну и вы в состоянии сделать что-то, что еще ни у кого нет. Мне сам WOW не понравился, не люблю мультяшную гафику. Но рынок там есть, а торгового бота который на копеечку изменяет стоимость заказа по моему нет. Как вариант.


    1. CrazyDeveloperZz Автор
      26.12.2018 00:28

      … а торгового бота который на копеечку изменяет стоимость заказа по моему нет. ..

      Есть. Я даже, где-то здесь, на Хабре видел статью о написании Аддона-бота, который покупал товары подешевле и продавал подороже.