内容参考于:易道云信息技术研究院VIP课
上一个内容:利用技能点属性分析角色数据基址-CSDN博客
码云地址(ui显示角色数据 分支):https://gitee.com/dye_your_fingers/sro_-ex.git
码云版本号:367aa71f60b9c10ff47ca913a96d2a2ede76b389
代码下载地址,在 SRO_EX 目录下,文件名为:SRO_Ex-自动化助手UI显示角色数据.zip
链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg
提取码:q9n5
--来自百度网盘超级会员V4的分享
HOOK引擎,文件名为:黑兔sdk.zip
链接:https://pan.baidu.com/s/1IB-Zs6hi3yU8LC2f-8hIEw
提取码:78h8
--来自百度网盘超级会员V4的分享
以 优化自动助手与游戏焦点的切换-CSDN博客 它的代码为基础进行修改
然后给窗口添加一个编辑框,如下图

编辑框的属性

然后给输入框添加一个变量

然后名字与等级乱码,等级的话它不是int应该是char类型,名字不知道要再分析,名字中文的话是可以正常显示的

然后更改角色之后,自动化窗口不重新刷新

把自动化窗口关了重开才会好

后面修复名字与等级问题
AIM.h文件的修改,新加 SkillPoint变量,SkillPoint是技能点
#pragma once
typedef class AIM
{
public:
	char pad_0000[276]; //0x0000
	short Name[7]; //0x0114 角色名字长度是7
	char pad_0115[902]; //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
	int32_t LV; //0x08D0 等级
	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
CUI.cpp文件的修改,修改了 InstallPage函数、OnInitDialog函数
// CUI.cpp: 实现文件
//
#include "pch.h"
#include "htdMfcDll.h"
#include "CUI.h"
#include "afxdialogex.h"
// CUI 对话框
IMPLEMENT_DYNAMIC(CUI, CDialogEx)
CUI::CUI(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MAIN, pParent)
{
}
CUI::~CUI()
{
}
void CUI::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_TAB1, mTab);
}
BOOL CUI::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	
	InstallPage(new CUIWnd_0(), IDD_PAGE_0, L"角色", TRUE);
	InstallPage(new CUIWnd_1(), IDD_PAGE_1, L"测试");
	SetBackgroundColor(0xFFFFFFFF);
	//PageINJ.Init(wAppPath);
	//PageRAN.SetAppPath(wAppPath);
	return TRUE;
}
bool CUI::InstallPage(CDialogEx* wnd, int IDD_WND, CString&& _Name, BOOL IsShow)
{
	if (CurPage >= MAX_PAGE_MAIN) return false;
	Pages[CurPage] = wnd;
	Pages[CurPage]->Create(IDD_WND, this);
	//Pages[CurPage]->SetParent(this);
	Pages[CurPage]->ShowWindow(IsShow);
	CRect rect;
	mTab.GetClientRect(&rect);
	rect.top += 46;
	rect.left = 0;
	rect.bottom -= 5;
	rect.right -= 5;
	Pages[CurPage]->MoveWindow(&rect);
	mTab.InsertItem(CurPage, _Name);
	CurPage++;
	return true;
}
BEGIN_MESSAGE_MAP(CUI, CDialogEx)
	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, &CUI::OnTcnSelchangeTab1)
	ON_WM_CLOSE()
END_MESSAGE_MAP()
// CUI 消息处理程序
void CUI::OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
	int n = mTab.GetCurSel();
	for (int i = 0; i < CurPage; i++)
	{
		Pages[i]->ShowWindow(i == n);
	}
}
void CUI::UIShow()
{
	auto hwndClient = ::FindWindow(L"CLIENT", L"SRO_CLIENT");
	::SetParent(this->m_hWnd, hwndClient);
	this->ShowWindow(ShowUI = !ShowUI);
	// 把焦点还给游戏
	::SetFocus(hwndClient);
}
void CUI::OnClose()
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	UIShow();
	// CDialogEx::OnClose();
}
GameBase.h文件的修改,新加 SRO_Player变量、AIM.h头文件
#pragma once
#include "Res.h"
#include "Notice.h"
#include "AIM.h"
class GameBase
{
	void InitClassProc(LPVOID proc_addr, unsigned value);
public:
	void Init();
	GameBase();
	PRes SRO_Res;
	PNotice SRO_Notice;
	PAIM SRO_Player;
};GameBase.cpp文件的修改,修改了Init函数
#include "pch.h"
#include "GameBase.h"
GameBase* _pgamebase;
void GameBase::Init()
{
	unsigned* addrRead = (unsigned*)0x1256E3C;
	SRO_Res = (PRes)0x1036518;
	SRO_Notice = (PNotice)addrRead[0];
	addrRead = (unsigned*)0x1037D3C;
	SRO_Player = (PAIM)addrRead[0];
	
	InitClassProc(&Res::_ReadTitle, 0x9A46C0);
	InitClassProc(&Notice::_NormalNotice, 0x848580);
	InitClassProc(&Notice::_NetNotice, 0x844E40);
	InitClassProc(&Notice::_ChatNotice, 0x844E80);
}
void GameBase::InitClassProc(LPVOID proc_addr, unsigned value)
{
	unsigned* uWrite = (unsigned*)proc_addr;
	uWrite[0] = value;
}
GameBase::GameBase()
{
	_pgamebase = this;
	// Init();// 初始化机制,完成游戏与我们dll的对接
}
CUIWnd_0.h文件的修改,新加 txt_Player变量、OnInitDialog函数、ShowPlayerTxt函数
#pragma once
#include "afxdialogex.h"
// CUIWnd_0 对话框
class CUIWnd_0 : public CDialogEx
{
	DECLARE_DYNAMIC(CUIWnd_0)
public:
	CUIWnd_0(CWnd* pParent = nullptr);   // 标准构造函数
	virtual ~CUIWnd_0();
// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_PAGE_0 };
#endif
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
	DECLARE_MESSAGE_MAP()
public:
	// 玩家信息
	CString txt_Player;
	BOOL OnInitDialog();
	void ShowPlayerTxt();
};
CUIWnd_0.cpp文件的修改,新加 OnInitDialog函数、ShowPlayerTxt函数、TimeProc函数、GameBase.h头文件、extern_all.h头文件
// 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, _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 消息处理程序



















