Эмулятор движения мыши по экрану. Mouse Recorder Запись движений мыши. Зацикливаем игровой процесс

Mouse Recorder - это универсальный сервис, созданный для освобождения пользователя от любого повторяющегося действия при выполнении задач на компьютере. Чтобы автоматизировать процесс следует записать алгоритм действий (макрос) - движения мыши и нажатий клавиш. Запись мыши и клавиатуры выполняется при помощи программы. Вам не потребуется специальных навыков программирования - процесс происходит легко и просто. Возможности программы позволяют индивидуально настроить любое движение мыши или нажатие клавиши на клавиатуре для быстрого выполнения определённой задачи. Автоматизация действий мыши и клавиатуры упрощает работу за компьютером, что позволяет Вам выполнить один и тот же процесс за меньшее время, увеличивая скорость выполнения проекта. При этом в приложении реализована уникальная возможность использования Ваших записей совместно с отдельным сервисом "PhraseExpress", который добавляет дополнительных возможностей Вашей работе.

Mouse Recorder - доступный сервис для автоматизации работы на Windows

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

Записать мышь с клавиатурой и повторить

Чтобы упростить себе монотонную работу над повторяющимися задачами достаточно установить Mouse Recorder, пользоваться которым сможет даже начинающий программист или веб-дизайнер. Автоматизация мыши и клавиатуры происходит в несколько этапов: для начала записываем нужный макрос при помощи кнопки "Запись (Record)", затем, чтобы в дальнейшем повторить записанные действия - надо нажать кнопку "Воспроизвести (Play)" на настраиваемой скорости воспроизведения. Так можно легко запомнить действия мыши и клавиатуры и повторить их в нужный момент. Удобный редактор позволяет настраивать под себя любые движения мыши, действия кнопок на клавиатуре, а также редактировать и добавлять необходимые паузы, клики и нажатия клавиш. Точность записи перемещения мыши и временные интервалы кликов соблюдаются программой в автоматическом режиме.

Имитация мыши и клавиатуры

Все создано для комфортного пользования - запись и автоматизация действий пользователя происходит под непосредственным руководством человека и автоматической системы утилиты. Программа Mouse Recorder обеспечит Вам восстановление позиций окна записанного приложения, если окно по каким-то причинам изменило свое положение на экране. Для многопользовательского использования программы Mouse Recorder можно осуществить синхронизацию с веб-сервисом Dropbox, что позволит получить доступ к записям другим пользователям.

Скриншоты программы Mouse Recorder



Официальный сайт: http://www.mouserecorder.com/
Операционные системы: Windows All
Поддерживаемые языки: Английский
Версия: 1.0.50
Лицензия: fre eware (бесплатная )

Размер файла 2,4 Мб

Еще интересные программы.

Каждый, играя, хоть раз думал: «вот бы написать программу, которая играла бы за меня!». Но обычно эта мысль, так мыслью и остается… Постоянно что-то мешает: незнание с чего начать, страх перед неподъемностью задачи, шепоток из-за левого плеча «и зачем это? кому это надо, чтобы программа играла с программой?» и т.д.

В данном цикле статей я собираюсь показать, что, во-первых: «не так страшен черт, как его малюют», а во-вторых: позже собираюсь ответить и на вопрос: «зачем это надо?».

Сейчас начнем с простого. С установления взаимосвязи между игрой и программой-игроком (ботом). В качестве подопытного кролика берется широкоизвестная игра Zuma.

Всякое взаимодействие складывается из двух процессов: отправки данных «им» и получения данных от «них». В Zuma всё управление делается мышой, а обратную связь игра выдает с помощью изображения. Соответственно, перво-наперво необходимо научиться программно эмулировать поведение мыши и получать изображение от игры.

Основная цель этой статьи: получить программу, которая самостоятельно раз за разом заходит в игровой процесс, там что-то делает, а при game over-е начинает всё заново. Далее этот каркас будет развиваться в направлении, чтобы бот всё дальше и всё дольше продержался в игре до game over-а.

Решаемые вспомогательные подзадачи: эмуляция мыши, перенаправление мыши на виртуальную машину, захват изображения.

Отступление

При разработке кода для данного цикла статей используется подход: как можно быстрее получить результат за минимум усилий. Такой подход позволяет поддерживать мотивацию на высоком уровне, и не дает опустить руки при виде неподъемности задачи. Из-за этого:
- во-первых, многие малозначимые (с точки зрения текущего результата) моменты будут быстро пробегаться, оставляя в коде «костыли и подпорки». И только на следующих итерациях эти моменты будут отдельно разбираться, и «костыли» будут заменяться на полноценный код.
- во-вторых, стиль кода больше «хакерский», чем классический C#-ный. В коде будет много лямд, анонимных данных, трюков, авторского произвола и полное отсутствие комментариев.

Эмуляция мыши

Windows поддерживает 2 штатных способа эмуляции мыши с помощью 4 различных функций WinApi.

Первый способ : посылка программе своих window-сообщений (WM_MOUSEMOVE , WM_LBUTTONDOWN и т.д.) с помощью функций SendMessage или PostMessage .

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

Второй способ : прямая эмуляция поведения мыши с помощью функций mouse_event или SendInput . Этот способ подходит для любых программ, в том числе и для полноэкранных DirectX-игр. Функция mouse_event попроще, но она считается устаревшей, SendInput - современнее, но более громоздкая. Остановимся на mouse_event.

WinApi-функции из C# вызываются с помощью технологии PInvoke . PInvoke-описание для большинства распространных WinApi-функций можно взять на сайте PInvoke.net . Функция mouse_event не является исключением .
public static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, UIntPtr dwExtraInfo);

Координаты мыши
Функция mouse_event имеет специфическую особенность: координаты мыши задаются в mickey, а не в пикселях. Перерасчет mickey в пиксели (и обратно) зависит от разрешения основного используемого монитора. (0,0) соответствует левому верхнему углу монитора, а (65535, 65535) нижнему правому, что дает формулы для пересчета mickey в пиксели и обратно: mickey_point = pixel_point * (65536, 65536) / screen_size и pixel_point = mickey_point * screen_size / (65536, 65536) .
Основные операции
Суммируя всё вышеперечисленное, получаем следующие операции для управления мышью.
Передвижение курсора мыши в точку (x,y):
mouse_event(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, x * 65536 / screen_width, y * 65536 / screen_height);
Клик левой кнопкой мыши:
mouse_event((MouseEventFlags.LEFTDOWN), 0, 0); System.Threading.Thread.Sleep(100); mouse_event((MouseEventFlags.LEFTUP), 0, 0);
Клик правой кнопкой мыши:
mouse_event((MouseEventFlags.RIGHTDOWN), 0, 0); System.Threading.Thread.Sleep(100); mouse_event((MouseEventFlags.RIGHTUP), 0, 0);
Проблема: эксклюзивность ввода
При эмуляции мыши через функцию mouse_event присутствует серьезное неудобство: mouse_event имитирует мышь для всей ОС сразу, а не для отдельного приложения. Из этого следует, что пока бот запущен и играется, то невозможна другая работа за компом: отладка бота, активный просмотр состояния бота, чтение интернета и т.д. Но есть выход: виртуальная машина!

Перенос игры на виртуальную машину

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

Бота, в отличии от самой игры, удобнее запускать на основной машине. Это позволяет перезапускать бота напрямую из Visual Studio, там же его отлаживать, есть куда выводить внутреннее состояние бота и т.д.

Развертывание виртуальной машины (в данном случае использовалась Oracle VirtualBox), установка гостевой ОС и перенос игры делается штатным образом за исключением одного момента: для бота необходима возможность установки связи по сети между хостовой ОС и гостевой ОС. Это делается множеством способов. Один из способов, прокинуть с помощью VirtualBox конкретный порт из гостевой ОС в хостовую. Другой способ, настроить режим Bridged Adapter, тогда виртуалка для всей сети будет выглядеть как обычный компьютер, и гостевая ОС будет получать свой ip-адрес через dhcp от роутера. По этому адресу и будет происходит доступ из хостовой ОС в гостевую. (автором, в данном случае, использовался вариант с bridged adapter)

Прокси
Для управления мышью на гостевой ОС напишем прокси, представляющий из себя простенький консольный tcp-сервер. Его полный код небольшой и представлен под катом. Для упрощения кода и уменьшения зависимостей прокси написан на голом socket-е без использования remoting-а, wcf и т.д.

Код прокси-сервера

using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; namespace InputProxy { class Program { static void Main(string args) { var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Bind(new System.Net.IPEndPoint(System.Net.IPAddress.Any, 7001)); socket.Listen(10); for (; ;) { var client = socket.Accept(); Console.WriteLine("connected.."); var thread = new System.Threading.Thread(() => { try { var clientReader = new System.IO.BinaryReader(new NetworkStream(client)); for (; ;) { if (client.Poll(1, SelectMode.SelectRead) && client.Available == 0) { Console.WriteLine("disconnected.."); break; } if (client.Available > 0) { var msgSize = clientReader.ReadInt32(); var message = clientReader.ReadBytes(msgSize); var messageReader = new System.IO.BinaryReader(new System.IO.MemoryStream(message)); var msgKind = messageReader.ReadInt32(); Console.WriteLine("message: kind:{0}, len:{1}", msgKind, message.Length); switch (msgKind) { case 0: { var flags = messageReader.ReadUInt32(); var x = messageReader.ReadInt32(); var y = messageReader.ReadInt32(); var data = messageReader.ReadUInt32(); mouse_event(flags, x, y, data, UIntPtr.Zero); } break; } } else System.Threading.Thread.Sleep(10); } } catch (Exception exc) { Console.WriteLine(exc); } }) { IsBackground = true }; thread.Start(); } } public static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, UIntPtr dwExtraInfo); } }


Для работы прокси достаточно его скопировать на виртуальную машину и запустить. Прокси ждет сообщения на порту 7001 и выводит лог своей работы на консоль. Для завершения работы прокси достаточно закрыть консольное окно.
Клиент
Подключение к прокси еще проще, чем код самого прокси.
var client = new System.Net.Sockets.TcpClient(vm_host, 7001); var clientStream = client.GetStream(); var clientWriter = new System.IO.BinaryWriter(clientStream); Action mouse_event = (flags, x, y) => { var messageStream = new System.IO.MemoryStream(); var messageWriter = new System.IO.BinaryWriter(messageStream); messageWriter.Write(0); messageWriter.Write((uint)flags); messageWriter.Write(x); messageWriter.Write(y); messageWriter.Write(0); var message = messageStream.ToArray(); clientWriter.Write(message.Length); clientWriter.Write(message); clientStream.Flush(); };

Перехват изображения

Изображение проще всего захватывать напрямую с экрана. В.net-е для этого есть готовая функция Graphics.CopyFromScreen . На этом способе и остановимся подробнее.
Во-первых, на выходе хочется получить Bitmap, а не Graphics - это решается с помощью вспомогательной функции:
public static Bitmap GetScreenImage(Rectangle rect) { var bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb); using (Graphics graphics = Graphics.FromImage(bmp)) { graphics.CopyFromScreen(rect.Left, rect.Top, 0, 0, rect.Size, CopyPixelOperation.SourceCopy); } return bmp; }
Во-вторых, необходимо знать какую часть экрана надо захватывать. Можно, конечно, захватывать всегда одну и ту же часть экрана, а игру руками располагать в этой части экрана, но это не спортивно не удобно. Тем более автоматизация этого процесса делается минимальными усилиями. В этом нам опять поможет WinApi и PInvoke, а конкретнее две функции: FindWindow и GetWindowRect . FindWindow позволяет по заголовку окна получить handle окна, а GetWindowRect по handle-у возвращает позицию и размер окна на экране.
Pinvoke-описание обеих функций есть на сайте pinvoke.net: FindWindow и GetWindowRect .
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); public struct RECT { public int Left; public int Top; public int Right; public int Bottom; }
И код захвата изображения окна виртуальной машины получается следующим:
var vm_left = 8; var vm_right = 8; var vm_top = 50; var vm_bottom = 30; var vm_title = "Windows81 - Oracle VM VirtualBox"; var handle = FindWindow(null, vm_title); if (handle == IntPtr.Zero) throw new Exception("Окно не найдено"); RECT rect; GetWindowRect(handle, out rect); var gameScreenRect = new System.Drawing.Rectangle(rect.Left + vm_left, rect.Top + vm_top, rect.Right - rect.Left - vm_right - vm_left, rect.Bottom - rect.Top - vm_bottom - vm_top); var gameBmp = GetScreenImage(gameScreenRect);
Слабое место
Существенным недостатком данного подхода является то, что захватываемое окно, во-первых: обязано целиком располагаться на экране, а во-вторых: обязано располагаться поверх всех остальных окон. Это неудобство нивелируется с помощью двух (и более) мониторов:), тогда окно виртуальной машины располагается на вспомогательном мониторе, ни кому не мешая, оставаясь поверх остальных окон. Также данная проблема полностью решается с помощью ранее расмотренного способа: переноса функции (захват экрана) внутрь виртуальной машины. Для этого достаточно добавить соответствующую функцию в InputProxy.

Зацикливаем игровой процесс

Наконец-то, приступаем непосредственно к решению поставленной на сегодня задаче: зацикливанию игрового процесса - все необходимые подзадачи решены. Игровой процесс в Zuma крутится вокруг трех окон: main, mission и action. Main-окно содержит основное меню, позволяя выбрать вид игры, mission-окно предлагает выбрать миссию, а в action-окне происходит сам игровой процесс.
Бот определяет текущее окно самым простым способом: по значению цвета в нескольких ключевых точках. Точки выбираются вручную: методом «пристального всматривания».
var screenChecks = new { new { Name = "main", Points = new { new CheckPoint(200, 190, 0xff554a22), new CheckPoint(65, 400, 0xfff44c41) } }, new { Name = "mission", Points = new { new CheckPoint(200, 190, 0xffb5d0c7), new CheckPoint(65, 400, 0xffad7630) } }, new { Name = "action", Points = new { new CheckPoint(950, 10, 0xff72554b), new CheckPoint(10, 10, 0xff462b1d), } }, }; Func check = image => screenChecks.Where(_check => image.Check(_check.Points)).Select(_check => _check.Name).FirstOrDefault();
Основной цикл бота:
var startButtonPoint = new Point(950, 430); var startMissionPoint = new Point(600, 750); for (; ;) { try { var bmp = GetScreenImage(gameScreenRect); var screenName = check(bmp); Console.Write(screenName + new string(" ", 20) + new string("\x8", 40)); switch (screenName) { case "main": mouse_event(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, startButtonPoint.X * 65536 / game_width, startButtonPoint.Y * 65536 / game_height); System.Threading.Thread.Sleep(400); mouse_event(MouseEventFlags.LEFTDOWN, 0, 0); System.Threading.Thread.Sleep(150); mouse_event(MouseEventFlags.LEFTUP, 0, 0); System.Threading.Thread.Sleep(50); System.Threading.Thread.Sleep(400); break; case "mission": mouse_event(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, startMissionPoint.X * 65536 / game_width, startMissionPoint.Y * 65536 / game_height); System.Threading.Thread.Sleep(10); mouse_event(MouseEventFlags.LEFTDOWN, 0, 0); System.Threading.Thread.Sleep(150); mouse_event(MouseEventFlags.LEFTUP, 0, 0); System.Threading.Thread.Sleep(50); break; case "action": mouse_event(MouseEventFlags.LEFTDOWN, 0, 0); System.Threading.Thread.Sleep(150); mouse_event(MouseEventFlags.LEFTUP, 0, 0); System.Threading.Thread.Sleep(50); break; case null: bmp.Save("unknown.bmp"); break; } } catch (Exception exc) { Console.WriteLine(exc); } }
В игровой фазе бот постоянно кликает, выпуская шарики в одну точку. На такой простой (скорее даже тупой) тактике бот в первой миссии набирает 1000-2000 очков, и иногда даже полностью набирает полоску Zuma.

Резюме

Поставленная цель выполнена: каркас бота написан - игровой процесс зациклен.
Следующие цели: подключить OpenCV, распознать положение и цвет шаров.
Ps
Изображение для привлечение внимания. (Оранжевым показаны области, которые следующая версия бота распознала как шары)

Move Mouse служит для имитации присутствия пользователя за компьютером за счёт движения курсора мыши и нажатия её кнопок. Кроме того ею можно воспользоваться для запуска каких-то программ, выполнения команд или скриптов PowerShell. Активироваться утилита может вручную или автоматически, при отсутствии активности пользователя и по расписанию, тоже самое касается и прекращения заданных операций.

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

Кроме автоостановки и автозапуска, о которых мы уже упоминали, в настройках поведения Move Mouse доступна опция автоматического изменения громкости звука, скрытия окна программы с рабочего стола, кнопки и иконки с панели задач, миниатюры из диалогового окна ALt+Tab и перезаписи заголовка. Последние опции помогут скрыть следы ей присутствия и использования на компьютере, если кому-то это потребуется.

Настроить расписание активации действий можно как при помощи простейшего планировщика, позволяющего выбрать день недели и время запуска или остановки программы, так и более продвинутого, поддерживающего ввод выражений Cron. По расписанию Move Mouse может и приостанавливать свою деятельность, длительность «блэкаута» также изменяется.

Распространяется программа бесплатно, язык интерфейса в текущей версии доступен только один — английский. Воспользоваться Move Mouse можно на компьютерах и планшетах с Windows 10. Судя по всему, после публикации программы в Магазине Windows, от распространения через другие источники разработчик отказался.

Установить из Microsoft Store