本节课中,我们要对选怪功能进行封装,
具体接口如下:
typedef struct PlAYER{
DWORD IsSel;
}_PLAYER;
class SelectFreak :public BaseData{
public:
SelectFreak();
~SelectFreak();
BOOL GetSel(DWORD index); //根据下标索引选中怪物
void PrintSel();//调试函数
private:
PlAYER *pPlayer;
DWORD GetIsSelOffset();//获取是否选中的偏移
DWORD IsSelOffset = 0x14b8;
};
函数实现如下:
//选怪类构造函数
SelectFreak::SelectFreak(){
memset(pPlayer, 0, sizeof(PlAYER));
pPlayer->IsSel = *(DWORD*)(*(DWORD*)this->GetBasePlayerAddr() + GetIsSelOffset());
}
SelectFreak::~SelectFreak(){
}
//获取是否选中的偏移
DWORD SelectFreak::GetIsSelOffset(){
return IsSelOffset;
}
void SelectFreak::PrintSel(){
DbgPrint_String("选中的ID为:%X", pPlayer->IsSel);
}
//根据怪物ID选中怪物
BOOL SelectFreak::GetSel(DWORD indexID){
//mov edi, [0x31e563c]
// MOV EAX, DWORD PTR DS : [EDI + 0x14B8]
// MOV ECX, DWORD PTR DS : [EAX * 4 + 0x31E5640]
// MOV EDX, DWORD PTR DS : [ECX]
// MOV EAX, DWORD PTR DS : [EDX + 0x4]
// PUSH 0x0
// PUSH 0x0
// PUSH 0x450
// CALL EAX
DWORD BasePlayAddr = GetBasePlayerAddr();
DWORD IsSelOffset = GetIsSelOffset();
DWORD BaseAllAddr = GetBaseAllAddr();
DWORD ndObj;
try{
__asm{
mov EDI, [BasePlayAddr]
MOV EAX, DWORD PTR DS : [EDI + IsSelOffset]
cmp eax, 0xffff
jz nextlable
MOV ECX, DWORD PTR DS : [EAX * 4 + BaseAllAddr]
MOV EDX, DWORD PTR DS : [ECX]
MOV EAX, DWORD PTR DS : [EDX + 0x4]
PUSH 0x0
PUSH 0x0
PUSH 0x450
CALL EAX
}
nextlable:
ndObj = *(DWORD*)GetBasePlayerAddr();
*(DWORD*)(ndObj + IsSelOffset) = indexID;
// MOV ECX, DWORD PTR DS : [EAX * 4 + 0x31E5640]
// MOV EDX, DWORD PTR DS : [ECX]
// MOV EAX, DWORD PTR DS : [EDX + 0x4]
// PUSH 0x0
// PUSH 0x1
// PUSH 0x450
// CALL EAX
__asm{
mov eax, indexID
mov ecx, DWORD PTR DS : [eax * 4 + BaseAllAddr]
mov edx, DWORD PTR DS : [ecx]
mov eax, DWORD PTR DS : [edx + 4]
push 0
push 1 //显示选中状态
push 0x450
call eax
}
}
catch (...){
DbgPrint_String("出现异常");
return FALSE;
}
return TRUE;
}
以上就完成了对选怪功能的封装,下节课我们将准备计算玩家和人物之间的距离,为实现自动打怪做准备。
Gitbub源码下载地址:点击下载