1 (изменено: 63OR63, 2011-02-26 17:29:22)

Тема: AHK: Использование памяти игры для автоматизирования скрипта

Я пишу скрипт под названием QuickScope plugin for ExternalHack на AHK для игры Black Ops. Он позиционируется мной как плагин к хаку ExternalHack, написанному на Python товарищем Sph4ck. Функционал ExternalHack, который я использую, это непосредственно аимбот - наводка прицела на противника при нажатии конкретной клавиши (в данном случае это "Home"). Основная часть моего скрипта реализует некоторую последовательность нажатия клавиш для выполнения "квикскоупа", однако есть и несколько других функций. В целом, скрипт прекрасно функционирует и без ExternalHack, хотя автонаводки в этом случае не происходит.
Вот сам скрипт:

;===============================================================================
;    QuickScope plugin for ExternalHack, Black Ops Edition
;    Version 1.3beta, 25 February 2011
;===============================================================================


;===============================================================================
;    Copyright © 2011 Георгий Минулин (also known as 63OR63) <g3or63126@gmail.com>

;    This file is part of QuickScope plugin for ExternalHack, Black Ops Edition.

;    QuickScope plugin for ExternalHack, Black Ops Edition is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by    the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

;    QuickScope plugin for ExternalHack, Black Ops Edition is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License along with QuickScope plugin for ExternalHack, Black Ops Edition. If not, see <http://www.gnu.org/licenses/>.
;===============================================================================


;===============================================================================
;    AutoIt: Copyright © 1999-2003 Jonathan Bennett <jon@hiddensoft.com>

;    AutoHotkey: Copyright © 2003-2009 Chris Mallett <support@autohotkey.com>
;===============================================================================


;-------------------------------------------------------------------------------
;    Settings                    
;-------------------------------------------------------------------------------

#NoEnv
#SingleInstance force
#MaxThreadsPerHotkey 1

SetWorkingDir %A_ScriptDir%

#IfWinActive ahk_class CoDBlackOps


;-------------------------------------------------------------------------------
;    Variables                    
;-------------------------------------------------------------------------------

Qs := 0
Fp := 0
Sw := 0
Nr := 0
Sn := 0


;-------------------------------------------------------------------------------
;    Preferences    Loading         
;-------------------------------------------------------------------------------

IniRead, EnableQuickscopeToggle, settings.ini, General, EnableQuickscopeToggle
IniRead, EnableFoolproofToggle, settings.ini, General, EnableFoolproofToggle
IniRead, EnableQuickSwitchToggle, settings.ini, General, EnableQuickSwitchToggle
IniRead, EnableNoRechambing, settings.ini, General, EnableNoRechambing
IniRead, EnableSniperRifleToggle, settings.ini, General, EnableSniperRifleToggle
IniRead, EnableFullautoQuickscope, settings.ini, General, EnableFullautoQuickscope
IniRead, EnableHalfmanualQuickscope, settings.ini, General, EnableHalfmanualQuickscope
IniRead, EnableNoBorders, settings.ini, General, EnableNoBorders

IniRead, h_QuickscopeToggle, settings.ini, Hotkeys, QuickscopeToggle
IniRead, h_FoolproofToggle, settings.ini, Hotkeys, FoolproofToggle
IniRead, h_QuickSwitchToggle, settings.ini, Hotkeys, QuickSwitchToggle
IniRead, h_QuickSwitch1, settings.ini, Hotkeys, QuickSwitch1
IniRead, h_QuickSwitch2, settings.ini, Hotkeys, QuickSwitch2
IniRead, h_NoRechambingToggle, settings.ini, Hotkeys, NoRechambingToggle
IniRead, h_NoRechambingFire, settings.ini, Hotkeys, NoRechambingFire
IniRead, h_SniperRifleToggle, settings.ini, Hotkeys, SniperRifleToggle
IniRead, h_FullautoQuickscope, settings.ini, Hotkeys, FullautoQuickscope
IniRead, h_HalfmanualQuickscope, settings.ini, Hotkeys, HalfmanualQuickscope

IniRead, g_Aim, settings.ini, GameKeyBindings, Aim
IniRead, g_Fire, settings.ini, GameKeyBindings, Fire
IniRead, g_R3load, settings.ini, GameKeyBindings, R3load
IniRead, g_Switch1, settings.ini, GameKeyBindings, Switch1
IniRead, g_Switch2, settings.ini, GameKeyBindings, Switch2

IniRead, a_Aimbot, settings.ini, ExternalHackKeyBindings, Aimbot


;-------------------------------------------------------------------------------
;    Hotkeys                    
;-------------------------------------------------------------------------------

if EnableQuickscopeToggle
{
    HotKey, %h_QuickscopeToggle%, QuickscopeToggle
}

if EnableFoolproofToggle
{
    HotKey, %h_FoolproofToggle%, FoolproofToggle
}

if EnableQuickSwitchToggle
{
    HotKey, %h_QuickSwitchToggle%, QuickSwitchToggle
    HotKey, $*%h_QuickSwitch1%, QuickSwitch1
    HotKey, $*%h_QuickSwitch2%, QuickSwitch2
}

if EnableNoRechambing
{
    HotKey, %h_NoRechambingToggle%, NoRechambingToggle
    if not EnableHalfmanualQuickscope
    {
        HotKey, $*%h_NoRechambingFire%, NoRechambingFire
    }
}

if EnableSniperRifleToggle
{
    HotKey, %h_SniperRifleToggle%, SniperRifleToggle
}

if EnableFullautoQuickscope
{
    HotKey, $*%h_FullautoQuickscope%, FullautoQuickscope
}

if EnableHalfmanualQuickscope
{
    HotKey, $*%h_HalfmanualQuickscope%, HalfmanualQuickscope
}

if EnableNoBorders
{
    NoBorders:
        Loop
        {
            WinWaitClose, ahk_class CoDBlackOps
            {
                FullScreen := 0
            }
            WinWait, ahk_class CoDBlackOps
            {    
                if not FullScreen = 1
                {
                    FullScreen := 1
                    WinActivate
                    WinSet, Style, -0xC00000
                    WinMove, 0, 0
                    WinMaximize
                }
            }
        sleep 10000
        }
        return
}
        
FeatureOn(PopupText)
{ 
    Gui, Destroy 
    Gui, +AlwaysOnTop +ToolWindow +LastFound -SysMenu -Caption 
    Gui, Color, 000000
    WinSet, Transparent, 200
    Gui, Font, s8, norm, Verdana
    Gui, Add, Text, x5 y5 c00ff00, %PopupText%  
    Gui, Show, NoActivate X0 Y18
    sleep 300
    Gui, Destroy
}

FeatureOff(PopupText)
{ 
    Gui, Destroy 
    Gui, +AlwaysOnTop +ToolWindow +LastFound -SysMenu -Caption 
    Gui, Color, 000000
    WinSet, Transparent, 200
    Gui, Font, s8, norm, Verdana
    Gui, Add, Text, x5 y5 cff0000, %PopupText%  
    Gui, Show, NoActivate X0 Y18
    sleep 300
    Gui, Destroy
}

QuickscopeToggle:
    if Qs < 1
    {
        Qs += 1
        if Qs = 1
        {
            SoundBeep, 800, 100
            FeatureOn("QUICKSCOPE ACTIVATED")
        }
    }
    else
    {
        Qs := 0
        SoundBeep, 200, 100
        SoundBeep, 200, 100
        FeatureOff("QUICKSCOPE DEACTIVATED")
    }
    return

FoolproofToggle:
    if Fp < 1
    {
        Fp += 1
        if Fp = 1
        {
            SoundBeep, 1000, 300
            FeatureOn("FOOLPROOF ACTIVATED")
        }
    }
    else
    {
        Fp := 0
        SoundBeep, 200, 100
        SoundBeep, 200, 100
        FeatureOff("FOOLPROOF DEACTIVATED")
    }
    return

QuickSwitchToggle:
    if Sw < 1
    {
        Sw += 1
        if Sw = 1
        {
            SoundBeep, 800, 200
            FeatureOn("QUICKSWITCH ACTIVATED")
        }
    }
    else
    {
        Sw := 0
        SoundBeep, 200, 100
        SoundBeep, 200, 100
        FeatureOff("QUICKSWITCH DEACTIVATED")
    }
    return

NoRechambingToggle:
    if Sn = 0
    {
        if Nr < 1
        {
            Nr += 1
            if Nr = 1
            {
                SoundBeep, 400, 50
                SoundBeep, 400, 50
                SoundBeep, 400, 50
                FeatureOn("NORECHAMBING ACTIVATED")
            }
        }
        else
        {
            Nr := 0
            SoundBeep, 100, 200
            FeatureOff("NORECHAMBING DEACTIVATED")
        }
    }
    return
    
SniperRifleToggle:
    if Sn < 1
    {
        Sn += 1
        if Sn = 1
        {
            SoundBeep, 100, 50
            SoundBeep, 100, 50
            SoundBeep, 100, 50
            FeatureOn("SEMI-AUTO SELECTED")
        }
    }
    else
    {
        Sn := 0
        SoundBeep, 400, 200
        FeatureOn("BOLT-ACTION SELECTED")
    }
    return

FullautoQuickscope:
    if Qs = 1  
    { 
        Loop 
        {
            Send {%g_Aim%}
            if Fp = 1
            {
                BlockInput MouseMove
            }
            Send {%a_Aimbot% down}
            Sleep 350
            Send {%g_Fire%}
            if Fp = 1
            {
                BlockInput MouseMoveOff
                Send {%a_Aimbot% up}
            }
            if Sn = 0
            {
                if Nr = 1
                {
                    send {%g_R3load%}
                    sleep 350
                    send {%g_Switch1%}
                    send {%g_Switch2%}
                }
            }
            if Nr = 0
            {
                Send {%g_Aim%}
            }
            if Sn = 0
            {
                if Nr = 0
                {
                    Sleep 740
                }
            }
            else if Sn = 1
            {
                Sleep 470
            }
            if not GetKeyState(h_FullautoQuickscope, "P") 
            break
        } 
    }
    else
    {
        Send {%h_FullautoQuickscope%}
    }
    return

HalfmanualQuickscope:
    if Qs = 1
    { 
        Loop 
        {
            Send {%a_Aimbot% down}
            Sleep 50
            Send {%g_Fire%}
            Send {%a_Aimbot% up}
            if Sn = 0
            {
                if Nr = 1
                {
                    send {%g_R3load%}
                    sleep 350
                    send {%g_Switch1%}
                    send {%g_Switch2%}
                }
            }
            if not GetKeyState(h_HalfmanualQuickscope, "P") 
            break 
        } 
    }
    else
    {
        if Sn = 0
        {
            if Nr = 1
            {
                Loop 
                {
                    Send {%g_Fire%}
                    send {%g_R3load%}
                    sleep 350
                    send {%g_Switch1%}
                    send {%g_Switch2%}
                    if not GetKeyState(h_NoRechambingFire, "P") 
                    break
                }
            }
            else
            {
                Send {%h_HalfmanualQuickscope%}
            }
        }
        else
        {
            Send {%h_HalfmanualQuickscope%}
        }
    }
    return

NoRechambingFire:
    if Sn = 0
    {
        if Nr = 1
        {
            Loop 
            {
                Send {%g_Fire%}
                send {%g_R3load%}
                sleep 350
                send {%g_Switch1%}
                send {%g_Switch2%}
                if not GetKeyState(h_NoRechambingFire, "P") 
                break
            }
        }
        else
        {
            Send {%h_NoRechambingFire%}
        }
    }
    else
    {
        Send {%h_NoRechambingFire%}
    }
    return

QuickSwitch1:
    if Sw = 1
    {
        send {%g_Switch1%}
        sleep 430
        send {%g_Switch1%}
        send {%g_Switch1%}
    }
    else
    {
        send {%g_Switch1%}
    }
    return
    
QuickSwitch2:
    if Sw = 1
    {
        send {%g_Switch2%}
        sleep 430
        send {%g_Switch2%}
        send {%g_Switch2%}
    }
    else
    {
        send {%g_Switch2%}
    }
    return

И файл "settings.ini":

;===============================================================================
;    QuickScope plugin for ExternalHack, Black Ops Edition
;    Version 1.3beta, 25 February 2011
;===============================================================================


;===============================================================================
;    Copyright © 2011 Георгий Минулин (also known as 63OR63) <g3or63126@gmail.com>
    
;    This file is part of QuickScope plugin for ExternalHack, Black Ops Edition.

;    QuickScope plugin for ExternalHack, Black Ops Edition is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by    the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

;    QuickScope plugin for ExternalHack, Black Ops Edition is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License along with QuickScope plugin for ExternalHack, Black Ops Edition. If not, see <http://www.gnu.org/licenses/>.
;===============================================================================


[General]
;enable/disable specific script functions (0=disabled, 1=enabled)
EnableQuickscopeToggle=1
EnableFoolproofToggle=1
EnableQuickSwitchToggle=1
EnableNoRechambing=1
EnableSniperRifleToggle=1
EnableFullautoQuickscope=1
EnableHalfmanualQuickscope=0
EnableNoBorders=1

[Hotkeys]
;hotkeys specific to the script
QuickscopeToggle=!VK5A ;=alt+z, virtual keys are used for compatibility with keyboards using multiple layouts.
FoolproofToggle=!VK58 ;=alt+x
QuickSwitchToggle=!VK43 ;=alt+c
QuickSwitch1=1
QuickSwitch2=2
NoRechambingToggle=!VK41 ;=alt+a
NoRechambingFire=LButton
SniperRifleToggle=!VK53 ;=alt+s
FullautoQuickscope=RButton
HalfmanualQuickscope=LButton

[GameKeyBindings]
;in-game key bindings: used to tell the script what keys you use in-game; it doesn't change your in-game key bindings.
Aim=RButton
Fire=LButton
R3load=VK52
Switch1=1
Switch2=2

[ExternalHackKeyBindings]
;ExternalHack key bindings: used to tell the script what keys the aimbot uses; it doesn't change your aimbot key bindings.
Aimbot=Home

;HELP: 
; - refer to this document for hotkey modifiers: http://www.autohotkey.com/docs/Hotkeys.htm
; - refer to this document for key listing: http://www.autohotkey.com/docs/KeyList.htm
; - refer to this document for virtual key listing: http://www.autohotkey.net/~goyyah/Tips-N-Tricks/InputKey/VK_NAMES.ini

Итак, перейдём к моему вопросу. Я хочу реализовать возможность автоматического переключения некоторых функций скрипта без нажатия хоткеев, а посредством чтения памяти игры и использования конкретных значений. То есть, вместо, к примеру этого "переключателя":

SniperRifleToggle:
    if Sn < 1
    {
        Sn += 1
        if Sn = 1
        {
            SoundBeep, 100, 50
            SoundBeep, 100, 50
            SoundBeep, 100, 50
            FeatureOn("SEMI-AUTO SELECTED")
        }
    }
    else
    {
        Sn := 0
        SoundBeep, 400, 200
        FeatureOn("BOLT-ACTION SELECTED")
    }
    return

Я бы хотел использовать следующий алгоритм:

Чтение адреса X из памяти игры
loop
{
Если X = N1, то установить Sn = 1
Если X = N2, то установить Sn = 0
}

Курение мануалов и поиск по форуму не особенно помогли, потому что везде идёт расчёт на то, что читатель уже знаком с основами использования памяти процесса, но это ко мне не относится. Поэтому прошу объяснить мне, желательно на конкретном примере - моём скрипте, как реализовать эту задумку, и как вообще происходит процесс чтения памяти.

2

Re: AHK: Использование памяти игры для автоматизирования скрипта

Пример чтения из памяти процесса есть здесь: AHK: Доступ к памяти других процессов. Вам, видимо, только нужно оформить код как функцию и вызывать её для считывания значения. Каких-то знаний о работе с памятью процесса Вам тут, думаю, не нужно, т.к. код вполне рабочий. Если всё-таки есть какие-то вопросы, то задавайте.

3

Re: AHK: Использование памяти игры для автоматизирования скрипта

YMP пишет:

Вам, видимо, только нужно оформить код как функцию и вызывать её для считывания значения.

Вот это я и не знаю как сделать.
Ладно, попытка номер раз:

#NoEnv

ProcessName = BlackOpsMP.exe
ReadAddress = X
ReadSize = 4  
VarSetCapacity(Buf, ReadSize, 0) 

PROCESS_VM_READ = 0x10  

Process, Exist, %ProcessName%

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID)

Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                  , UInt, ReadAddress
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)

DllCall("CloseHandle", UInt, hProcess)

Result := NumGet(Buf, 0, "UInt")

SniperRifleToggle:
    loop
    {
        if %Result% = N1
        {
            Sn := 1
        }
        else if %Result% = N2
        {
            Sn := 0
        }
        sleep 500
    }
    return

Проверить рработоспособность, к сожалению, не могу, так как пока не знаю адрес, который мне нужно считать (буду спрашивать на другом форуме). Временно пометил его как "X", а значения как "N1" и "N2".
Что скажете? Я вас правильно понял?

4

Re: AHK: Использование памяти игры для автоматизирования скрипта

Нет, неправильно. Вам только за одним адресом следить нужно? Если есть какие-то варианты, то лучше сразу скажите, опишите всё полностью.

5 (изменено: 63OR63, 2011-02-26 19:17:25)

Re: AHK: Использование памяти игры для автоматизирования скрипта

YMP пишет:

Нет, неправильно. Вам только за одним адресом следить нужно? Если есть какие-то варианты, то лучше сразу скажите, опишите всё полностью.

Мне нужно следить за адресом, отвечающим за тип оружия в руках, и в соответствии с его текущим значением ставить нужное значение переменной "Sn", которая в свою очередь влияет на работу нескольких хоткеев, таких как "FullautoQuickscope", "HalfmanualQuickscope" и "NoRechambingFire". Также мне нужно следить за количеством пуль и наличием нужных перков, то есть ещё 2 "переключателя" значений переменных, оба работают схожим образом. Главное написать 1 работающий "переключатель", а все остальные можно сделать по его подобию, различий особых нет, только разные адреса.

6

Re: AHK: Использование памяти игры для автоматизирования скрипта

Ну так пример чтения с одного адреса — это и есть мой скрипт. От Вас требуется чисто АНК-шный кодинг. Loop, я вижу, Вы знаете, If-Else тоже. Конкретно в чём Ваша проблема заключается? Вы сами пишете свой скрипт или Вам его пишут по частям другие люди?

7

Re: AHK: Использование памяти игры для автоматизирования скрипта

YMP пишет:

Ну так пример чтения с одного адреса — это и есть мой скрипт. От Вас требуется чисто АНК-шный кодинг. Loop, я вижу, Вы знаете, If-Else тоже. Конкретно в чём Ваша проблема заключается? Вы сами пишете свой скрипт или Вам его пишут по частям другие люди?

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

код вполне рабочий.

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

Если всё-таки есть какие-то вопросы, то задавайте.

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

8

Re: AHK: Использование памяти игры для автоматизирования скрипта

Во-первых, Вы убрали вот эту строчку:

PID := ErrorLevel                 ; Идентификатор процесса будет в ErrorLevel.

Думаю, из комментария понятно, зачем она.

Далее у Вас число из памяти процесса считывается один раз в переменную Result и она начинает циклически проверяться. Зачем? Что в ней есть, то там и будет. Для чего цикл-то?

9 (изменено: 63OR63, 2011-02-27 23:33:26)

Re: AHK: Использование памяти игры для автоматизирования скрипта

YMP пишет:

Во-первых, Вы убрали вот эту строчку:

PID := ErrorLevel                 ; Идентификатор процесса будет в ErrorLevel.

Думаю, из комментария понятно, зачем она.

Далее у Вас число из памяти процесса считывается один раз в переменную Result и она начинает циклически проверяться. Зачем? Что в ней есть, то там и будет. Для чего цикл-то?

То есть, если я просто верну эту строку, то всё будет работать? Я так и не понял, за что она отвечает, и комментарий мне ни о чём не говорит Переменная PID больше нигде в скрипте не встречается, как и значение ErrorLevel. Или это не переменная?

А в луп я пихаю проверку адреса потому что количество патронов, или оружие - вещь не постоянная. Или всё сложнее, и информация об этом хранится не в одном адресе?

10 (изменено: YMP, 2011-02-28 09:25:54)

Re: AHK: Использование памяти игры для автоматизирования скрипта

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

Переменная PID в скрипте встречается.

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ
                                 , Int, False
                                 , UInt, PID

Выражение "идентификатор процесса" Вам непонятно?

Извините, но когда я приглашал Вас задавать вопросы, я предполагал наличие у Вас каких-то знаний. Вы же писали, что проблема, мол, в работе с памятью процесса. Таких вопросов я и ожидал. Но похоже, что знаний у Вас нет даже базовых. Зачем же Вы вводите людей в заблуждение? Вы фактически задаёте вопросы о том, как сложить 2 и 2. У АНК есть отличная справка, там всё разжёвано. ErrorLevel там упоминается в каждой статье, так что в "курение мануалов" поверить трудно.

11 (изменено: 63OR63, 2011-02-28 12:26:19)

Re: AHK: Использование памяти игры для автоматизирования скрипта

YMP пишет:

Извините, но когда я приглашал Вас задавать вопросы, я предполагал наличие у Вас каких-то знаний. Вы же писали, что проблема, мол, в работе с памятью процесса. Таких вопросов я и ожидал. Но похоже, что знаний у Вас нет даже базовых. Зачем же Вы вводите людей в заблуждение? Вы фактически задаёте вопросы о том, как сложить 2 и 2. У АНК есть отличная справка, там всё разжёвано. ErrorLevel там упоминается в каждой статье, так что в "курение мануалов" поверить трудно.

Вы только пишете о том, что я ничего не понимаю и всё делаю не правильно, а как сделать правильно умалчиваете. Напомню, что этот форум как раз предназначен для того, чтобы делиться своими знаниями, и что посылать читать документацию в таком месте не только не имеет смысла, но и даже неприлично. У адекватных людей тяга самоутверждаться за счёт чужого незнания проходит ещё в подростковом возрасте.

Итак, если суть моих вопросов всё ещё не ясна, попробую изложить поподробнее на примере вашего кода:

#NoEnv

ProcessName = notepad.exe         ; Имя процесса - ясно
ReadAddress = 0x7C800000          ; Адрес, откуда читать - ясно
ReadSize = 4                      ; Сколько байт читать - ясно
VarSetCapacity(Buf, ReadSize, 0)  ; Буфер, куда считывать - ясно

PROCESS_VM_READ = 0x10            ; Права на процесс - почему именно 0x10 и какие значения, кроме 0x10 бывают?

Process, Exist, %ProcessName%     ; Поиск процесса - ясно

PID := ErrorLevel                 ; Идентификатор процесса будет в ErrorLevel - ничего не понял

hProcess := DllCall("OpenProcess", UInt, PROCESS_VM_READ - почему так много параметров и аргументов? за что каждый отвечает?
                                 , Int, False
                                 , UInt, PID)

Ret := DllCall("ReadProcessMemory", UInt, hProcess - почему так много параметров и аргументов? за что каждый отвечает?
                                  , UInt, ReadAddress
                                  , UInt, &Buf
                                  , UInt, ReadSize
                                  , UInt, 0)

DllCall("CloseHandle", UInt, hProcess) ; Освобождение хэндла процесса - что будет, если пропустить этот шаг?

Result := NumGet(Buf, 0, "UInt")  ; Считывание из буфера в переменную - ясно

MsgBox, %Result% - ясно

И ещё: как реализовать динамическую проверку адреса на наличие изменений, если мой вариант с лупом тут не подходит?

12

Re: AHK: Использование памяти игры для автоматизирования скрипта

63OR63 пишет:

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

Вполне прилично. Адекватные люди ценят чужое время, поэтому читают документацию, и только если что-то из неё не поняли или в ней не нашли, спрашивают на форуме.

Я лично так и делал, когда писал свой скрипт. О параметрах функций Windows API (почему столько и зачем каждый) я узнал из документации Microsoft, автора этих самых функций. Она без труда находится по именам этих функций в Гугле. Искать и переписывать её сюда персонально для Вас я не буду, ибо с какой стати? Мне никто такого сервиса сроду не оказывал.

О командах и функциях AutoHotkey я узнаю из документации AutoHotkey.

63OR63 пишет:

Идентификатор процесса будет в ErrorLevel - ничего не понял

Не поняли, потому что не читали описания команды Process в справке AutoHotkey. Оттуда же заодно узнаете, что такое ErrorLevel. Переписывать справку сюда персонально для Вас я не буду.

63OR63 пишет:

DllCall("CloseHandle", UInt, hProcess) ; Освобождение хэндла процесса - что будет, если пропустить этот шаг?

Не помню. Возможно, в описании OpenProcess сказано, что это нужно делать. Интересно — посмотрите сами. Я для Вас искать и сюда переписывать документацию Майкрософта не буду.

63OR63 пишет:

И ещё: как реализовать динамическую проверку адреса на наличие изменений, если мой вариант с лупом тут не подходит?

Периодически читать число с нужного адреса процесса игры и сравнивать с контрольным значением. А как ещё? Код, читающий с нужного адреса в другом процессе, у Вас есть. Чего ещё надобно, старче? (с) Я никак не могу понять, в чём конкретно заключается Ваша проблема. Что мешает Вам написать код? Loop Вы знаете, If-Else Вы знаете, а больше-то не нужно ничего. Давайте пишите варианты, пробуйте. Только не такую лажу, как "попытка номер раз", где Вы просто приткнули свой код к концу моего и ждали какого-то чуда. Включайте голову и пишите варианты решения.

13

Re: AHK: Использование памяти игры для автоматизирования скрипта

63OR63 пишет:

Напомню, что этот форум как раз предназначен для того, чтобы делиться своими знаниями, и что посылать читать документацию в таком месте не только не имеет смысла, но и даже неприлично. У адекватных людей тяга самоутверждаться за счёт чужого незнания проходит ещё в подростковом возрасте.

63OR63, напомню, что назначение, цели и задачи форума оговорены в Правилах форума, в частности §4.1:

Форум не является линией поддержки каких-либо программных продуктов, поэтому никто на форуме не обязан отвечать на заданные вопросы. Молчание в ответ на Ваш вопрос может означать объективную трудность вопроса или то, что Ваш вопрос не чётко сформулирован. В любом случае, Вам никто ничего не должен. Если Вы считаете, что Ваш вопрос очень лёгок, это вовсе не значит, что Вам кто-то обязан помогать только поэтому. Более того - упрёки подобного рода будут восприняты как оскорбление.

которые Вы читали и с которыми Вы соглашались, регистрируясь на форуме.

14

Re: AHK: Использование памяти игры для автоматизирования скрипта

Вполне прилично. Адекватные люди ценят чужое время, поэтому читают документацию, и только если что-то из неё не поняли или в ней не нашли, спрашивают на форуме.

Я как раз и не понял, поэтому и спрашивал.
Остальное даже цитировать отказываюсь - детский лепет, срывающийся на переход на личности.


alexii пишет:
63OR63 пишет:

Напомню, что этот форум как раз предназначен для того, чтобы делиться своими знаниями, и что посылать читать документацию в таком месте не только не имеет смысла, но и даже неприлично. У адекватных людей тяга самоутверждаться за счёт чужого незнания проходит ещё в подростковом возрасте.

63OR63, напомню, что назначение, цели и задачи форума оговорены в Правилах форума, в частности §4.1:

Форум не является линией поддержки каких-либо программных продуктов, поэтому никто на форуме не обязан отвечать на заданные вопросы. Молчание в ответ на Ваш вопрос может означать объективную трудность вопроса или то, что Ваш вопрос не чётко сформулирован. В любом случае, Вам никто ничего не должен. Если Вы считаете, что Ваш вопрос очень лёгок, это вовсе не значит, что Вам кто-то обязан помогать только поэтому. Более того - упрёки подобного рода будут восприняты как оскорбление.

которые Вы читали и с которыми Вы соглашались, регистрируясь на форуме.

И? Что вы этим хотели сказать? Я никого не принуждаю помогать мне, а прошу. А тем, для кого моя неподкованность в кодинге для AHK является личным оскорблением, лучше было бы воздержаться от постинга. Я не нарушил никаких правил.

Что ж, раз тут такое отношение к новичкам, пойду лучше спрашивать совета на англоязычные ресурсы. Всё таки, взаимопомощь и доброжелательность там можно встретить гораздо чаще, чем у нас, в чём я уже не раз убеждался.

15

Re: AHK: Использование памяти игры для автоматизирования скрипта

63OR63 пишет:

И? Что вы этим хотели сказать?

Что Ваше утверждение из #11:

63OR63 пишет:

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

не верно. Чтобы Вы поняли, почему Вы не правы в данном утверждении — дал там же ссылку на пункт Правил форума и цитату из них. Никто здесь никому ничем не обязан.

63OR63 пишет:

Я не нарушил никаких правил.

Я этого не говорил. Речь шла только об искреннем заблуждении. Я Вас поправил.

OFF:

63OR63 пишет:

Что ж, раз тут такое отношение к новичкам, пойду лучше спрашивать совета на англоязычные ресурсы. Всё таки, взаимопомощь и доброжелательность там можно встретить гораздо чаще, чем у нас, в чём я уже не раз убеждался.

Угу, сходите, спросите . А у нас всё как-то так .

16

Re: AHK: Использование памяти игры для автоматизирования скрипта

63OR63 пишет:

Я как раз и не понял, поэтому и спрашивал.

Не читали, потому и не поняли. ErrorLevel упоминается на каждой странице справки, вы о нём не знаете. Вывод однозначен.

63OR63 пишет:

Остальное даже цитировать отказываюсь

Потому что возразить нечего.

63OR63 пишет:

Что ж, раз тут такое отношение к новичкам

Новичок новичку рознь, так что и отношение разное. К тем, кто хочет сидеть и ждать, пока им всё напишут, у меня отношение отрицательное.