Доброго дня друзья.
Интересует вопрос следующего плана.
Имеется игра в котороой в неактивном окне не работает отправка left, send - что крайне необходимо для управления. Kleft работает нормально - активирует окно и кликает в заданные координаты.
Возникла мысль играя в 6 и более окон выполнять действия в всех запущенных клиентах игры.
Собственно вопрос. Возможно ли написав необходимый скрипт, и привязав каждый скрипт к одному клиенту, реализовать поочередное выполнение каждого скрипта с последующей активацией следующего скрипта, управляющего другим клиентом?
Действия будут одинаковые - на компе (сервере) лидер ставить группу в очередь на арену, на клиенте кликер ждет подтверждения сбора арены и жмет кнопку "битться на арене" - отдает управление следующему скрипту - тот делает тоже в своем окне и так далее. После чего скрипт ждет результатов арены и выходит с нее вставая в ожидание следующей.
Запуск скриптов
https://uopilot.tati.pro/index.php?title=Start_script_(Lua)
https://uopilot.uokit.com/wiki/index.php?title=Start_script
Если действия одинаковые для всех окон, то можно использовать один скрипт, в нём менять рабочее окно.
Start_script нашел. Но почему то напрямую
kleft 216 278
wait 1500
sendex {f3}
wait 1500
kleft 141 541
wait 2000
sendex {ESC}
wait 500
Start_script 1
end_script
set %handle findwindow ("Блокнот") // найти окна с указанным именем
log clear
log mode compact
set #n size(%handle) // количество окон
if #n = 0
log Окна не найдены, скрипт остановлен
end_script
end_if
log Всего найдено окон: #n
for #i 1 #n // цикл для всех окон
showwindow %handle[#i 1] // показывать окно
wait 2000 // пауза 2 секунды
// тут нужные действия для окна
end_for
end_script
То что надо) Благодарю! Какие возможности прям открываются ) Пойду эксперементировать
А как при открытии окна перейти в Относительные координаты окна?
Разобрался с координатами
set workwindow %handle[#i 1]//переключаемся в координаты окна
showwindow %handle[#i 1] minimize //сворачиваем отработанное окно
Еще вопросик. Переменные между скриптами передаются? Или в каждом скрипте необходимо объявлять свои? Если в одном скрипте хендл окна определить - в другом его можно использовать?
https://uopilot.uokit.com/wiki/index.php?title=Переменные_из_других_скриптов
Cirus, Уважаемый - подскажи следущее
- Есть окно игры в котором скажем открыт чат. Если в скрипте пишем
sendex "сообщение пользователю"
// Пример 3
// печатаем одной строкой текста: Вася.Пупкин@gmail.com
set $var setlayout (0419) // включили русскую раскладку
sendex Dfcz/Gegrby // Вася.Пупкин (смотрим на клавиатуру)
set $var setlayout (0409) // включили английскую раскладку
sendex ~2gmail.com // @gmail.com
End_script
wait 3000 // пауза 3 секунды
set #h getwindow (0) // получить хендл активного окна
set workwindow #h // сделать рабочим окном
set $var setlayout (0419) // переключить на русскую раскладку
sendex "сообщение пользователю" // написать текст
end_script
А если после необходимо на английском написать что либо?
wait 3000 // пауза 3 секунды
set #h getwindow (0) // получить хендл активного окна
set workwindow #h // сделать рабочим окном
set $var setlayout (0419) // переключить на русскую раскладку
set SendExDelay 100
sendex "сообщение пользователю" // написать текст
wait 2000
set $var setlayout (0409) // включили английскую раскладку
sendex hello cirus // написать текст
end_script
Вопросик еще возник.
Имеется окно браузера, в нем есть строка меню из 8 пунктов.
Можно ли в зависимости от ширины окна - вычислить координаты клика?
Умеет ли пилот производить математические действия?
set #X1 %arr[#1 1] / 8*6
log clear
log mode compact
get windowpos workwindow #X #Y #width #height
log Размеры окна: #width #height
log Позиция окна: #X #Y
set #posX #width / 8 * 6
log #posX
move #posX 100
end_script
else
get mouse_pos #x #y
set #x #x + 5
mouse enable
move #x #y
kleft #x #y
end_if
end_while
//...
//repeat 213 // полный оборот
repeat 107
call move 10 0 // сдвинуть курсор на 100 вправо и на 0 вверх
end_repeat
sendex_down w
wait 3000
sendex {Spacebar}
wait 3000
sendex_up w
//...
end_script
proc move #x #y $abs
set linedelay 0
set #flags 1
if $abs = abs
set #flags 32769
set #x 65536 * #x / screenwidth
set #y 65536 * #y / screenheight
end_if
exec winapiexec.exe u@mouse_event #flags #x #y 0 0
end_proc
Товарищи - подскажите как перемешать массив? А то боты все время в одноой и той же последовательности входят в игру)) Как то палевно...
set %mult [1] mult1 // имя мульта
set %mult [2] mult2 // имя второго мульта
set %mult [3] mult3 // третьего
set %mult [4] mult4 // имя четвертого
set #size size(%mult) // всего мультов
set %mult [1] mult1 // имя мульта
set %mult [2] mult2 // имя второго мульта
set %mult [3] mult3 // третьего
set %mult [4] mult4 // имя четвертого
set #size size(%mult) // всего мультов
log clear
log mode compact
// перемешивание
for #i 1 #size
set #rand 1 + random(#size)
set $tmp %mult [#i]
set %mult [#i] %mult [#rand]
set %mult [#rand] $tmp
end_for
// вывод массива
for #i 1 #size
log %mult [#i]
end_for
end_script
При таком методе - как я понимаю, имеется вероятность попадания в массив при перемешивании одного и того же значения. Что не допустимо в моем случае...
Просто думал - что есть какая то встроенная функция перемешивания, которую я не нашел в документации
Извиняюсь - не разобралсо )
А кто-нибудь заморачиввался попыткой управления в 3д шутере?
Было дело. Смысла мало - динамика слишком велика для графического анализа. Если прям хочется, то тупо читать память, искать там координаты врагов, свои, считать вектора. Правда пилот тут уже становится постольку поскольку.
Вобщем не поленился я... Потестил нормальное распределение. Разница существенная, при статичном свапе от 1 до #arr отклонения от ожидаемого до 20%. math.random(i, #arr) однозначно лучше - отклонения в пределах статистической погрешности.
-- 1 - обмен позиций 1-10
-- 2 - обмен позиций i-10
local method = 2
math.randomseed(os.clock())
local n = 1000000
-- инициализируем счетчик
local counter = {}
for i = 1, 10 do
counter[i] = {}
for j = 1, 10 do
counter[i][j] = 0
end
end
for z = 1, n do
local a = {1,2,3,4,5,6,7,8,9,10}
for i = 1, #a do
local tmp = a[i]
local r
if method == 1 then
r = math.random(1,10)
else
r = math.random(i,10)
end
a[i] = a[r]
a[r] = tmp
end
for i = 1, #a do
counter[a[i]][i] = counter[a[i]][i] + 1
end
end
local p = {}
for i = 1, 10 do
p[i] = {}
for j = 1, 10 do
p[i][j] = math.abs(10 - counter[i][j] / (n / 100)) * 10
end
end
for i = 1, 10 do
log("% отклонения перемещения "..i.." от ожидаемого в позицию:")
for j = 1, 10 do
local s = string.format("%f",p[i][j])
if p[i][j] < 10 then
s = "0"..s
end
if j < 10 then
log(" "..j..": "..s)
else
log(j..": "..s)
end
end
end
local shuffle = function(a)
math.randomseed(os.clock())
for i = 1, #a do
local tmp = a[i]
local r = math.random(i, #a)
a[i] = a[r]
a[r] = tmp
end
return a
end
В игре - мобы и игроки разным цветом горят - это я вижу более менее решаемым. Сканировать экран на поиск цвета - при совпадении поворачивать игрока и центрировать на совпадение цвета.
Но тут встает вопрос - если игрок дальнобойный, то хорошо. А вот если ближнего боя - встает вопрос о дистанции. Как ее определить?
скилы всегда активны - они не привязаны к дистанции. Можно просто стоять и лупить со всех стволов в пустоту)) На миникарте кроме твоего расположения тоже нет информации..
А вот с размером цели - надо подумать. Мониторить массив совпадений цвета?
затык очередной - почему скрипт так себя ведет?
set $X findimage (20 70 300 200 (Scripts\Blade\img\arena_box.bmp) %arrt 2) // ищем панель управления аренами
if $X >0 //
log найдена панель управления аренами
set #X1 %arrt[#1 1]
set #Y1 %arrt[#1 2]
kleft #X1,#Y1 //
log тут #X1,#Y1
wait 2000
в логе получаем
21:34:22 2 (test.txt, 21): Открывваем управление аренами
21:34:25 2 (test.txt, 28): найдена панель управления аренами
21:34:26 2 (test.txt, 32): тут 0,0
set $X findimage (10 70 300 1400 (Scripts\Blade\img\arena_box1.bmp) %arr 2) // Так все работает норм
if $X > 0
log lose
set $T FindImage (20 70 300 200 (Scripts\Blade\img\arena_box1.bmp) %ar 2) // так находит картинку даже если ее на экране нет
if $T >0 //
log найдена панель управления аренами вне цикла
set #X1 %ar[#1 1]
set #Y1 %ar[#1 2]
kleft #X1,#Y1 //
log тут #X1,#Y1 ar
else
log вне цикла нет панели арен
end_if
end_if
Народ через какую функцию в с++ осущесвлекн клик мышью по хендлеру, поскажите, я перепробовал sendmessage, postmessage,SendInput не идет чего то
проблема решена
Неверно заданы значения констант WM_LBUTTONDOWN и WM_LBUTTONUP.
Через пилот так:
--lua
local ffi = require("ffi")
local WM_LBUTTONDOWN = 0x0201
local WM_LBUTTONUP = 0x0202
ffi.cdef[[
int SendMessageA(int hWnd, int Msg, int wParam, int lParam);
int PostMessageA(int hWnd, int Msg, int wParam, int lParam);
]]
local wndHandle = workwindow() -- привязаться к окну Ctrl+A
local x = 200
local y = 100
ffi.C.SendMessageA(wndHandle, WM_LBUTTONDOWN, 0, y * 65536 + x)
wait (100)
ffi.C.SendMessageA(wndHandle, WM_LBUTTONUP, 0, y * 65536 + x)
--lua
local ffi = require("ffi")
local WM_LBUTTONDOWN = 0x0201
local WM_LBUTTONUP = 0x0202
ffi.cdef[[
int SendMessageA(int hWnd, int Msg, int wParam, int lParam);
int PostMessageA(int hWnd, int Msg, int wParam, int lParam);
]]
local wndHandle = workwindow() -- привязаться к окну Ctrl+A
local x = 200
local y = 100
ffi.C.SendMessageA(wndHandle, WM_LBUTTONDOWN, 0, y * 65536 + x)
wait (100)
ffi.C.SendMessageA(wndHandle, WM_LBUTTONUP, 0, y * 65536 + x)
еще такой вопрос перекрытое окно скриншот можно в с++ сделать? как?
клик мышью вот так венрнее не знаю что у вас
SendMessage(wndHandle, WM_MOUSEMOVE, 0, coord);
SendMessage(wndHandle, WM_LBUTTONDOWN, 0, coord);
Thread.Sleep(100);
SendMessage(wndHandle, WM_LBUTTONUP, 0, coord);
далее принтскрин неактивного окна, вернее перекрытого, с# код, я думаю кому надо разберется полезно для бота, который работает по поиску в картинке, а не с памятью, что бы не забанили
это если есть манипуляции с масштабом
public class Scale
{
[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
public enum DeviceCap
{
VERTRES = 10,
DESKTOPVERTRES = 117,
// http://pinvoke.net/default.aspx/gdi32/GetDeviceCaps.html
}
public float getScalingFactor()
{
Graphics g = Graphics.FromHwnd(IntPtr.Zero);
IntPtr desktop = g.GetHdc();
int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);
float ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
return ScreenScalingFactor; // 1.25 = 125%
}
}
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
[DllImport("user32.dll")]
static extern bool GetWindowRect(IntPtr handle, ref Rectangle rect);
private static double SCALEoFsCREEN = new Scale().getScalingFactor();
public void CaptureWindow(IntPtr handle)
{
// Get the size of the window to capture
Rectangle rect = new Rectangle();
GetWindowRect(handle, ref rect);
// GetWindowRect returns Top/Left and Bottom/Right, so fix it
rect.Width = rect.Width - rect.X;
rect.Height = rect.Height - rect.Y;
// Create a bitmap to draw the capture into
using (Bitmap bitmap = new Bitmap((int)(rect.Width * SCALEoFsCREEN), (int)(rect.Height* SCALEoFsCREEN)))
{
// Use PrintWindow to draw the window into our bitmap
using (Graphics g = Graphics.FromImage(bitmap))
{
IntPtr hdc = g.GetHdc();
if (!PrintWindow(handle, hdc, 0))
{
int error = Marshal.GetLastWin32Error();
var exception = new System.ComponentModel.Win32Exception(error);
Debug.WriteLine("ERROR: " + error + ": " + exception.Message);
// TODO: Throw the exception?
}
g.ReleaseHdc(hdc);
}
// Save it as a .png just to demo this
bitmap.Save("Example.png");
}
}
а вот еще вопрос про сендмесседж, у меня несколько мониторов и клик мышью происходит только в том случае, если курсор мыши находится в испольнительном мониторе, как с этим бороться?: переставлять каждый раз курсор? на это 100 мс требуется а как без них?
Убери внизу окна программы задержку. Вместо 100 - выставить 0
нее проверено если мышь нахолддится в другом мониторе sendmessage не пашет, movecursor тоже. может что то еще есть?
Привязка окна и активация его при необходимости действий? Работа с координатами активного привязанного окна? Тогда вроде пофиг где мышь находится...
2 моника, проблем нет.
народ а взгляните скрипт Ctrl+ space как катится в уо пилот*? заранее благодарен
Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)