97.网络游戏逆向分析与漏洞攻防-ui界面的设计-通过逆向分析确认角色信息
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
如果看不懂、不知道现在做的什么,那就跟着做完看效果,代码看不懂是正常的,只要会抄就行,抄着抄着就能懂了
内容参考于:易道云信息技术研究院
上一个内容:96.角色管理功能的界面设计
码云版本号:bc950992bfd853df20f2f587b5ce79d3446b70de
代码下载地址,在 titan 目录下,文件名为:titan-通过逆向分析确认角色信息.zip
链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg
提取码:q9n5
--来自百度网盘超级会员V4的分享
HOOK引擎,文件名为:黑兔sdk升级版.zip
链接:https://pan.baidu.com/s/1IB-Zs6hi3yU8LC2f-8hIEw
提取码:78h8
--来自百度网盘超级会员V4的分享
以 96.角色管理功能的界面设计 它的代码为基础进行修改
效果图:进入游戏按钮、删除角色按钮功能都以实现
字符串里数字代表的东西
可以看到上图中职业、性别、阵营、种族等用的都是数字来表示的,它既然用的数据那是不是可以直接用这些数组当数组的下标了?所以接下来去逆向找它通过数字连接的字符串表(语言包)
然后在下图红框位置打断点(0x102960AD位置,这个位置是在 87.技能名称显示的逆向分析 这里找技能中文名时得到的)
然后输入账号点击登录,就会断下来,这里会断好几次,一直按F9
然后弹出下图的弹框,然后点确定
点了确定之后又会断下来,还是一直按f9
然后就看到了职业,发现它是数字前面加了一个job_
然后继续按F9会看到阵营(格兰蒂尔是奇幻),数字前面加了一个camp_
然后会看到种族,它是数字前面加了一个race_
然后还能看到职业的描述,数字前面加了 desc_job_
还能看到当前所在位置
然后通过地图传的id可以看到56是当前所在地图、
CUIWnd_0.h文件的修改:新加 OnBnClickedButton3函数
#pragma once
#include "afxdialogex.h"
class CUI;// 如果引入CUI.h文件,会冲突,所以这里自己搞一个CUI类型
// CUIWnd_0 对话框
class CUIWnd_0 : public CDialogEx
{
DECLARE_DYNAMIC(CUIWnd_0)
public:
CUIWnd_0(CUI* _netUI, CWnd* pParent = nullptr); // 标准构造函数
virtual ~CUIWnd_0();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_PAGE_0 };
#endif
private:
CUI* netUI;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
CListCtrl lstRole;
afx_msg void OnBnClickedButton3();
};
CUIWnd_0.cpp文件的修改:修改了 OnInitDialog函数、OnBnClickedButton2函数,新加 OnBnClickedButton3函数
// CUIWnd_0.cpp: 实现文件
//
#include "pch.h"
#include "htdMfcDll.h"
#include "CUIWnd_0.h"
#include "afxdialogex.h"
#include "extern_all.h"
#include "GameOBJECTDef.h"
// CUIWnd_0 对话框
float _xNext = 0.0f;
float _yNext = 0.0f;
void _stdcall loops(HWND, UINT, UINT_PTR, DWORD) {
PAIM aim = Client->GetAimByName(L"r");
if (aim == nullptr) {
return;
}
//AfxMessageBox(aim->Name);
float xDis = fabs(Client->Player.x - aim->x);
float hDis = fabs(Client->Player.h - aim->h);
float yDis = fabs(Client->Player.y - aim->y);
float xNext, yNext, thisx, thisy;
int v[2]{ -1, 1 };
if (xDis > 12) {
// 强制修改角色x坐标的值
thisx = Client->Player.x;
Client->Player.x = Client->Player.x + 6 * v[Client->Player.x < aim->x];
xNext = Client->Player.x;
}
else {
xNext = aim->x;
}
if (yDis > 12) {
// 强制修改角色y坐标的值
thisy = Client->Player.y;
Client->Player.y = Client->Player.y + 6 * v[Client->Player.y < aim->y];
yNext = Client->Player.y;
}else{
yNext = aim->y;
}
if ((xDis < 2)&&(hDis < 2)&&(yDis < 2)) {
Client->MoveStop(aim->x, aim->h, aim->y, 0.0f);
}
else {
Client->MoveWalk(Client->Player.x,aim->h, Client->Player.x, 0.0f, 0.0f, xNext, yNext);
}
}
IMPLEMENT_DYNAMIC(CUIWnd_0, CDialogEx)
CUIWnd_0::CUIWnd_0(CUI* _netUI, CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_PAGE_0, pParent)
{
netUI = _netUI;
}
CUIWnd_0::~CUIWnd_0()
{
}
void CUIWnd_0::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST2, lstRole);
}
BOOL CUIWnd_0::OnInitDialog()
{
CDialogEx::OnInitDialog();
netUI->SetListView(&lstRole);
lstRole.InsertColumn(0, L"序号", 0, 50);
lstRole.InsertColumn(1, L"名字", 0, 160);
lstRole.InsertColumn(2, L"等级", 0, 50);
lstRole.InsertColumn(3, L"性别", 0, 40);
lstRole.InsertColumn(4, L"阵营", 0, 130);
lstRole.InsertColumn(5, L"场景", 0, 130);
lstRole.InsertColumn(6, L"种族", 0, 130);
lstRole.InsertColumn(7, L"职业", 0, 130);
return TRUE;
}
BEGIN_MESSAGE_MAP(CUIWnd_0, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON1, &CUIWnd_0::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CUIWnd_0::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &CUIWnd_0::OnBnClickedButton3)
END_MESSAGE_MAP()
// CUIWnd_0 消息处理程序
void CUIWnd_0::OnBnClickedButton1()
{
// 释放技能
float x = Client->Player.x;
float h = Client->Player.h;
float y = Client->Player.y;
Client->UseSkill("Skill_Mg2692_01_1", x, h, y, Client->Player.face);
// 发送坠落数据包
//Client->Fall();
设置移动速度
// float Speed = 30.0;
// Client->SetProperty(Client->Player.lId, INDEX_MoveSpeed, &Speed);
/*
// 修改血量
int HP = 10000000;
Client->SetProperty(Client->Player.lId, INDEX_HP, &HP);*/
/*CString txt;
txt.Format(L"通过AIM类获取角色信息 名字:%s,x坐标:%f", Client->Player.Name, Client->Player.x);
AfxMessageBox(txt);*/
// Client->HeartBeep();
// Client->TalkTo(L"r", L"打架吗?");
// Client->Talk(L"[欢迎来到麟科思]");
// Client->SelectRole(L"今晚打老虎");
/*Client->CreateRole(L"am4", 1.0, 2.0, 4.0, 8.0, "gui\BG_team\TeamRole\Teamrole_zq_humF_001.PNG",
"Face,0;Hat,0;Eyes,0;Beard,0;Ears,0;Tail,0;Finger,0;Cloth,0;Pants,0;Gloves,0;Shoes,0;Trait,0;HairColor,0;SkinColor,0;SkinMtl,0;Tattoo,0;TattooColor,16777215;",
"", 0.0);*/
//Client->SelectCamp("xuanrenZQ");
//Client->StartCreateRole();
//Client->DelRole(L"ranzhi11111");
/*
char buff[] = {
0xA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x4, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 00 ,0x00,
0x00, 0x07, 0x0E, 0x00, 0x00, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x31, 0x00, 0x32 ,0x00,
0x33, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
WinSock->OnSend(buff, sizeof(buff));
*/
/*char buff[] = {
0x27, 0x46, 0x92, 0x02, 0x00, 0x00, 0x89, 0x02, 0x00, 0x00, 0x06, 0x00, 0x06, 0x05,
0x00, 0x00, 0x00, 0x63, 0x68, 0x61, 0x74, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x07,
0x0A, 0x00, 0x00, 0x00, 0x34, 0x00, 0x33, 0x00, 0x39, 0x00, 0x39, 0x00, 0x00, 0x00,
0x07, 0x5A, 0x02, 0x00, 0x00, 0x31, 0x00, 0x32, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31,
0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31,
0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31,
0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31,
0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31,
0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31,
0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31,
0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31,
0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31,
0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32,
0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32,
0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32,
0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32,
0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32,
0x00, 0x32, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33,
0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33,
0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33,
0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33,
0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33,
0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33,
0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x35,
0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35,
0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35,
0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35,
0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35,
0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35,
0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x34,
0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34,
0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34,
0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34,
0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34,
0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34,
0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36,
0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36,
0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36,
0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x37,
0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00,
0x38, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00
};
WinSock->OnRecv(buff, sizeof(buff));*/
}
//TextManger txtMangerMain;
void CUIWnd_0::OnBnClickedButton2()
{
int index = lstRole.GetSelectionMark();
if (index > -1) {
CString txtName = lstRole.GetItemText(index, 1);
netUI->DelRole(txtName.GetBuffer());
}
// 根据语言表获取文字
//CString txt = txtManger->ReadTextById("npc_GRZJ_0001");// PGameProc->GetTextName("npc_GRZJ_0001");
//AfxMessageBox(txt);
//txtManger->CreateTextDat("F:\\语言包.txt");
// 读取导出到本地的语言包
//txtMangerMain.LoadTextData("F:\\语言包.txt");
// CString txt = txtMangerMain.ReadTextById("npc_GRZJ_0001");// npc_GRZJ_0001没有哈希冲突
/*
Hui_event_3_1有哈希冲突,通过打印 textDatas 变量的内存地址
去x96db找的(第一个就冲突了,ui_event_3_1是第一个哈希表里的链表的最后一个)
如果第一个没有冲突,那就找一个 next 不是 -1 的,不是-1说明是链表,然后找链表最后一个就可以了
*/
/*CString txt = txtMangerMain.ReadTextById("ui_event_3_1");
AfxMessageBox(txt);
txt = txtMangerMain.ReadTextById("desc_Item_A550001_01_2");
AfxMessageBox(txt);*/
// 瞬移
//float decX = 3843.776123f;
//float decH = 11.731983f;
//float decY = -2005.533813f;
//float face = 0.0f;
//Client->Teleport(decX, decH, decY, face);
//PAIM aim = Client->GetAimByName(L"r");
//if (aim == nullptr) {
//return;
//}
//Client->Teleport(aim->x, aim->h, aim->y, aim->face);
// 修正坐标
/*PAIM aim = Client->GetAimByName(L"r");
if (aim == nullptr) {
return;
}
Client->SetCoord(Client->Player.lId, aim->x, aim->h, aim->y, aim->face);*/
// 面向
// Client->FaceTo(L"r");
// 飞天
// Client->HideMode = true;
// 遁地
//Client->MoveStop(Client->Player.x, Client->Player.h - 5, Client->Player.y, 0.0f);
// 跟随
// ::SetTimer(m_hWnd, 0x1000, 2000, loops);
//
// Client->Backtoroles();
}
// 进入游戏按钮点击事件处理函数
void CUIWnd_0::OnBnClickedButton3()
{
int index = lstRole.GetSelectionMark();
if (index > -1) {
CString txtName = lstRole.GetItemText(index, 1);
netUI->SelectRole(txtName.GetBuffer());
}
}
CUI.cpp文件的修改:修改了 loginok函数,新加 ReadValue函数
// CUI.cpp: 实现文件
//
#include "pch.h"
#include "htdMfcDll.h"
#include "CUI.h"
#include "afxdialogex.h"
#include "extern_all.h"
// CUI 对话框
IMPLEMENT_DYNAMIC(CUI, CDialogEx)
CUI::CUI(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_MAIN, pParent)
{
}
CUI::~CUI()
{
}
void CUI::SetListView(CListCtrl* lst)
{
auto lStyle = GetWindowLongPtr(lst->m_hWnd, GWL_STYLE); // 获取窗口样式
lStyle |= LVS_REPORT; // 设置为报表模式
SetWindowLongPtr(lst->m_hWnd, GWL_STYLE, lStyle);// 给窗口设置样式
auto dStyle = lst->GetExtendedStyle(); // 获取扩展样式
dStyle |= LVS_EX_FULLROWSELECT; // 设置选择时选择一行
dStyle |= LVS_EX_GRIDLINES; // 画网格线
lst->SetExtendedStyle(dStyle); // 设置扩展样式
}
void CUI::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TAB1, mTab);
DDX_Control(pDX, IDC_LIST1, lstlog);
}
BOOL CUI::OnInitDialog()
{
CDialogEx::OnInitDialog();
SetListView(&lstlog);
InstallPage(new CUIWnd_0(this), IDD_PAGE_0, L"角色", TRUE);
InstallPage(new CUIWnd_1(this), IDD_PAGE_1, L"信息");
lstlog.InsertColumn(0, L"消息", 0, 70);
lstlog.InsertColumn(1, L"内容", 0, 700);
lstlog.InsertColumn(2, L"时间", 0, 200);
//PageINJ.Init(wAppPath);
//PageRAN.SetAppPath(wAppPath);
return TRUE;
}
bool CUI::InstallPage(CDialogEx* wnd, int IDD_WND, CString&& _Name, BOOL IsShow)
{
if (CurPage >= (sizeof(WNDS) / sizeof(CDialogEx*))) 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 += 32;
rect.left += 5;
rect.bottom -= 4;
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)
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);
}
}
PTextManger CUI::getTxtManger()
{
if (!txtManger)txtManger = new TextManger("F:\\语言包.txt");
return txtManger;
}
void CUI::loginok(ROLE_DATA* _roles, int count)
{
PushLog(LOGTYPE::SYS, L"账号登录成功");
NetClient::loginok(_roles, count);
wnds.wndRole->lstRole.DeleteAllItems();
CString txtInfos;
for (int i = 0; i < count; i++)
{
txtInfos = _roles[i].infos.value();
txtInfos = txtInfos + L";";
CString txtIndex, txtSex, txtMap, txtJob, txtCamp, txtRace, txtLv;
CStringA stxtMap, stxtJob, stxtCamp, stxtRace;
txtSex = ReadValue(txtInfos, L"1,", L";");
txtMap = ReadValue(txtInfos, L"56,", L";");
txtJob = L"job_" + ReadValue(txtInfos, L"37,", L";");
txtCamp = L"camp_" + ReadValue(txtInfos, L"35,", L";");
txtRace = L"race_" + ReadValue(txtInfos, L"36,", L";");
txtLv = ReadValue(txtInfos, L"38,", L";");
txtIndex.Format(L"%d", _roles[i].index.value());
stxtMap = txtMap;
stxtJob = txtJob;
stxtCamp = txtCamp;
stxtRace = txtRace;
txtSex = SexName[txtSex == L"1"];
wnds.wndRole->lstRole.InsertItem(0, txtIndex);
wnds.wndRole->lstRole.SetItemText(0, 1, _roles[i].name);
wnds.wndRole->lstRole.SetItemText(0, 2, txtLv);
wnds.wndRole->lstRole.SetItemText(0, 3, txtSex);
wnds.wndRole->lstRole.SetItemText(0, 4, getTxtManger()->ReadTextById(stxtCamp.GetBuffer()));
wnds.wndRole->lstRole.SetItemText(0, 5, getTxtManger()->ReadTextById(stxtMap.GetBuffer()));
wnds.wndRole->lstRole.SetItemText(0, 6, getTxtManger()->ReadTextById(stxtRace.GetBuffer()));
wnds.wndRole->lstRole.SetItemText(0, 7, getTxtManger()->ReadTextById(stxtJob.GetBuffer()));
}
}
bool CUI::Tips(int code)
{
CString logName;
logName.Format(L"服务器提示:%d", code);
PushLog(LOGTYPE::TIPS, logName.GetBuffer());
// NetClient::Tips(code);
return true;
}
CString CUI::ReadValue(CString& txt, wchar_t* key, wchar_t* endStr)
{
CString result = L"";
int iStart = txt.Find(key);
if (iStart > -1) {
iStart = iStart + wcslen(key);
int iend = txt.Find(endStr, iStart);
if (iend > -1)result = txt.Mid(iStart, iend - iStart);
}
return result;
}
void CUI::PushLog(LOGTYPE type, wchar_t* txt)
{
struct tm newtiem {};
time_t t;
time(&t);
localtime_s(&newtiem, &t); // 获取时间
CString logName;
logName.Format(L"%.4d-%.2d-%.2d %.2d:%.2d:%.2d", newtiem.tm_year + 1900, newtiem.tm_mon + 1, newtiem.tm_mday, newtiem.tm_hour, newtiem.tm_min, newtiem.tm_sec);
lstlog.InsertItem(0, MsgName[(int)type]);
lstlog.SetItemText(0, 1, txt);
lstlog.SetItemText(0, 2, logName);
}
CUI.h文件的修改:修改了 LOGTYPE枚举类型、MsgName数组,新加 SexName变量、ReadValue函数
#pragma once
#include "afxdialogex.h"
#include "NetClient.h"
#include "TextManger.h"
//增加页面头文件
#include "CUIWnd_0.h"
#include "CUIWnd_1.h"
//游戏辅助UI类
// CUI 对话框
enum class LOGTYPE {
TIPS = 0,
SYS = 1,
MAX
};
typedef struct WNDS {
CUIWnd_0* wndRole;
CUIWnd_1* wndInfo;
};
// #define MAX_PAGE_MAIN 3
// 这里用了多重继承,这回有一个问题,函数名一样的会发生冲突
// 所以在继承的时候要注意函数名
class CUI : public CDialogEx,public NetClient
{
DECLARE_DYNAMIC(CUI)
public:
CUI(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CUI();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MAIN };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
union {
CDialogEx* Pages[sizeof(WNDS)/sizeof(CDialogEx*)];
WNDS wnds;
};
short CurPage = 0;
public:
CTabCtrl mTab;
virtual BOOL OnInitDialog();
bool InstallPage(CDialogEx* wnd, int IDD_WND, CString&& _Name, BOOL IsShow=FALSE);
afx_msg void OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult);
public:
void SetListView(CListCtrl* lst);
PTextManger getTxtManger();
CListCtrl lstlog;
protected:
CString MsgName[(unsigned int)LOGTYPE::MAX]{
L"错误",
L"系统"
};
CString SexName[2]{
L"男",
L"女"
};
void PushLog(LOGTYPE type, wchar_t* txt);
protected:
void virtual loginok(ROLE_DATA* _roles, int count);
bool virtual Tips(int code);
// 解析角色的信息,性别、种族、阵营等
CString ReadValue(CString&txt, wchar_t* key, wchar_t* endStr);
};
原文地址:https://blog.csdn.net/qq_36301061/article/details/139276917
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!