对以下版本有效,其它版本有待测试:
春天夏傲0.504、陈沐1.68v108p、原版1.05(由于太累,暂不支持原版1.00)
快捷键
F3:初始化,默认启动不后选、陈沐版不自动装备
Ctrl:按住 Ctrl 选出战阵形,可更换兵种
Shift + F2:恢复后选
F5:将鼠标放在“内政自治”或点搜索后任一将上再按F5,自动狂点。所有城默认就有自治,无需手工设置)
Esc: 停止自动狂点。(“Esc”是键盘最左上角的那个键)
例:
1. 点开本程序,再开始游戏(先后无所谓,都运行就行)。
2. 进入游戏内政界面,请确认你还有将没搜索或开发过。
3. 请将鼠标放在内政自治上,点 F5,程序狂点开始,按 Esc 停止。
临战换兵:(无视兵种学习,每种阵形代表一个兵种)
1. 在战斗准备状态,点选择阵形,出现阵形菜单。
2. 此时按下 Ctrl 不放,点方形阵,再放开 Ctrl 键。
3. 该将兵种已换为大刀兵。
4. 再保持不按 Ctrl 键的状态,选所需阵形。
引入 INI 文件控制,可控选项:
1. 是否有出征人数限制
2. 是否能搜出唯一物品
3. 陈沐版是否自动装备
对上一版的区别:
1. 增加临战换兵
2. 增加陈沐版不自动装备
对于找不到唯一物品:
几乎所有的三国群英2都有这毛病,本外挂让这毛病一目了然而已。
在游戏过程中点 “回主菜单”->“开始游戏”,所产生的进度会找不到唯一物品。应该关闭三国群英2的程序,再重新打开,再点“开始游戏”,这样的进度才可以。
注意:以上的“开始游戏”是指主菜单中的按钮,并不是说开始打游戏。
对于无限出征人数:
1. 尽量不要出多于城所能容纳的人数,如果一个城只能容 13 人,你却非要出 15 人去打。当它只能容 13 人,还要考虑到打了以后只能容 10 人,所以只能出 10 去打。
2. 城为空城,队伍人数大于城的容量。例如一个城只能容 5 人,你却出 10 人去入住。此时队伍就会一直走在城上,无法入住,点队伍 -> 进入城内,选 5 人入城后,将会发生城里住满人,但城不是你的。此时点城,发现没有军师与太守,重新任命军师与太守就好。
跟上一版一样,源代码都在里面。
最后感谢所有为三国群英2更加好玩作出贡献的朋友。
1. 首先请放心,本外挂根本没有病毒,CRC 如下:
Sango2Hotkey.AHK 2AEDBE2C
Sango2Hotkey.exe 457C03AF
Sango2Hotkey.ini A313F847
2. 大多数杀毒软件并不会报,如 ClamWin、NOD32 等等,一开始,我并没在意。
3. 个别国产的杀毒软件会误报, 原因是程序中调用了修改内存的函数。
4. 如果你不放心,本外挂是开源的(*.AHK 是源代码),请到 www.autohotkey.com 下载编译器重新编译。
#MaxThreads 2 ;最多同时运行两个线程
#NoEnv ;不使用 windows 的环境变量
;-------------------------------------------------------
; Here Functions define
;-------------------------------------------------------
WriteProcessMemory(win_id, addr, addr_value, addr_offset = 0, value_size = 4)
{
if (win_id > 0)
{
addr += addr_offset
WinGet, proc_id, PID, ahk_id %win_id%
ProcessHandle := DllCall("OpenProcess", "UInt", 0x28, "char", 0, "UInt", proc_id, "UInt")
write_success := DllCall("WriteProcessMemory", "UInt", ProcessHandle, "UInt", addr, "UInt *", addr_value, "Uint", value_size, "Uint *", BytesWritten)
DllCall("CloseHandle", "int", ProcessHandle)
}
return, % write_success
}
ReadProcessMemory(win_id, addr, ByRef addr_value, addr_offset = 0, value_size = 4)
{
if (win_id > 0)
{
addr += addr_offset
WinGet, proc_id, PID, ahk_id %win_id%
ProcessHandle := DllCall("OpenProcess", "Int", 24, "char", 0, "UInt", proc_id, "UInt")
read_success := DllCall("ReadProcessMemory", "UInt", ProcessHandle, "UInt", addr, "UInt *", addr_value, "Uint", value_size, "Uint *", 0)
DllCall("CloseHandle", "int", ProcessHandle)
}
return, % read_success
}
ValueWrite(win_id, addr, addr_value, addr_value_orig)
{
ReadProcessMemory(win_id, addr, addr_value_read)
if addr_value_read = %addr_value_orig%
WriteProcessMemory(win_id, addr, addr_value)
}
ListValueWrite(win_id, List, WriteBack = 0)
{
if WriteBack = 0
Loop, parse, List, %A_Tab%%A_Space%
ValueWrite(win_id, addr%A_LoopField%, addr%A_LoopField%_value, addr%A_LoopField%_value_orig)
else
Loop, parse, List, %A_Tab%%A_Space%
ValueWrite(win_id, addr%A_LoopField%, addr%A_LoopField%_value_orig, addr%A_LoopField%_value)
}
;-------------------------------------------------------
; Start
;-------------------------------------------------------
;-------------------------------------------------------
CrazyClick := 0
;-------------------------------------------------------
IniRead, SearchUniq, Sango2Hotkey.ini, User, SearchUniq
IniRead, AutoItem, Sango2Hotkey.ini, User, AutoItem
IniRead, RenShu, Sango2Hotkey.ini, User, RenShu
; 从 INI 文件中读取需要改的地址及值,暂设最多64项。
Loop, 64
{
IniRead, addr%A_Index%, Sango2Hotkey.ini, ProcessMemory, addr%A_Index%
if addr%A_Index% = ERROR
break
IniRead, addr%A_index%_value, Sango2Hotkey.ini, ProcessMemory, addr%A_index%_value
IniRead, addr%A_index%_value_orig, Sango2Hotkey.ini, ProcessMemory, addr%A_index%_value_orig
}
#IfWinActive ahk_class Sango2 for Windows
F3::
init:
hwnd := hwndSango2
WinGet, hwndSango2, ID, ahk_class Sango2 for Windows
; 从INI中选取初始化所要改的项
; 搜索相关
List := "1 2 3 4 5 13 14 15 16 17"
; 自动后选相关
List .= " 6 12 18 22"
; 自动装备
if AutoItem != 1
List .= " 21"
; 出征人数
if RenShu = 1
List .= " 7 8 23 24"
if (hwnd != hwndSango2 or A_ThisHotkey = "F3")
ListValueWrite(hwndSango2, List)
Return
~Ctrl::
gosub init
; 将阵形选择改为兵种选择
ListValueWrite(hwndSango2, "9 10 19 20")
return
~Ctrl UP::
; 恢愎阵形选择
ListValueWrite(hwndSango2, "9 10 19 20", 1)
return
+F2::
; 恢愎自动后选
ListValueWrite(hwndSango2, "6 12 18", 1)
return
F5::
gosub init
; 去除物品唯一性
if SearchUniq = 1
ListValueWrite(hwndSango2, "11")
CrazyClick := 1
SetTimer, LoopClick, 60
return
LoopClick:
if CrazyClick = 0
SetTimer, LoopClick, Off
SendInput {Click down}
Sleep, 30
SendInput {Click up}
return
;-------------------------------------------------------
; The End
;-------------------------------------------------------
#IfWinActive
~Esc::
if CrazyClick = 1
{
; 去除物品唯一性
if SearchUniq = 1
ListValueWrite(hwndSango2, "11", 1)
CrazyClick := 0
}
else
{
SendInput {ESC down}
Sleep, 30
SendInput {ESC up}
}
return