1 (изменено: Remelibo, 2015-07-23 16:34:21)

Тема: Определение запущенных окон (League of Legends)

Цель - сделать скрипт, который бы запускал League of Legends, вбивал логин/пароль, автоматически принимал игру по нажатию на кнопку (f11, например), а при закрытии игры - закрывался бы и скрипт.

Почти со всем перечисленным хоть и наверняка кривовато, но справился, кроме одного - что бы "при закрытии игры - закрывался бы и скрипт". Проблема в том, что League of Legends имеет, по сути, 3 окна - LoL Patcher (игра обновляется), Клиент PvP.net (сам клиент из которого ищется игра и т.д.) и League of Legends (TM) Client (непосредственно игра). Когда одно окно закрывается, другое открывается.

Через WinWait и WinWaitClose можно реализовать отслеживание скорее всего. LoL Patcher только в начале вылезает, потом нужно отслеживать. По идее, нужно детектить есть ли в системе окно Клиент PvP.net или League of Legends (TM) Client и если нет ни одного - закрывать скрипт.

Сейчас мой корявенький скрипт выглядит так:

#SingleInstance force

Run, "%A_ScriptDir%\lol.launcher.exe"

WinWait, LoL Patcher

if ErrorLevel
{
    MsgBox, Истекло время ожидания. ;Наверное, можно и без этого обойтись
    return
}
else
{
    Loop, 9999
        {
        sleep 2000
        ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, *50 %A_ScriptDir%\play.png ;Клик по кнопке "играть" в патчере (поиск по картинке).
        if ErrorLevel = 0
        
        {       
            MouseMove, FoundX, FoundY             
            sleep,1
            Click
            
            WinWait, LoL Patcher
            if ErrorLevel            
            {
                MsgBox, Истекло время ожидания.
                return
            }
            else
            {
            Loop, 9999
            {
            sleep 3000
            ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, *50 %A_ScriptDir%\nick.png ;Ищется картинка на экране логина (никнейм).
            if ErrorLevel = 0
            {       
            MouseMove, 400, 390
                
            sleep,1

            Send pass ;Вбивается пароль
            Send, {ENTER}
            return
            }
        }
        
        return
       }
       return
        }
    }
    return
}
return

 
F11:: ;Функция подтверждалки - нажимается кнопка "Принять" при нахождении матча (поиск по картинке)
    gojoin:=!gojoin

if gojoin

{

gosub, Accepter

sleep 100

SetTimer, Accepter, 2012

}

else

{

ToolTip

SetTimer, Accepter, off

}

Accepter:
ifWinActive, Клиент PvP.net ; Если активно окно клиента "лиги"

{

ToolTip, Accepter is active`nPress F11 to deactivate

ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, *50 %A_ScriptDir%\OK_button.png
    if ErrorLevel = 0
    {       
        MouseMove, FoundX+100, FoundY+40        
        sleep,1
        Click        
    }
ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, *50 %A_ScriptDir%\OK_buttonflash.png
    if ErrorLevel = 0
    {       
        MouseMove, FoundX+100, FoundY+40     
        sleep,1
        Click        
    }
    return
}

Наверняка есть что улучшить в коде, кроме детекта определения закрытия всех окон. Ещё проблемка со строкой ToolTip, Accepter is active`nPress F11 to deactivate - по нажатию F11, подтверждалка работает, после повторного нажатия F11, подтверждалка выключается, но надпись Accepter is active остаётся висеть на экране.

2 (изменено: Indomito, 2015-07-23 19:47:59)

Re: Определение запущенных окон (League of Legends)

Где то... так

Удалил - слишком сложная и объёмная проверка.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

3 (изменено: Indomito, 2015-07-23 19:54:53)

Re: Определение запущенных окон (League of Legends)

Можно намного проще, сорри - погорячился.

;Обычный таймер
lTimer:
Thread, NoTimers
DetectHiddenWindows, on
;SetTitleMatchMode, 1 или что требуется
If (WinExist("окно1") || WinExist("окно2") || WinExist("окно3"))
      {  
        Thread, NoTimers, False
        Return ; Одно из окон существует даже если оно скрыто
      }
    Else ;Ни одного окна нет
     {
       ;Сигнал к выходу
       ;Или просто...
       ExitApp
     }
Return
"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

4 (изменено: Remelibo, 2015-07-23 19:22:35)

Re: Определение запущенных окон (League of Legends)

Indomito, ого, сколько строк! Я думал, что можно уложиться в 1-10 строчек. И мне кажется, что таки можно . )) Но спасибо, посмотрю что к чему, но на первый взгляд, страшновато выглядит для не сильно прошаренного в AHK человека.

Ага, а вот второе более понятно и компактно выглядит, спасибо, попробую так. )

5 (изменено: Indomito, 2015-07-23 19:49:25)

Re: Определение запущенных окон (League of Legends)

И ещё.

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

1. Частота таймера не менее 5 секунд.
2. Я бы добавил внутри таймера, в цикле длительностью 2-3 секунды ожидание окна по While или Loop проверку на WinExist("имя окна") -  для надёжности.

Да, первый мой ответ явный перебор, но это то что у меня было открыто... я дописывал скрипт.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

6 (изменено: Indomito, 2015-07-23 20:10:54)

Re: Определение запущенных окон (League of Legends)

Ещё проблемка со строкой ToolTip, Accepter is active`nPress F11 to deactivate - по нажатию F11, подтверждалка работает, после повторного нажатия F11, подтверждалка выключается, но надпись Accepter is active остаётся висеть на экране.

Что бы убрать последнюю надпись от ToolTip  надо написать.

Sleep 100
ToolTip

Скрипт твой не смотрел, т.е. смотрел, но не понял, как ты отключаешь - там таймер и много чего.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

7

Re: Определение запущенных окон (League of Legends)

Таймер вкл/выкл в этом участке кода:

F11::
    gojoin:=!gojoin

if gojoin

{

gosub, Accepter ;там уже поиск по изображению и "ToolTip, Accepter is active`nPress F11 to deactivate"

sleep 100

SetTimer, Accepter, 2012

}

else

{

ToolTip ;вроде должен был отключить надпись

SetTimer, Accepter, off

}

С кодом таймера пока не совсем разобрался, как его в общий код корректно добавить или хотя бы как отдельно запустить данный код. Его следует зациклить? Что-то пытался через Loop зациклить - не вышло. Для проверки на Notepad проверял:

If (WinExist("ahk_class Notepad"))

и добавил 5 секундную паузу:

Thread, NoTimers, False
sleep, 5000
Return ; Одно из окон существует даже если оно скрыто

Если не трудно, подскажи, с какой стороны к коду подобраться.

8 (изменено: Indomito, 2015-07-25 00:18:04)

Re: Определение запущенных окон (League of Legends)

Начнём с таймера.
Вот, на 100% работающий код, у меня точно на 100% работает.

F11::
    gojoin:=!gojoin
    If (gojoin)
      {
        SetTimer, Accepter, 200 ; Частоту исправил, для тестирования
        gosub, Accepter ; На таймер для быстрой его активации - не обязательно       
      }
      Else
      {
        SetTimer, Accepter, off
        sleep 100
        ToolTip ;Отключение сообщения с экрана
        
      }
Return

Accepter:
    ToolTip, Accepter is active`nPress F11 to deactivate
    ;Что то делаем, можно временно сделать Thread, NoTimers
    ;Если обработка по таймеру длительная.
Return

  Просто кое где упустил:
- скобки в IF ( условие  должно быть в скобках);
- нет конечного  Return в коде обработки.

F11::
;код обработки
Return
"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

9

Re: Определение запущенных окон (League of Legends)

Дальше, я запутался с твоим постом - что не работает, то?

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

10

Re: Определение запущенных окон (League of Legends)

Remelibo Решил дописать, то что спрашивал. Не очень идеально, так сказать, общий вариант.
И чего не сделаешь во благо рода человеческого.

; Всё отлажено и работает, обязательно читать комментарии!!!
; Точки отладки по поиску окон при необходимости раскомментировать, для проверки своих экспериментов.
+ Сам код ТУТ.
; Всё отлажено и работает, обязательно читать комментарии!!!
; Точки отладки по поиску окон при необходимости раскомментировать, для проверки своих экспериментов.
F11::
  gojoin:=!gojoin
  If (gojoin)
      {
        ;Частота таймера отладочная, можно поменять на свою
        SetTimer, Accepter, 200
        ;Активация таймера контроля окон, поставил здесь, т.к. не знал куда ещё.
        SetTimer, lWinExistApp, 2000  ; Частота проверка окон = 2 секунды
      }
    Else
      {
        SetTimer, Accepter, off
        SetTimer, lWinExistApp, Off
        sleep 100
        ;Убрать надпись последнего ToolTip сообщения с экрана, в играх может не сработать
        ToolTip 
      }
Return

Accepter:
    ;Очень часто, но что бы поправить нужны доп. условия
    ToolTip, Accepter is active`nPress F11 to deactivate
    ;Что то делаем, можно временно сделать Thread, NoTimers, но тогда проверка окон не будет работать!!!
    ;Если обработка по таймеру длительная.
Return

lWinExistApp:
  ; Пример на двух окнах виндовый NotePad("Блокнот") и Total Commander("Total Commander")
  ; Пример обобщённый - можно сделать всё проще
  Thread, NoTimers
  cWaitWin := 2000        ; сколько ждать окна в сумме всех шагов цикла
  j        := 10          ; число шагов с задержкой cSleep
  cSleep   := cWaitWin//j ; // - Целочисленное деление
  ;DetectHiddenWindows нужен только для работы со скрытими окнами. Max Min oкна находятся.
  ;WinExist возвращает HWID окна, два одинаковых приложения будут иметь разный HWID, при False(0) окно не найдено
  DetectHiddenWindows, on ; Обнаруживать скрытые окна, не путать с минимизацией!!!
  SetTitleMatchMode, 2    ; Имя окна должно содержать указанное слово
  Loop %j%
    {
      If (WinExist("Блокнот") || WinExist("Total Commander"))
              {
                i := 0
                ;MsgBox True %A_Index% - для отладки
                Break ; Хотя бы из одних окон существует - завершаем цикл
              }  
            Else
            {
              Sleep %cSleep% ; Ждём сколько указали
              i := A_Index   ; Запомнили шаг итерации, при отсутствии окон J = I
              ;MsgBox False %A_Index% - для отладки
            }
    }        
  If (i = j) ; Окон так и не нашли
      {
         ;MsgBox Окна нет %i% и %j%   - для отладки
         ExitApp
      }     
   ;MsgBox Окна есть %i% и %j%    - для отладки
   Thread, NoTimers, False ; Вкл таймеры и продолжаем "Танец с бубном"
Return
"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

11 (изменено: Remelibo, 2015-07-25 04:41:34)

Re: Определение запущенных окон (League of Legends)

Спасибо, на следующей неделе проверю работоспособность (дача на выходных).

Насчёт "что не работает" - не очень разобрался с кодом "таймера". Дописав в начале хоткей и закинув код в чистый файл - всё работает как надо, по нажатию на хоткей, проверяется есть/отсутствует нужное окно. Но как сделать эту проверку не разовой, не привязанной к хоткею? "Таймер" надо зациклить через loop или ещё что-то сделать? И как "таймер" добавить в код, т.е. что бы он работал как надо. Через Gosub или ещё как реализовать запуск таймера, этой проверки есть/нет окон? Эх, наверное слишком много прошу...

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

В общих чертах разобрал код, проверил. Проверка есть/нет окон, начинает работать по нажатию на F11, когда включен accepter. Впринципе, можно наверное в отдельный скрипт закинуть "таймер" и сделать, что бы он запускался в самом начале исполнения основного скрипта, дописав в условие "если окон не найдено" что-то вроде Process,Close, и название основного скрипта. Думаю, должно работать, хотя такое решение, наверное, корявенькое...

12 (изменено: Indomito, 2015-07-25 04:48:27)

Re: Определение запущенных окон (League of Legends)

-del

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

13 (изменено: Indomito, 2015-07-25 04:52:42)

Re: Определение запущенных окон (League of Legends)

Remelibo пишет:

"Таймер" надо зациклить через loop или ещё что-то сделать? И как "таймер" добавить в код, т.е. что бы он работал как надо. Через Gosub или ещё как реализовать запуск таймера, этой проверки есть/нет окон?

1. Таймер не нужно зацикливать и делать прочие пакости, таймер отдельный поток он работает сам по себе.
2. Использование Gosub на подпрограмму таймера не нужно, если только ты не вырубил таймеры и надо окна отдельно проверять.
3. Про добавить в код... сейчас напишу это просто.

;-----Инициализация
;Скрипт не выгружается до явного определения
#Persistent
;Запрет повторного запуска
#SingleInstance  Ignore

; принудительная проверка или же...
Gosub lWinExistApp

;Написать код ожидания одного из окон и вкл. таймер.

;1 - Ждём окно одно из трёх, как в таймере просто от туда взять кусок ожидания, можно бесконечный или с ограничением по времени

;2- Вкл таймер и выходим.
; Его желательно не выключать без нужды, хотя и можно использовать Thread, NoTimers, но включать не забывать обратно
; То есть соблюдать парность Thread, NoTimers и Thread, NoTimers, False
SetTimer, lWinExistApp, 2000 
Return

Это должно быть в самом начале скрипта и более таймер lWinExistApp не трогать.

Всё ясно?

UPD

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

так наиболее верно, но проще из скрипта запускать программу и ждать скажем 5-7 секунд.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download