内容参考于:易道云信息技术研究院VIP课
上一个内容:自动化助手UI显示角色数据-CSDN博客
码云地址(ui显示角色数据 分支):https://gitee.com/dye_your_fingers/sro_-ex.git
码云版本号:0049452c079867779f639c4bfab9bd1cd0c68932
代码下载地址,在 SRO_EX 目录下,文件名为:SRO_Ex-修复角色名与等级显示问题.zip
链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg
提取码:q9n5
--来自百度网盘超级会员V4的分享
HOOK引擎,文件名为:黑兔sdk.zip
链接:https://pan.baidu.com/s/1IB-Zs6hi3yU8LC2f-8hIEw
提取码:78h8
--来自百度网盘超级会员V4的分享
以 自动化助手UI显示角色数据-CSDN博客它的代码为基础进行修改
等级它有时候显示正确有时候显示不正确,这个问题就出在数据类型上,角色名字用的还是我们的SRO_String类型。
然后打开 Cheat Engine 看它的内存,这里 Cheat Engine也读不出字符串了
然后点击浏览相关的内存区域
很明显的看出这里并不是名字,是一个内存地址
它还是与SRO_String一样
然后自动化助手可以正常显示的名字的内存,它与不正常显示的内存不一样,不能直接用SRO_String需要修改
修改之后就正常了
这个也正常
AIM.h文件的修改
#pragma once
#include "SRO_String.h"
typedef class AIM
{
public:
char pad_0000[272]; //0x0000
SRO_String Name; //0x0114 角色名字长度是7
char pad_0115[892]; //0x0115
int32_t MP; //0x04A8 蓝量
int32_t MaxHP; //0x04AC 最大生命值
int32_t MaxMP; //0x04B0 最大蓝量
int32_t HP; //0x04B4 生命值
char pad_04B8[608]; //0x04B8
float x; //0x0718 x坐标
float h; //0x071C z坐标
float y; //0x0720 y坐标
char pad_0724[428]; //0x0724
char LV; //0x08D0 等级
char unlv[3];
char pad_08D4[4]; //0x08D4
int32_t Exp; //0x08D8 经验
char pad_08DC[12]; //0x08DC
int SkillPoint; // 技能点数
char UnUSERage; // 怒气
char unknownH33;
char Rage; //0x08EE 怒气值
char RageEx; //0x08EF 怒气值副本
char pad_08F0[1883]; //0x08F0
}*PAIM; //Size: 0x104B
CUIWnd_0.cpp文件的修改
// CUIWnd_0.cpp: 实现文件
//
#include "pch.h"
#include "htdMfcDll.h"
#include "CUIWnd_0.h"
#include "GameBase.h"
#include "extern_all.h"
// CUIWnd_0 对话框
CUIWnd_0* UI_0;
void _stdcall TimeProc(HWND, UINT, UINT_PTR, DWORD) {
if (UI_0) {
UI_0->ShowPlayerTxt();
}
}
IMPLEMENT_DYNAMIC(CUIWnd_0, CDialogEx)
CUIWnd_0::CUIWnd_0(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_PAGE_0, pParent)
, txt_Player(_T(""))
{
UI_0 = this;
}
CUIWnd_0::~CUIWnd_0()
{
}
void CUIWnd_0::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, txt_Player);
}
BOOL CUIWnd_0::OnInitDialog()
{
CDialogEx::OnInitDialog();
::SetTimer(this->m_hWnd, 0x100001, 10, TimeProc);
return TRUE;
}
void CUIWnd_0::ShowPlayerTxt()
{
if ((_pgamebase) && (_pgamebase->SRO_Player)) {
CString txtTmp;
txtTmp.Format(L"角色名:[%s] 等级[lv:%d]\r\n", _pgamebase->SRO_Player->Name.wcstrByName(), _pgamebase->SRO_Player->LV);
txt_Player = txtTmp;
txtTmp.Format(L"经验值:[%d] 技能点[%d]\r\n", _pgamebase->SRO_Player->Exp, _pgamebase->SRO_Player->SkillPoint);
txt_Player += txtTmp;
txtTmp.Format(L"血量:[%d/%d]\r\n", _pgamebase->SRO_Player->HP, _pgamebase->SRO_Player->MaxHP);
txt_Player += txtTmp;
txtTmp.Format(L"蓝量:[%d/%d]\r\n", _pgamebase->SRO_Player->MP, _pgamebase->SRO_Player->MaxMP);
txt_Player += txtTmp;
txtTmp.Format(L"坐标:[%f][%f][%f]\r\n", _pgamebase->SRO_Player->x, _pgamebase->SRO_Player->h, _pgamebase->SRO_Player->y);
txt_Player += txtTmp;
// 计算百分比
txtTmp.Format(L"怒气:[%f/100]\r\n", (float)_pgamebase->SRO_Player->Rage/5*100);
txt_Player += txtTmp;
}
UpdateData(FALSE);
}
BEGIN_MESSAGE_MAP(CUIWnd_0, CDialogEx)
END_MESSAGE_MAP()
// CUIWnd_0 消息处理程序
SRO_String.cpp文件的修改
#include "pch.h"
#include "SRO_String.h"
int SRO_String::stringlength(const wchar_t* str)
{
for (lenth = 0; str[lenth]; lenth++);
size = lenth * 2 + 1;
return size;
}
wchar_t* SRO_String::wcstr()
{
if (size < 0x8) {
return title;
}
else {
return Ptitle;
}
}
wchar_t* SRO_String::wcstrByName()
{
if (0xF<(lenth + 1)*2) {
return Ptitle;
}
return title;
}
SRO_String& SRO_String::operator=(const wchar_t* _txt)
{
int _size = stringlength(_txt);
if (_size > 8) {
Ptitle = (wchar_t*)_txt;
}
else {
memcpy(title, _txt, _size);
}
return *this;
}
SRO_String.h文件的修改
#pragma once
typedef class SRO_String
{
private:
int un1;
union {
wchar_t title[0x8];
wchar_t* Ptitle;
};
unsigned lenth;
unsigned size;
int stringlength(const wchar_t* str);
public:
wchar_t* wcstr();
wchar_t* wcstrByName();
SRO_String& operator=(const wchar_t* _txt);
}*PSROSTRING;