Тема: 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
}
Курение мануалов и поиск по форуму не особенно помогли, потому что везде идёт расчёт на то, что читатель уже знаком с основами использования памяти процесса, но это ко мне не относится. Поэтому прошу объяснить мне, желательно на конкретном примере - моём скрипте, как реализовать эту задумку, и как вообще происходит процесс чтения памяти.