对以下版本有效,其它版本有待测试:
春天夏傲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