Что нового

[Ошибки] Error:subscript used on non-accessible variable

Akigis

Новичок
Сообщения
4
Репутация
0
Здравствуйте. Какое-то время пользовался данным скриптом, но спустя время он перестал работать, хотя в коде ничего не менял.
Вот сам код:
Код:
global $state = 1
global $aPos
    ;1 - Начало работы скрипта
    ;2 - Запускаем клиент из GG
    ;3 - Выбираем чара в чарселекте

While $state > 0
    If not WinExists("Ragnarok") Then
        TrayTip("", "Не найдено окно 'Ragnarok', запускаем GG", 1, 3)
        start()
    elseif WinExists("Ragnarok") Then
        if $state = 1 Or $state = 2 then
            TrayTip("", "Найдено окно 'Ragnarok', ищем окно 'Выбор сервера'", 1, 2)
            $state = 2
            sleep(2000)
            ragexeWait ()
        elseif $state = 3 then
            TrayTip("", "Найдено окно 'Ragnarok', ищем окно с дисконнектом", 1, 3)
            SearchDisconnect()
        endif
    endif
    TrayTip("Статус: "&$state, "Ничего не найдено, ждём 5 секунд", 1, 3)
    sleep (5000)
WEnd


Func start()
    $c = IniRead ( "!GameGate.ini", "Raggame", "GameGate", 0)
    if not $c then 
        MsgBox(0, "Func start", "Не найден файл !GameGate.ini. Скрипт будет закрыт.")
        exit
    endif
    Run ($c&'GameGate.exe', $c)
    WinWait("Ingamba GG")
    Sleep(5000)
    $hWnd = WinGetHandle("Ingamba GG")

    $aPos = WinGetPos("Ingamba GG")

    $b = PixelChecksum ($aPos[0]+625, $aPos[1]+435, $aPos[0]+795, $aPos[1]+465, $hWnd)
    while ($b <> 25362625)
        TrayTip ("", "Пытаюсь найти кнопку 'Начать играть'", 1, 1)
        sleep (5000)

        $aPos = WinGetPos("Ingamba GG")

        $b = PixelChecksum ($aPos[0]+625, $aPos[1]+435, $aPos[0]+795, $aPos[1]+465, $hWnd)
    WEnd
    TrayTip ("Func start", "Кнопка найдена, нажимаю..", 1, 1)

    MouseMove($aPos[0]+700, $aPos[1]+450);Нажимаем "Начать играть"

    sleep(1000)
    MouseClick("left")
    $state = 2
    ragexeWait ()
EndFunc

Func ragexeWait ()
    WinWait("Ragnarok")
;    TrayTip ("Func ragexeWait", "Ждём 20 секунд", 5, 1)
;    Sleep(20000)
    while ($state = 2)
        sleep (5000)
        WinActivate("Ragnarok")
        WinMove("Ragnarok","",0,0)
        $aPos = WinGetPos("Ragnarok")
        $hWnd = WinGetHandle("Ragnarok")
        $a = PixelChecksum ($aPos[0]+375, $aPos[1]+425, $aPos[0]+460, $aPos[1]+440, "Ragnarok")
        $b = PixelChecksum ($aPos[0]+200, $aPos[1]+230, $aPos[0]+440, $aPos[1]+300, "Ragnarok")
        If ($a = 985042166 or $a = 3404893879) Then
            TrayTip ("Func ragexeWait", "Найдено окно 'Выбор сервера', нажимаем Enter, Enter", 3, 1)
            MouseMove($aPos[0]+400, $aPos[1]+430);Нажимаем "ОК"
            sleep(2000)

            MouseClick("left")
            MouseClick("left")

            ;Send("{ENTER}")
            $state = 3
            Sleep(3000)
            CharSelect()
            ExitLoop
        elseif ($b = 3522986379) then
            TrayTip ("Func ragexeWait", "Найдено окно 'Сервер еще обрабатывает Вашу ошибку...', нажимаем ОК и перезапускаем клиент", 3, 1)
            $state = 1
            start()
        Else
            TrayTip("Func ragexeWait", "Не найдено окно 'Выбор сервера'. $a="&$a&" $b="&$b, 3, 1)
        Endif
    wend
EndFunc

Func CharSelect()
    ;поумолчанию выбирается активный чар
;    WinActivate("Ragnarok")
    MouseMove($aPos[0]+540, $aPos[1]+435);Нажимаем "ОК"
    sleep(2000)

    MouseClick("left")
    MouseClick("left")

    ;Send("{ENTER}")
EndFunc

Func SearchDisconnect()
    $hWnd = WinGetHandle("Ragnarok")
    $aPos = WinGetPos("Ragnarok")
    ;MsgBox(4096, "", $hWnd)
    $b = PixelChecksum ($aPos[0]+190, $aPos[1]+210, $aPos[0]+460, $aPos[1]+320, $hWnd)
    while ($b <> 77267562 and $b <> 77398635)
        sleep (5000)
        $aPos = WinGetPos("Ragnarok")
        $b = PixelChecksum ($aPos[0]+190, $aPos[1]+210, $aPos[0]+460, $aPos[1]+320, $hWnd)
    ;    MsgBox(4096, "", $a&" HEX:"&Hex($a, 6)&" md5:"&$b)
        ;100467454
        ;77267562
    WEnd
    MsgBox(0, "", "Найдено окно 'Потеряно соединение с сервером'", 3)
    sleep(2000)
    MouseMove($aPos[0]+440, $aPos[1]+310);Нажимаем "ОК"
    MouseClick("left")
    $state = 1
    sleep(2000)
EndFunc


Спустя время он перестал работать, выдавая такую ошибку:
Ошибка появляется при выполнении функции ragexeWait.
 

erlik

Продвинутый
Сообщения
317
Репутация
84
Ну дак в чем затруднение? Есть ошибка (переведи гугелем текст и узреешь ее тайный смысл), есть номер строки в которой происходит ошибка. Вооружившись переводом гугеля, справкой по AutoIt и фатальной строкой, напрягаем мозг и внезапно понимаем, что переменные стоить объявлять раньше, чем они будут использованы.

Цитата с оффорума по данной ошибке:
I'm not sure why you won't declare them where you should declare them, but conditionally declaring a variable is going to end up causing problems many many times. If you are going to use Global variables, declare all of them at the top of your script before you ever use them. You have numerous instances in your script where you're declaring controls in a function as global variables, and then using them in another section of your code.
 
Автор
A

Akigis

Новичок
Сообщения
4
Репутация
0
Понимаю. Но все равно не могу найти в чем тут проблема :( Ткните пальцем, если не затруднит.
Дело то в том, что он работал месяц назад, а спустя этот месяц перестал работать. Файл лежал скомпилированный уже, его всегда и запускал. Но запустив вновь, не захотел работать. Почему получается так, что ошибки месяц назад не было, а потом появилась? Все переменные указаны вовремя, не могу найти проблему...
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Ты понимаешь, Akigis, даже если кто-то тебе ответит по существу, то ответ его, скорее всего, всё равно будет удалён.
Если тема оформлена с нарушениями правил, то не разрешается отвечать на вопрос, пока автор не исправит своё сообщение в соответствиями с правилами. На это тебе, конечно, должен был указать модератор, но, видимо, он временно отсутствует (или не успевает читать).
 
Автор
A

Akigis

Новичок
Сообщения
4
Репутация
0
Прошу извинить, все исправил в оформлении темы.
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Проверь
Код:
$c = IniRead ( "!GameGate.ini", "Raggame", "GameGate", 0)
MsgBox(0, '', $c)

нет ли в пути знака "!"
если есть, и это ошибочно, правь файл ini
 

erlik

Продвинутый
Сообщения
317
Репутация
84
Akigis
Ты внимательно прочитал приведенную мной цитату? Там написано, что НУЖНО все переменные, которые будут использоваться глобально объявлять в САМОМ начале скрипта. Во избежании БУДУЩИХ проблем. Лично, я так делал всегда - и поэтому никогда с данной с ошибкой не сталкивался.
А тыкать носом, где какая переменная у тебя не там стоит никто не будет. Это никому не интересно, потому что твоя проблема это проблема неграмотного кода. Здесь помогают с решением конкретных задач, а не с "орфографией" кода.
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
erlik
Ошибка Subscript used on non-accessible variable может быть не связана с объявлением переменной. Например, обращение к элементу массива при отсутствии самого массива.
Код:
$aPos = WinGetPos("Нет такого окна")
ConsoleWrite($aPos[0] & @CRLF)

Код:
>Running:(3.3.10.2):D:\AutoIt3\autoit3.exe "D:\test.au3"    
--> Press Ctrl+Alt+F5 to Restart or Ctrl+Break to Stop
"D:\test.au3" (2) : ==> Subscript used on non-accessible variable.:
ConsoleWrite($aPos[0] & @CRLF)
ConsoleWrite($aPos^ ERROR

Akigis
Если запустить скрипт из SciTE, то можно увидеть конкретную переменную.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Akigis
56-ая строка в твоём экзешнике - вот эта
Код:
$a = PixelChecksum ($aPos[0]+375, $aPos[1]+425, $aPos[0]+460, $aPos[1]+440, "Ragnarok")


Очевидно что тебе надо проверить что ты получаешь чуть выше
Код:
$aPos = WinGetPos("Ragnarok")
 
Автор
A

Akigis

Новичок
Сообщения
4
Репутация
0
Yuriy сказал(а):
Проверь
Код:
$c = IniRead ( "!GameGate.ini", "Raggame", "GameGate", 0)
MsgBox(0, '', $c)

нет ли в пути знака "!"
если есть, и это ошибочно, правь файл ini
Нет, тут все правильно и работает как надо.

InnI сказал(а):
erlik
Ошибка Subscript used on non-accessible variable может быть не связана с объявлением переменной. Например, обращение к элементу массива при отсутствии самого массива.
Код:
$aPos = WinGetPos("Нет такого окна")
ConsoleWrite($aPos[0] & @CRLF)

Код:
>Running:(3.3.10.2):D:\AutoIt3\autoit3.exe "D:\test.au3"    
--> Press Ctrl+Alt+F5 to Restart or Ctrl+Break to Stop
"D:\test.au3" (2) : ==> Subscript used on non-accessible variable.:
ConsoleWrite($aPos[0] & @CRLF)
ConsoleWrite($aPos^ ERROR

Akigis
Если запустить скрипт из SciTE, то можно увидеть конкретную переменную.
В том то и дело, что окно такое есть, то есть приложение запущено и работает. Это видно из того, что окно по команде в скрипте становится активным и перемещается в нужное место. Но вот видимо проблема в том, что координаты почему-то не определяются и не записываются. Проверил и $aPos[0] выдает ошибку в консоли, при $aPos выдает "0".
Почему вдруг перестали координаты считываться не понятно, ведь окно есть.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Akigis [?]
Почему вдруг перестали координаты считываться не понятно, ведь окно есть.
Это не имеет значения, нужно в любом случае проверять ошибочность выполнения функций, особенно если она возвращает массив.
Об этом написано в НЕофициальном FAQ'е: Как предотвратить критические ошибки скрипта?
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Akigis [?]
тут все правильно и работает как надо
Нет, не всё:
- строка 28: замените ноль на пустую строку
Код:
$c = IniRead ( "!GameGate.ini", "Raggame", "GameGate", "")

- строка 40 и все подобные: пропущен пятый параметр
Код:
$b = PixelChecksum ($aPos[0]+625, $aPos[1]+435, $aPos[0]+795, $aPos[1]+465, 1, $hWnd)

- строки 69, 70: вместо заголовка должен быть дескриптор
Код:
$a = PixelChecksum ($aPos[0]+375, $aPos[1]+425, $aPos[0]+460, $aPos[1]+440, 1, $hWnd)

И ещё. Из start() вызывается ragexeWait(), из которой при условии $b = 3522986379 снова вызывается start(). Возможна неконтролируемая рекурсия.
 
Верх