内容:
1.组队的地址:
队员信息 =[[[[[[&H8C9E54]+&H24]+&H430]+&H14]+位置]+偏移]
位置:队友排位*4(0至4)
偏移:
当前血 +&h18
最大血 +&h20
当前蓝 +&h1C
最大蓝 +&h24
等级 +&h10
状态个数 +&h4C
队员ID +&hC这是我们已知的数据,判断队员是否要加血已经足够了。
2.设计思路:
软件的功能只是判断那个或者某个队员是否要加血,然后再向
游戏窗口发送某个加血技能快捷键消息,前提条件是要在
游戏中选中加血对象才行。
3.代码内容:

核心显示代码:
Private Sub Timer1_Timer()
Dim name(31) As Byte '存储人物名称
Dim name_temp As Long
Dim base As Long
Dim team As Long
Dim team_hp As Long
Dim team_hpmax As Long
Dim team_mp As Long
Dim team_mpmax As Long
Dim team_level As Long
Dim team_id As Long
If hProcess Then
ReadProcessMemory hProcess, ByVal &H8C9E54, base, 4, 0&
ReadProcessMemory hProcess, ByVal base + &H24, base, 4, 0& '得到为人物基地址,方便以后使用
ReadProcessMemory hProcess, ByVal base + &H390, name_temp, 4, 0&
ReadProcessMemory hProcess, ByVal name_temp, name(0), 32, 0& '得到人物名称
ReadProcessMemory hProcess, ByVal base + &H430, team, 4, 0&
ReadProcessMemory hProcess, ByVal team + &H14, team, 4, 0&
ReadProcessMemory hProcess, ByVal team + 4 * Val(Combo2.Text), team, 4, 0& '队员首地址
ReadProcessMemory hProcess, ByVal team + &H18, team_hp, 4, 0& '生命值
ReadProcessMemory hProcess, ByVal team + &H20, team_hpmax, 4, 0& '生命最大值
ReadProcessMemory hProcess, ByVal team + &H1C, team_mp, 4, 0& '真气值
ReadProcessMemory hProcess, ByVal team + &H24, team_mpmax, 4, 0& '真气最大值
ReadProcessMemory hProcess, ByVal team + &H10, team_level, 4, 0& '队员等级
ReadProcessMemory hProcess, ByVal team + &HC, team_id, 4, 0& '队员ID
End If
Label1.Caption = "医生: " & CStr(name)
Label5.Caption = "队员ID " & team_id
Label6.Caption = "队员等级 " & team_level
Label7.Caption = "生命值 " & team_hp & " / " & team_hpmax
Label8.Caption = "真气值 " & team_mp & " / " & team_mpmax
End Sub
我们得到了队员的信息,不过需要通过Combo2选择队伍中的队员(你自己也包括在这个队伍里),而且还要在游戏中选定这名队员才能实现加血功能。
[size=-0]
4.如何实现自动选定加血对象:我们可以通过游戏提供的队员选择快捷键(Shift+1/2/3..)达到选择队员的功能。当然,我们还要判断通过快捷键选择的对象是不是我们指定的队员。
5.继续编辑延伸我的程序,我又添加一个一些控件,如下图所示:

复选框:用于激活自动选定功能
标签*4:用于显示相关信息
6.[size=-0]模块声明要用到API函数:
'得到窗体句柄的函数,FindWindow函数用来返回符合指定的类名( ClassName )和窗口名( WindowTitle )的窗口句柄
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA"(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
'得到窗体控件句柄的函数
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA"(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVallpsz2 As String) As Long
'得到进程标识符的函数
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
'得到目标进程句柄的函数
Public Declare Function OpenProcess Lib "kernel32" (ByValdwDesiredAccess As Long, ByVal bInheritHandle As Long, ByValdwProcessId As Long) As Long
'关闭句柄的函数
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
'读取进程内存的函数
Public Declare Function ReadProcessMemory Lib "kernel32.dll" (ByValhProcess As Long, ByVal lpBaseAddress As Long, ByRef lpBuffer As Any,ByVal nSize As Long, ByRef lpNumberOfBytesWritten As Long) As Long
'发送信息的函数
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA"(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParamAs Any) As Long
Public Declare Function PostMessage Lib "user32" Alias "PostMessageA"(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVallParam As Long) As Long
'定义常量
Public Const PROCESS_ALL_ACCESS = &HFFF
Public Const PROCESS_VM_OPERATION = &H8&
Public Const PROCESS_VM_READ = &H10&
Public Const PROCESS_VM_WRITE = &H20&
7.代码逐步讲解:
接下来我们要做到向游戏窗口发送Shift+1的按键消息,接着得到选择的人物信息,判断选择队员ID与选择人物的ID是否为同一人,如果是则跳出选择,如果不是则按下Shift+2,之后再次判断...
7.1.首先来编写判断是否选人功能:
If Check1.Value = 1 And team_id <> 0 And Label5.Caption <> Label10.Caption Then
'team_id <> 0用于判断是否在组队功能中选择队员
'Label5.Caption <>Label10.Caption主要用于程序再次运行至此时的跳过。当激活选定功能时,且程序已经运行过一次,并且正确的选择了人物,则程序不再执行选择人物功能。当激活选定功能时,程序已经运行过一次,中途改变组队中选定人物,Label5.Caption <>Label10.Caption为假,执行选定人物功能。
End if
注:
Check1(控件):自动选人复选框
team_id(变量):组队选择后的得到的ID
Label5(控件):显示组队选择后的得到的队员ID
Label10(控件):显示选择的人物ID
7.2.下面我们编写选人按键循环,这个循环要放在上面的if里:
Dim key_num As Integer
For key_num = 8 To 12 '从1键按到5键的循环
SendMessage hwd, &H100, &H10, 0& '按住Shift键
SendMessage hwd, &H100, Key(key_num), 0&
SendMessage hwd, &H101, Key(key_num), 0&
SendMessage hwd, &H101, &H10, 0& '松开Shift键
Next key_num
这里只用到Shift(&H10)、1、2、3、4、5这六个键,所以我延用了以前编写的按键转换函数,这里传递的值为8-12
...
Case 8
Key = &H31 '1
Case 9
Key = &H32 '2
Case 10
Key = &H33 '3
Case 11
Key = &H34
Case 12
Key = &H35
...
7.3.接下来来编写显示选择人物信息功能,这个模块要放在上面For里:
'##获取选定人物信息##
Dim choose As Long
Dim choose_ecx As Long
Dim choose_max As Long
Dim choose_add As Long
Dim choose_id As Long
Dim choose_name_temp As Long
Dim choose_name(31) As Byte
Dim choose_x As Single
Dim choose_y As Single
ReadProcessMemory hProcess, ByVal base + &H138, choose, 4, 0&
ReadProcessMemory hProcess, ByVal choose + &H18, choose_ecx, 4, 0&
ReadProcessMemory hProcess, ByVal choose + &H24, choose_max, 4, 0&
choose_add = (team_id Mod choose_max) * 4 '取得选定人物偏移
ReadProcessMemory hProcess, ByVal choose_ecx + choose_add, choose_ecx, 4, 0&
ReadProcessMemory hProcess, ByVal choose_ecx + &H8, choose_id, 4, 0&
ReadProcessMemory hProcess, ByVal choose_ecx + &H4, choose_ecx, 4, 0&
ReadProcessMemory hProcess, ByVal choose_ecx + &H390, choose_name_temp, 4, 0&
ReadProcessMemory hProcess, ByVal choose_name_temp, choose_name(0), 32, 0&
ReadProcessMemory hProcess, ByVal choose_ecx + &H3DC, choose_x, 4, 0&
ReadProcessMemory hProcess, ByVal choose_ecx + &H3E4, choose_y, 4, 0&
Label10.Caption = "队员ID:" & choose_id
Label12.Caption = "队员名称:" & CStr(choose_name)
Label13.Caption = "X:" & CDec(choose_x)
Label14.Caption = "Y:" & CDec(choose_y)
参考:游戏玩家数组对象
[size=-0]ECX=[[[0012F824]+&h24]+&h138]
当前玩家数量=[ECX2+&h14]
玩家数组的最大值 [size=-0]Max=[ECX2+&h24]
偏移=(玩家ID mod Max)*4
选中玩家的列表 = [[ECX2+&h18]+偏移]
选中玩家的ID =[[[ECX2+&h18]+偏移]+&h8]
选中玩家的基址知道了,[[[ECX2+&h18]+偏移]+&h4]
当前血 =[[[[ECX2+&h18]+偏移]+&h4]+&h254]
最大血 =[[[[ECX2+&h18]+偏移]+&h4]+&h26C]
当前蓝 =[[[[ECX2+&h18]+偏移]+&h4]+&h258]
最大蓝 =[[[[ECX2+&h18]+偏移]+&h4]+&h270]
当前等级 =[[[[ECX2+&h18]+偏移]+&h4]+&h24C]
当前
辅助技能个数=[[[[ECX2+&h18]+偏移]+&h4]+&h118]
人物坐标X =[[[[ECX2+&h18]+偏移]+&h4]+&h3dc]
人物坐标Y =[[[[ECX2+&h18]+偏移]+&h4]+&h3e4]
人物名称 =[[[[[ECX2+&h18]+偏移]+&h4]+&h390]+0]
7.4.最后重要的一步就是判断选择的人物是否就是我们之前选定的队员:
If team_id = choose_id Then Exit For
这个choose_id是选择人物后得到的人物ID,根据这个值判断是否要跳出选择循环。
7.5.最后结构总结:
队员信息显示
判断是否要自动选人
选人循环
选人信息显示
选人信息对比的判断 信息一致:跳出循环
选人循环-继续
判断是否要自动选人-结束
8.最后效果:

[size=-0]9.关于方法二:
我们锁定了队伍中一名队员来给他加血,那能不能同时给队伍中多名队员加血呢?我们只要动态改变队伍中的队员就可以实现这个功能,是不是有点思路了,愿阳光永远照耀着你!!!