赞
踩
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
如果看不懂、不知道现在做的什么,那就跟着做完看效果
内容参考于:易道云信息技术研究院VIP课
上一个内容:46.设计通用的解码处理过程
码云地址(master 分支):https://gitee.com/dye_your_fingers/titan
码云版本号:e7b59fe6a41bb2cf79502a3b4802af86536d2f89
代码下载地址,在 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的分享
以 46.设计通用的解码处理过程 它的代码为基础进行修改
在游戏里面发现发送的数据很多都是0A开头的,也比较有规律(详情看44.角色创建服务器反馈数据包分析),里面有数据参数个数和数据参数,现在读取已经是没问题了,然后接下来肯定要有模拟发送的操作,所以现在就是设计数据模拟发送通用的方案,不能每个数据包都去分别实现一遍,这样不专业,代码写起来工程量很大也麻烦,所以要设计一个比较好的综合性的通用的方案。
效果图:
通过点击 Button1按钮,在角色选择界面,非创建角色界面,发送选择阵营数据包
![]()
CUIWnd_0.cpp文件的修改:修改了 OnBnClickedButton1函数,OnBnClickedButton1函数是Button1按钮点击事件处理函数
- // CUIWnd_0.cpp: 实现文件
- //
-
- #include "pch.h"
- #include "htdMfcDll.h"
- #include "CUIWnd_0.h"
- #include "afxdialogex.h"
- #include "extern_all.h"
-
- // CUIWnd_0 对话框
-
- IMPLEMENT_DYNAMIC(CUIWnd_0, CDialogEx)
-
- CUIWnd_0::CUIWnd_0(CWnd* pParent /*=nullptr*/)
- : CDialogEx(IDD_PAGE_0, pParent)
- {
-
- }
-
- CUIWnd_0::~CUIWnd_0()
- {
- }
-
- void CUIWnd_0::DoDataExchange(CDataExchange* pDX)
- {
- CDialogEx::DoDataExchange(pDX);
- }
-
-
- BEGIN_MESSAGE_MAP(CUIWnd_0, CDialogEx)
- ON_BN_CLICKED(IDC_BUTTON1, &CUIWnd_0::OnBnClickedButton1)
- END_MESSAGE_MAP()
-
-
- // CUIWnd_0 消息处理程序
-
-
- void CUIWnd_0::OnBnClickedButton1()
- {
- 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));*/
- }
NetClient.cpp文件的修改:修改了 SelectCamp函数、Tips函数
- #include "pch.h"
- #include "NetClient.h"
- #include "extern_all.h"
-
- bool NetClient::login(const char* Id, const char* Pass)
- {
-
- const int bufflen = sizeof(DATA_LOGIN) + 1;
- char buff[bufflen];
- DATA_LOGIN data;
- // 有些操作系统这样写会报错,因为内存不对齐,现在Windows下没事
- //PDATALOGIN _data = (PDATALOGIN)(buff + 1);
- // 这样写就能解决内存对齐问题
- PDATALOGIN _data =&data;
- int len = strlen(Id);
- memcpy(_data->Id, Id, len);
- len = strlen(Pass);
- memcpy(_data->Pass, Pass, len);
- memcpy(buff+1, _data, sizeof(DATA_LOGIN));
- buff[0] = I_LOGIN;
- return WinSock->OnSend(buff, sizeof(buff));
-
- }
-
- bool NetClient::DelRole(wchar_t* rolename)
- {
- PROLEDATA _role = GetRoleByName(rolename);
- if (_role == nullptr) {
- return false;
- }
- else {
- return DelRole(rolename, _role->name.lenth);
- }
- return false;
- }
-
- bool NetClient::StartCreateRole()
- {
- NET_CREATEROLE_START _data;
- return WinSock->OnSend(&_data.op, _data.len);
- }
-
- bool NetClient::SelectCamp(const char* _campname)
- {
- NET_SEND_BUFF _buff;
- NET_SEND_CHOOSECAMP _data;
- _data.opcode.Set(SC_CHOOSECAMP);
- _data.camps.Set(_campname);
- /*
- sizeof(_data) / sizeof(EnCode)的原因
- NET_SEND_CHOOSECAMP结构体里面,没别 东西
- 全是 EnCode 这个结构
- */
- short count = sizeof(_data) / sizeof(EnCode);
- _buff.count = count;
-
- /*
- CodeMe函数给 _buff.buff里写数据参数的数据
- 也就是给0A开头数据包里写,数据参数个数后面的内容
- 然后返回值是写了多长的数据
- 也就是给0A开头数据包里的数据参数个数后面的数据写了多长
- */
- int ilen = _data.CodeMe(count, _buff.buff);
- ilen = ilen + sizeof(NET_SEND_HEAD) - 1;
- return WinSock->OnSend(&_buff.op, ilen);
- }
-
- PROLEDATA NetClient::GetRoleByName(wchar_t* rolename)
- {
- //PROLEDATA result = nullptr;
- for (int i = 0; i < rolecount; i++)
- {
- // StrCmpW判断两个字符串是否相同
- // 比较时区分大小写,如果字符串相同返回0
- if (StrCmpW(roles[i].name.value(), rolename) == 0) {
- return &roles[i];
- }
-
- }
- return nullptr;
- }
-
- bool NetClient::DelRole(wchar_t* rolename, unsigned _len)
- {
- DATA_DELROLE _data;
- _data.op = 0x06;
- _data.len = _len;
- memcpy(_data.buff, rolename, _len);
- return WinSock->OnSend((char*)&_data, sizeof(DATA_DELROLE) - 1);
- }
-
- bool NetClient::OnDelRole(wchar_t* rolename, unsigned _len)
- {
- AfxMessageBox(rolename);
- return true;
- }
-
- void NetClient::Onlogin(const char* Id, const char* Pass)
- {
-
- /*
- const int bufflen = sizeof(DATA_LOGIN) + 1;
- char buff[bufflen];
- DATA_LOGIN data;
- // 有些操作系统这样写会报错,因为内存不对齐,现在Windows下没事
- //PDATALOGIN _data = (PDATALOGIN)(buff + 1);
- // 这样写就能解决内存对齐问题
- PDATALOGIN _data =&data;
- int len = strlen(Id);
- memcpy(_data->Id, Id, len);
- len = strlen(Pass);
- memcpy(_data->Pass, Pass, len);
- memcpy(buff+1, _data, sizeof(DATA_LOGIN));
- buff[0] = I_LOGIN;
- return WinSock->OnSend(buff, sizeof(buff));
- */
- }
-
- bool NetClient::OnStartCreateRole(int code)
- {
- return true;
- }
-
- bool NetClient::OnSendCustom(PNET_SEND_CHEAD _coder, char*& buffer, unsigned& len)
- {
- switch (_coder->opcode.value())
- {
- case SC_CHOOSECAMP:
- return OnChooseCamp((PNS_CHOOSECAMP)_coder);
- break;
- default:
- break;
- }
- return true;
- }
-
- bool NetClient::OnChooseCamp(PNS_CHOOSECAMP _coder)
- {
- PNS_CHOOSECAMP _p = (PNS_CHOOSECAMP)_coder;
- MessageBoxA(0, _p->camps, _p->camps, MB_OK);
-
- return true;
- }
-
- bool NetClient::Tips(int code)
- {
- #ifdef Anly
- CString txt;
- if (code == 51001) {
- txt = L"登陆失败,易道云通行证不存在!";
- }else if (code == 51002) {
- txt = L"登录失败,密码错误!";
- }
- else {
- txt.Format(L"未知登录错误:%d", code);
- }
-
-
- anly->SendData(TTYPE::I_LOG, 0, txt.GetBuffer(), (txt.GetLength() + 1)*2);
- #endif
- return true;
- }
-
- void NetClient::loginok(ROLE_DATA* _roles, int count)
- {
- logined = true;
- if(roles) delete[] roles;
- roles = _roles;
- rolecount = count;
- }
-
- bool NetClient::OnScrStartCreateRole(short code, wchar_t* _txt)
- {
- return true;
- }
-
NetClient.h文件的修改:新加 CAMP_NAME_QH宏、CAMP_NAME_ZE宏
- #pragma once
- #include "NetClass.h"
- #define CAMP_NAME_QH "xuanrenQH"
- #define CAMP_NAME_ZE "xuanrenZQ"
- class NetClient // 监视客户端每一个操作
- {
- private:
- PROLEDATA roles;
- unsigned rolecount;
- bool logined = false;
-
- bool DelRole(wchar_t* rolename, unsigned _len);
- public:
- /*
- 模拟登陆的方法
- Id是账号
- Pass是密码
- 它要基于发送的方法实现,因为我们没有连接socket的操作
- */
- bool login(const char* Id, const char* Pass);
- bool DelRole(wchar_t* rolename);
- bool StartCreateRole();// 用于创建角色
- bool SelectCamp(const char* _campname);// 选择阵营
-
- // 根据角色名字获取一个登录成功数据包(选择角色列表里的一个数据)
- PROLEDATA GetRoleByName(wchar_t* rolename);
- public:
- // 用于拦截游戏删除角色功能
- bool virtual OnDelRole(wchar_t* rolename, unsigned _len);
- // 用于拦截游戏登录功能
- void virtual Onlogin(const char* Id, const char*Pass);
- // 用于拦截游戏创建角色功能
- bool virtual OnStartCreateRole(int code);
- // opcode意思是操作码,count意思是数量,buffStart意思是解码的内容开始,buffend意思是解码的内容结束,buffer是原始的数据,len是原始数据的长度
- // char& buffer, int& len这俩参数带&的原因是,在 OnSendCustom 里进行修改之后,通过&的方式传递回去
- bool virtual OnSendCustom(PNET_SEND_CHEAD _coder, char*& buffer, unsigned& len);
- public:
- bool virtual OnChooseCamp(PNS_CHOOSECAMP _coder);
- public:
- // 处理失败,参数是错误码
- bool virtual Tips(int code);
- void virtual loginok(ROLE_DATA* _roles, int count);
- bool virtual OnScrStartCreateRole(short code,wchar_t* _txt);
- };
-
-
NetClass.cpp文件的修改:修改了 CodeMe函数
- #include "pch.h"
- #include "NetClass.h"
- #include "extern_all.h"
-
- unsigned NET_SEND_CHEAD::CodeMe(int size, char* buffer)
- {
- EnCode* _coders = (EnCode*)this;
- unsigned iResult = 0;
- unsigned ilenth;
- for (int i = 0; i < size; i++)
- {
- ilenth = data_desc[_coders[i].index][_coders[i].op].lenth + 1;
- memcpy(buffer + iResult, &_coders[i].op, ilenth);
- iResult += ilenth;
- if ((_coders[i].op == 0x07)||((_coders[i].op == 0x06) && ((_coders[i].index == 1)))) {
- ilenth = _coders[i].lenth;
- memcpy(buffer + iResult, _coders[i].pointer, ilenth);
- iResult += ilenth;
- }
- }
- return iResult;
- }
-
NetClass.h文件的修改:新加 NET_SEND_BUFF结构体,修改了 NET_SEND_CHEAD结构体
- #pragma once
- #include "EnCode.h"
- /*
- 最多的数据项, 0A开头的数据包里有数据参数个数,这个宏就是用来设定
- 数据参数个数最大数量是多少,0A开头的数据包目前见过最大
- 数据参数个数是十几个,这里写20应该完全够用,如果不够用
- 到时候再增加
- */
- #define MAX_SEND_COUNT 20
- // 发送数据操作码定义
- #define SC_CHOOSECAMP 591 // 阵营选择操作码
- // 发送数据标准头
- typedef struct NET_SEND_HEAD {
- // 为了内存对齐,当前结构不可能超过255,所以这样写是没问题的
- char len = sizeof(NET_SEND_HEAD) - 1;
- char op = 0x0A;
- short unst = 0;
- int unnt[4]{};
- short unst1 = 0;
- short count = 0;
- }*PNET_SEND_HEAD;
-
- // 发送数据包含内存空间,也就是数据参数,数据参数的意思看44文章里的内容
- typedef struct NET_SEND_BUFF:public NET_SEND_HEAD {
- char buff[0x1000]{};
- }*PNET_SEND_BUFF;
-
- typedef class NET_SEND_CHEAD {
- public:
- GINT opcode;
- // 实现编码操作,模拟游戏数据包给服务端发送数据,这个模拟的数据包通过调用 CodeMe函数得到
- unsigned CodeMe(int size, char* buffer);
- }*PNET_SEND_CHEAD;
-
- typedef class NET_SEND_CHOOSECAMP :public NET_SEND_CHEAD {
- public:
- GCHAR camps;
- }*PNS_CHOOSECAMP;
-
- // 申请创建角色结构体
- typedef struct NET_CREATEROLE_START {
- char un[0x02];// 用来做内存对齐
- char len = sizeof(NET_CREATEROLE_START) - 3;// 用来做内存对齐
- char op = 0x03;
- int code = 0x01;
- }*PNET_CREATEROLE_START;
-
- // 删除角色数据结构
- typedef struct DATA_DELROLE {
- char op;
- char buff[0x1F];
- int len;
- int un[8] = { 0x01 , 0x03};
-
- }*PDATADELROLE;
-
- /*
- 数据包还原结构体要注意内存对齐,如果数据不满4字节,它字段会补齐
- 比如结构体里有一个char变量,它是1字节,在内存里它可能会为了内存对齐
- 让它变成4字节,所以这要注意
- */
- // 登录数据
- typedef struct DATA_LOGIN {
- int op = 0x0300;
- char buff[0x10]{};
- int lenId = 0x10;
- /*
- 这个是登录的账号,它可能会变成0x20或更长,现在默认让它0x10
- 读的时候以长度为准就好了
- */
- char Id[0x10]{};
- int lenPass = 0x10;
- /*
- 这个是登录的密码,它可能会变成0x20或更长,现在默认让它0x10
- 读的时候以长度为准就好了
- */
- char Pass[0x10]{};
- int lenCode = 0x10;
- char Code[0x10]{};
- int eop = 0x01;
- }*PDATALOGIN;
- typedef struct DATA_LOGIN_OK {// 登录成功数据包头
- int un[8] = { 0, 0, 0x76B, 0x0C, 0x1E,0, 0, 0 };
- int index = 0;
- int RoleCount = 0;
- }*PDATALOGINOK;
- typedef class ROLE_DATA {// 登录成功数据包
- public:
- GBYTE byte;
- GINT un;
- GINT un1;
- GUTF16 name;
- GUTF16 infos;
- GINT un2;
- GINT64 un3;
- }*PROLEDATA;
-
EnCode.cpp文件的修改:新加 AllocPointer函数,新加多个 Set函数,修改了 Init函数
- #include "pch.h"
- #include "EnCode.h"
- #include "extern_all.h"
-
-
-
- void EnCode::Init(char*& buff, char EnIndex)
- {
- index = EnIndex;
- op = buff[0];
- int len = data_desc[index][op].lenth;
- /*
- 比如 07 0A 00 00 00 34 00 33 00 39 00 39 00 00 00
- buff + 1 的结果是 0A 00 00 00 34 00 33 00 39 00 39 00 00 00
- len是 07 所代表的类型的长度,也就是0A 00 00 00 这个东西
- memcpy(dataPool, buff + 1, len);也就是把 0A 00 00 00 复制到 dataPool里
- 然后从下方的if ((op == 0x7))得到它的字符串
- */
- memcpy(dataPool, buff + 1, len);
- buff = buff + 1 + len;// 下一个结构
-
- if (index == 0) {
- if ((op == 0x7)) {
- AllocPointer(lenth);
- // if (pointer)delete[]pointer;
- /*
- dataPool 与 lenth是一个联合体,联合体的特性就是
- 所有变量共用一个内存,所以 dataPool 的值就是lenth的值
- 从上方的注释得知现在dataPool的值是0A 00 00 00
- 然后通过 lenth去读 0A 00 00 00结果就是十进制的 10
- 然后创建一个10字节的空间给pointer
- 然后在通过 memcpy(pointer, buff, lenth); 把字符串赋值给pointer
- */
- // pointer = new char[lenth];
- memcpy(pointer, buff, lenth);
- buff = buff + lenth;// 指向下一个字符串
- }
- }
-
- if (index == 1) {
- if ((op == 0x06) || (op == 0x7)) {
- AllocPointer(lenth);
- memcpy(pointer, buff, lenth);
- buff = buff + lenth;
- }
- }
- }
- /*
- buff是数据包
- _len暂时没用
- ExIndex是解析方式,因为分析的时候发现6有时是char类型有时是char*类型
- 看懂此方法需要分析手动分析一次数据包(数据解析约定的数据包)
- 然后带着数据包去看这个函数
- */
- EnCode::EnCode(char*& buff,char EnIndex)
- {
- Init(buff,EnIndex);
- }
-
- EnCode::~EnCode()
- {
- if(pointer)
- delete[] pointer;
- }
-
- void EnCode::AllocPointer(int size)
- {
- if (size > AllocCount) {
- if (pointer) delete[]pointer;
- pointer = new char[size];
- AllocCount = size;
- }
- }
-
- EnCode::EnCode()
- {
- }
-
- EnCode& EnCode::operator=(char*& buff)
- {
- Init(buff);
- return *this;
- }
-
- GBYTE::operator char()
- {
- return this->byte;
- }
-
- char GBYTE::value()
- {
- return this->byte;
- }
-
- GSHORT::operator short()
- {
- return this->stval;
- }
-
- short GSHORT::value()
- {
- return this->stval;
- }
-
- GINT::operator int()
- {
- return this->val;
- }
-
- int GINT::value()
- {
- return this->val;
- }
-
- /*
- GINT::Set函数得到的数据是
- 02 03 00 00 00
- 02是数据类型,表示int类型
- 03 00 00 00 int类型的值
- */
- void GINT::Set(int _invalue, char EnIndex)
- {
- index = EnIndex;// 处理类型
- op = 2; // 数据解析约定的数据02表示int
- val = _invalue; // 数据
- }
-
- GFLOAT::operator float()
- {
- return this->fval;
- }
-
- float GFLOAT::value()
- {
- return this->fval;
- }
-
- void GFLOAT::Set(float invalue, char EnIndex)
- {
- index = EnIndex;
- op = 0x04 ;
- fval = invalue;
- }
-
- GINT64::operator long long()
- {
- return this->lval;
- }
-
- long long GINT64::value()
- {
- return this->lval;
- }
-
- void GINT64::Set(long long invalue, char EnIndex)
- {
- index = EnIndex;
- op = 0x03;
- lval = invalue;
- }
-
-
- GDOUBLE::operator double()
- {
- return this->dbval;
- }
-
- double GDOUBLE::value()
- {
- return this->dbval;
- }
-
- void GDOUBLE::Set(double invalue, char EnIndex)
- {
- index = EnIndex;
- op = 0x05;
- dbval = invalue;
- }
-
-
- GCHAR::operator const char*()
- {
- return this->pointer;
- }
-
- const char* GCHAR::value()
- {
- return this->pointer;
- }
-
- /*
- GCHAR::Set函数得到的数据是
- 06 03 00 00 00 77 65 72 00
- 06是数据类型,表示char*类型
- 03 00 00 00 表示字符串长度
- 77 65 72 00 是字符串
- */
- void GCHAR::Set(const char* _txt, char EnIndex)
- {
- index = EnIndex;
- op = 6;
- lenth = strlen(_txt) + 1;
- AllocPointer(lenth);
- memcpy(pointer, _txt, lenth);
- }
-
- GUTF16::operator const wchar_t*()
- {
- return (wchar_t*)this->pointer;
- }
-
- const wchar_t* GUTF16::value()
- {
- return (wchar_t*)this->pointer;
- }
-
- /*
- GUTF16::Set函数得到的数据是
- 07 03 00 00 00 77 00 65 00 72 00
- 07是数据类型,表示wchar_t*类型
- 03 00 00 00 表示字符串长度
- 77 00 65 00 72 00 是字符串
- */
- void GUTF16::Set(const wchar_t* _txt, char EnIndex)
- {
- index = EnIndex;
- op = 7;
- lenth = wcslen(_txt) + 1;
- AllocPointer(lenth);
- memcpy(pointer, _txt, lenth);
- }
-
-
EnCode.h文件的修改:修改了 EnCode类,其它类新加 Set函数
- #pragma once
-
- /*
- EnCode结构体
- un[6]、index、op是8字节
- union里也是8字节
- pointer、back它俩虽然是char类型,但它俩是指针类型,所以它们一共是8字节
- EnCode结构体一共是24字节
- */
- class EnCode// 用于表示数据解析约定的数据
- {
- private:
-
- char un[6]{};//
- public:
- char index = 0;
- // op + un[3]是四字节,op与buffer是6字节,如果自动内存对齐op与buffer可能不会挨在一起
- char op = 0;
-
- /*
- 这个位置会导致编译器代码生成出现问题
- 就是在当前文件一个类里写一个新的函数声明
- 这个时候会因为下方的 union 导致编译器无法
- 通过函数声明在cpp实现函数,这是因为编译器
- 不知道下方的 union 是什么东西导致的
- */
- union
- {
- char dataPool[0x8];
- int lenth;
- char byte;
- short stval;
- int val;
- float fval;
- double dbval;
- long long lval = 0;
- };
- char* pointer = 0;
- int AllocCount = 0;// 记录内存大小
- protected:
- void AllocPointer(int size);
- public:
- EnCode();
- EnCode(char*& buff, char ExIndex = 1);
- EnCode& operator=(char*& buff);
- void Init(char*& buff, char EnIndex = 1);
- ~EnCode();
- };
-
- class GBYTE :public EnCode {
- public:
- using EnCode::EnCode;
- using EnCode::operator=;
- public:
- operator char();
- char value();
- };
- class GSHORT :public EnCode {
- public:
- using EnCode::EnCode;
- using EnCode::operator=;
- public:
- operator short();
- short value();
- };
- class GINT :public EnCode {
- public:
- using EnCode::EnCode;
- using EnCode::operator=;
- public:
- operator int();
- int value();
- void Set(int _invalue, char EnIndex = 1);
- };
- class GFLOAT :public EnCode {
- public:
- using EnCode::EnCode;
- using EnCode::operator=;
- operator float();
- float value();
- void Set(float invalue, char EnIndex = 1);
- };
- class GINT64 :public EnCode {
- public:
- using EnCode::EnCode;
- using EnCode::operator=;
- operator long long();
- long long value();
- void Set(long long invalue, char EnIndex = 1);
- };
- class GDOUBLE :public EnCode {
- public:
- using EnCode::EnCode;
- using EnCode::operator=;
- operator double();
- double value();
- void Set(double invalue, char EnIndex = 1);
- };
- class GCHAR :public EnCode {
- public:
- using EnCode::EnCode;
- using EnCode::operator=;
- operator const char*();
- const char* value();
- void Set(const char* _txt, char EnIndex = 1);
- };
- class GUTF16 :public EnCode {
- public:
- using EnCode::EnCode;
- using EnCode::operator=;
- operator const wchar_t*();
- const wchar_t* value();
- void Set(const wchar_t* _txt, char EnIndex = 1);
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。