From a698e0a9f4d1e64f724a4ef703da0ddb75ba0d49 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 22 Aug 2025 10:41:52 +0800 Subject: [PATCH 01/22] fixed:http verification status incorrect --- .../XEngine_AuthorizeService/Authorize_HttpTask.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp index 0f47080..77c2beb 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp @@ -89,6 +89,7 @@ bool XEngine_Client_HttpTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int st_HDRParam.nHttpCode = 401; st_HDRParam.bIsClose = true; + st_HDRParam.bAuth = true; //打包验证信息 int nHDRLen = 0; XCHAR tszHDRBuffer[XPATH_MAX] = {}; @@ -128,6 +129,7 @@ bool XEngine_Client_HttpTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int XCHAR* ptszMSGBuffer = NULL; if (!APIClient_Http_Request(_X("GET"), st_AuthConfig.st_XApiVer.tszAPIUrl, NULL, &nHTTPCode, &ptszMSGBuffer, &nMSGLen, NULL, NULL, &st_APIHttp)) { + st_HDRParam.nHttpCode = 500; Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, ERROR_AUTHORIZE_PROTOCOL_UNAUTHORIZE, "api server is down,cant verification"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,GET请求验证服务:%s 失败,错误码:%lX"), lpszClientAddr, st_AuthConfig.st_XApiVer.tszAPIUrl, APIClient_GetLastError()); @@ -135,6 +137,7 @@ bool XEngine_Client_HttpTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int } if (200 != nHTTPCode) { + st_HDRParam.nHttpCode = 500; Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, ERROR_AUTHORIZE_PROTOCOL_UNAUTHORIZE, "api server is down,cant verification"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,GET请求验证服务:%s 失败,错误:%d"), lpszClientAddr, st_AuthConfig.st_XApiVer.tszAPIUrl, nHTTPCode); @@ -143,6 +146,7 @@ bool XEngine_Client_HttpTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int AUTHORIZE_PROTOCOL_USERAUTHEX st_UserAuth = {}; if (!Protocol_Parse_HttpParseAuth(ptszMSGBuffer, nMsgLen, &st_UserAuth)) { + st_HDRParam.nHttpCode = 500; Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, ERROR_AUTHORIZE_PROTOCOL_UNAUTHORIZE, "api server reply failure,cant verification"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,返回内容:%s 错误,无法继续"), lpszClientAddr, ptszMSGBuffer); From a4b72638fdf828b7d99b6480d2be693a20947b6f Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 29 Aug 2025 11:02:11 +0800 Subject: [PATCH 02/22] fixed:sometimes memory leak when read configure --- .../ModuleConfigure_Json/ModuleConfigure_Json.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp b/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp index 49a8b12..fe9a25d 100644 --- a/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp +++ b/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp @@ -332,21 +332,12 @@ bool CModuleConfigure_Json::ModuleConfigure_Json_Switch(LPCXSTR lpszConfigFile, Config_dwErrorCode = ERROR_AUTHORIZE_MODULE_CONFIGURE_OPENFILE; return false; } - size_t nCount = 0; - XCHAR tszMsgBuffer[4096]; - while (1) - { - size_t nRet = fread(tszMsgBuffer + nCount, 1, 2048, pSt_File); - if (nRet <= 0) - { - break; - } - nCount += nRet; - } + XCHAR tszMsgBuffer[8192] = {}; + size_t nRet = fread(tszMsgBuffer, 1, sizeof(tszMsgBuffer), pSt_File); fclose(pSt_File); //开始解析配置文件 std::unique_ptr const pSt_JsonReader(st_JsonBuilder.newCharReader()); - if (!pSt_JsonReader->parse(tszMsgBuffer, tszMsgBuffer + nCount, &st_JsonRoot, &st_JsonError)) + if (!pSt_JsonReader->parse(tszMsgBuffer, tszMsgBuffer + nRet, &st_JsonRoot, &st_JsonError)) { Config_IsErrorOccur = true; Config_dwErrorCode = ERROR_AUTHORIZE_MODULE_CONFIGURE_PARSE; From 811b1bae14744afcfd89df8dc927caa01a4ba027 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 13 Oct 2025 14:47:58 +0800 Subject: [PATCH 03/22] delete:client module --- .../AuthClient_Connector.cpp | 361 ------------------ .../AuthClient_Connector.h | 42 -- .../AuthClient_Define.h | 175 --------- .../AuthorizeModule_Client/AuthClient_Error.h | 30 -- .../AuthClient_HTTPVer/AuthClient_HTTPVer.cpp | 216 ----------- .../AuthClient_HTTPVer/AuthClient_HTTPVer.h | 24 -- .../AuthorizeModule_Client.def | 13 - .../AuthorizeModule_Client.vcxproj | 277 -------------- .../AuthorizeModule_Client.vcxproj.filters | 68 ---- .../AuthorizeModule_Client.vcxproj.user | 4 - .../AuthorizeModule_Client/Makefile | 69 ---- .../AuthorizeModule_Client/dllmain.cpp | 19 - .../AuthorizeModule_Client/framework.h | 5 - XEngine_Source/AuthorizeModule_Client/pch.cpp | 64 ---- XEngine_Source/AuthorizeModule_Client/pch.h | 81 ---- XEngine_Source/XAuth_BuildSwitch.h | 18 - 16 files changed, 1466 deletions(-) delete mode 100644 XEngine_Source/AuthorizeModule_Client/AuthClient_Connector/AuthClient_Connector.cpp delete mode 100644 XEngine_Source/AuthorizeModule_Client/AuthClient_Connector/AuthClient_Connector.h delete mode 100644 XEngine_Source/AuthorizeModule_Client/AuthClient_Define.h delete mode 100644 XEngine_Source/AuthorizeModule_Client/AuthClient_Error.h delete mode 100644 XEngine_Source/AuthorizeModule_Client/AuthClient_HTTPVer/AuthClient_HTTPVer.cpp delete mode 100644 XEngine_Source/AuthorizeModule_Client/AuthClient_HTTPVer/AuthClient_HTTPVer.h delete mode 100644 XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.def delete mode 100644 XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj delete mode 100644 XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj.filters delete mode 100644 XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj.user delete mode 100644 XEngine_Source/AuthorizeModule_Client/Makefile delete mode 100644 XEngine_Source/AuthorizeModule_Client/dllmain.cpp delete mode 100644 XEngine_Source/AuthorizeModule_Client/framework.h delete mode 100644 XEngine_Source/AuthorizeModule_Client/pch.cpp delete mode 100644 XEngine_Source/AuthorizeModule_Client/pch.h delete mode 100644 XEngine_Source/XAuth_BuildSwitch.h diff --git a/XEngine_Source/AuthorizeModule_Client/AuthClient_Connector/AuthClient_Connector.cpp b/XEngine_Source/AuthorizeModule_Client/AuthClient_Connector/AuthClient_Connector.cpp deleted file mode 100644 index e0e957a..0000000 --- a/XEngine_Source/AuthorizeModule_Client/AuthClient_Connector/AuthClient_Connector.cpp +++ /dev/null @@ -1,361 +0,0 @@ -#include "pch.h" -#include "AuthClient_Connector.h" -/******************************************************************** -// Created: 2023/11/15 10:36:04 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\AuthClient_Connector\AuthClient_Connector.cpp -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\AuthClient_Connector -// File Base: AuthClient_Connector -// File Ext: cpp -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 验证客户端示例模块 -// History: -*********************************************************************/ -CAuthClient_Connector::CAuthClient_Connector() -{ -} -CAuthClient_Connector::~CAuthClient_Connector() -{ -} -////////////////////////////////////////////////////////////////////////// -// 公有函数 -////////////////////////////////////////////////////////////////////////// -/******************************************************************** -函数名称:AuthClient_Connector_Connect -函数功能:链接到服务器 - 参数.一:lpszClientAddr - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:服务器地址 - 参数.二:nPort - In/Out:In - 类型:整数型 - 可空:N - 意思:服务器端口 - 参数.三:lpszPass - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:服务器密码,如果没有填空 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CAuthClient_Connector::AuthClient_Connector_Connect(LPCXSTR lpszClientAddr, int nPort, LPCXSTR lpszPass /* = NULL */) -{ - AuthClient_IsErrorOccur = true; - - if (NULL == lpszClientAddr) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_CLIENT_PARAMENT; - return false; - } -#if (1 == _XAUTH_BUILD_SWITCH_CLIENT_TCP) - if (!XClient_TCPSelect_Create(&m_hSocket, lpszClientAddr, nPort, 2)) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = XClient_GetLastError(); - return false; - } - if (NULL != lpszPass) - { - _tcsxcpy(tszPassStr, lpszPass); - } -#endif - return true; -} -/******************************************************************** -函数名称:AuthClient_Connector_Close -函数功能:销毁关闭客户端 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CAuthClient_Connector::AuthClient_Connector_Close() -{ - AuthClient_IsErrorOccur = false; - -#if (1 == _XAUTH_BUILD_SWITCH_CLIENT_TCP) - if (NULL != pSTDThread) - { - m_bRun = false; - pSTDThread->join(); - } - m_bLogin = false; - m_bAuth = false; - m_bHeart = false; - XClient_TCPSelect_Close(m_hSocket); -#endif - return true; -} -/******************************************************************** -函数名称:AuthClient_Connector_GetAuth -函数功能:验证用户是否登录或者超时 - 参数.一:pbAuth - In/Out:Out - 类型:逻辑型指针 - 可空:Y - 意思:输出是否验证,如果登录成功但是参数为假.说明没有剩余时间了 -返回值 - 类型:逻辑型 - 意思:是否登录,如果没有登录将返回假,登录成功才需要判断是否通过验证 -备注: -*********************************************************************/ -bool CAuthClient_Connector::AuthClient_Connector_GetAuth(bool* pbAuth /* = NULL */) -{ - AuthClient_IsErrorOccur = false; - -#if (1 == _XAUTH_BUILD_SWITCH_CLIENT_TCP) - if (NULL != pbAuth) - { - *pbAuth = m_bAuth; - } -#endif - return m_bLogin; -} -/******************************************************************** -函数名称:AuthClient_Connector_Login -函数功能:登录到服务器 - 参数.一:lpszUser - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入用户名 - 参数.二:lpszPass - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入密码 - 参数.三:lpszHWCode - In/Out:In - 类型:常量字符指针 - 可空:Y - 意思:输入硬件码,如果服务器开启了硬件绑定 - 参数.四:nDYCode - In/Out:In - 类型:整数型 - 可空:Y - 意思:输入动态码 - 参数.五:xhToken - In/Out:In - 类型:句柄型 - 可空:Y - 意思:输入动态码绑定的句柄 - 参数.六:dwCryption - In/Out:In - 类型:整数型 - 可空:Y - 意思:输入密码加密类型 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CAuthClient_Connector::AuthClient_Connector_Login(LPCXSTR lpszUser, LPCXSTR lpszPass, LPCXSTR lpszHWCode /* = NULL */, XSHOT nDYCode /* = 0 */, XNETHANDLE xhToken /* = 0 */, XLONG dwCryption /* = 0 */) -{ - AuthClient_IsErrorOccur = false; - - if ((NULL == lpszUser) || (NULL == lpszPass)) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_CLIENT_PARAMENT; - return false; - } -#if (1 == _XAUTH_BUILD_SWITCH_CLIENT_TCP) - XCHAR tszMsgBuffer[2048] = {}; - XENGINE_PROTOCOLHDR st_ProtocolHdr = {}; - AUTHORIZE_PROTOCOL_USERAUTHEX st_AuthUser = {}; - //协议头 - st_ProtocolHdr.wHeader = XENGIEN_COMMUNICATION_PACKET_PROTOCOL_HEADER; - st_ProtocolHdr.unOperatorType = ENUM_XENGINE_COMMUNICATION_PROTOCOL_TYPE_AUTH; - st_ProtocolHdr.unOperatorCode = XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQLOGIN; - st_ProtocolHdr.unPacketSize = sizeof(AUTHORIZE_PROTOCOL_USERAUTHEX); - st_ProtocolHdr.wTail = XENGIEN_COMMUNICATION_PACKET_PROTOCOL_TAIL; - -#ifdef _MSC_BUILD - st_AuthUser.enDeviceType = ENUM_PROTOCOL_FOR_DEVICE_TYPE_PC_WINDOWS; -#elif __linux__ - st_AuthUser.enDeviceType = ENUM_PROTOCOL_FOR_DEVICE_TYPE_PC_LINUX; -#else - st_AuthUser.enDeviceType = ENUM_PROTOCOL_FOR_DEVICE_TYPE_PC_MACOS; -#endif - _tcsxcpy(st_AuthUser.tszUserName, lpszUser); - if (NULL != lpszHWCode) - { - _tcsxcpy(st_AuthUser.tszHWCode, lpszHWCode); - } - - if (dwCryption > 0) - { - int nPLen = _tcsxlen(lpszPass); - XBYTE byMD5Buffer[XPATH_MAX] = {}; - Cryption_Api_Digest(lpszPass, byMD5Buffer, &nPLen, false, dwCryption); - BaseLib_String_StrToHex((LPCXSTR)byMD5Buffer, nPLen, st_AuthUser.tszUserPass); - } - else - { - _tcsxcpy(st_AuthUser.tszUserPass, lpszPass); - } - //是否有动态码 - if (nDYCode > 0) - { - st_ProtocolHdr.xhToken = xhToken; - _xstprintf(st_AuthUser.tszDCode, _X("%d"), nDYCode); - } - //是否加密 - int nMsgLen = 0; - if (_tcsxlen(tszPassStr) > 0) - { - XCHAR tszCodecBuffer[2048] = {}; - - st_ProtocolHdr.wCrypto = ENUM_XENGINE_PROTOCOLHDR_CRYPTO_TYPE_XCRYPT; - Cryption_XCrypto_Encoder((LPCXSTR)&st_AuthUser, (int*)&st_ProtocolHdr.unPacketSize, (XBYTE*)tszCodecBuffer, tszPassStr); - - memcpy(tszMsgBuffer, &st_ProtocolHdr, sizeof(XENGINE_PROTOCOLHDR)); - memcpy(tszMsgBuffer + sizeof(XENGINE_PROTOCOLHDR), tszCodecBuffer, st_ProtocolHdr.unPacketSize); - - nMsgLen = sizeof(XENGINE_PROTOCOLHDR) + st_ProtocolHdr.unPacketSize; - } - else - { - memcpy(tszMsgBuffer, &st_ProtocolHdr, sizeof(XENGINE_PROTOCOLHDR)); - memcpy(tszMsgBuffer + sizeof(XENGINE_PROTOCOLHDR), &st_AuthUser, st_ProtocolHdr.unPacketSize); - - nMsgLen = sizeof(XENGINE_PROTOCOLHDR) + sizeof(AUTHORIZE_PROTOCOL_USERAUTHEX); - } - //发送数据 - if (!XClient_TCPSelect_SendMsg(m_hSocket, tszMsgBuffer, nMsgLen)) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_CLIENT_SEND; - return false; - } - - nMsgLen = 0; - XCHAR* ptszMsgBuffer; - st_ProtocolHdr = {}; - //接受数据 - if (!XClient_TCPSelect_RecvPkt(m_hSocket, &ptszMsgBuffer, &nMsgLen, &st_ProtocolHdr)) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_CLIENT_RECV; - return false; - } - //判断是否登录协议 - if (XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPLOGIN != st_ProtocolHdr.unOperatorCode) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_CLIENT_LOGIN; - return false; - } - //登录失败,错误码 - if (0 != st_ProtocolHdr.wReserve) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = st_ProtocolHdr.wReserve; - return false; - } - m_bRun = true; - m_bLogin = true; - m_bAuth = true; - //登录成功,创建线程 - pSTDThread = make_shared(AuthClient_Connector_Thread, this); - if (NULL == pSTDThread) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_CLIENT_THREAD; - return false; - } -#endif - return true; -} -/******************************************************************** -函数名称:AuthClient_Connector_Heart -函数功能:启用禁用客户端心跳 - 参数.一:bEnable - In/Out:In - 类型:逻辑型 - 可空:Y - 意思:是启用还是禁用 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CAuthClient_Connector::AuthClient_Connector_Heart(bool bEnable /* = true */) -{ - AuthClient_IsErrorOccur = false; - - if (!m_bAuth) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_CLIENT_NOTAUTH; - return false; - } - m_bHeart = bEnable; - return true; -} -////////////////////////////////////////////////////////////////////////// -// 保护函数 -////////////////////////////////////////////////////////////////////////// -XHTHREAD XCALLBACK CAuthClient_Connector::AuthClient_Connector_Thread(XPVOID lParam) -{ - CAuthClient_Connector* pClass_This = (CAuthClient_Connector*)lParam; - - time_t nTimeStart = time(NULL); - -#if (1 == _XAUTH_BUILD_SWITCH_CLIENT_TCP) - while (pClass_This->m_bRun) - { - int nMsgLen = 0; - XCHAR* ptszMsgBuffer; - XENGINE_PROTOCOLHDR st_ProtocolHdr = {}; - - if (!XClient_TCPSelect_RecvPkt(pClass_This->m_hSocket, &ptszMsgBuffer, &nMsgLen, &st_ProtocolHdr)) - { - pClass_This->m_bRun = false; - pClass_This->m_bLogin = false; - pClass_This->m_bAuth = false; - break; - } - XCHAR tszMsgBuffer[4096] = {}; - if (nMsgLen > 0 && _tcsxlen(pClass_This->tszPassStr) > 0) - { - //只有有后续数据的情况才需要解密 - Cryption_XCrypto_Decoder(ptszMsgBuffer, &nMsgLen, tszMsgBuffer, pClass_This->tszPassStr); - } - else - { - memcpy(tszMsgBuffer, ptszMsgBuffer, nMsgLen); - } - - if (XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_TIMEDOUT == st_ProtocolHdr.unOperatorCode) - { - pClass_This->m_bAuth = false; - } - //心跳支持 - if (pClass_This->m_bHeart) - { - time_t nTimeEnd = time(NULL); - if ((nTimeEnd - nTimeStart) > 2) - { - XENGINE_PROTOCOLHDR st_ProtocolHdr = {}; - st_ProtocolHdr.wHeader = XENGIEN_COMMUNICATION_PACKET_PROTOCOL_HEADER; - st_ProtocolHdr.unOperatorType = ENUM_XENGINE_COMMUNICATION_PROTOCOL_TYPE_HEARTBEAT; - st_ProtocolHdr.unOperatorCode = XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_HB_SYN; - st_ProtocolHdr.byVersion = 1; - st_ProtocolHdr.wTail = XENGIEN_COMMUNICATION_PACKET_PROTOCOL_TAIL; - - nTimeStart = nTimeEnd; - XClient_TCPSelect_SendMsg(pClass_This->m_hSocket, (LPCXSTR)&st_ProtocolHdr, sizeof(XENGINE_PROTOCOLHDR)); - } - } - std::this_thread::sleep_for(std::chrono::seconds(1)); - } -#endif - return 0; -} \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Client/AuthClient_Connector/AuthClient_Connector.h b/XEngine_Source/AuthorizeModule_Client/AuthClient_Connector/AuthClient_Connector.h deleted file mode 100644 index b17f64f..0000000 --- a/XEngine_Source/AuthorizeModule_Client/AuthClient_Connector/AuthClient_Connector.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2023/11/15 10:34:36 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\AuthClient_Connector\AuthClient_Connector.h -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\AuthClient_Connector -// File Base: AuthClient_Connector -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 验证客户端示例模块 -// History: -*********************************************************************/ -typedef struct -{ - XNETHANDLE xhToken; - int nDynamicCode; - time_t nTimeStart; -}AUTHHELP_DYNAMICCODE; - -class CAuthClient_Connector -{ -public: - CAuthClient_Connector(); - ~CAuthClient_Connector(); -public: - bool AuthClient_Connector_Connect(LPCXSTR lpszClientAddr, int nPort, LPCXSTR lpszPass = NULL); - bool AuthClient_Connector_Close(); - bool AuthClient_Connector_GetAuth(bool* pbAuth = NULL); - bool AuthClient_Connector_Login(LPCXSTR lpszUser, LPCXSTR lpszPass, LPCXSTR lpszHWCode = NULL, XSHOT nDYCode = 0, XNETHANDLE xhToken = 0, XLONG dwCryption = 0); - bool AuthClient_Connector_Heart(bool bEnable = true); -protected: - static XHTHREAD XCALLBACK AuthClient_Connector_Thread(XPVOID lParam); -private: - bool m_bRun = false; - bool m_bLogin = false; - bool m_bAuth = false; - bool m_bHeart = false; - XSOCKET m_hSocket = 0; - XCHAR tszPassStr[128] = {}; -private: - shared_ptr pSTDThread; -}; \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Client/AuthClient_Define.h b/XEngine_Source/AuthorizeModule_Client/AuthClient_Define.h deleted file mode 100644 index 520d6e1..0000000 --- a/XEngine_Source/AuthorizeModule_Client/AuthClient_Define.h +++ /dev/null @@ -1,175 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2023/11/15 11:29:49 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\AuthClient_Define.h -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client -// File Base: AuthClient_Define -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 为了方便使用,封装了验证客户端,可以通过c/c++ e 等语言使用 -// History: -*********************************************************************/ -////////////////////////////////////////////////////////////////////////// -// 导出的函数 -////////////////////////////////////////////////////////////////////////// -extern "C" XLONG AuthClient_GetLastError(int *pInt_SysError = NULL); -/************************************************************************/ -/* 验证客户端导出函数 */ -/************************************************************************/ -/******************************************************************** -函数名称:AuthClient_Connector_Connect -函数功能:链接到服务器 - 参数.一:lpszClientAddr - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:服务器地址 - 参数.二:nPort - In/Out:In - 类型:整数型 - 可空:N - 意思:服务器端口 - 参数.三:lpszPass - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:服务器密码,如果没有填空 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool AuthClient_Connector_Connect(LPCXSTR lpszClientAddr, int nPort, LPCXSTR lpszPass = NULL); -/******************************************************************** -函数名称:AuthClient_Connector_Close -函数功能:销毁关闭客户端 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool AuthClient_Connector_Close(); -/******************************************************************** -函数名称:AuthClient_Connector_GetAuth -函数功能:验证用户是否登录或者超时 - 参数.一:pbAuth - In/Out:Out - 类型:逻辑型指针 - 可空:Y - 意思:输出是否验证,如果登录成功但是参数为假.说明没有剩余时间了 -返回值 - 类型:逻辑型 - 意思:是否登录,如果没有登录将返回假,登录成功才需要判断是否通过验证 -备注: -*********************************************************************/ -extern "C" bool AuthClient_Connector_GetAuth(bool* pbAuth = NULL); -/******************************************************************** -函数名称:AuthClient_Connector_Login -函数功能:登录到服务器 - 参数.一:lpszUser - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入用户名 - 参数.二:lpszPass - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入密码 - 参数.三:lpszHWCode - In/Out:In - 类型:常量字符指针 - 可空:Y - 意思:输入硬件码,如果服务器开启了硬件绑定 - 参数.四:nDYCode - In/Out:In - 类型:整数型 - 可空:Y - 意思:输入动态码 - 参数.五:xhToken - In/Out:In - 类型:句柄型 - 可空:Y - 意思:输入动态码绑定的句柄 - 参数.六:dwCryption - In/Out:In - 类型:整数型 - 可空:Y - 意思:输入密码加密类型 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool AuthClient_Connector_Login(LPCXSTR lpszUser, LPCXSTR lpszPass, LPCXSTR lpszHWCode = NULL, XSHOT nDYCode = 0, XNETHANDLE xhToken = 0, XLONG dwCryption = 0); -/******************************************************************** -函数名称:AuthClient_Connector_Heart -函数功能:启用禁用客户端心跳 - 参数.一:bEnable - In/Out:In - 类型:逻辑型 - 可空:Y - 意思:是启用还是禁用 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注:服务器开启了心跳,那么客户端也需要开启 -*********************************************************************/ -extern "C" bool AuthClient_Connector_Heart(bool bEnable = true); -/************************************************************************/ -/* 临时验证函数 */ -/************************************************************************/ -/******************************************************************** -函数名称:AuthClient_HTTPVer_TryRequest -函数功能:试用版请求 - 参数.一:lpszURLAddr - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:服务器地址 - 参数.二:lpszPass - In/Out:In - 类型:常量字符指针 - 可空:Y - 意思:输入密码,如果服务端设置了密码客户端也必须使用加密通信 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool AuthClient_HTTPVer_TryRequest(LPCXSTR lpszURLAddr); -/******************************************************************** -函数名称:AuthClient_HTTPVer_GetDCode -函数功能:获取动态码 - 参数.一:lpszURLAddr - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:服务器地址,完成的API地址,比如:http://127.0.0.1:5302/api?function=dcode&user=get - 参数.二:pInt_DYCode - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出动态码 - 参数.三:pxhToken - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出绑定的句柄 - 参数.四:pInt_Timeout - In/Out:Out - 类型:整数型指针 - 可空:Y - 意思:输出动态码超时时间 - 参数.五:lpszPass - In/Out:In - 类型:常量字符指针 - 可空:Y - 意思:输入密码,如果服务端设置了密码客户端也必须使用加密通信 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool AuthClient_HTTPVer_GetDCode(LPCXSTR lpszURLAddr, int* pInt_DYCode, XNETHANDLE* pxhToken, int* pInt_Timeout = NULL); \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Client/AuthClient_Error.h b/XEngine_Source/AuthorizeModule_Client/AuthClient_Error.h deleted file mode 100644 index 9f9c297..0000000 --- a/XEngine_Source/AuthorizeModule_Client/AuthClient_Error.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2023/11/15 11:32:27 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\AuthClient_Error.h -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client -// File Base: AuthClient_Error -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 错误表 -// History: -*********************************************************************/ -////////////////////////////////////////////////////////////////////////// -// 导出的错误表 -////////////////////////////////////////////////////////////////////////// -/************************************************************************/ -/* 网络协议错误 */ -/************************************************************************/ -#define ERROR_AUTHORIZE_MODULE_CLIENT_PARAMENT 0x0060000 //参数错误,无法继续 -#define ERROR_AUTHORIZE_MODULE_CLIENT_SEND 0x0060001 //发送数据失败 -#define ERROR_AUTHORIZE_MODULE_CLIENT_RECV 0x0060002 //接受数据失败 -#define ERROR_AUTHORIZE_MODULE_CLIENT_LOGIN 0x0060003 //登录失败,请查看错误码 -#define ERROR_AUTHORIZE_MODULE_CLIENT_THREAD 0x0060004 //创建线程失败 -#define ERROR_AUTHORIZE_MODULE_CLIENT_NOTAUTH 0x0060005 //没有验证无法启用心跳 -/************************************************************************/ -/* HTTP验证错误 */ -/************************************************************************/ -#define ERROR_AUTHORIZE_MODULE_HTTPVER_PARAMENT 0x0060010 -#define ERROR_AUTHORIZE_MODULE_HTTPVER_PARSE 0x0060011 -#define ERROR_AUTHORIZE_MODULE_HTTPVER_VERFAILED 0x0060012 \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Client/AuthClient_HTTPVer/AuthClient_HTTPVer.cpp b/XEngine_Source/AuthorizeModule_Client/AuthClient_HTTPVer/AuthClient_HTTPVer.cpp deleted file mode 100644 index c1e8f1d..0000000 --- a/XEngine_Source/AuthorizeModule_Client/AuthClient_HTTPVer/AuthClient_HTTPVer.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include "pch.h" -#include "AuthClient_HTTPVer.h" -/******************************************************************** -// Created: 2024/01/04 09:44:04 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\AuthClient_HTTPVer\AuthClient_HTTPVer.cpp -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\AuthClient_HTTPVer -// File Base: AuthClient_HTTPVer -// File Ext: cpp -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 临时授权客户端 -// History: -*********************************************************************/ -CAuthClient_HTTPVer::CAuthClient_HTTPVer() -{ -} -CAuthClient_HTTPVer::~CAuthClient_HTTPVer() -{ -} -////////////////////////////////////////////////////////////////////////// -// 公有函数 -////////////////////////////////////////////////////////////////////////// -/******************************************************************** -函数名称:AuthClient_HTTPVer_TryRequest -函数功能:试用版请求 - 参数.一:lpszURLAddr - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:函数的API地址,需要输入完整的URL - 参数.二:lpszPass - In/Out:In - 类型:常量字符指针 - 可空:Y - 意思:输入密码,如果服务端设置了密码客户端也必须使用加密通信 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CAuthClient_HTTPVer::AuthClient_HTTPVer_TryRequest(LPCXSTR lpszURLAddr, LPCXSTR lpszPass /* = NULL */) -{ - AuthClient_IsErrorOccur = true; - - if (NULL == lpszURLAddr) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_HTTPVER_PARAMENT; - return false; - } -#if (1 == _XAUTH_BUILD_SWITCH_CLIENT_HTTP) - int nHTTPCode = 0; - XCHAR tszJsonStr[XPATH_MAX] = {}; - Json::Value st_JsonRoot; - Json::Value st_JsonObject; - JSONCPP_STRING st_JsonError; - Json::CharReaderBuilder st_ReaderBuilder; - SYSTEMAPI_SERIAL_INFOMATION st_SDKSerial = {}; - - SystemApi_HardWare_GetSerial(&st_SDKSerial); - - _xstprintf(tszJsonStr, _X("%s"), st_SDKSerial.tszBoardSerial); - - st_JsonObject["tszVSerial"] = tszJsonStr; - st_JsonRoot["st_VERTemp"] = st_JsonObject; - //请求 - int nMsgLen = 0; - XCHAR* ptszMsgBuffer = NULL; - - if (NULL != lpszPass) - { - XCHAR tszENCodec[2048] = {}; - XCHAR tszDECodec[2048] = {}; - - nMsgLen = st_JsonRoot.toStyledString().length(); - Cryption_XCrypto_Encoder(st_JsonRoot.toStyledString().c_str(), &nMsgLen, (XBYTE*)tszENCodec, lpszPass); - APIClient_Http_Request(_X("POST"), lpszURLAddr, tszENCodec, &nHTTPCode, &ptszMsgBuffer, &nMsgLen); - - Cryption_XCrypto_Decoder(ptszMsgBuffer, &nMsgLen, tszDECodec, lpszPass); - st_JsonRoot.clear(); - st_JsonObject.clear(); - //解析回复 - std::unique_ptr const pSt_JsonReader(st_ReaderBuilder.newCharReader()); - if (!pSt_JsonReader->parse(tszDECodec, tszDECodec + nMsgLen, &st_JsonRoot, &st_JsonError)) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_HTTPVER_PARSE; - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMsgBuffer); - return false; - } - } - else - { - APIClient_Http_Request(_X("POST"), lpszURLAddr, st_JsonRoot.toStyledString().c_str(), &nHTTPCode, &ptszMsgBuffer, &nMsgLen); - st_JsonRoot.clear(); - st_JsonObject.clear(); - //解析回复 - std::unique_ptr const pSt_JsonReader(st_ReaderBuilder.newCharReader()); - if (!pSt_JsonReader->parse(ptszMsgBuffer, ptszMsgBuffer + nMsgLen, &st_JsonRoot, &st_JsonError)) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_HTTPVER_PARSE; - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMsgBuffer); - return false; - } - } - - if (0 != st_JsonRoot["code"].asInt()) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_HTTPVER_VERFAILED; - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMsgBuffer); - return false; - } - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMsgBuffer); -#endif - return true; -} -/******************************************************************** -函数名称:AuthClient_HTTPVer_GetDCode -函数功能:获取动态码 - 参数.一:lpszURLAddr - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:服务器地址,完成的API地址,比如:http://127.0.0.1:5302/api?function=dcode&user=get - 参数.二:pInt_DYCode - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出动态码 - 参数.三:pxhToken - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出绑定的句柄 - 参数.四:pInt_Timeout - In/Out:Out - 类型:整数型指针 - 可空:Y - 意思:输出动态码超时时间 - 参数.五:lpszPass - In/Out:In - 类型:常量字符指针 - 可空:Y - 意思:输入密码,如果服务端设置了密码客户端也必须使用加密通信 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CAuthClient_HTTPVer::AuthClient_HTTPVer_GetDCode(LPCXSTR lpszURLAddr, int* pInt_DYCode, XNETHANDLE* pxhToken, int* pInt_Timeout /* = NULL */, LPCXSTR lpszPass /* = NULL */) -{ - AuthClient_IsErrorOccur = true; - - if (NULL == lpszURLAddr) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_HTTPVER_PARAMENT; - return false; - } -#if (1 == _XAUTH_BUILD_SWITCH_CLIENT_HTTP) - int nHTTPCode = 0; - Json::Value st_JsonRoot; - JSONCPP_STRING st_JsonError; - Json::CharReaderBuilder st_ReaderBuilder; - //请求 - int nMsgLen = 0; - XCHAR* ptszMsgBuffer = NULL; - - APIClient_Http_Request(_X("GET"), lpszURLAddr, NULL, &nHTTPCode, &ptszMsgBuffer, &nMsgLen); - if (NULL != lpszPass) - { - XCHAR tszDECodec[2048] = {}; - Cryption_XCrypto_Decoder(ptszMsgBuffer, &nMsgLen, tszDECodec, lpszPass); - - std::unique_ptr const pSt_JsonReader(st_ReaderBuilder.newCharReader()); - if (!pSt_JsonReader->parse(tszDECodec, tszDECodec + nMsgLen, &st_JsonRoot, &st_JsonError)) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_HTTPVER_PARSE; - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMsgBuffer); - return false; - } - } - else - { - //解析回复 - std::unique_ptr const pSt_JsonReader(st_ReaderBuilder.newCharReader()); - if (!pSt_JsonReader->parse(ptszMsgBuffer, ptszMsgBuffer + nMsgLen, &st_JsonRoot, &st_JsonError)) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_HTTPVER_PARSE; - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMsgBuffer); - return false; - } - } - - if (0 != st_JsonRoot["code"].asInt()) - { - AuthClient_IsErrorOccur = true; - AuthClient_dwErrorCode = ERROR_AUTHORIZE_MODULE_HTTPVER_VERFAILED; - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMsgBuffer); - return false; - } - - *pInt_DYCode = st_JsonRoot["nDynamicCode"].asInt(); - *pxhToken = st_JsonRoot["xhToken"].asUInt64(); - if (NULL != pInt_Timeout) - { - *pInt_Timeout = st_JsonRoot["nTimeout"].asInt(); - } - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMsgBuffer); -#endif - return true; -} \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Client/AuthClient_HTTPVer/AuthClient_HTTPVer.h b/XEngine_Source/AuthorizeModule_Client/AuthClient_HTTPVer/AuthClient_HTTPVer.h deleted file mode 100644 index aff8887..0000000 --- a/XEngine_Source/AuthorizeModule_Client/AuthClient_HTTPVer/AuthClient_HTTPVer.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2024/01/04 09:42:55 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\AuthClient_HTTPVer\AuthClient_HTTPVer.h -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\AuthClient_HTTPVer -// File Base: AuthClient_HTTPVer -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 临时授权客户端 -// History: -*********************************************************************/ - -class CAuthClient_HTTPVer -{ -public: - CAuthClient_HTTPVer(); - ~CAuthClient_HTTPVer(); -public: - bool AuthClient_HTTPVer_TryRequest(LPCXSTR lpszURLAddr, LPCXSTR lpszPass = NULL); - bool AuthClient_HTTPVer_GetDCode(LPCXSTR lpszURLAddr, int* pInt_DYCode, XNETHANDLE* pxhToken, int* pInt_Timeout = NULL, LPCXSTR lpszPass = NULL); -protected: -private: -}; \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.def b/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.def deleted file mode 100644 index 44b2beb..0000000 --- a/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.def +++ /dev/null @@ -1,13 +0,0 @@ -LIBRARY - -EXPORTS - AuthClient_GetLastError - - AuthClient_Connector_Connect - AuthClient_Connector_Close - AuthClient_Connector_GetAuth - AuthClient_Connector_Login - AuthClient_Connector_Heart - - AuthClient_HTTPVer_TryRequest - AuthClient_HTTPVer_GetDCode \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj b/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj deleted file mode 100644 index 5431318..0000000 --- a/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj +++ /dev/null @@ -1,277 +0,0 @@ - - - - - Debug - ARM64 - - - Debug - Win32 - - - Release - ARM64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 17.0 - Win32Proj - {dd8cb5f1-980f-48c3-ba2f-3cf534903b14} - AuthorizeModuleClient - 10.0 - - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - $(XEngine_Include);../XEngine_DependLibrary/XEngine_Module/jsoncpp;$(IncludePath) - $(XEngine_Lib32);$(LibraryPath) - - - $(XEngine_Include);..\AuthorizeModule_Client;../XEngine_DependLibrary/XEngine_Module/jsoncpp;$(IncludePath) - $(XEngine_Lib32);$(LibraryPath) - - - $(XEngine_Include);../XEngine_DependLibrary/XEngine_Module/jsoncpp;$(IncludePath) - $(XEngine_Lib64);$(LibraryPath) - - - $(XEngine_Include);../XEngine_DependLibrary/XEngine_Module/jsoncpp;$(IncludePath) - $(XEngine_LibArm64);$(LibraryPath) - - - $(XEngine_Include);../XEngine_DependLibrary/XEngine_Module/jsoncpp;$(IncludePath) - $(XEngine_Lib64);$(LibraryPath) - - - $(XEngine_Include);../XEngine_DependLibrary/XEngine_Module/jsoncpp;$(IncludePath) - $(XEngine_LibArm64);$(LibraryPath) - - - - Level3 - true - WIN32;_DEBUG;AUTHORIZEMODULECLIENT_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - - - Windows - true - false - AuthorizeModule_Client.def - - - - - Level3 - true - true - true - WIN32;NDEBUG;AUTHORIZEMODULECLIENT_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - /utf-8 %(AdditionalOptions) - MultiThreadedDLL - - - Windows - true - true - true - false - AuthorizeModule_Client.def - - - - - Level3 - true - _DEBUG;AUTHORIZEMODULECLIENT_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - - - Windows - true - false - AuthorizeModule_Client.def - - - - - Level3 - true - _DEBUG;AUTHORIZEMODULECLIENT_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - - - Windows - true - false - AuthorizeModule_Client.def - - - - - Level3 - true - true - true - NDEBUG;AUTHORIZEMODULECLIENT_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - MultiThreadedDLL - /utf-8 %(AdditionalOptions) - - - Windows - true - true - true - false - AuthorizeModule_Client.def - - - - - Level3 - true - true - true - NDEBUG;AUTHORIZEMODULECLIENT_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - MultiThreadedDLL - /utf-8 %(AdditionalOptions) - - - Windows - true - true - true - false - AuthorizeModule_Client.def - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj.filters b/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj.filters deleted file mode 100644 index 94729c0..0000000 --- a/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj.filters +++ /dev/null @@ -1,68 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {8e7e2cf3-2b0b-423c-ac1e-1397e7a6b105} - - - {af74d4d4-f721-4060-b98b-6f9d5eda9354} - - - {4a9a85f2-55f9-47e4-9049-14245fc56628} - - - {a5434c6b-9493-4a10-ae83-7dc2f1f6d489} - - - - - 头文件 - - - 头文件 - - - 头文件\AuthClient_Connector - - - 头文件 - - - 头文件 - - - 头文件\AuthClient_HTTPVer - - - - - 源文件 - - - 源文件 - - - 源文件\AuthClient_Connector - - - 源文件\AuthClient_HTTPVer - - - - - 源文件 - - - \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj.user b/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj.user deleted file mode 100644 index 88a5509..0000000 --- a/XEngine_Source/AuthorizeModule_Client/AuthorizeModule_Client.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Client/Makefile b/XEngine_Source/AuthorizeModule_Client/Makefile deleted file mode 100644 index 310b153..0000000 --- a/XEngine_Source/AuthorizeModule_Client/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -CC = g++ -Wall -std=c++20 -fPIC -PLATVER = -FILEEXT = -LIBFLAG = -LOADHDR = -I ./ -I ../XEngine_DependLibrary/XEngine_Module/jsoncpp -LOADSO = -L ../XEngine_DependLibrary/XEngine_Module/jsoncpp -LIB = -ljsoncpp -lXEngine_BaseLib -lXEngine_Cryption -lXClient_Socket -lXClient_APIHelp -lXEngine_SystemApi -LIBEX = -OBJECTS = AuthClient_Connector.o AuthClient_HTTPVer.o pch.o - -ifeq ($(RELEASE),1) -FLAGS = -c -D _RELEASE -DEBUG = -O2 -else - ifeq ($(PLATFORM),mac) - FLAGS = -c - DEBUG = -g -D _DEBUG - else - FLAGS = -c -lc_p - DEBUG = -g -pg -D _DEBUG - endif -endif - -ifeq ($(UNICODE),1) -override UNICODE := -D __UNICODE__ -else -override UNICODE := -D __ANSI__ -endif - -ifeq ($(PLATFORM),linux) - ifeq (/etc/redhat-release,$(wildcard /etc/redhat-release)) - PLATVER = -D __CENTOS__ - else - PLATVER = -D __UBUNTU__ - endif - FILEEXT = so - LIBFLAG = -shared - LIBEX = -lpthread -lrt -ldl - LOADBIN = -Wl,-rpath=./,--disable-new-dtags -else ifeq ($(PLATFORM),mac) - CC += -Wno-deprecated-declarations - PLATVER = -D __MACOS__ - FILEEXT = dylib - LIBFLAG = -dynamiclib - LIBEX = -lpthread -ldl - LOADBIN = -Wl,-rpath,@loader_path/./ -endif - -all:$(OBJECTS) - $(CC) $(DEBUG) $(OBJECTS) -o libAuthorizeModule_Client.$(FILEEXT) $(LIBFLAG) $(LIB) $(LIBEX) $(LOADSO) $(LOADBIN) - -AuthClient_Connector.o:./AuthClient_Connector/AuthClient_Connector.cpp - $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./AuthClient_Connector/AuthClient_Connector.cpp -AuthClient_HTTPVer.o:./AuthClient_HTTPVer/AuthClient_HTTPVer.cpp - $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./AuthClient_HTTPVer/AuthClient_HTTPVer.cpp - -pch.o:pch.cpp - $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) pch.cpp - -InstallAll:InstallSo -InstallSo:./libAuthorizeModule_Client.$(FILEEXT) - cp ./libAuthorizeModule_Client.$(FILEEXT) ../../XEngine_Release/libAuthorizeModule_Client.$(FILEEXT) - - -CleanAll:CleanObj CleanMk -CleanObj: - rm *.o -CleanMk: - rm *.$(FILEEXT) diff --git a/XEngine_Source/AuthorizeModule_Client/dllmain.cpp b/XEngine_Source/AuthorizeModule_Client/dllmain.cpp deleted file mode 100644 index daed8c8..0000000 --- a/XEngine_Source/AuthorizeModule_Client/dllmain.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// dllmain.cpp : 定义 DLL 应用程序的入口点。 -#include "pch.h" - -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} - diff --git a/XEngine_Source/AuthorizeModule_Client/framework.h b/XEngine_Source/AuthorizeModule_Client/framework.h deleted file mode 100644 index 80cbbc9..0000000 --- a/XEngine_Source/AuthorizeModule_Client/framework.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 -// Windows 头文件 -#include diff --git a/XEngine_Source/AuthorizeModule_Client/pch.cpp b/XEngine_Source/AuthorizeModule_Client/pch.cpp deleted file mode 100644 index 743b2d8..0000000 --- a/XEngine_Source/AuthorizeModule_Client/pch.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "pch.h" -#include "AuthClient_Connector/AuthClient_Connector.h" -#include "AuthClient_HTTPVer/AuthClient_HTTPVer.h" -/******************************************************************** -// Created: 2023/11/15 11:28:22 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\pch.cpp -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client -// File Base: pch -// File Ext: cpp -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 导出实现 -// History: -*********************************************************************/ -bool AuthClient_IsErrorOccur = false; -XLONG AuthClient_dwErrorCode = 0; -////////////////////////////////////////////////////////////////////////// -CAuthClient_Connector m_Connector; -CAuthClient_HTTPVer m_HTTPVer; -////////////////////////////////////////////////////////////////////////// -// 导出的函数 -////////////////////////////////////////////////////////////////////////// -extern "C" XLONG AuthClient_GetLastError(int* pInt_SysError) -{ - if (NULL != pInt_SysError) - { - *pInt_SysError = errno; - } - return AuthClient_dwErrorCode; -} -/************************************************************************/ -/* 验证客户端导出函数 */ -/************************************************************************/ -extern "C" bool AuthClient_Connector_Connect(LPCXSTR lpszClientAddr, int nPort, LPCXSTR lpszPass) -{ - return m_Connector.AuthClient_Connector_Connect(lpszClientAddr, nPort, lpszPass); -} -extern "C" bool AuthClient_Connector_Close() -{ - return m_Connector.AuthClient_Connector_Close(); -} -extern "C" bool AuthClient_Connector_GetAuth(bool* pbAuth) -{ - return m_Connector.AuthClient_Connector_GetAuth(pbAuth); -} -extern "C" bool AuthClient_Connector_Login(LPCXSTR lpszUser, LPCXSTR lpszPass, LPCXSTR lpszHWCode, XSHOT nDYCode, XNETHANDLE xhToken, XLONG dwCryption) -{ - return m_Connector.AuthClient_Connector_Login(lpszUser, lpszPass, lpszHWCode, nDYCode, xhToken, dwCryption); -} -extern "C" bool AuthClient_Connector_Heart(bool bEnable) -{ - return m_Connector.AuthClient_Connector_Heart(bEnable); -} -/************************************************************************/ -/* 临时验证函数 */ -/************************************************************************/ -extern "C" bool AuthClient_HTTPVer_TryRequest(LPCXSTR lpszURLAddr) -{ - return m_HTTPVer.AuthClient_HTTPVer_TryRequest(lpszURLAddr); -} -extern "C" bool AuthClient_HTTPVer_GetDCode(LPCXSTR lpszURLAddr, int* pInt_DYCode, XNETHANDLE * pxhToken, int* pInt_Timeout) -{ - return m_HTTPVer.AuthClient_HTTPVer_GetDCode(lpszURLAddr, pInt_DYCode, pxhToken, pInt_Timeout); -} \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Client/pch.h b/XEngine_Source/AuthorizeModule_Client/pch.h deleted file mode 100644 index 90f1f56..0000000 --- a/XEngine_Source/AuthorizeModule_Client/pch.h +++ /dev/null @@ -1,81 +0,0 @@ -// pch.h: 这是预编译标头文件。 -// 下方列出的文件仅编译一次,提高了将来生成的生成性能。 -// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 -// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 -// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 - -#ifndef PCH_H -#define PCH_H - -// 添加要在此处预编译的标头 -#ifdef _MSC_BUILD -#include "framework.h" -#include -#endif -#endif //PCH_H -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../XAuth_BuildSwitch.h" -#if (1 == _XAUTH_BUILD_SWITCH_CLIENT_TCP) -#include -#include -#include -#include -#include "../XAuth_Protocol.h" -#endif -#if (1 == _XAUTH_BUILD_SWITCH_CLIENT_HTTP) -#include -#include -#include -#include -#endif -#include "AuthClient_Define.h" -#include "AuthClient_Error.h" -using namespace std; -/******************************************************************** -// Created: 2023/11/15 10:37:19 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client\pch.h -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Client -// File Base: pch -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 公有头文件 -// History: -*********************************************************************/ -extern bool AuthClient_IsErrorOccur; -extern XLONG AuthClient_dwErrorCode; - -#ifdef _MSC_BUILD -#pragma comment(lib,"XEngine_BaseLib/XEngine_BaseLib") -#pragma comment(lib,"XEngine_Core/XEngine_Cryption") -#pragma comment(lib,"XEngine_Client/XClient_Socket") -#pragma comment(lib,"XEngine_Client/XClient_APIHelp") -#pragma comment(lib,"XEngine_SystemSdk/XEngine_SystemApi") -#ifdef _DEBUG -#ifdef _M_X64 -#pragma comment(lib,"../x64/Debug/jsoncpp") -#elif _M_ARM64 -#pragma comment(lib,"../ARM64/Debug/jsoncpp") -#elif _M_IX86 -#pragma comment(lib,"../Debug/jsoncpp") -#endif -#else -#ifdef _M_X64 -#pragma comment(lib,"../x64/Release/jsoncpp") -#elif _M_ARM64 -#pragma comment(lib,"../ARM64/Release/jsoncpp") -#elif _M_IX86 -#pragma comment(lib,"../Release/jsoncpp") -#endif -#endif -#endif \ No newline at end of file diff --git a/XEngine_Source/XAuth_BuildSwitch.h b/XEngine_Source/XAuth_BuildSwitch.h deleted file mode 100644 index 7ec160f..0000000 --- a/XEngine_Source/XAuth_BuildSwitch.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2024/01/04 10:01:07 -// File Name: D:\XEngine_Authorize\XEngine_Source\XAuth_BuildSwitch.h -// File Path: D:\XEngine_Authorize\XEngine_Source -// File Base: XAuth_BuildSwitch -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 编译选项 -// History: -*********************************************************************/ -#define _XAUTH_BUILD_SWITCH_CLIENT_TCP 1 -#define _XAUTH_BUILD_SWITCH_CLIENT_HTTP 1 - -#if (XENGINE_VERSION_KERNEL <= 9) && (XENGINE_VERSION_MAIN < 10) -typedef XENGINE_LIBTIMER XENGINE_LIBTIME; -#endif \ No newline at end of file From 9e261029aca2ace832b51ec07e5b552eed51c714 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 13 Oct 2025 15:08:39 +0800 Subject: [PATCH 04/22] delete:cd key module --- .../AuthorizeModule_CDKey.def | 18 - .../AuthorizeModule_CDKey.vcxproj | 277 ---- .../AuthorizeModule_CDKey.vcxproj.filters | 68 - .../AuthorizeModule_CDKey.vcxproj.user | 4 - .../Authorize_CDKey/Authorize_CDKey.cpp | 1279 ----------------- .../Authorize_CDKey/Authorize_CDKey.h | 31 - .../Authorize_Serial/Authorize_Serial.cpp | 509 ------- .../Authorize_Serial/Authorize_Serial.h | 35 - .../AuthorizeModule_CDKey/CDKey_Define.h | 308 ---- .../AuthorizeModule_CDKey/CDKey_Error.h | 36 - XEngine_Source/AuthorizeModule_CDKey/Makefile | 70 - .../AuthorizeModule_CDKey/dllmain.cpp | 19 - .../AuthorizeModule_CDKey/framework.h | 5 - XEngine_Source/AuthorizeModule_CDKey/pch.cpp | 84 -- XEngine_Source/AuthorizeModule_CDKey/pch.h | 57 - 15 files changed, 2800 deletions(-) delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.def delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj.filters delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj.user delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/Authorize_CDKey/Authorize_CDKey.cpp delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/Authorize_CDKey/Authorize_CDKey.h delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/Authorize_Serial/Authorize_Serial.cpp delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/Authorize_Serial/Authorize_Serial.h delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/CDKey_Define.h delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/CDKey_Error.h delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/Makefile delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/dllmain.cpp delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/framework.h delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/pch.cpp delete mode 100644 XEngine_Source/AuthorizeModule_CDKey/pch.h diff --git a/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.def b/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.def deleted file mode 100644 index 99100dc..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.def +++ /dev/null @@ -1,18 +0,0 @@ -LIBRARY - -EXPORTS - Authorize_GetLastError - - Authorize_Serial_Creator - Authorize_Serial_Create - Authorize_Serial_GetType - - Authorize_CDKey_WriteKey - Authorize_CDKey_ReadKey - Authorize_CDKey_WriteMemory - Authorize_CDKey_ReadMemory - Authorize_CDKey_BuildKeyTime - Authorize_CDKey_UserRegister - Authorize_CDKey_GetLeftTimer - Authorize_CDKey_WriteTime - Authorize_CDKey_ReadTime \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj b/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj deleted file mode 100644 index eca66d9..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj +++ /dev/null @@ -1,277 +0,0 @@ - - - - - Debug - ARM64 - - - Debug - Win32 - - - Release - ARM64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 17.0 - Win32Proj - {02a75bd0-416e-4aef-bf34-bd85bd86384f} - AuthorizeModuleCDKey - 10.0 - - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - $(XEngine_Include);..\AuthorizeModule_CDKey;$(IncludePath) - $(XEngine_Lib32);$(LibraryPath) - - - $(XEngine_Include);$(IncludePath) - $(XEngine_Lib64);$(LibraryPath) - - - $(XEngine_Include);$(IncludePath) - $(XEngine_LibArm64);$(LibraryPath) - - - $(XEngine_Include);$(IncludePath) - $(XEngine_Lib32);$(LibraryPath) - - - $(XEngine_Include);$(IncludePath) - $(XEngine_Lib64);$(LibraryPath) - - - $(XEngine_Include);$(IncludePath) - $(XEngine_LibArm64);$(LibraryPath) - - - - Level3 - true - WIN32;_DEBUG;AUTHORIZEMODULECDKEY_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - - - Windows - true - false - AuthorizeModule_CDKey.def - - - - - Level3 - true - true - true - WIN32;NDEBUG;AUTHORIZEMODULECDKEY_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - /utf-8 %(AdditionalOptions) - MultiThreadedDLL - - - Windows - true - true - true - false - AuthorizeModule_CDKey.def - - - - - Level3 - true - _DEBUG;AUTHORIZEMODULECDKEY_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - - - Windows - true - false - AuthorizeModule_CDKey.def - - - - - Level3 - true - _DEBUG;AUTHORIZEMODULECDKEY_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - - - Windows - true - false - AuthorizeModule_CDKey.def - - - - - Level3 - true - true - true - NDEBUG;AUTHORIZEMODULECDKEY_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - MultiThreadedDLL - /utf-8 %(AdditionalOptions) - - - Windows - true - true - true - false - AuthorizeModule_CDKey.def - - - - - Level3 - true - true - true - NDEBUG;AUTHORIZEMODULECDKEY_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - stdcpp20 - stdc17 - MultiThreadedDLL - /utf-8 %(AdditionalOptions) - - - Windows - true - true - true - false - AuthorizeModule_CDKey.def - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj.filters b/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj.filters deleted file mode 100644 index 03c0f6a..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj.filters +++ /dev/null @@ -1,68 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {0a186122-00ae-4ad3-91b5-8a6fdf3950bc} - - - {c4ce44ad-ed56-48d6-92d8-49f68b1029d4} - - - {a33f91ec-f718-45b9-9ec5-d4f93a6482d0} - - - {39fc0e03-6422-475a-be30-30d77154b7d1} - - - - - 头文件 - - - 头文件 - - - 头文件\Authorize_CDKey - - - 头文件\Authorize_Serial - - - 头文件 - - - 头文件 - - - - - 源文件 - - - 源文件 - - - 源文件\Authorize_CDKey - - - 源文件\Authorize_Serial - - - - - 源文件 - - - \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj.user b/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj.user deleted file mode 100644 index 88a5509..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/AuthorizeModule_CDKey.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_CDKey/Authorize_CDKey/Authorize_CDKey.cpp b/XEngine_Source/AuthorizeModule_CDKey/Authorize_CDKey/Authorize_CDKey.cpp deleted file mode 100644 index 102927b..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/Authorize_CDKey/Authorize_CDKey.cpp +++ /dev/null @@ -1,1279 +0,0 @@ -#include "pch.h" -#include "Authorize_CDKey.h" -/******************************************************************** -// Created: 2024/07/08 17:30:39 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey\Authorize_CDKey\Authorize_CDKey.cpp -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey\Authorize_CDKey -// File Base: Authorize_CDKey -// File Ext: cpp -// Project: XEngine -// Author: qyt -// Purpose: 本地验证实现 -// History: -*********************************************************************/ -CAuthorize_CDKey::CAuthorize_CDKey() -{ -} -CAuthorize_CDKey::~CAuthorize_CDKey() -{ - -} -////////////////////////////////////////////////////////////////////////// -// 公有函数 -////////////////////////////////////////////////////////////////////////// -/******************************************************************** -函数名称:Authorize_CDKey_WriteKey -函数功能:写一个CDKey文件 - 参数.一:lpszFileKey - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:要操作的文件路径 - 参数.二:pSt_AuthLocal - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:要写入的文件信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注:写入读取必须是明文,建议你加密处理CDKEY,通过OPENSSL模块,来加解密,在读写 -*********************************************************************/ -bool CAuthorize_CDKey::Authorize_CDKey_WriteKey(LPCXSTR lpszFileKey, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal) -{ - Authorize_IsErrorOccur = false; - - if ((NULL == lpszFileKey) || (NULL == pSt_AuthLocal)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - //添加连接信息文本 - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey, _X("Connection"), _X("tszAddr"), pSt_AuthLocal->tszAddr)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_CONNECT; - return false; - } - if (!SystemConfig_File_WriteInt64FromFile(lpszFileKey, _X("Connection"), _X("nPort"), pSt_AuthLocal->nPort)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_CONNECT; - return false; - } - //添加程序名称文本 - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey, _X("AppInfo"), _X("tszAppName"), pSt_AuthLocal->st_AuthAppInfo.tszAppName)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_APPINFO; - return false; - } - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey,_X("AppInfo"), _X("tszAppVer"), pSt_AuthLocal->st_AuthAppInfo.tszAppVer)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_APPINFO; - return false; - } - if (!SystemConfig_File_WriteInt64FromFile(lpszFileKey, _X("AppInfo"), _X("nExecTime"), pSt_AuthLocal->st_AuthAppInfo.nExecTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_APPINFO; - return false; - } - if (!SystemConfig_File_WriteInt64FromFile(lpszFileKey,_X("AppInfo"), _X("bInit"), pSt_AuthLocal->st_AuthAppInfo.bInit)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_APPINFO; - return false; - } - //更新使用时间 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == pSt_AuthLocal->st_AuthRegInfo.enSerialType) - { - XCHAR tszTimeStart[64]; - XCHAR tszTimeEnd[64]; - __int64x nUsedTime = 0; - - memset(tszTimeStart, '\0', sizeof(tszTimeStart)); - memset(tszTimeEnd, '\0', sizeof(tszTimeEnd)); - BaseLib_Time_TimeToStr(tszTimeEnd); - BaseLib_TimeSpan_GetForStr(pSt_AuthLocal->st_AuthRegInfo.tszStartTime, tszTimeEnd, &nUsedTime, ENUM_XENGINE_BASELIB_TIME_TYPE_SECOND); - pSt_AuthLocal->st_AuthRegInfo.nHasTime -= nUsedTime; - } - //添加注册信息 - if (!SystemConfig_File_WriteInt64FromFile(lpszFileKey,_X("AuthReg"), _X("nHasTime"), pSt_AuthLocal->st_AuthRegInfo.nHasTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (!SystemConfig_File_WriteInt64FromFile(lpszFileKey,_X("AuthReg"), _X("enHWType"), pSt_AuthLocal->st_AuthRegInfo.enHWType)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (!SystemConfig_File_WriteInt64FromFile(lpszFileKey,_X("AuthReg"), _X("enRegType"), pSt_AuthLocal->st_AuthRegInfo.enRegType)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (!SystemConfig_File_WriteInt64FromFile(lpszFileKey,_X("AuthReg"), _X("enSerialType"), pSt_AuthLocal->st_AuthRegInfo.enSerialType)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (!SystemConfig_File_WriteInt64FromFile(lpszFileKey,_X("AuthReg"), _X("enVModeType"), pSt_AuthLocal->st_AuthRegInfo.enVModeType)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey,_X("AuthReg"), _X("tszHardware"), pSt_AuthLocal->st_AuthRegInfo.tszHardware)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - BaseLib_Time_TimeToStr(pSt_AuthLocal->st_AuthRegInfo.tszCreateTime); - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey,_X("AuthReg"), _X("tszCreateTime"), pSt_AuthLocal->st_AuthRegInfo.tszCreateTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey,_X("AuthReg"), _X("tszRegisterTime"), pSt_AuthLocal->st_AuthRegInfo.tszRegisterTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey,_X("AuthReg"), _X("tszLeftTime"), pSt_AuthLocal->st_AuthRegInfo.tszLeftTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey,_X("AuthReg"), _X("tszStartTime"), pSt_AuthLocal->st_AuthRegInfo.tszStartTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey,_X("AuthReg"), _X("tszExpiryTime"), pSt_AuthLocal->st_AuthRegInfo.tszExpiryTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - //临时序列号 - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey, _X("AuthSerial"), _X("tszTimeSerial"), pSt_AuthLocal->st_AuthSerial.st_TimeLimit.tszTimeSerial)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_SERIAL; - return false; - } - if (!SystemConfig_File_WriteInt64FromFile(lpszFileKey, _X("AuthSerial"), _X("nTimeCount"), pSt_AuthLocal->st_AuthSerial.st_TimeLimit.nTimeCount)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_SERIAL; - return false; - } - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey, _X("AuthSerial"), _X("tszDataSerial"), pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataSerial)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_SERIAL; - return false; - } - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey, _X("AuthSerial"), _X("tszDataTime"), pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_SERIAL; - return false; - } - if (!SystemConfig_File_WriteInt64FromFile(lpszFileKey, _X("AuthSerial"), _X("bTimeAdd"), pSt_AuthLocal->st_AuthSerial.st_DataLimit.bTimeAdd)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_SERIAL; - return false; - } - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey, _X("AuthSerial"), _X("tszUNLimitSerial"), pSt_AuthLocal->st_AuthSerial.st_UNLimit.tszUNLimitSerial)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_SERIAL; - return false; - } - //自定义用户信息 - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey, _X("AuthUser"), _X("tszUserName"), pSt_AuthLocal->st_AuthUserInfo.tszUserName)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_USER; - return false; - } - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey, _X("AuthUser"), _X("tszUserContact"), pSt_AuthLocal->st_AuthUserInfo.tszUserContact)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_USER; - return false; - } - if (!SystemConfig_File_WriteProfileFromFile(lpszFileKey, _X("AuthUser"), _X("tszCustom"), pSt_AuthLocal->st_AuthUserInfo.tszCustom)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_USER; - return false; - } - return true; -} -/******************************************************************** -函数名称:Authorize_CDKey_ReadKey -函数功能:读一个数据文件 - 参数.一:lpszFileKey - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:要操作的文件路径 - 参数.二:pSt_AuthLocal - In/Out:Out - 类型:数据结构指针 - 可空:N - 意思:导出获取到的文件信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CAuthorize_CDKey::Authorize_CDKey_ReadKey(LPCXSTR lpszFileKey, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal) -{ - Authorize_IsErrorOccur = false; - - if ((NULL == lpszFileKey) || (NULL == pSt_AuthLocal)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - //添加连接信息文本 - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("Connection"), _X("tszAddr"), pSt_AuthLocal->tszAddr) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_CONNECT; - return false; - } - pSt_AuthLocal->nPort = SystemConfig_File_ReadIntFromFile(lpszFileKey, _X("Connection"), _X("nPort")); - //添加程序名称文本 - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AppInfo"), _X("tszAppName"), pSt_AuthLocal->st_AuthAppInfo.tszAppName) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_APPINFO; - return false; - } - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AppInfo"), _X("tszAppVer"), pSt_AuthLocal->st_AuthAppInfo.tszAppVer) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_APPINFO; - return false; - } - pSt_AuthLocal->st_AuthAppInfo.nExecTime = SystemConfig_File_ReadIntFromFile(lpszFileKey, _X("AppInfo"), _X("nExecTime")); - pSt_AuthLocal->st_AuthAppInfo.bInit = SystemConfig_File_ReadIntFromFile(lpszFileKey, _X("AppInfo"), _X("bInit")); - //添加注册信息 - pSt_AuthLocal->st_AuthRegInfo.enHWType = (ENUM_AUTHORIZE_MODULE_HW_TYPE)SystemConfig_File_ReadIntFromFile(lpszFileKey, _X("AuthReg"), _X("enHWType")); - pSt_AuthLocal->st_AuthRegInfo.enRegType = (ENUM_AUTHORIZE_MODULE_CDKEY_TYPE)SystemConfig_File_ReadIntFromFile(lpszFileKey, _X("AuthReg"), _X("enRegType")); - pSt_AuthLocal->st_AuthRegInfo.enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)SystemConfig_File_ReadIntFromFile(lpszFileKey, _X("AuthReg"), _X("enSerialType")); - pSt_AuthLocal->st_AuthRegInfo.enVModeType = (ENUM_AUTHORIZE_MODULE_VERMODE_TYPE)SystemConfig_File_ReadIntFromFile(lpszFileKey, _X("AuthReg"), _X("enVModeType")); - pSt_AuthLocal->st_AuthRegInfo.nHasTime = SystemConfig_File_ReadInt64FromFile(lpszFileKey, _X("AuthReg"), _X("nHasTime")); - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthReg"), _X("tszHardware"), pSt_AuthLocal->st_AuthRegInfo.tszHardware) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthReg"), _X("tszCreateTime"), pSt_AuthLocal->st_AuthRegInfo.tszCreateTime) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthReg"), _X("tszRegisterTime"), pSt_AuthLocal->st_AuthRegInfo.tszRegisterTime) < 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthReg"), _X("tszLeftTime"), pSt_AuthLocal->st_AuthRegInfo.tszLeftTime) < 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthReg"), _X("tszStartTime"), pSt_AuthLocal->st_AuthRegInfo.tszStartTime) < 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - //设置启动时间 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY == pSt_AuthLocal->st_AuthRegInfo.enSerialType) - { - XENGINE_LIBTIME st_EndTimer; - XENGINE_LIBTIME st_StartTime; - - memset(&st_EndTimer, '\0', sizeof(XENGINE_LIBTIME)); - memset(&st_StartTime, '\0', sizeof(XENGINE_LIBTIME)); - - BaseLib_Time_GetSysTime(&st_EndTimer); - BaseLib_Time_StrToTime(pSt_AuthLocal->st_AuthRegInfo.tszStartTime, &st_StartTime); - if ((st_EndTimer.wYear != st_StartTime.wYear) || (st_EndTimer.wMonth != st_StartTime.wMonth) || (st_EndTimer.wDay != st_StartTime.wDay)) - { - pSt_AuthLocal->st_AuthRegInfo.nHasTime--; - } - BaseLib_Time_TimeToStr(pSt_AuthLocal->st_AuthRegInfo.tszStartTime); - } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == pSt_AuthLocal->st_AuthRegInfo.enSerialType) - { - memset(pSt_AuthLocal->st_AuthRegInfo.tszStartTime, '\0', sizeof(pSt_AuthLocal->st_AuthRegInfo.tszStartTime)); - BaseLib_Time_TimeToStr(pSt_AuthLocal->st_AuthRegInfo.tszStartTime); - } - - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthReg"), _X("tszExpiryTime"), pSt_AuthLocal->st_AuthRegInfo.tszExpiryTime) < 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG; - return false; - } - //临时序列号 - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthSerial"), _X("tszTimeSerial"), pSt_AuthLocal->st_AuthSerial.st_TimeLimit.tszTimeSerial) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_SERIAL; - return false; - } - pSt_AuthLocal->st_AuthSerial.st_TimeLimit.nTimeCount = SystemConfig_File_ReadIntFromFile(lpszFileKey, _X("AuthSerial"), _X("nTimeCount")); - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthSerial"), _X("tszDataSerial"), pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataSerial) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_SERIAL; - return false; - } - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthSerial"), _X("tszDataTime"), pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataTime) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_SERIAL; - return false; - } - pSt_AuthLocal->st_AuthSerial.st_DataLimit.bTimeAdd = SystemConfig_File_ReadIntFromFile(lpszFileKey, _X("AuthSerial"), _X("bAddTime")); - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthSerial"), _X("tszUNLimitSerial"), pSt_AuthLocal->st_AuthSerial.st_UNLimit.tszUNLimitSerial) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_SERIAL; - return false; - } - //用户信息 - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthUser"), _X("tszUserName"), pSt_AuthLocal->st_AuthUserInfo.tszUserName) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_USER; - return false; - } - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthUser"), _X("tszUserContact"), pSt_AuthLocal->st_AuthUserInfo.tszUserContact) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_USER; - return false; - } - if (SystemConfig_File_ReadProfileFromFile(lpszFileKey, _X("AuthUser"), _X("tszCustom"), pSt_AuthLocal->st_AuthUserInfo.tszCustom) < 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_USER; - return false; - } - return true; -} -/******************************************************************** -函数名称:Authorize_CDKey_WriteMemory -函数功能:写配置信息到内存 - 参数.一:ptszMsgBuffer - In/Out:Out - 类型:字符指针 - 可空:N - 意思:写到的内存 - 参数.二:pInt_MsgLen - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:写到的内存大小 - 参数.三:pSt_AuthLocal - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:输入要写的信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CAuthorize_CDKey::Authorize_CDKey_WriteMemory(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal) -{ - Authorize_IsErrorOccur = false; - - if ((NULL == ptszMsgBuffer) || (NULL == pInt_MsgLen) || (NULL == pSt_AuthLocal)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - int nMsgLen = 0; - //添加连接信息文本 - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("Connection"), _X("tszAddr"), pSt_AuthLocal->tszAddr, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteInt64FromMemory(ptszMsgBuffer, nMsgLen, _X("Connection"), _X("nPort"), pSt_AuthLocal->nPort, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - //添加程序名称文本 - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AppInfo"), _X("tszAppName"), pSt_AuthLocal->st_AuthAppInfo.tszAppName, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AppInfo"), _X("tszAppVer"), pSt_AuthLocal->st_AuthAppInfo.tszAppVer, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteInt64FromMemory(ptszMsgBuffer, nMsgLen, _X("AppInfo"), _X("nExecTime"), pSt_AuthLocal->st_AuthAppInfo.nExecTime, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteInt64FromMemory(ptszMsgBuffer, nMsgLen, _X("AppInfo"), _X("bInit"), pSt_AuthLocal->st_AuthAppInfo.bInit, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - //更新使用时间 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == pSt_AuthLocal->st_AuthRegInfo.enSerialType) - { - XCHAR tszTimeStart[64]; - XCHAR tszTimeEnd[64]; - __int64x nUsedTime = 0; - - memset(tszTimeStart, '\0', sizeof(tszTimeStart)); - memset(tszTimeEnd, '\0', sizeof(tszTimeEnd)); - BaseLib_Time_TimeToStr(tszTimeEnd); - BaseLib_TimeSpan_GetForStr(pSt_AuthLocal->st_AuthRegInfo.tszStartTime, tszTimeEnd, &nUsedTime, ENUM_XENGINE_BASELIB_TIME_TYPE_SECOND); - pSt_AuthLocal->st_AuthRegInfo.nHasTime -= nUsedTime; - } - //添加注册信息 - if (!SystemConfig_File_WriteInt64FromMemory(ptszMsgBuffer, nMsgLen, _X("AuthReg"), _X("nHasTime"), pSt_AuthLocal->st_AuthRegInfo.nHasTime, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteInt64FromMemory(ptszMsgBuffer, nMsgLen, _X("AuthReg"), _X("enHWType"), pSt_AuthLocal->st_AuthRegInfo.enHWType, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteInt64FromMemory(ptszMsgBuffer, nMsgLen, _X("AuthReg"), _X("enRegType"), pSt_AuthLocal->st_AuthRegInfo.enRegType, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteInt64FromMemory(ptszMsgBuffer, nMsgLen, _X("AuthReg"), _X("enSerialType"), pSt_AuthLocal->st_AuthRegInfo.enSerialType, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteInt64FromMemory(ptszMsgBuffer, nMsgLen, _X("AuthReg"), _X("enVModeType"), pSt_AuthLocal->st_AuthRegInfo.enVModeType, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszHardware"), pSt_AuthLocal->st_AuthRegInfo.tszHardware, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - BaseLib_Time_TimeToStr(pSt_AuthLocal->st_AuthRegInfo.tszCreateTime); - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszCreateTime"), pSt_AuthLocal->st_AuthRegInfo.tszCreateTime, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszRegisterTime"), pSt_AuthLocal->st_AuthRegInfo.tszRegisterTime, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszLeftTime"), pSt_AuthLocal->st_AuthRegInfo.tszLeftTime, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszStartTime"), pSt_AuthLocal->st_AuthRegInfo.tszStartTime, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszExpiryTime"), pSt_AuthLocal->st_AuthRegInfo.tszExpiryTime, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - //临时序列号 - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("tszTimeSerial"), pSt_AuthLocal->st_AuthSerial.st_TimeLimit.tszTimeSerial, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteInt64FromMemory(ptszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("nTimeCount"), pSt_AuthLocal->st_AuthSerial.st_TimeLimit.nTimeCount, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("tszDataSerial"), pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataSerial, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("tszDataTime"), pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataTime, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteInt64FromMemory(ptszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("bAddTime"), pSt_AuthLocal->st_AuthSerial.st_DataLimit.bTimeAdd, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("tszUNLimitSerial"), pSt_AuthLocal->st_AuthSerial.st_UNLimit.tszUNLimitSerial, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - //用户信息 - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthUser"), _X("tszUserName"), pSt_AuthLocal->st_AuthUserInfo.tszUserName, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthUser"), _X("tszUserContact"), pSt_AuthLocal->st_AuthUserInfo.tszUserContact, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_WriteProfileFromMemory(ptszMsgBuffer, nMsgLen, _X("AuthUser"), _X("tszCustom"), pSt_AuthLocal->st_AuthUserInfo.tszCustom, ptszMsgBuffer, &nMsgLen)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - *pInt_MsgLen = nMsgLen; - return true; -} -/******************************************************************** -函数名称:Authorize_CDKey_ReadMemory -函数功能:内存配置文件读取 - 参数.一:lpszMsgBuffer - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要读取配置的内存 - 参数.二:nMsgLen - In/Out:In - 类型:整数型 - 可空:N - 意思:输入读取内存大小 - 参数.三:pSt_AuthLocal - In/Out:Out - 类型:数据结构指针 - 可空:N - 意思:输出读取到的信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CAuthorize_CDKey::Authorize_CDKey_ReadMemory(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal) -{ - Authorize_IsErrorOccur = false; - - if ((NULL == lpszMsgBuffer) || (NULL == pSt_AuthLocal)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - //添加连接信息文本 - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("Connection"), _X("tszAddr"), pSt_AuthLocal->tszAddr)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_ReadIntFromMemory(lpszMsgBuffer, nMsgLen, _X("Connection"), _X("nPort"), &pSt_AuthLocal->nPort)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - //添加程序名称文本 - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AppInfo"), _X("tszAppName"), pSt_AuthLocal->st_AuthAppInfo.tszAppName)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AppInfo"), _X("tszAppVer"), pSt_AuthLocal->st_AuthAppInfo.tszAppVer)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - SystemConfig_File_ReadIntFromMemory(lpszMsgBuffer, nMsgLen, _X("AppInfo"), _X("bInit"), (int*)&pSt_AuthLocal->st_AuthAppInfo.bInit); - SystemConfig_File_ReadInt64FromMemory(lpszMsgBuffer, nMsgLen, _X("AppInfo"), _X("nExecTime"), &pSt_AuthLocal->st_AuthAppInfo.nExecTime); - //添加注册信息 - SystemConfig_File_ReadIntFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthReg"), _X("enHWType"), (int*)&pSt_AuthLocal->st_AuthRegInfo.enHWType); - SystemConfig_File_ReadIntFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthReg"), _X("enRegType"), (int*)&pSt_AuthLocal->st_AuthRegInfo.enRegType); - SystemConfig_File_ReadIntFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthReg"), _X("enSerialType"), (int*)&pSt_AuthLocal->st_AuthRegInfo.enSerialType); - SystemConfig_File_ReadIntFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthReg"), _X("enVModeType"), (int*)&pSt_AuthLocal->st_AuthRegInfo.enVModeType); - SystemConfig_File_ReadInt64FromMemory(lpszMsgBuffer, nMsgLen, _X("AuthReg"), _X("nHasTime"), &pSt_AuthLocal->st_AuthRegInfo.nHasTime); - - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszHardware"), pSt_AuthLocal->st_AuthRegInfo.tszHardware)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszCreateTime"), pSt_AuthLocal->st_AuthRegInfo.tszCreateTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszRegisterTime"), pSt_AuthLocal->st_AuthRegInfo.tszRegisterTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszLeftTime"), pSt_AuthLocal->st_AuthRegInfo.tszLeftTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszStartTime"), pSt_AuthLocal->st_AuthRegInfo.tszStartTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - //设置启动时间 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY == pSt_AuthLocal->st_AuthRegInfo.enSerialType) - { - XENGINE_LIBTIME st_EndTimer; - XENGINE_LIBTIME st_StartTime; - - memset(&st_EndTimer, '\0', sizeof(XENGINE_LIBTIME)); - memset(&st_StartTime, '\0', sizeof(XENGINE_LIBTIME)); - - BaseLib_Time_GetSysTime(&st_EndTimer); - BaseLib_Time_StrToTime(pSt_AuthLocal->st_AuthRegInfo.tszStartTime, &st_StartTime); - if ((st_EndTimer.wYear != st_StartTime.wYear) || (st_EndTimer.wMonth != st_StartTime.wMonth) || (st_EndTimer.wDay != st_StartTime.wDay)) - { - pSt_AuthLocal->st_AuthRegInfo.nHasTime--; - } - BaseLib_Time_TimeToStr(pSt_AuthLocal->st_AuthRegInfo.tszStartTime); - } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == pSt_AuthLocal->st_AuthRegInfo.enSerialType) - { - memset(pSt_AuthLocal->st_AuthRegInfo.tszStartTime, '\0', sizeof(pSt_AuthLocal->st_AuthRegInfo.tszStartTime)); - BaseLib_Time_TimeToStr(pSt_AuthLocal->st_AuthRegInfo.tszStartTime); - } - - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthReg"), _X("tszExpiryTime"), pSt_AuthLocal->st_AuthRegInfo.tszExpiryTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - //序列号信息 - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("tszTimeSerial"), pSt_AuthLocal->st_AuthSerial.st_TimeLimit.tszTimeSerial)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_ReadIntFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("nTimeCount"), &pSt_AuthLocal->st_AuthSerial.st_TimeLimit.nTimeCount)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("tszDataSerial"), pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataSerial)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("tszDataTime"), pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - SystemConfig_File_ReadIntFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("bAddTime"), (int*)&pSt_AuthLocal->st_AuthSerial.st_DataLimit.bTimeAdd); - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthSerial"), _X("tszUNLimitSerial"), pSt_AuthLocal->st_AuthSerial.st_UNLimit.tszUNLimitSerial)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - //用户信息 - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthUser"), _X("tszUserName"), pSt_AuthLocal->st_AuthUserInfo.tszUserName)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthUser"), _X("tszUserContact"), pSt_AuthLocal->st_AuthUserInfo.tszUserContact)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!SystemConfig_File_ReadProfileFromMemory(lpszMsgBuffer, nMsgLen, _X("AuthUser"), _X("tszCustom"), pSt_AuthLocal->st_AuthUserInfo.tszCustom)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = BaseLib_GetLastError(); - return false; - } - return true; -} -/******************************************************************** -函数名称:Authorize_CDKey_BuildKeyTime -函数功能:构造注册的时间结构体信息 - 参数.一:pSt_AuthLocal - In/Out:In - 类型:结构体指针 - 可空:N - 意思:要构造的结构体 - 参数.二:nDayTimer - In/Out:In - 类型:整数型 - 可空:Y - 意思:可用时间或者次数.非自定义时间需要设置此值 - 参数.三:pSt_DayTimer - In/Out:In - 类型:结构体指针 - 可空:Y - 意思:如果是自定义时间,这个参数需要设置,其他类型请设置参数二 -返回值 - 类型:逻辑型 - 意思:是否构造成功 -备注:此函数会修改st_AuthRegInfo的时间信息成员,必须重写CDKEY -*********************************************************************/ -bool CAuthorize_CDKey::Authorize_CDKey_BuildKeyTime(XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal, __int64x nDayTimer /* = 0 */, XENGINE_LIBTIME* pSt_DayTimer /* = NULL */) -{ - Authorize_IsErrorOccur = false; - - pSt_AuthLocal->st_AuthAppInfo.bInit = true; - //判断注册时间方式 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM == pSt_AuthLocal->st_AuthRegInfo.enSerialType) - { - //按照到期时间计算 - _xstprintf(pSt_AuthLocal->st_AuthRegInfo.tszLeftTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), pSt_DayTimer->wYear, pSt_DayTimer->wMonth, pSt_DayTimer->wDay, pSt_DayTimer->wHour, pSt_DayTimer->wMinute, pSt_DayTimer->wSecond); - } - else - { - pSt_AuthLocal->st_AuthRegInfo.nHasTime = nDayTimer; - _xstprintf(pSt_AuthLocal->st_AuthRegInfo.tszLeftTime, _X("%lld"), nDayTimer); - } - return true; -} -/******************************************************************** -函数名称:Authorize_CDKey_UserRegister -函数功能:用户注册CDKEY函数 - 参数.一:pSt_AuthLocal - In/Out:In - 类型:结构体指针 - 可空:N - 意思:要构造的结构体 - 参数.二:lpszSerialStr - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入注册验证的序列号 -返回值 - 类型:逻辑型 - 意思:是否构造成功 -备注:此函数会修改st_AuthRegInfo的时间信息成员,必须重写CDKEY -*********************************************************************/ -bool CAuthorize_CDKey::Authorize_CDKey_UserRegister(XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal, LPCXSTR lpszSerialStr) -{ - Authorize_IsErrorOccur = false; - - if (NULL == pSt_AuthLocal || NULL == lpszSerialStr) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - bool bSerial = false; - - if (0 == _tcsxncmp(pSt_AuthLocal->st_AuthSerial.st_TimeLimit.tszTimeSerial, lpszSerialStr, _tcsxlen(pSt_AuthLocal->st_AuthSerial.st_TimeLimit.tszTimeSerial))) - { - //次数验证 - bSerial = true; - pSt_AuthLocal->st_AuthRegInfo.enSerialType = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME; - pSt_AuthLocal->st_AuthRegInfo.enRegType = ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_OFFICIAL; - Authorize_CDKey_BuildKeyTime(pSt_AuthLocal, pSt_AuthLocal->st_AuthSerial.st_TimeLimit.nTimeCount); - } - else if (0 == _tcsxncmp(pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataSerial, lpszSerialStr, _tcsxlen(pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataSerial))) - { - //日期序列 - bSerial = true; - pSt_AuthLocal->st_AuthRegInfo.enSerialType = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM; - pSt_AuthLocal->st_AuthRegInfo.enRegType = ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_OFFICIAL; - XENGINE_LIBTIME st_LibTime = {}; - BaseLib_Time_GetSysTime(&st_LibTime); - if (pSt_AuthLocal->st_AuthSerial.st_DataLimit.bTimeAdd) - { - __int64x nTimeCount = 0; - XENGINE_LIBTIME st_AddTime = {}; - - BaseLib_TimeSpan_GetForStr(pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataTime, pSt_AuthLocal->st_AuthRegInfo.tszCreateTime, &nTimeCount); - st_AddTime.wDay = (int)nTimeCount; - BaseLib_TimeSpan_CalForStu(&st_LibTime, &st_AddTime); - - Authorize_CDKey_BuildKeyTime(pSt_AuthLocal, 0, &st_AddTime); - } - else - { - __int64x nTimeCount = 0; - XCHAR tszTimeStr[128] = {}; - XENGINE_LIBTIME st_LibTime = {}; - BaseLib_Time_TimeToStr(tszTimeStr); - - BaseLib_TimeSpan_GetForStr(tszTimeStr, pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataTime, &nTimeCount); - if (nTimeCount <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_TIMEOUT; - return false; - } - BaseLib_Time_StrToTime(pSt_AuthLocal->st_AuthSerial.st_DataLimit.tszDataTime, &st_LibTime); - Authorize_CDKey_BuildKeyTime(pSt_AuthLocal, 0, &st_LibTime); - } - } - else if (0 == _tcsxncmp(pSt_AuthLocal->st_AuthSerial.st_UNLimit.tszUNLimitSerial, lpszSerialStr, _tcsxlen(pSt_AuthLocal->st_AuthSerial.st_UNLimit.tszUNLimitSerial))) - { - //无限制 - bSerial = true; - pSt_AuthLocal->st_AuthRegInfo.enRegType = ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_UNLIMIT; - } - - if (!bSerial) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_FAILED; - return false; - } - BaseLib_Time_TimeToStr(pSt_AuthLocal->st_AuthRegInfo.tszRegisterTime); - return true; -} -/******************************************************************** -函数名称:Authorize_CDKey_GetLeftTimer -函数功能:验证CDKey - 参数.一:pSt_AuthLocal - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:输入Authorize_CDKey_ReadKey获取到的值 - 参数.二:lpszSerialNumber - In/Out:In - 类型:常量字符指针 - 可空:Y - 意思:如果CDKEY带序列号,可以输入序列号进行验证(优先序列号验证,失败进行常规CDKEY验证) -返回值 - 类型:逻辑型 - 意思:是否成功 -备注:无限制版本不做验证 - 其他验证nHasTime将被设置还拥有时间 - 此函数在程序启动的时候必须调用,可以设置更新CDKEY信息也可以验证CDKEY -*********************************************************************/ -bool CAuthorize_CDKey::Authorize_CDKey_GetLeftTimer(XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal, LPCXSTR lpszSerialNumber /* = NULL */) -{ - Authorize_IsErrorOccur = false; - - if (NULL == pSt_AuthLocal) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - //验证CDKEY本身情况 - XENGINE_LIBTIME st_StartTimer; - XENGINE_LIBTIME st_EndTimer; - XENGINE_LIBTIME st_SysTimer; - - memset(&st_StartTimer, '\0', sizeof(XENGINE_LIBTIME)); - memset(&st_EndTimer, '\0', sizeof(XENGINE_LIBTIME)); - memset(&st_SysTimer, '\0', sizeof(XENGINE_LIBTIME)); - - BaseLib_Time_TimeToStr(pSt_AuthLocal->st_AuthRegInfo.tszStartTime); - //处理注册类型 - if (ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_UNLIMIT == pSt_AuthLocal->st_AuthRegInfo.enRegType) - { - return true; - } - else if (ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_UNKNOW == pSt_AuthLocal->st_AuthRegInfo.enRegType) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_UNKNOW; - return false; - } - else if (ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_TEMP == pSt_AuthLocal->st_AuthRegInfo.enRegType) - { - if (_tcsxlen(pSt_AuthLocal->st_AuthRegInfo.tszExpiryTime) > 1) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_TEMP; - return false; - } - else - { - pSt_AuthLocal->st_AuthRegInfo.enRegType = ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_EXPIRED; - _xstprintf(pSt_AuthLocal->st_AuthRegInfo.tszExpiryTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), st_SysTimer.wYear, st_SysTimer.wMonth, st_SysTimer.wDay, st_SysTimer.wHour, st_SysTimer.wMinute, st_SysTimer.wSecond); - } - } - else if (ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_EXPIRED == pSt_AuthLocal->st_AuthRegInfo.enRegType) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_EXPIRED; - return false; - } - else - { - //其他类型的注册机制 - BaseLib_Time_GetSysTime(&st_SysTimer); - //计算超时时间 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == pSt_AuthLocal->st_AuthRegInfo.enSerialType) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_NOTSUPPORT; - return false; - } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY == pSt_AuthLocal->st_AuthRegInfo.enSerialType) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_NOTSUPPORT; - return false; - } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME == pSt_AuthLocal->st_AuthRegInfo.enSerialType) - { - pSt_AuthLocal->st_AuthRegInfo.nHasTime--; - } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM == pSt_AuthLocal->st_AuthRegInfo.enSerialType) - { - _stxscanf(pSt_AuthLocal->st_AuthRegInfo.tszLeftTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), &st_EndTimer.wYear, &st_EndTimer.wMonth, &st_EndTimer.wDay, &st_EndTimer.wHour, &st_EndTimer.wMinute, &st_EndTimer.wSecond); - BaseLib_TimeSpan_GetForStu(&st_SysTimer, &st_EndTimer, &pSt_AuthLocal->st_AuthRegInfo.nHasTime, ENUM_XENGINE_BASELIB_TIME_TYPE_SECOND); - } - else - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_NOTSUPPORT; - return false; - } - if (pSt_AuthLocal->st_AuthRegInfo.nHasTime < 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_TIMEOUT; - pSt_AuthLocal->st_AuthRegInfo.enRegType = ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_EXPIRED; - _xstprintf(pSt_AuthLocal->st_AuthRegInfo.tszExpiryTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), st_SysTimer.wYear, st_SysTimer.wMonth, st_SysTimer.wDay, st_SysTimer.wHour, st_SysTimer.wMinute, st_SysTimer.wSecond); - return false; - } - } - pSt_AuthLocal->st_AuthAppInfo.nExecTime++; - return true; -} -/******************************************************************** -函数名称:Authorize_CDKey_WriteTime -函数功能:记录一次执行时间 - 参数.一:lpszFileKey - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要操作的文件 - 参数.二:nCount - In/Out:In - 类型:整数型 - 可空:Y - 意思:输入最大允许记录个数,0不限制 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注:记录次数越多,文件越大.读取需要的内存就越多 -*********************************************************************/ -bool CAuthorize_CDKey::Authorize_CDKey_WriteTime(LPCXSTR lpszFileKey, int nCount /* = 0 */) -{ - Authorize_IsErrorOccur = false; - - if (NULL == lpszFileKey) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - //添加执行信息 - bool bFound = false; - LPCXSTR lpszTimeStr = _X("[TimeList]"); - FILE* pSt_File = _xtfopen(lpszFileKey, _X("r+")); - if (NULL == pSt_File) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_OPENFILE; - return false; - } - XCHAR tszMsgBuffer[XPATH_MAX]; - memset(tszMsgBuffer, '\0', XPATH_MAX); - //查找是否有时间列表字段 - while (1) - { - if (NULL == fgets(tszMsgBuffer, XPATH_MAX, pSt_File)) - { - break; - } - if (0 == _tcsxncmp(lpszTimeStr, tszMsgBuffer, _tcsxlen(lpszTimeStr))) - { - bFound = true; - break; - } - } - //设置文件指针 - if (bFound) - { - //如果设置了最大个数 - if (nCount > 0) - { - int nListCount = 0; - XCHAR** pptszListTime = NULL; - //读取现有的 - Authorize_CDKey_ReadTime(lpszFileKey, &pptszListTime, &nListCount); - //是否大于14 >= 10 - if (nListCount >= nCount) - { - long lFSize = ftell(pSt_File); - //需要截断文件 - fclose(pSt_File); - int hFile = _xtopen(lpszFileKey, O_RDWR | O_CREAT, S_IREAD | S_IWRITE); -#ifdef _MSC_BUILD - if (0 != _chsize_s(hFile, lFSize)) -#else - if (0 != ftruncate(hFile, lFSize)) -#endif - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_SETFILE; - return false; - } - _close(hFile); - //重新打开文件 - pSt_File = _xtfopen(lpszFileKey, _X("r+")); - fseek(pSt_File, 0, SEEK_END); - //从我们要保留的地方开始轮训 - for (int i = (nListCount - nCount + 1); i < nListCount; i++) - { - fwrite(pptszListTime[i], 1, _tcsxlen(pptszListTime[i]), pSt_File); - fwrite(_X("|"), 1, 1, pSt_File); - } - } - else - { - //在末尾添加 - fseek(pSt_File, -1, SEEK_END); - XCHAR cChar = fgetc(pSt_File); - if (cChar == '\n') - { - fseek(pSt_File, -2, SEEK_END); - } - else - { - fseek(pSt_File, 0, SEEK_END); - } - } - } - else - { - //在末尾添加 - fseek(pSt_File, -1, SEEK_END); - XCHAR cChar = fgetc(pSt_File); - if (cChar == '\n') - { - fseek(pSt_File, -2, SEEK_END); - } - else - { - fseek(pSt_File, 0, SEEK_END); - } - } - } - else - { - fseek(pSt_File, 0, SEEK_END); - if (tszMsgBuffer[_tcsxlen(tszMsgBuffer) - 1] != '\n') - { - fwrite(_X("\n"), 1, 1, pSt_File); - } - fwrite(lpszTimeStr, 1, _tcsxlen(lpszTimeStr), pSt_File); - fwrite(_X("\n"), 1, 1, pSt_File); - } - memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer)); -#ifdef _MSC_BUILD - _xstprintf(tszMsgBuffer, _X("%lld|"), time(NULL)); -#else - _xstprintf(tszMsgBuffer, _X("%ld|"), time(NULL)); -#endif - //追加 - fwrite(tszMsgBuffer, 1, _tcsxlen(tszMsgBuffer), pSt_File); - fclose(pSt_File); - return true; -} -/******************************************************************** -函数名称:Authorize_CDKey_ReadTime -函数功能:读取记录的时间列表信息 - 参数.一:lpszFileKey - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要读取的文件 - 参数.二:ppptszTimeList - In/Out:Out - 类型:三级指针 - 可空:N - 意思:输出时间信息列表 - 参数.三:pInt_ListCount - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出个数 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CAuthorize_CDKey::Authorize_CDKey_ReadTime(LPCXSTR lpszFileKey, XCHAR*** ppptszTimeList, int* pInt_ListCount) -{ - Authorize_IsErrorOccur = false; - - if ((NULL == lpszFileKey) || (NULL == pInt_ListCount)) - { - return false; - } - bool bFound = false; - LPCXSTR lpszTimeStr = _X("[TimeList]"); - FILE* pSt_File = _xtfopen(lpszFileKey, _X("rb")); - if (NULL == pSt_File) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_OPENFILE; - return false; - } - XCHAR tszMsgBuffer[XPATH_MAX]; - //查找是否有时间列表字段 - while (1) - { - memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer)); - if (NULL == fgets(tszMsgBuffer, XPATH_MAX, pSt_File)) - { - break; - } - if (0 == _tcsxncmp(lpszTimeStr, tszMsgBuffer, _tcsxlen(lpszTimeStr))) - { - bFound = true; - break; - } - } - //设置文件指针 - if (!bFound) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_TIMELIST; - return false; - } - list stl_ListTime; - struct stat st_FileStat; - stat(lpszFileKey, &st_FileStat); - //申请足够的内存 - XCHAR* ptszMsgBuffer = (XCHAR*)malloc(st_FileStat.st_size); - if (NULL == ptszMsgBuffer) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_MALLOC; - return false; - } - memset(ptszMsgBuffer, '\0', st_FileStat.st_size); - if (fread(ptszMsgBuffer, 1, st_FileStat.st_size, pSt_File) <= 0) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_READ; - free(ptszMsgBuffer); - ptszMsgBuffer = NULL; - return false; - } - //申请内存 - XCHAR* ptszTokStr = _tcsxtok(ptszMsgBuffer, _X("|")); - while (NULL != ptszTokStr) - { - if (_tcsxlen(ptszTokStr) > 4) - { - stl_ListTime.push_back(ptszTokStr); - } - ptszTokStr = _tcsxtok(NULL, _X("|")); - } - fclose(pSt_File); - free(ptszMsgBuffer); - ptszMsgBuffer = NULL; - //导出 - *pInt_ListCount = (int)stl_ListTime.size(); - BaseLib_Memory_Malloc((XPPPMEM)ppptszTimeList, *pInt_ListCount, 64); - list::const_iterator stl_ListIterator = stl_ListTime.begin(); - for (int i = 0; stl_ListIterator != stl_ListTime.end(); stl_ListIterator++, i++) - { - _tcsxcpy((*ppptszTimeList)[i], stl_ListIterator->c_str()); - } - stl_ListTime.clear(); - return true; -} \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_CDKey/Authorize_CDKey/Authorize_CDKey.h b/XEngine_Source/AuthorizeModule_CDKey/Authorize_CDKey/Authorize_CDKey.h deleted file mode 100644 index af62493..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/Authorize_CDKey/Authorize_CDKey.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2024/07/08 17:27:26 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey\Authorize_CDKey\Authorize_CDKey.h -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey\Authorize_CDKey -// File Base: Authorize_CDKey -// File Ext: h -// Project: XEngine -// Author: qyt -// Purpose: 本地授权服务 -// History: -*********************************************************************/ - -class CAuthorize_CDKey -{ -public: - CAuthorize_CDKey(); - ~CAuthorize_CDKey(); -public: - bool Authorize_CDKey_WriteKey(LPCXSTR lpszFileKey, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal); - bool Authorize_CDKey_ReadKey(LPCXSTR lpszFileKey, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal); - bool Authorize_CDKey_WriteMemory(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal); - bool Authorize_CDKey_ReadMemory(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal); -public: - bool Authorize_CDKey_BuildKeyTime(XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal, __int64x nDayTimer = 0, XENGINE_LIBTIME* pSt_DayTimer = NULL); - bool Authorize_CDKey_UserRegister(XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal, LPCXSTR lpszSerialStr); - bool Authorize_CDKey_GetLeftTimer(XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal, LPCXSTR lpszSerialNumber = NULL); - bool Authorize_CDKey_WriteTime(LPCXSTR lpszFileKey, int nCount = 0); - bool Authorize_CDKey_ReadTime(LPCXSTR lpszFileKey, XCHAR*** ppptszTimeList, int* pInt_ListCount); -private: -}; diff --git a/XEngine_Source/AuthorizeModule_CDKey/Authorize_Serial/Authorize_Serial.cpp b/XEngine_Source/AuthorizeModule_CDKey/Authorize_Serial/Authorize_Serial.cpp deleted file mode 100644 index 2dc41a4..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/Authorize_Serial/Authorize_Serial.cpp +++ /dev/null @@ -1,509 +0,0 @@ -#include "pch.h" -#include "Authorize_Serial.h" -/******************************************************************** -// Created: 2024/07/08 17:30:53 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey\Authorize_Serial\Authorize_Serial.cpp -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey\Authorize_Serial -// File Base: Authorize_Serial -// File Ext: cpp -// Project: XEngine -// Author: qyt -// Purpose: 序列卡生成器 -// History: -*********************************************************************/ -CAuthorize_Serial::CAuthorize_Serial() -{ - memset(tszTimerSecond, '\0', sizeof(tszTimerSecond)); - memset(tszTimerDay, '\0', sizeof(tszTimerDay)); - memset(tszTimerTime, '\0', sizeof(tszTimerTime)); - memset(tszTimerCustom, '\0', sizeof(tszTimerCustom)); - - _tcsxcpy(tszTimerSecond, _X("XYRYS")); - _tcsxcpy(tszTimerDay, _X("XYRYD")); - _tcsxcpy(tszTimerTime, _X("XYRYT")); - _tcsxcpy(tszTimerCustom, _X("XYRYC")); -} -CAuthorize_Serial::~CAuthorize_Serial() -{ - -} -////////////////////////////////////////////////////////////////////////// -// 公有函数 -////////////////////////////////////////////////////////////////////////// -/******************************************************************** -函数名称:Authorize_Serial_Creator -函数功能:开始生成指定的序列号 - 参数.一:ppptszSerialNumber - In/Out:Out - 类型:三级指针 - 可空:N - 意思:输出序列卡列表,根据nCardNumber 来确定列表个数 - 参数.二:lpszUserHeader - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:自定义头,长度为6,填充5 比如 XHEAD - 参数.三:nCardNumber - In/Out:In - 类型:整数型 - 可空:N - 意思:要生成多少张卡,生成多了,此函数会阻塞程序,那么请放置线程中运行 - 参数.四:nFieldNumber - In/Out:In - 类型:整数型 - 可空:N - 意思:卡的段数,AAAAA-BBBBB-CCCCC-DDDDD-EEEEE,不包含三段自定义头,总字段:3 + nFieldNumber - 参数.五:pSt_CustomTimer - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:如果第五个参数为自定义日期,那么这个参数必须赋值。如果第五个参数为天数卡,这个结构体的nDay 必须赋值,表明拥有几天。 - 如果是分钟卡,那么这个值的nMinute必须有值,表示拥有的分钟.如果是次数卡,那么这个值的wFlags必须有值,表示拥有的次数,其他类型可以为NULL - 参数.六:enSerialType - In/Out:In - 类型:枚举型 - 可空:Y - 意思:要生成的卡类型 -返回值 - 类型:逻辑型 - 意思:是否生成成功 -备注:输入的时间不能超过99999,多天卡现在由用户直接使用pSt_CustomTimer参数指定,不在内部指定了 -*********************************************************************/ -bool CAuthorize_Serial::Authorize_Serial_Creator(XCHAR*** ppptszSerialNumber, LPCXSTR lpszUserHeader, int nCardNumber, int nFieldNumber, XENGINE_LIBTIME* pSt_CustomTimer, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType /* = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY */) -{ - Authorize_IsErrorOccur = false; - //参数检查 - if ((NULL == ppptszSerialNumber) || (NULL == lpszUserHeader)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - BaseLib_Memory_Malloc((XPPPMEM)ppptszSerialNumber, nCardNumber, XPATH_MAX); - srand((unsigned int)time(NULL)); //取随机因子 - - for (int i = 0; i < nCardNumber; i++) - { - XCHAR tszSerialNumber[XPATH_MAX]; - memset(tszSerialNumber, '\0', XPATH_MAX); - //检查生成类型 - switch (enSerialType) - { - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND: - { - if (NULL == pSt_CustomTimer) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - XCHAR tszFillBuffer[10]; - XCHAR tszDayBuffer[10]; - memset(tszFillBuffer, '\0', sizeof(tszFillBuffer)); - memset(tszDayBuffer, '\0', sizeof(tszDayBuffer)); - - Authorize_Serial_RandomWord(tszFillBuffer); - _xstprintf(tszDayBuffer, _X("%d"), pSt_CustomTimer->wSecond); - memcpy(tszFillBuffer + (_tcsxlen(tszFillBuffer) - _tcsxlen(tszDayBuffer)), tszDayBuffer, _tcsxlen(tszDayBuffer)); - - _xstprintf(tszSerialNumber, _X("%s-%s-%s"), lpszUserHeader, tszTimerSecond, tszFillBuffer); - if (!Authorize_Serial_Fill(tszSerialNumber, nFieldNumber)) - { - return false; - } - } - break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY: - { - if (NULL == pSt_CustomTimer) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - XCHAR tszFillBuffer[10]; - XCHAR tszDayBuffer[10]; - memset(tszFillBuffer, '\0', sizeof(tszFillBuffer)); - memset(tszDayBuffer, '\0', sizeof(tszDayBuffer)); - - Authorize_Serial_RandomWord(tszFillBuffer); - _xstprintf(tszDayBuffer, _X("%d"), pSt_CustomTimer->wDay); - memcpy(tszFillBuffer + (_tcsxlen(tszFillBuffer) - _tcsxlen(tszDayBuffer)), tszDayBuffer, _tcsxlen(tszDayBuffer)); - - _xstprintf(tszSerialNumber, _X("%s-%s-%s"), lpszUserHeader, tszTimerDay, tszFillBuffer); - if (!Authorize_Serial_Fill(tszSerialNumber, nFieldNumber)) - { - return false; - } - } - break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME: - XCHAR tszFillBuffer[10]; - XCHAR tszTimeBuffer[10]; - memset(tszFillBuffer, '\0', sizeof(tszFillBuffer)); - memset(tszTimeBuffer, '\0', sizeof(tszTimeBuffer)); - - Authorize_Serial_RandomWord(tszFillBuffer); - _xstprintf(tszTimeBuffer, _X("%d"), pSt_CustomTimer->wFlags); - memcpy(tszFillBuffer + (_tcsxlen(tszFillBuffer) - _tcsxlen(tszTimeBuffer)), tszTimeBuffer, _tcsxlen(tszTimeBuffer)); - - _xstprintf(tszSerialNumber, _X("%s-%s-%s"), lpszUserHeader, tszTimerTime, tszFillBuffer); - if (!Authorize_Serial_Fill(tszSerialNumber, nFieldNumber)) - { - return false; - } - break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM: - if (NULL == pSt_CustomTimer) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - XCHAR tszTimer[128]; - memset(tszTimer, '\0', 128); - - if ((pSt_CustomTimer->wHour > 0) || (pSt_CustomTimer->wMinute > 0) || (pSt_CustomTimer->wSecond > 0)) - { - _xstprintf(tszTimer, _X("%04d%02d%02d-%02d%02d%02d"), pSt_CustomTimer->wYear, pSt_CustomTimer->wMonth, pSt_CustomTimer->wDay, pSt_CustomTimer->wHour, pSt_CustomTimer->wMinute, pSt_CustomTimer->wSecond); - nFieldNumber--; - } - else - { - _xstprintf(tszTimer, _X("%04d%02d%02d"), pSt_CustomTimer->wYear, pSt_CustomTimer->wMonth, pSt_CustomTimer->wDay); - } - _xstprintf(tszSerialNumber, _X("%s-%s-%s"), lpszUserHeader, tszTimerCustom, tszTimer); - if (!Authorize_Serial_Fill(tszSerialNumber, nFieldNumber)) - { - return false; - } - break; - default: - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_NOTSUPPORT; - return false; - } - _tcsxcpy((*ppptszSerialNumber)[i], tszSerialNumber); - } - return true; -} -/******************************************************************** -函数名称:Authorize_Serial_Creator -函数功能:创建自定义无类型序列号 - 参数.一:ppptszSerialNumber - In/Out:Out - 类型:三级指针 - 可空:N - 意思:输出序列卡列表,根据nCardNumber 来确定列表个数 - 参数.二:lpszUserHeader - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:自定义头,长度为6,填充5 比如 XHEAD - 参数.三:nCardNumber - In/Out:In - 类型:整数型 - 可空:N - 意思:要生成多少张卡,生成多了,此函数会阻塞程序,那么请放置线程中运行 - 参数.四:nFieldNumber - In/Out:In - 类型:整数型 - 可空:N - 意思:卡的段数,AAAAA-BBBBB-CCCCC-DDDDD-EEEEE -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CAuthorize_Serial::Authorize_Serial_Create(XCHAR*** ppptszSerialNumber, LPCXSTR lpszUserHeader, int nCardNumber, int nFieldNumber) -{ - Authorize_IsErrorOccur = false; - //参数检查 - if ((NULL == ppptszSerialNumber) || (NULL == lpszUserHeader)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - BaseLib_Memory_Malloc((XPPPMEM)ppptszSerialNumber, nCardNumber, XPATH_MAX); - srand((unsigned int)time(NULL)); //取随机因子 - - for (int i = 0; i < nCardNumber; i++) - { - XCHAR tszSerialNumber[XPATH_MAX]; - memset(tszSerialNumber, '\0', XPATH_MAX);; - - _xstprintf(tszSerialNumber, _X("%s"), lpszUserHeader); - if (!Authorize_Serial_Fill(tszSerialNumber, nFieldNumber)) - { - return false; - } - _tcsxcpy((*ppptszSerialNumber)[i], tszSerialNumber); - } - return true; -} -/******************************************************************** -函数名称:Authorize_Serial_GetType -函数功能:获取一个序列号的类型 - 参数.一:lpszSerialNumber - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:要获取的缓冲区 - 参数.二:penSerialType - In/Out:Out - 类型:枚举型 - 可空:Y - 意思:导出此卡的类型 - 参数.三:pSt_CustomTimer - In/Out:Out - 类型:数据结构指针 - 可空:Y - 意思:如果不是自定义类型或者天数卡,或者次数卡,这个参数将不起作用 -返回值 - 类型:逻辑型 - 意思:是否获取成功 -备注: -*********************************************************************/ -bool CAuthorize_Serial::Authorize_Serial_GetType(LPCXSTR lpszSerialNumber, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE* penSerialType, XENGINE_LIBTIME* pSt_CustomTimer /* = NULL */) -{ - Authorize_IsErrorOccur = false; - - if (NULL == penSerialType) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - - XCHAR tszBuffer[6]; - XCHAR tszBuffertemp[6]; - XCHAR tszTimeData[128]; - XCHAR tszTimeTime[128]; - - memset(tszBuffer, '\0', 6); - memset(tszBuffertemp, '\0', 6); - memset(tszTimeData, '\0', sizeof(tszTimeData)); - memset(tszTimeTime, '\0', sizeof(tszTimeTime)); - //获取指定内容 - if (4 != _stxscanf(lpszSerialNumber, _X("%[^-]-%[^-]-%[^-]-%[^-]"), tszBuffertemp, tszBuffer, tszTimeData, tszTimeTime)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_BUFFER; - return false; - } - //匹配类型 - if (0 == _tcsxncmp(tszTimerSecond, tszBuffer, 5)) - { - if (NULL == pSt_CustomTimer) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - unsigned int i = 0; - for (i = 0; i < _tcsxlen(tszTimeData); i++) - { - if (0 != isdigit(tszTimeData[i])) - { - break; - } - } - XCHAR tszIntBuffer[64]; - memset(tszIntBuffer, '\0', sizeof(tszIntBuffer)); - memcpy(tszIntBuffer, tszTimeData + i, _tcsxlen(tszTimeData) - i); - pSt_CustomTimer->wSecond = _ttxoi(tszIntBuffer); - - *penSerialType = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND; - } - else if (0 == _tcsxncmp(tszTimerDay, tszBuffer, 5)) - { - if (NULL == pSt_CustomTimer) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - unsigned int i = 0; - for (i = 0; i < _tcsxlen(tszTimeData); i++) - { - if (0 != isdigit(tszTimeData[i])) - { - break; - } - } - XCHAR tszIntBuffer[64]; - memset(tszIntBuffer, '\0', sizeof(tszIntBuffer)); - memcpy(tszIntBuffer, tszTimeData + i, _tcsxlen(tszTimeData) - i); - pSt_CustomTimer->wDay = _ttxoi(tszIntBuffer); - - *penSerialType = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY; - } - else if (0 == _tcsxncmp(tszTimerTime, tszBuffer, 5)) - { - if (NULL == pSt_CustomTimer) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - unsigned int i = 0; - for (i = 0; i < _tcsxlen(tszTimeData); i++) - { - if (0 != isdigit(tszTimeData[i])) - { - break; - } - } - XCHAR tszIntBuffer[64]; - memset(tszIntBuffer, '\0', sizeof(tszIntBuffer)); - memcpy(tszIntBuffer, tszTimeData + i, _tcsxlen(tszTimeData) - i); - pSt_CustomTimer->wFlags = _ttxoi(tszIntBuffer); - - *penSerialType = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME; - } - else if (0 == _tcsxncmp(tszTimerCustom, tszBuffer, 5)) - { - *penSerialType = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM; - if (NULL == pSt_CustomTimer) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT; - return false; - } - if (3 != _stxscanf(tszTimeData, _X("%04d%02d%02d"), &pSt_CustomTimer->wYear, &pSt_CustomTimer->wMonth, &pSt_CustomTimer->wDay)) - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_CUSTOM; - return false; - } - if (3 != _stxscanf(tszTimeTime, _X("%02d%02d%02d"), &pSt_CustomTimer->wHour, &pSt_CustomTimer->wMinute, &pSt_CustomTimer->wSecond)) - { - pSt_CustomTimer->wHour = 0; - pSt_CustomTimer->wMinute = 0; - pSt_CustomTimer->wSecond = 0; - } - } - else - { - Authorize_IsErrorOccur = true; - Authorize_dwErrorCode = ERROR_AUTHORIZE_MODULE_CDKEY_UNKNOW; - return false; - } - return true; -} -////////////////////////////////////////////////////////////////////////// -// 保护函数 -////////////////////////////////////////////////////////////////////////// -/******************************************************************** -函数名称:Authorize_Serial_Fill -函数功能:填充缓冲区 - 参数.一:ptszFillBuffer - In/Out:In/Out - 类型:字符指针 - 可空:N - 意思:输入填充了头和序列号类型的缓冲区 HEARD-XYRYD - 参数.二:nCardNumer - In/Out:In - 类型:整数型 - 可空:N - 意思:要生成的卡的段数 -返回值 - 类型:逻辑型 - 意思:是否生成成功 -备注: -*********************************************************************/ -bool CAuthorize_Serial::Authorize_Serial_Fill(XCHAR *ptszFillBuffer, int nCardNumer) -{ - Authorize_IsErrorOccur = false; - - int nPosType = 0; - - for (int i = 3; i < nCardNumer; i++) - { - XCHAR tszRandom[6]; - memset(tszRandom, '\0', 6); - if (0 == nPosType) - { - Authorize_Serial_Random(tszRandom); - _tcsxcat(ptszFillBuffer, _X("-")); - _tcsxcat(ptszFillBuffer, tszRandom); - nPosType = 1; - } - else if (1 == nPosType) - { - Authorize_Serial_RandomWord(tszRandom); - _tcsxcat(ptszFillBuffer, _X("-")); - _tcsxcat(ptszFillBuffer, tszRandom); - nPosType = 2; - } - else - { - Authorize_Serial_RandomNumber(tszRandom); - _tcsxcat(ptszFillBuffer, _X("-")); - _tcsxcat(ptszFillBuffer, tszRandom); - nPosType = 0; - } - } - return true; -} -/******************************************************************** -函数名称:Authorize_Serial_Random -函数功能:取随机字母数字 - 参数.一:ptszFillBuffer - In/Out:In/Out - 类型:字符指针 - 可空:N - 意思:输入已经初始化为0的字符串,内存空间为6,导出生成成功的字符串 -返回值 - 类型:逻辑型 - 意思:是否生成成功 -备注: -*********************************************************************/ -bool CAuthorize_Serial::Authorize_Serial_Random(XCHAR *ptszFillBuffer) -{ - Authorize_IsErrorOccur = false; - - BaseLib_Handle_CreateStr(ptszFillBuffer, 5, 0, 1); - return true; -} -/******************************************************************** -函数名称:Authorize_Serial_RandomWord -函数功能:取随机字母,大写 - 参数.一:ptszFillBuffer - In/Out:In/Out - 类型:字符指针 - 可空:N - 意思:输入已经初始化为0的字符串,内存空间为6,导出生成成功的字符串 -返回值 - 类型:逻辑型 - 意思:是否生成成功 -备注: -*********************************************************************/ -bool CAuthorize_Serial::Authorize_Serial_RandomWord(XCHAR *ptszFillBuffer) -{ - Authorize_IsErrorOccur = false; - - BaseLib_Handle_CreateStr(ptszFillBuffer, 5, 2, 1); - return true; -} -/******************************************************************** -函数名称:Authorize_Serial_RandomNumber -函数功能:取随机数 - 参数.一:ptszFillBuffer - In/Out:In/Out - 类型:字符指针 - 可空:N - 意思:输入已经初始化为0的字符串,内存空间为6,导出生成成功的字符串 -返回值 - 类型:逻辑型 - 意思:是否生成成功 -备注: -*********************************************************************/ -bool CAuthorize_Serial::Authorize_Serial_RandomNumber(XCHAR *ptszFilleBuffer) -{ - Authorize_IsErrorOccur = false; - - BaseLib_Handle_CreateStr(ptszFilleBuffer, 5, 1); - return true; -} diff --git a/XEngine_Source/AuthorizeModule_CDKey/Authorize_Serial/Authorize_Serial.h b/XEngine_Source/AuthorizeModule_CDKey/Authorize_Serial/Authorize_Serial.h deleted file mode 100644 index e69642a..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/Authorize_Serial/Authorize_Serial.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2024/07/08 17:30:06 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey\Authorize_Serial\Authorize_Serial.h -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey\Authorize_Serial -// File Base: Authorize_Serial -// File Ext: h -// Project: XEngine -// Author: qyt -// Purpose: 序列卡生成器 -// History: -*********************************************************************/ - - -class CAuthorize_Serial -{ -public: - CAuthorize_Serial(); - ~CAuthorize_Serial(); -public: - bool Authorize_Serial_Creator(XCHAR*** ppptszSerialNumber, LPCXSTR lpszUserHeader, int nCardNumber, int nFieldNumber, XENGINE_LIBTIME* pSt_CustomTimer, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY); - bool Authorize_Serial_Create(XCHAR*** ppptszSerialNumber, LPCXSTR lpszUserHeader, int nCardNumber, int nFieldNumber); - bool Authorize_Serial_GetType(LPCXSTR lpszSerialNumber, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE* penSerialType, XENGINE_LIBTIME* pSt_CustomTimer = NULL); -protected: - bool Authorize_Serial_Fill(XCHAR *ptszFillBuffer, int nCardNumer); //填充后面的字段 -protected: - bool Authorize_Serial_Random(XCHAR *ptszFillBuffer); //取随机字母数字 - bool Authorize_Serial_RandomWord(XCHAR *ptszFillBuffer); //随机取单词 - bool Authorize_Serial_RandomNumber(XCHAR *ptszFilleBuffer); //取随机数 -private: - XCHAR tszTimerSecond[6]; //按照秒钟时间格式 - XCHAR tszTimerDay[6]; //按照天的时间格式 - XCHAR tszTimerTime[6]; //次数卡 - XCHAR tszTimerCustom[32]; //自定义到期时间 -}; diff --git a/XEngine_Source/AuthorizeModule_CDKey/CDKey_Define.h b/XEngine_Source/AuthorizeModule_CDKey/CDKey_Define.h deleted file mode 100644 index c238bfa..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/CDKey_Define.h +++ /dev/null @@ -1,308 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2024/07/08 17:30:14 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey\Authorize_Define.h -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey -// File Base: Authorize_Define -// File Ext: h -// Project: XEngine -// Author: qyt -// Purpose: CDKEY授权验证服务 -// History: -*********************************************************************/ -////////////////////////////////////////////////////////////////////////// -// 导出函数 -////////////////////////////////////////////////////////////////////////// -extern "C" XLONG Authorize_GetLastError(int *pInt_SysError = NULL); -/************************************************************************/ -/* 序列卡导出函数 */ -/************************************************************************/ -/******************************************************************** -函数名称:Authorize_Serial_Creator -函数功能:开始生成指定的序列号 - 参数.一:ppptszSerialNumber - In/Out:Out - 类型:三级指针 - 可空:N - 意思:输出序列卡列表,根据nCardNumber 来确定列表个数 - 参数.二:lpszUserHeader - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:自定义头,长度为6,填充5 比如 XHEAD - 参数.三:nCardNumber - In/Out:In - 类型:整数型 - 可空:N - 意思:要生成多少张卡,生成多了,此函数会阻塞程序,那么请放置线程中运行 - 参数.四:nFieldNumber - In/Out:In - 类型:整数型 - 可空:N - 意思:卡的段数,AAAAA-BBBBB-CCCCC-DDDDD-EEEEE,不包含三段自定义头,总字段:3 + nFieldNumber - 参数.五:pSt_CustomTimer - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:如果第五个参数为自定义日期,那么这个参数必须赋值。如果第五个参数为天数卡,这个结构体的nDay 必须赋值,表明拥有几天。 - 如果是分钟卡,那么这个值的nMinute必须有值,表示拥有的分钟.如果是次数卡,那么这个值的wFlags必须有值,表示拥有的次数,其他类型可以为NULL - 参数.六:enSerialType - In/Out:In - 类型:枚举型 - 可空:Y - 意思:要生成的卡类型 -返回值 - 类型:逻辑型 - 意思:是否生成成功 -备注:输入的时间不能超过99999,多天卡现在由用户直接使用pSt_CustomTimer参数指定,不在内部指定了 -*********************************************************************/ -extern "C" bool Authorize_Serial_Creator(XCHAR * **ppptszSerialNumber, LPCXSTR lpszUserHeader, int nCardNumber, int nFieldNumber, XENGINE_LIBTIME * pSt_CustomTimer, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY); -/******************************************************************** -函数名称:Authorize_Serial_Create -函数功能:创建自定义无类型序列号 - 参数.一:ppptszSerialNumber - In/Out:Out - 类型:三级指针 - 可空:N - 意思:输出序列卡列表,根据nCardNumber 来确定列表个数 - 参数.二:lpszUserHeader - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:自定义头,长度为6,填充5 比如 XHEAD - 参数.三:nCardNumber - In/Out:In - 类型:整数型 - 可空:N - 意思:要生成多少张卡,生成多了,此函数会阻塞程序,那么请放置线程中运行 - 参数.四:nFieldNumber - In/Out:In - 类型:整数型 - 可空:N - 意思:卡的段数,AAAAA-BBBBB-CCCCC-DDDDD-EEEEE -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool Authorize_Serial_Create(XCHAR*** ppptszSerialNumber, LPCXSTR lpszUserHeader, int nCardNumber, int nFieldNumber); -/******************************************************************** -函数名称:Authorize_Serial_GetType -函数功能:获取一个序列号的类型 - 参数.一:lpszSerialNumber - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:要获取的缓冲区 - 参数.二:penSerialType - In/Out:Out - 类型:枚举型 - 可空:Y - 意思:导出此卡的类型 - 参数.三:pSt_CustomTimer - In/Out:Out - 类型:数据结构指针 - 可空:Y - 意思:如果不是自定义类型或者天数卡,或者次数卡,这个参数将不起作用 -返回值 - 类型:逻辑型 - 意思:是否获取成功 -备注: -*********************************************************************/ -extern "C" bool Authorize_Serial_GetType(LPCXSTR lpszSerialNumber, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE* penSerialType, XENGINE_LIBTIME* pSt_CustomTimer = NULL); -/************************************************************************/ -/* 本地授权导出函数 */ -/************************************************************************/ -/******************************************************************** -函数名称:Authorize_CDKey_WriteKey -函数功能:写一个CDKey文件 - 参数.一:lpszFileKey - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:要操作的文件路径 - 参数.二:pSt_AuthLocal - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:要写入的文件信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注:写入读取必须是明文,建议你加密处理CDKEY,通过OPENSSL模块,来加解密,在读写 -*********************************************************************/ -extern "C" bool Authorize_CDKey_WriteKey(LPCXSTR lpszFileKey, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal); -/******************************************************************** -函数名称:Authorize_CDKey_ReadKey -函数功能:读一个数据文件 - 参数.一:lpszFileKey - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:要操作的文件路径 - 参数.二:pSt_AuthLocal - In/Out:Out - 类型:数据结构指针 - 可空:N - 意思:导出获取到的文件信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool Authorize_CDKey_ReadKey(LPCXSTR lpszFileKey, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal); -/******************************************************************** -函数名称:Authorize_CDKey_WriteMemory -函数功能:写配置信息到内存 - 参数.一:ptszMsgBuffer - In/Out:Out - 类型:字符指针 - 可空:N - 意思:写到的内存 - 参数.二:pInt_MsgLen - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:写到的内存大小 - 参数.三:pSt_AuthLocal - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:输入要写的信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool Authorize_CDKey_WriteMemory(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal); -/******************************************************************** -函数名称:Authorize_CDKey_ReadMemory -函数功能:内存配置文件读取 - 参数.一:lpszMsgBuffer - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要读取配置的内存 - 参数.二:nMsgLen - In/Out:In - 类型:整数型 - 可空:N - 意思:输入读取内存大小 - 参数.三:pSt_AuthLocal - In/Out:Out - 类型:数据结构指针 - 可空:N - 意思:输出读取到的信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool Authorize_CDKey_ReadMemory(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal); -/******************************************************************** -函数名称:Authorize_CDKey_BuildKeyTime -函数功能:构造注册的时间结构体信息 - 参数.一:pSt_AuthLocal - In/Out:In - 类型:结构体指针 - 可空:N - 意思:要构造的结构体 - 参数.二:nDayTimer - In/Out:In - 类型:整数型 - 可空:Y - 意思:可用时间或者次数.非自定义时间需要设置此值 - 参数.三:pSt_DayTimer - In/Out:In - 类型:结构体指针 - 可空:Y - 意思:如果是自定义时间,这个参数需要设置,其他类型请设置参数二 -返回值 - 类型:逻辑型 - 意思:是否构造成功 -备注:此函数会修改st_AuthRegInfo的时间信息成员 -*********************************************************************/ -extern "C" bool Authorize_CDKey_BuildKeyTime(XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal, __int64x nDayTimer = 0, XENGINE_LIBTIME* pSt_DayTimer = NULL); -/******************************************************************** -函数名称:Authorize_CDKey_UserRegister -函数功能:用户注册CDKEY函数 - 参数.一:pSt_AuthLocal - In/Out:In - 类型:结构体指针 - 可空:N - 意思:要构造的结构体 - 参数.二:lpszSerialStr - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入注册验证的序列号 -返回值 - 类型:逻辑型 - 意思:是否构造成功 -备注:此函数会修改st_AuthRegInfo的时间信息成员,必须重写CDKEY -*********************************************************************/ -extern "C" bool Authorize_CDKey_UserRegister(XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal, LPCXSTR lpszSerialStr); -/******************************************************************** -函数名称:Authorize_CDKey_GetLeftTimer -函数功能:验证CDKey - 参数.一:pSt_AuthLocal - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:输入Authorize_CDKey_ReadKey获取到的值 - 参数.二:lpszSerialNumber - In/Out:In - 类型:常量字符指针 - 可空:Y - 意思:如果CDKEY带序列号,可以输入序列号进行验证(优先序列号验证,失败进行常规CDKEY验证) -返回值 - 类型:逻辑型 - 意思:是否成功 -备注:无限制版本不做验证 - 其他验证nHasTime将被设置还拥有时间 - 此函数在程序启动的时候必须调用,可以设置更新CDKEY信息也可以验证CDKEY -*********************************************************************/ -extern "C" bool Authorize_CDKey_GetLeftTimer(XENGINE_AUTHORIZE_LOCAL * pSt_AuthLocal, LPCXSTR lpszSerialNumber = NULL); -/******************************************************************** -函数名称:Authorize_CDKey_WriteTime -函数功能:记录一次执行时间 - 参数.一:lpszFileKey - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要操作的文件 - 参数.二:nCount - In/Out:In - 类型:整数型 - 可空:Y - 意思:输入最大允许记录个数,0不限制 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注:记录次数越多,文件越大.读取需要的内存就越多 -*********************************************************************/ -extern "C" bool Authorize_CDKey_WriteTime(LPCXSTR lpszFileKey, int nCount = 0); -/******************************************************************** -函数名称:Authorize_CDKey_ReadTime -函数功能:读取记录的时间列表信息 - 参数.一:lpszFileKey - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要读取的文件 - 参数.二:ppptszTimeList - In/Out:Out - 类型:三级指针 - 可空:N - 意思:输出时间信息列表 - 参数.三:pInt_ListCount - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出个数 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool Authorize_CDKey_ReadTime(LPCXSTR lpszFileKey, XCHAR*** ppptszTimeList, int* pInt_ListCount); \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_CDKey/CDKey_Error.h b/XEngine_Source/AuthorizeModule_CDKey/CDKey_Error.h deleted file mode 100644 index 88ca362..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/CDKey_Error.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2024/07/08 17:30:28 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey\Authorize_Error.h -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey -// File Base: Authorize_Error -// File Ext: h -// Project: XEngine -// Author: qyt -// Purpose: 错误导出表 -// History: -*********************************************************************/ -////////////////////////////////////////////////////////////////////////// -// 序列卡授权导出错误表 -////////////////////////////////////////////////////////////////////////// -#define ERROR_AUTHORIZE_MODULE_CDKEY_PARAMENT 0x50A0001 //参数不合适 -#define ERROR_AUTHORIZE_MODULE_CDKEY_NOTSUPPORT 0x50A0002 //不支持此生成类型 -#define ERROR_AUTHORIZE_MODULE_CDKEY_BUFFER 0x50A0003 //这个缓冲区有问题,获取卡类型失败 -#define ERROR_AUTHORIZE_MODULE_CDKEY_CUSTOM 0x50A0004 //获取自定义时间序列号的过期时间失败。 -#define ERROR_AUTHORIZE_MODULE_CDKEY_UNKNOW 0x50A0005 //获取类型失败,这个类型未知 -#define ERROR_AUTHORIZE_MODULE_CDKEY_CONNECT 0x50A1001 //连接信息写入失败 -#define ERROR_AUTHORIZE_MODULE_CDKEY_APPINFO 0x50A1002 //程序信息写入失败 -#define ERROR_AUTHORIZE_MODULE_CDKEY_AUTHREG 0x50A1003 //添加注册信息失败 -#define ERROR_AUTHORIZE_MODULE_CDKEY_SERIAL 0x50A1004 //写入序列号失败 -#define ERROR_AUTHORIZE_MODULE_CDKEY_USER 0x50A1005 //写入用户信息失败 -#define ERROR_AUTHORIZE_MODULE_CDKEY_NOTREG 0x50A1021 //没有注册 -#define ERROR_AUTHORIZE_MODULE_CDKEY_NOTHASTIME 0x50A1022 //没有可用时间 -#define ERROR_AUTHORIZE_MODULE_CDKEY_TIMEOUT 0x50A1024 //CDKEY已经超时,没有可用时间 -#define ERROR_AUTHORIZE_MODULE_CDKEY_TEMP 0x50A1026 //临时版本已不可用 -#define ERROR_AUTHORIZE_MODULE_CDKEY_EXPIRED 0x50A1027 //已经过期的CDKEY,无法继续使用 -#define ERROR_AUTHORIZE_MODULE_CDKEY_OPENFILE 0x50A1031 //文件不存在 -#define ERROR_AUTHORIZE_MODULE_CDKEY_SETFILE 0x50A1032 //设置文件失败 -#define ERROR_AUTHORIZE_MODULE_CDKEY_TIMELIST 0x50A1041 //不存在时间列表 -#define ERROR_AUTHORIZE_MODULE_CDKEY_MALLOC 0x50A1042 //申请内存失败 -#define ERROR_AUTHORIZE_MODULE_CDKEY_READ 0x50A1043 //读取文件失败 -#define ERROR_AUTHORIZE_MODULE_CDKEY_FAILED 0x50A1044 //序列号验证失败,输入的序列号错误 \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_CDKey/Makefile b/XEngine_Source/AuthorizeModule_CDKey/Makefile deleted file mode 100644 index 209c6f0..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -CC = g++ -Wall -std=c++20 -fPIC -PLATVER = -FILEEXT = -LIBFLAG = -LOADHDR = -I ./ -LIB = -lXEngine_BaseLib -lXEngine_SystemConfig -LIBEX = -LOADSO = -OBJECTS = Authorize_Serial.o Authorize_CDKey.o pch.o - -ifeq ($(RELEASE),1) -FLAGS = -c -D _RELEASE -DEBUG = -O2 -else - ifeq ($(PLATFORM),mac) - FLAGS = -c - DEBUG = -g -D _DEBUG - else - FLAGS = -c -lc_p - DEBUG = -g -pg -D _DEBUG - endif -endif - -ifeq ($(UNICODE),1) -override UNICODE := -D __UNICODE__ -else -override UNICODE := -D __ANSI__ -endif - -ifeq ($(PLATFORM),linux) - ifeq (/etc/redhat-release,$(wildcard /etc/redhat-release)) - PLATVER = -D __CENTOS__ - else - PLATVER = -D __UBUNTU__ - endif - FILEEXT = so - LIBFLAG = -shared - LIBEX = -lpthread -lrt -ldl - LOADBIN = -Wl,-rpath=../XEngine_BaseLib,--disable-new-dtags -else ifeq ($(PLATFORM),mac) - CC += -Wno-deprecated-declarations - PLATVER = -D __MACOS__ - FILEEXT = dylib - LIBFLAG = -dynamiclib - LIBEX = -lpthread -ldl - LOADBIN = -Wl,-rpath,@loader_path/../XEngine_BaseLib/ -endif - -all:$(OBJECTS) - $(CC) $(DEBUG) $(OBJECTS) -o libAuthorizeModule_CDKey.$(FILEEXT) $(LIBFLAG) $(LIB) $(LIBEX) $(LOADSO) $(LOADBIN) - -Authorize_Serial.o:./Authorize_Serial/Authorize_Serial.cpp - $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./Authorize_Serial/Authorize_Serial.cpp -Authorize_CDKey.o:./Authorize_CDKey/Authorize_CDKey.cpp - $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./Authorize_CDKey/Authorize_CDKey.cpp - -pch.o:pch.cpp - $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) pch.cpp - - -InstallAll:InstallSo -InstallSo:./libAuthorizeModule_CDKey.$(FILEEXT) - cp ./libAuthorizeModule_CDKey.$(FILEEXT) ../../XEngine_Release/libAuthorizeModule_CDKey.$(FILEEXT) - - -CleanAll:CleanObj CleanMk -CleanObj: - rm *.o -CleanMk: - rm *.$(FILEEXT) diff --git a/XEngine_Source/AuthorizeModule_CDKey/dllmain.cpp b/XEngine_Source/AuthorizeModule_CDKey/dllmain.cpp deleted file mode 100644 index daed8c8..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/dllmain.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// dllmain.cpp : 定义 DLL 应用程序的入口点。 -#include "pch.h" - -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} - diff --git a/XEngine_Source/AuthorizeModule_CDKey/framework.h b/XEngine_Source/AuthorizeModule_CDKey/framework.h deleted file mode 100644 index 80cbbc9..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/framework.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 -// Windows 头文件 -#include diff --git a/XEngine_Source/AuthorizeModule_CDKey/pch.cpp b/XEngine_Source/AuthorizeModule_CDKey/pch.cpp deleted file mode 100644 index ec70fe9..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/pch.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "pch.h" -#include "Authorize_CDKey/Authorize_CDKey.h" -#include "Authorize_Serial/Authorize_Serial.h" -/******************************************************************** -// Created: 2021/07/20 13:11:54 -// File Name: D:\XEngine\XEngine_SourceCode\XEngine_HelpComponents\HelpComponents_Authorize\pch.cpp -// File Path: D:\XEngine\XEngine_SourceCode\XEngine_HelpComponents\HelpComponents_Authorize -// File Base: pch -// File Ext: cpp -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 导出实现 -// History: -*********************************************************************/ -bool Authorize_IsErrorOccur = false; -XLONG Authorize_dwErrorCode = 0; -////////////////////////////////////////////////////////////////////////// -CAuthorize_Serial m_Serial; -CAuthorize_CDKey m_Local; -////////////////////////////////////////////////////////////////////////// -// 导出函数 -////////////////////////////////////////////////////////////////////////// -extern "C" XLONG Authorize_GetLastError(int* pInt_SysError) -{ - if (NULL != pInt_SysError) - { - *pInt_SysError = errno; - } - return Authorize_dwErrorCode; -} -/************************************************************************/ -/* 卡导出函数 */ -/************************************************************************/ -extern "C" bool Authorize_Serial_Creator(XCHAR * **ppptszSerialNumber, LPCXSTR lpszUserHeader, int nCardNumber, int nFieldNumber, XENGINE_LIBTIME * pSt_CustomTimer, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType) -{ - return m_Serial.Authorize_Serial_Creator(ppptszSerialNumber, lpszUserHeader, nCardNumber, nFieldNumber, pSt_CustomTimer, enSerialType); -} -extern "C" bool Authorize_Serial_Create(XCHAR * **ppptszSerialNumber, LPCXSTR lpszUserHeader, int nCardNumber, int nFieldNumber) -{ - return m_Serial.Authorize_Serial_Create(ppptszSerialNumber, lpszUserHeader, nCardNumber, nFieldNumber); -} -extern "C" bool Authorize_Serial_GetType(LPCXSTR lpszSerialNumber, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE * penSerialType, XENGINE_LIBTIME * pSt_CustomTimer) -{ - return m_Serial.Authorize_Serial_GetType(lpszSerialNumber, penSerialType, pSt_CustomTimer); -} -/************************************************************************/ -/* 本地授权导出函数 */ -/************************************************************************/ -extern "C" bool Authorize_CDKey_WriteKey(LPCXSTR lpszFileKey, XENGINE_AUTHORIZE_LOCAL * pSt_AuthLocal) -{ - return m_Local.Authorize_CDKey_WriteKey(lpszFileKey, pSt_AuthLocal); -} -extern "C" bool Authorize_CDKey_ReadKey(LPCXSTR lpszFileKey, XENGINE_AUTHORIZE_LOCAL * pSt_AuthLocal) -{ - return m_Local.Authorize_CDKey_ReadKey(lpszFileKey, pSt_AuthLocal); -} -extern "C" bool Authorize_CDKey_WriteMemory(XCHAR * ptszMsgBuffer, int* pInt_MsgLen, XENGINE_AUTHORIZE_LOCAL * pSt_AuthLocal) -{ - return m_Local.Authorize_CDKey_WriteMemory(ptszMsgBuffer, pInt_MsgLen, pSt_AuthLocal); -} -extern "C" bool Authorize_CDKey_ReadMemory(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AUTHORIZE_LOCAL * pSt_AuthLocal) -{ - return m_Local.Authorize_CDKey_ReadMemory(lpszMsgBuffer, nMsgLen, pSt_AuthLocal); -} -extern "C" bool Authorize_CDKey_BuildKeyTime(XENGINE_AUTHORIZE_LOCAL * pSt_AuthLocal, __int64x nDayTimer, XENGINE_LIBTIME * pSt_DayTimer) -{ - return m_Local.Authorize_CDKey_BuildKeyTime(pSt_AuthLocal, nDayTimer, pSt_DayTimer); -} -extern "C" bool Authorize_CDKey_UserRegister(XENGINE_AUTHORIZE_LOCAL* pSt_AuthLocal, LPCXSTR lpszSerialStr) -{ - return m_Local.Authorize_CDKey_UserRegister(pSt_AuthLocal, lpszSerialStr); -} -extern "C" bool Authorize_CDKey_GetLeftTimer(XENGINE_AUTHORIZE_LOCAL * pSt_AuthLocal, LPCXSTR lpszSerialNumber) -{ - return m_Local.Authorize_CDKey_GetLeftTimer(pSt_AuthLocal, lpszSerialNumber); -} -extern "C" bool Authorize_CDKey_WriteTime(LPCXSTR lpszFileKey, int nCount) -{ - return m_Local.Authorize_CDKey_WriteTime(lpszFileKey, nCount); -} -extern "C" bool Authorize_CDKey_ReadTime(LPCXSTR lpszFileKey, XCHAR * **ppptszTimeList, int* pInt_ListCount) -{ - return m_Local.Authorize_CDKey_ReadTime(lpszFileKey, ppptszTimeList, pInt_ListCount); -} \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_CDKey/pch.h b/XEngine_Source/AuthorizeModule_CDKey/pch.h deleted file mode 100644 index 22cd7c8..0000000 --- a/XEngine_Source/AuthorizeModule_CDKey/pch.h +++ /dev/null @@ -1,57 +0,0 @@ -// pch.h: 这是预编译标头文件。 -// 下方列出的文件仅编译一次,提高了将来生成的生成性能。 -// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 -// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 -// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 - -#ifndef PCH_H -#define PCH_H - -#ifdef _MSC_BUILD -// 添加要在此处预编译的标头 -#include "framework.h" -#include -#include -#else -#include -#endif -#endif //PCH_H -#include -#include -#include -#include -#include -#include -#include -using namespace std; -#include -#include -#include -#include -#include -#include -#include -#include "../XAuth_BuildSwitch.h" -#include "../XAuth_Protocol.h" -#include "CDKey_Define.h" -#include "CDKey_Error.h" -/******************************************************************** -// Created: 2024/07/08 17:29:57 -// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey\pch.h -// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_CDKey -// File Base: pch -// File Ext: h -// Project: XEngine -// Author: qyt -// Purpose: 公有头文件 -// History: -*********************************************************************/ -extern bool Authorize_IsErrorOccur; -extern XLONG Authorize_dwErrorCode; - -typedef std::string xstring; - -#ifdef _MSC_BUILD -#pragma comment(lib,"XEngine_BaseLib/XEngine_BaseLib.lib") -#pragma comment(lib,"XEngine_SystemSdk/XEngine_SystemConfig.lib") -#endif \ No newline at end of file From fbf45506ae2877036f0015c5e5dbfbacb0913e78 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 15 Oct 2025 14:07:35 +0800 Subject: [PATCH 05/22] modify:cdkey module to verification module from depend library --- .../DBModule_MySQL/DBModule_MySQL.cpp | 121 +++++----------- .../DBModule_MySQL/DBModule_MySQL.h | 6 +- .../DBModule_SQLite/DBModule_SQLite.cpp | 123 +++++----------- .../DBModule_SQLite/DBModule_SQLite.h | 6 +- .../Database_Define.h | 26 ++-- .../AuthorizeModule_Database/pch.cpp | 12 +- XEngine_Source/AuthorizeModule_Database/pch.h | 23 +-- XEngine_Source/AuthorizeModule_Help/pch.h | 1 - .../Protocol_Define.h | 8 +- .../Protocol_Packet/Protocol_Packet.cpp | 4 +- .../Protocol_Packet/Protocol_Packet.h | 2 +- .../Protocol_Parse/Protocol_Parse.cpp | 24 ++-- .../Protocol_Parse/Protocol_Parse.h | 6 +- .../AuthorizeModule_Protocol/pch.cpp | 8 +- XEngine_Source/AuthorizeModule_Protocol/pch.h | 4 +- .../Session_Authorize/Session_Authorize.cpp | 6 +- .../AuthorizeModule_Session/Session_Define.h | 2 +- XEngine_Source/AuthorizeModule_Session/pch.h | 4 +- XEngine_Source/XAuth_Protocol.h | 134 +++--------------- XEngine_Source/XEngine.sln | 40 ------ .../Authorize_Dialog/Dialog_CDKey.cpp | 67 +++------ .../Authorize_Dialog/Dialog_CDKey.h | 4 +- .../Authorize_Dialog/Dialog_Modify.cpp | 2 +- .../Authorize_Dialog/Dialog_Try.cpp | 2 +- .../XEngine_AuthorizeApp/pch.h | 17 ++- .../AuthorizeHTTP_CDKey.cpp | 63 ++++---- .../AuthorizeHTTP_Post/AuthorizeHTTP_Pass.cpp | 4 +- .../AuthorizeHTTP_Serial.cpp | 32 +---- .../AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp | 12 +- .../XEngine_AuthorizeService/Authorize_Hdr.h | 19 +-- .../Authorize_HttpTask.cpp | 2 +- .../Authorize_TCPTask.cpp | 20 +-- .../Authorize_Task.cpp | 4 +- .../XEngine_AuthorizeService/Authorize_Task.h | 2 +- .../Authorize_WSTask.cpp | 6 +- .../XEngine_AuthorizeService.cpp | 44 ++---- XEngine_Source/XEngine_DependLibrary | 2 +- 37 files changed, 247 insertions(+), 615 deletions(-) diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp index 0992d0e..5cbe3ec 100644 --- a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp @@ -235,7 +235,7 @@ bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USE nFliedValue++; if (NULL != pptszResult[nFliedValue]) { - pSt_UserInfo->enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(pptszResult[nFliedValue]); + pSt_UserInfo->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(pptszResult[nFliedValue]); } //QQ号 @@ -332,25 +332,25 @@ bool CDBModule_MySQL::DBModule_MySQL_UserPay(LPCXSTR lpszUserName, LPCXSTR lpszS //分析插入方式 switch (st_SerialTable.enSerialType) { - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND: if (!DBModule_MySQL_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY: if (!DBModule_MySQL_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME: if (!DBModule_MySQL_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_CUSTOM: if (!DBModule_MySQL_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; @@ -391,7 +391,7 @@ bool CDBModule_MySQL::DBModule_MySQL_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_TimePr memset(tszSQLStatement, '\0', 1024); - if ((ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY == pSt_TimeProtocol->enSerialType) || (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM == pSt_TimeProtocol->enSerialType)) + if ((ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY == pSt_TimeProtocol->enSerialType) || (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_CUSTOM == pSt_TimeProtocol->enSerialType)) { //天数卡只有剩余时间没有的时候才需要做处理 if (pSt_TimeProtocol->nTimeLeft <= 0) @@ -399,7 +399,7 @@ bool CDBModule_MySQL::DBModule_MySQL_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_TimePr _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '0' WHERE UserName = '%s'"), pSt_TimeProtocol->tszUserName); } } - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == pSt_TimeProtocol->enSerialType) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND == pSt_TimeProtocol->enSerialType) { //分钟卡必须要有在线时间才能计算 if (pSt_TimeProtocol->nTimeLeft <= 0) @@ -408,7 +408,7 @@ bool CDBModule_MySQL::DBModule_MySQL_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_TimePr } _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%lld' WHERE UserName = '%s'"), pSt_TimeProtocol->nTimeLeft, pSt_TimeProtocol->tszUserName); } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME == pSt_TimeProtocol->enSerialType) + else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME == pSt_TimeProtocol->enSerialType) { //次数卡不需要在线时间,直接减去一次就可以了 _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%lld' WHERE UserName = '%s'"), _ttxoll(pSt_TimeProtocol->tszLeftTime), pSt_TimeProtocol->tszUserName); @@ -539,7 +539,7 @@ bool CDBModule_MySQL::DBModule_MySQL_UserList(AUTHREG_USERTABLE*** pppSt_UserInf _tcsxcpy((*pppSt_UserInfo)[i]->tszHardCode, ppszResult[nFliedValue]); //充值卡类型 nFliedValue++; - (*pppSt_UserInfo)[i]->enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + (*pppSt_UserInfo)[i]->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); //QQ号 nFliedValue++; (*pppSt_UserInfo)[i]->st_UserInfo.nPhoneNumber = _ttxoll(ppszResult[nFliedValue]); @@ -649,65 +649,30 @@ bool CDBModule_MySQL::DBModule_MySQL_QueryLogin(LPCXSTR lpszUserName, LPCXSTR lp /******************************************************************** 函数名称:DBModule_MySQL_SerialInsert 函数功能:插入一个序列号到数据库 - 参数.一:lpszSerialNumber + 参数.一:pSt_SerialTable In/Out:In - 类型:常量字符指针 + 类型:数据结构指针 可空:N 意思:要插入的序列号 - 参数.二:lpszExpiredTime - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:过期日期 返回值 类型:逻辑型 意思:是否插入成功 备注: *********************************************************************/ -bool CDBModule_MySQL::DBModule_MySQL_SerialInsert(LPCXSTR lpszSerialNumber, LPCXSTR lpszExpiredTime) +bool CDBModule_MySQL::DBModule_MySQL_SerialInsert(AUTHREG_SERIALTABLE* pSt_SerialTable) { SQLPacket_IsErrorOccur = false; XCHAR tszSQLStatement[1024]; //SQL语句 memset(tszSQLStatement, '\0', 1024); - if (DBModule_MySQL_SerialQuery(lpszSerialNumber)) + if (DBModule_MySQL_SerialQuery(pSt_SerialTable->tszSerialNumber)) { SQLPacket_IsErrorOccur = true; SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; return false; } - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enAuthSerialType; - XENGINE_LIBTIME st_AuthTimer; - memset(&st_AuthTimer, '\0', sizeof(st_AuthTimer)); - - if (!Authorize_Serial_GetType(lpszSerialNumber, &enAuthSerialType, &st_AuthTimer)) - { - return false; - } - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == enAuthSerialType) - { - _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s','%d','%d',0,NOW(),'%s')"), lpszSerialNumber, st_AuthTimer.wSecond, enAuthSerialType, lpszExpiredTime); - } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY == enAuthSerialType) - { - _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s','%d','%d',0,NOW(),'%s')"), lpszSerialNumber, st_AuthTimer.wDay, enAuthSerialType, lpszExpiredTime); - } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME == enAuthSerialType) - { - _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s','%d','%d',0,NOW(),'%s')"), lpszSerialNumber, st_AuthTimer.wFlags, enAuthSerialType, lpszExpiredTime); - } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM == enAuthSerialType) - { - XCHAR tszLeftTime[XPATH_MAX]; - memset(tszLeftTime, '\0', XPATH_MAX); - _xstprintf(tszLeftTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), st_AuthTimer.wYear, st_AuthTimer.wMonth, st_AuthTimer.wDay, st_AuthTimer.wHour, st_AuthTimer.wMinute, st_AuthTimer.wSecond); - _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s','%s','%d',0,NOW(),'%s')"), lpszSerialNumber, tszLeftTime, enAuthSerialType, lpszExpiredTime); - } - else - { - _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s',0,'%d',0,NOW(),'%s')"), lpszSerialNumber, enAuthSerialType, lpszExpiredTime); - } + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s','%s','%d',0,NOW(),'%s')"), pSt_SerialTable->tszSerialNumber, pSt_SerialTable->tszMaxTime, pSt_SerialTable->enSerialType, pSt_SerialTable->tszExpiredTime); if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) { @@ -807,7 +772,7 @@ bool CDBModule_MySQL::DBModule_MySQL_SerialQuery(LPCXSTR lpszSerialNumber, LPAUT _tcsxcpy(pSt_SerialTable->tszMaxTime, ppszResult[nFliedValue]); //序列卡类型 nFliedValue++; - pSt_SerialTable->enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + pSt_SerialTable->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); //是否已经使用 nFliedValue++; pSt_SerialTable->bIsUsed = _ttxoi(ppszResult[nFliedValue]); @@ -901,7 +866,7 @@ bool CDBModule_MySQL::DBModule_MySQL_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt _tcsxcpy((*pppSt_SerialTable)[i]->tszMaxTime, ppszResult[nFliedValue]); nFliedValue++; //序列卡类型 - (*pppSt_SerialTable)[i]->enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + (*pppSt_SerialTable)[i]->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //是否已经使用 (*pppSt_SerialTable)[i]->bIsUsed = _ttxoi(ppszResult[nFliedValue]); @@ -1060,7 +1025,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer) //试用类型 if (NULL != ppszResult[nFliedValue]) { - pSt_AuthVer->enVMode = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + pSt_AuthVer->enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); } //试用时间 @@ -1141,7 +1106,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TryDelete(LPCXSTR lpszSerial) 意思:是否成功 备注: *********************************************************************/ -bool CDBModule_MySQL::DBModule_MySQL_TryClear(int nThanValue, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enVerMode) +bool CDBModule_MySQL::DBModule_MySQL_TryClear(int nThanValue, ENUM_VERIFICATION_MODULE_SERIAL_TYPE enVerMode) { SQLPacket_IsErrorOccur = false; @@ -1177,7 +1142,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TryClear(int nThanValue, ENUM_AUTHORIZE_MOD _tcsxcpy(st_AuthVer.tszVSerial, ppszResult[nFliedValue]); nFliedValue++; //模式 - st_AuthVer.enVMode = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + st_AuthVer.enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //测试时间 st_AuthVer.nVTime = _ttxoi(ppszResult[nFliedValue]); @@ -1196,7 +1161,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TryClear(int nThanValue, ENUM_AUTHORIZE_MOD for (; stl_ListIterator != stl_ListVer.end(); stl_ListIterator++) { //判断是不是不关心注册的模式直接清理 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW == enVerMode) + if (ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW == enVerMode) { if (nThanValue > stl_ListIterator->nVTime) { @@ -1323,7 +1288,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, i _tcsxcpy((*pppSt_AuthVer)[i]->tszVSerial, ppszResult[nFliedValue]); nFliedValue++; //类型 - (*pppSt_AuthVer)[i]->enVMode = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + (*pppSt_AuthVer)[i]->enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //时间 (*pppSt_AuthVer)[i]->nVTime = _ttxoi(ppszResult[nFliedValue]); @@ -1974,7 +1939,7 @@ bool CDBModule_MySQL::DBModule_MySQL_AnnouncementList(AUTHREG_ANNOUNCEMENT*** pp 意思:是否成功充值 备注: *********************************************************************/ -bool CDBModule_MySQL::DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_AuthSerialType, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_AuthUserType) +bool CDBModule_MySQL::DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_VERIFICATION_MODULE_SERIAL_TYPE en_AuthSerialType, ENUM_VERIFICATION_MODULE_SERIAL_TYPE en_AuthUserType) { SQLPacket_IsErrorOccur = false; XCHAR tszSQLStatement[1024]; @@ -1983,7 +1948,7 @@ bool CDBModule_MySQL::DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR l if (en_AuthSerialType != en_AuthUserType) { //如果不等于,需要重写 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW != en_AuthUserType) + if (ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW != en_AuthUserType) { //判断是否允许改写。 if (!m_bChange) @@ -2006,41 +1971,30 @@ bool CDBModule_MySQL::DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR l //处理卡类型 switch (en_AuthSerialType) { - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND: { //如果是分钟卡 //如果当前的充值卡类型不匹配,那么他以前的充值内容全部都会被删除! _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), _ttxoi(lpszCardTime), lpszUserName); //更新用户表的过期时间 } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY: { //如果是天数卡 //更新用户表的过期时间 _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), _ttxoi(lpszCardTime), lpszUserName); //更新用户表的过期时间 } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME: { //如果是次数卡 //更新用户表的过期时间 _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), _ttxoi(lpszCardTime), lpszUserName); } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_CUSTOM: { XCHAR tszTime[128]; - XENGINE_LIBTIME st_AuthTime; - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_GeneraterSerialType; - - memset(tszTime, '\0', sizeof(tszTime)); - memset(&st_AuthTime, '\0', sizeof(XENGINE_LIBTIME)); - //获取重置卡类型和时间 - if (!Authorize_Serial_GetType(lpszCardTime, &en_GeneraterSerialType, &st_AuthTime)) - { - return false; - } - _xstprintf(tszTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), st_AuthTime.wYear, st_AuthTime.wMonth, st_AuthTime.wDay, st_AuthTime.wHour, st_AuthTime.wMinute, st_AuthTime.wSecond); //更新用户表的过期时间 _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%s' WHERE UserName = '%s'"), tszTime, lpszUserName); } @@ -2053,14 +2007,14 @@ bool CDBModule_MySQL::DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR l { switch (en_AuthSerialType) { - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND: { int nCardTime = _ttxoi(lpszCardTime); nCardTime += _ttxoi(lpszUserTime); //我们把用户以前的时间也加上 _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), nCardTime, lpszUserName); //更新用户表的过期时间 } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY: { int nCardTime = _ttxoi(lpszCardTime); nCardTime += _ttxoi(lpszUserTime); //我们把用户以前的时间也加上 @@ -2068,7 +2022,7 @@ bool CDBModule_MySQL::DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR l _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), nCardTime, lpszUserName); } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME: { //如果是次数卡 int nCardTime = _ttxoi(lpszCardTime); @@ -2076,21 +2030,10 @@ bool CDBModule_MySQL::DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR l _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), nCardTime, lpszUserName); //更新用户表的过期时间 } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_CUSTOM: { //自定义卡,无法相加 - XCHAR tszTime[128]; - XENGINE_LIBTIME st_AuthTime; - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_GeneraterSerialType; - - memset(tszTime, '\0', sizeof(tszTime)); - memset(&st_AuthTime, '\0', sizeof(XENGINE_LIBTIME)); - //获取重置卡类型和时间 - if (!Authorize_Serial_GetType(lpszCardTime, &en_GeneraterSerialType, &st_AuthTime)) - { - return false; - } - _xstprintf(tszTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), st_AuthTime.wYear, st_AuthTime.wMonth, st_AuthTime.wDay, st_AuthTime.wHour, st_AuthTime.wMinute, st_AuthTime.wSecond); + XCHAR tszTime[128] = {}; //更新用户表的过期时间 _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%s' WHERE UserName = '%s'"), tszTime, lpszUserName); } diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h index faed785..f134755 100644 --- a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h @@ -33,7 +33,7 @@ class CDBModule_MySQL bool DBModule_MySQL_UserLogin(LPCXSTR lpszUserName, LPCXSTR lpszUserAddr); bool DBModule_MySQL_QueryLogin(LPCXSTR lpszUserName, LPCXSTR lpszUserAddr); public: - bool DBModule_MySQL_SerialInsert(LPCXSTR lpszSerialNumber, LPCXSTR lpszExpiredTime); //插入序列卡 + bool DBModule_MySQL_SerialInsert(AUTHREG_SERIALTABLE* pSt_SerialTable); //插入序列卡 bool DBModule_MySQL_SerialDelete(LPCXSTR lpszSerialNumber); //删除一个序列号 bool DBModule_MySQL_SerialQuery(LPCXSTR lpszSerialNumber, LPAUTHREG_SERIALTABLE pSt_SerialTable = NULL); //按照卡号或者用户查询 bool DBModule_MySQL_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd);//查询所有序列卡 @@ -42,7 +42,7 @@ class CDBModule_MySQL bool DBModule_MySQL_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer); //网络使用模式插入一条数据 bool DBModule_MySQL_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer); //试用序列号查询函数 bool DBModule_MySQL_TryDelete(LPCXSTR lpszSerial); //删除一条指定的试用数据 - bool DBModule_MySQL_TryClear(int nThanValue, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enVerMode = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW); //清理函数,自动清理过期数据 + bool DBModule_MySQL_TryClear(int nThanValue, ENUM_VERIFICATION_MODULE_SERIAL_TYPE enVerMode = ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW); //清理函数,自动清理过期数据 bool DBModule_MySQL_TrySet(AUTHREG_TEMPVER* pSt_AuthVer); //设置用户信息函数 bool DBModule_MySQL_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart = 0, int nPosEnd = 1000); //请求试用期列表 public: @@ -56,7 +56,7 @@ class CDBModule_MySQL bool DBModule_MySQL_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement); //公告删除 bool DBModule_MySQL_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount); //列举所有公告 protected: - bool DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_AuthSerialType, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_AuthUserType); //日期方式充值方式 + bool DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_VERIFICATION_MODULE_SERIAL_TYPE en_AuthSerialType, ENUM_VERIFICATION_MODULE_SERIAL_TYPE en_AuthUserType); //日期方式充值方式 private: bool m_bChange; XNETHANDLE xhData; //数据库句柄 diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp index 81e7bd1..140684d 100644 --- a/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp @@ -212,7 +212,7 @@ bool CDBModule_SQLite::DBModule_SQLite_UserQuery(LPCXSTR lpszUserName, AUTHREG_U _tcsxcpy(pSt_UserInfo->tszHardCode, ppszResult[nFliedValue]); //充值卡类型 nFliedValue++; - pSt_UserInfo->enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + pSt_UserInfo->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); //QQ号 nFliedValue++; pSt_UserInfo->st_UserInfo.nPhoneNumber = _ttxoll(ppszResult[nFliedValue]); @@ -292,25 +292,25 @@ bool CDBModule_SQLite::DBModule_SQLite_UserPay(LPCXSTR lpszUserName, LPCXSTR lps //分析插入方式 switch (st_SerialTable.enSerialType) { - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND: if (!DBModule_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY: if (!DBModule_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME: if (!DBModule_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_CUSTOM: if (!DBModule_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; @@ -350,7 +350,7 @@ bool CDBModule_SQLite::DBModule_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_Time XCHAR tszSQLStatement[1024]; //SQL语句 memset(tszSQLStatement, '\0', 1024); - if ((ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY == pSt_TimeProtocol->enSerialType) || (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM == pSt_TimeProtocol->enSerialType)) + if ((ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY == pSt_TimeProtocol->enSerialType) || (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_CUSTOM == pSt_TimeProtocol->enSerialType)) { //天数卡只有剩余时间没有的时候才需要做处理 if (pSt_TimeProtocol->nTimeLeft <= 0) @@ -358,7 +358,7 @@ bool CDBModule_SQLite::DBModule_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_Time _xstprintf(tszSQLStatement, _X("UPDATE Authorize_User SET LeftTime = '0' WHERE UserName = '%s'"), pSt_TimeProtocol->tszUserName); } } - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == pSt_TimeProtocol->enSerialType) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND == pSt_TimeProtocol->enSerialType) { //分钟卡必须要有在线时间才能计算 if (pSt_TimeProtocol->nTimeLeft <= 0) @@ -367,7 +367,7 @@ bool CDBModule_SQLite::DBModule_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_Time } _xstprintf(tszSQLStatement, _X("UPDATE Authorize_User SET LeftTime = '%lld' WHERE UserName = '%s'"), pSt_TimeProtocol->nTimeLeft, pSt_TimeProtocol->tszUserName); } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME == pSt_TimeProtocol->enSerialType) + else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME == pSt_TimeProtocol->enSerialType) { //次数卡不需要在线时间,直接减去一次就可以了 _xstprintf(tszSQLStatement, _X("UPDATE Authorize_User SET LeftTime = '%lld' WHERE UserName = '%s'"), _ttxoll(pSt_TimeProtocol->tszLeftTime), pSt_TimeProtocol->tszUserName); @@ -491,7 +491,7 @@ bool CDBModule_SQLite::DBModule_SQLite_UserList(AUTHREG_USERTABLE*** pppSt_UserI _tcsxcpy((*pppSt_UserInfo)[i]->tszHardCode, ppszResult[nFliedValue]); //充值卡类型 nFliedValue++; - (*pppSt_UserInfo)[i]->enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + (*pppSt_UserInfo)[i]->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); //QQ号 nFliedValue++; (*pppSt_UserInfo)[i]->st_UserInfo.nPhoneNumber = _ttxoll(ppszResult[nFliedValue]); @@ -600,65 +600,30 @@ bool CDBModule_SQLite::DBModule_SQLite_QueryLogin(LPCXSTR lpszUserName, LPCXSTR /******************************************************************** 函数名称:DBModule_SQLite_SerialInsert 函数功能:插入一个序列号到数据库 - 参数.一:lpszSerialNumber + 参数.一:pSt_SerialTable In/Out:In - 类型:常量字符指针 + 类型:数据结构指针 可空:N 意思:要插入的序列号 - 参数.二:lpszExpiredTime - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:过期日期 返回值 类型:逻辑型 意思:是否插入成功 备注: *********************************************************************/ -bool CDBModule_SQLite::DBModule_SQLite_SerialInsert(LPCXSTR lpszSerialNumber, LPCXSTR lpszExpiredTime) +bool CDBModule_SQLite::DBModule_SQLite_SerialInsert(AUTHREG_SERIALTABLE *pSt_SerialTable) { SQLPacket_IsErrorOccur = false; XCHAR tszSQLStatement[1024]; //SQL语句 memset(tszSQLStatement, '\0', 1024); - if (DBModule_SQLite_SerialQuery(lpszSerialNumber)) + if (DBModule_SQLite_SerialQuery(pSt_SerialTable->tszSerialNumber)) { SQLPacket_IsErrorOccur = true; SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; return false; } - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enAuthSerialType; - XENGINE_LIBTIME st_AuthTimer; - memset(&st_AuthTimer, '\0', sizeof(st_AuthTimer)); - - if (!Authorize_Serial_GetType(lpszSerialNumber, &enAuthSerialType, &st_AuthTimer)) - { - return false; - } - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == enAuthSerialType) - { - _xstprintf(tszSQLStatement, _X("INSERT INTO Authorize_Serial values(NULL,'NOT','%s','%d','%d',0,datetime('now', 'localtime'),'%s')"), lpszSerialNumber, st_AuthTimer.wSecond, enAuthSerialType, lpszExpiredTime); - } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY == enAuthSerialType) - { - _xstprintf(tszSQLStatement, _X("INSERT INTO Authorize_Serial values(NULL,'NOT','%s','%d','%d',0,datetime('now', 'localtime'),'%s')"), lpszSerialNumber, st_AuthTimer.wDay, enAuthSerialType, lpszExpiredTime); - } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME == enAuthSerialType) - { - _xstprintf(tszSQLStatement, _X("INSERT INTO Authorize_Serial values(NULL,'NOT','%s','%d','%d',0,datetime('now', 'localtime'),'%s')"), lpszSerialNumber, st_AuthTimer.wFlags, enAuthSerialType, lpszExpiredTime); - } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM == enAuthSerialType) - { - XCHAR tszLeftTime[XPATH_MAX]; - memset(tszLeftTime, '\0', XPATH_MAX); - _xstprintf(tszLeftTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), st_AuthTimer.wYear, st_AuthTimer.wMonth, st_AuthTimer.wDay, st_AuthTimer.wHour, st_AuthTimer.wMinute, st_AuthTimer.wSecond); - _xstprintf(tszSQLStatement, _X("INSERT INTO Authorize_Serial values(NULL,'NOT','%s','%s','%d',0,datetime('now', 'localtime'),'%s')"), lpszSerialNumber, tszLeftTime, enAuthSerialType, lpszExpiredTime); - } - else - { - _xstprintf(tszSQLStatement, _X("INSERT INTO Authorize_Serial values(NULL,'NOT','%s',0,'%d',0,datetime('now', 'localtime'),'%s')"), lpszSerialNumber, enAuthSerialType, lpszExpiredTime); - } + _xstprintf(tszSQLStatement, _X("INSERT INTO Authorize_Serial values(NULL,'NOT','%s','%s','%d',0,datetime('now', 'localtime'),'%s')"), pSt_SerialTable->tszSerialNumber, pSt_SerialTable->tszMaxTime, pSt_SerialTable->enSerialType, pSt_SerialTable->tszExpiredTime); if (!DataBase_SQLite_Exec(xhData, tszSQLStatement)) { @@ -753,7 +718,7 @@ bool CDBModule_SQLite::DBModule_SQLite_SerialQuery(LPCXSTR lpszSerialNumber, LPA _tcsxcpy(pSt_SerialTable->tszMaxTime, ppszResult[nFliedValue]); //序列卡类型 nFliedValue++; - pSt_SerialTable->enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + pSt_SerialTable->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); //是否已经使用 nFliedValue++; pSt_SerialTable->bIsUsed = _ttxoi(ppszResult[nFliedValue]); @@ -841,7 +806,7 @@ bool CDBModule_SQLite::DBModule_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE*** ppp _tcsxcpy((*pppSt_SerialTable)[i]->tszMaxTime, ppszResult[nFliedValue]); nFliedValue++; //序列卡类型 - (*pppSt_SerialTable)[i]->enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + (*pppSt_SerialTable)[i]->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //是否已经使用 (*pppSt_SerialTable)[i]->bIsUsed = _ttxoi(ppszResult[nFliedValue]); @@ -991,7 +956,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer) //序列号 nFliedValue++; //试用类型 - pSt_AuthVer->enVMode = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + pSt_AuthVer->enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //试用时间 pSt_AuthVer->nVTime = _ttxoi(ppszResult[nFliedValue]); @@ -1058,7 +1023,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TryDelete(LPCXSTR lpszSerial) 意思:是否成功 备注: *********************************************************************/ -bool CDBModule_SQLite::DBModule_SQLite_TryClear(int nThanValue, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enVMode /* = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW */) +bool CDBModule_SQLite::DBModule_SQLite_TryClear(int nThanValue, ENUM_VERIFICATION_MODULE_SERIAL_TYPE enVMode /* = ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW */) { SQLPacket_IsErrorOccur = false; @@ -1089,7 +1054,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TryClear(int nThanValue, ENUM_AUTHORIZE_M _tcsxcpy(st_AuthVer.tszVSerial, ppszResult[nFliedValue]); nFliedValue++; //模式 - st_AuthVer.enVMode = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + st_AuthVer.enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //测试时间 st_AuthVer.nVTime = _ttxoi(ppszResult[nFliedValue]); @@ -1108,7 +1073,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TryClear(int nThanValue, ENUM_AUTHORIZE_M for (; stl_ListIterator != stl_ListVer.end(); stl_ListIterator++) { //判断是不是不关心注册的模式直接清理 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW == enVMode) + if (ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW == enVMode) { if (nThanValue > stl_ListIterator->nVTime) { @@ -1230,7 +1195,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, _tcsxcpy((*pppSt_AuthVer)[i]->tszVSerial, ppszResult[nFliedValue]); nFliedValue++; //类型 - (*pppSt_AuthVer)[i]->enVMode = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + (*pppSt_AuthVer)[i]->enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //时间 (*pppSt_AuthVer)[i]->nVTime = _ttxoi(ppszResult[nFliedValue]); @@ -1834,7 +1799,7 @@ bool CDBModule_SQLite::DBModule_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT*** 意思:是否成功充值 备注: *********************************************************************/ -bool CDBModule_SQLite::DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_AuthSerialType, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_AuthUserType) +bool CDBModule_SQLite::DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_VERIFICATION_MODULE_SERIAL_TYPE en_AuthSerialType, ENUM_VERIFICATION_MODULE_SERIAL_TYPE en_AuthUserType) { SQLPacket_IsErrorOccur = false; @@ -1844,7 +1809,7 @@ bool CDBModule_SQLite::DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR if (en_AuthSerialType != en_AuthUserType) { //如果不等于,需要重写 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW != en_AuthUserType) + if (ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW != en_AuthUserType) { //判断是否允许改写。 if (!m_bChange) @@ -1867,41 +1832,30 @@ bool CDBModule_SQLite::DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR //处理卡类型 switch (en_AuthSerialType) { - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND: { //如果是分钟卡 //如果当前的充值卡类型不匹配,那么他以前的充值内容全部都会被删除! _xstprintf(tszSQLStatement, _X("UPDATE Authorize_User SET LeftTime = '%d' WHERE UserName = '%s'"), _ttxoi(lpszCardTime), lpszUserName); //更新用户表的过期时间 } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY: { //如果是天数卡 //更新用户表的过期时间 _xstprintf(tszSQLStatement, _X("UPDATE Authorize_User SET LeftTime = '%d' WHERE UserName = '%s'"), _ttxoi(lpszCardTime), lpszUserName); //更新用户表的过期时间 } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME: { //如果是次数卡 //更新用户表的过期时间 _xstprintf(tszSQLStatement, _X("UPDATE Authorize_User SET LeftTime = '%d' WHERE UserName = '%s'"), _ttxoi(lpszCardTime), lpszUserName); } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_CUSTOM: { - XCHAR tszTime[128]; - XENGINE_LIBTIME st_AuthTime; - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_GeneraterSerialType; - - memset(tszTime, '\0', sizeof(tszTime)); - memset(&st_AuthTime, '\0', sizeof(XENGINE_LIBTIME)); - //获取重置卡类型和时间 - if (!Authorize_Serial_GetType(lpszCardTime, &en_GeneraterSerialType, &st_AuthTime)) - { - return false; - } - _xstprintf(tszTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), st_AuthTime.wYear, st_AuthTime.wMonth, st_AuthTime.wDay, st_AuthTime.wHour, st_AuthTime.wMinute, st_AuthTime.wSecond); + XCHAR tszTime[128] = {}; //更新用户表的过期时间 _xstprintf(tszSQLStatement, _X("UPDATE Authorize_User SET LeftTime = '%s' WHERE UserName = '%s'"), tszTime, lpszUserName); } @@ -1914,14 +1868,14 @@ bool CDBModule_SQLite::DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR { switch (en_AuthSerialType) { - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND: { int nCardTime = _ttxoi(lpszCardTime); nCardTime += _ttxoi(lpszUserTime); //我们把用户以前的时间也加上 _xstprintf(tszSQLStatement, _X("UPDATE Authorize_User SET LeftTime = '%d' WHERE UserName = '%s'"), nCardTime, lpszUserName); //更新用户表的过期时间 } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY: { int nCardTime = _ttxoi(lpszCardTime); nCardTime += _ttxoi(lpszUserTime); //我们把用户以前的时间也加上 @@ -1929,7 +1883,7 @@ bool CDBModule_SQLite::DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR _xstprintf(tszSQLStatement, _X("UPDATE Authorize_User SET LeftTime = '%d' WHERE UserName = '%s'"), nCardTime, lpszUserName); } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME: { //如果是次数卡 int nCardTime = _ttxoi(lpszCardTime); @@ -1937,21 +1891,10 @@ bool CDBModule_SQLite::DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR _xstprintf(tszSQLStatement, _X("UPDATE Authorize_User SET LeftTime = '%d' WHERE UserName = '%s'"), nCardTime, lpszUserName); //更新用户表的过期时间 } break; - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_CUSTOM: { //自定义卡,无法相加 - XCHAR tszTime[128]; - XENGINE_LIBTIME st_AuthTime; - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_GeneraterSerialType; - - memset(tszTime, '\0', sizeof(tszTime)); - memset(&st_AuthTime, '\0', sizeof(XENGINE_LIBTIME)); - //获取重置卡类型和时间 - if (!Authorize_Serial_GetType(lpszCardTime, &en_GeneraterSerialType, &st_AuthTime)) - { - return false; - } - _xstprintf(tszTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), st_AuthTime.wYear, st_AuthTime.wMonth, st_AuthTime.wDay, st_AuthTime.wHour, st_AuthTime.wMinute, st_AuthTime.wSecond); + XCHAR tszTime[128] = {}; //更新用户表的过期时间 _xstprintf(tszSQLStatement, _X("UPDATE Authorize_User SET LeftTime = '%s' WHERE UserName = '%s'"), tszTime, lpszUserName); } diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.h b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.h index edf0127..a7822cb 100644 --- a/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.h +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.h @@ -33,7 +33,7 @@ class CDBModule_SQLite bool DBModule_SQLite_UserLogin(LPCXSTR lpszUserName, LPCXSTR lpszUserAddr); bool DBModule_SQLite_QueryLogin(LPCXSTR lpszUserName, LPCXSTR lpszUserAddr); public: - bool DBModule_SQLite_SerialInsert(LPCXSTR lpszSerialNumber, LPCXSTR lpszExpiredTime); //插入序列卡 + bool DBModule_SQLite_SerialInsert(AUTHREG_SERIALTABLE* pSt_SerialTable); //插入序列卡 bool DBModule_SQLite_SerialDelete(LPCXSTR lpszSerialNumber); //删除一个序列号 bool DBModule_SQLite_SerialQuery(LPCXSTR lpszSerialNumber,LPAUTHREG_SERIALTABLE pSt_SerialTable = NULL); //按照卡号或者用户查询 bool DBModule_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE ***pppSt_SerialTable,int *pInt_ListCount, int nPosStart, int nPosEnd);//查询所有序列卡 @@ -42,7 +42,7 @@ class CDBModule_SQLite bool DBModule_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer); bool DBModule_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer); bool DBModule_SQLite_TryDelete(LPCXSTR lpszSerial); - bool DBModule_SQLite_TryClear(int nThanValue, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enVerMode = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW); + bool DBModule_SQLite_TryClear(int nThanValue, ENUM_VERIFICATION_MODULE_SERIAL_TYPE enVerMode = ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW); bool DBModule_SQLite_TrySet(AUTHREG_TEMPVER* pSt_AuthVer); bool DBModule_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart = 0, int nPosEnd = 1000); public: @@ -56,7 +56,7 @@ class CDBModule_SQLite bool DBModule_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement); bool DBModule_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount); protected: - bool DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_AuthSerialType, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE en_AuthUserType); + bool DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_VERIFICATION_MODULE_SERIAL_TYPE en_AuthSerialType, ENUM_VERIFICATION_MODULE_SERIAL_TYPE en_AuthUserType); private: bool m_bChange; XNETHANDLE xhData; //数据库句柄 diff --git a/XEngine_Source/AuthorizeModule_Database/Database_Define.h b/XEngine_Source/AuthorizeModule_Database/Database_Define.h index b5d951c..464343c 100644 --- a/XEngine_Source/AuthorizeModule_Database/Database_Define.h +++ b/XEngine_Source/AuthorizeModule_Database/Database_Define.h @@ -214,22 +214,17 @@ extern "C" bool DBModule_SQLite_QueryLogin(LPCXSTR lpszUserName, LPCXSTR lpszUse /******************************************************************** 函数名称:DBModule_SQLite_SerialInsert 函数功能:插入一个序列号到数据库 - 参数.一:lpszSerialNumber + 参数.一:pSt_SerialTable In/Out:In - 类型:常量字符指针 + 类型:数据结构指针 可空:N 意思:要插入的序列号 - 参数.二:lpszExpiredTime - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:过期日期 返回值 类型:逻辑型 意思:是否插入成功 备注: *********************************************************************/ -extern "C" bool DBModule_SQLite_SerialInsert(LPCXSTR lpszSerialNumber, LPCXSTR lpszExpiredTime); +extern "C" bool DBModule_SQLite_SerialInsert(AUTHREG_SERIALTABLE* pSt_SerialTable); /******************************************************************** 函数名称:DBModule_SQLite_SerialDelete 函数功能:从数据库删除指定序列号 @@ -366,7 +361,7 @@ extern "C" bool DBModule_SQLite_TryDelete(LPCXSTR lpszSerial); 意思:是否成功 备注: *********************************************************************/ -extern "C" bool DBModule_SQLite_TryClear(int nThanValue, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enVerMode = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW); +extern "C" bool DBModule_SQLite_TryClear(int nThanValue, ENUM_VERIFICATION_MODULE_SERIAL_TYPE enVerMode = ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW); /******************************************************************** 函数名称:DBModule_SQLite_TrySet 函数功能:设置用户信息函数 @@ -712,22 +707,17 @@ extern "C" bool DBModule_MySQL_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int /******************************************************************** 函数名称:DBModule_MySQL_SerialInsert 函数功能:插入一个序列号到数据库 - 参数.一:lpszSerialNumber + 参数.一:pSt_SerialTable In/Out:In - 类型:常量字符指针 + 类型:数据结构指针 可空:N 意思:要插入的序列号 - 参数.二:lpszExpiredTime - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:过期日期 返回值 类型:逻辑型 意思:是否插入成功 备注: *********************************************************************/ -extern "C" bool DBModule_MySQL_SerialInsert(LPCXSTR lpszSerialNumber, LPCXSTR lpszExpiredTime); +extern "C" bool DBModule_MySQL_SerialInsert(AUTHREG_SERIALTABLE* pSt_SerialTable); /******************************************************************** 函数名称:DBModule_MySQL_SerialDelete 函数功能:从数据库删除指定序列号 @@ -864,7 +854,7 @@ extern "C" bool DBModule_MySQL_TryDelete(LPCXSTR lpszSerial); 意思:是否成功 备注: *********************************************************************/ -extern "C" bool DBModule_MySQL_TryClear(int nThanValue, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enVerMode = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW); +extern "C" bool DBModule_MySQL_TryClear(int nThanValue, ENUM_VERIFICATION_MODULE_SERIAL_TYPE enVerMode = ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW); /******************************************************************** 函数名称:DBModule_MySQL_TrySet 函数功能:设置用户信息函数 diff --git a/XEngine_Source/AuthorizeModule_Database/pch.cpp b/XEngine_Source/AuthorizeModule_Database/pch.cpp index 3467a41..de26270 100644 --- a/XEngine_Source/AuthorizeModule_Database/pch.cpp +++ b/XEngine_Source/AuthorizeModule_Database/pch.cpp @@ -75,9 +75,9 @@ extern "C" bool DBModule_SQLite_QueryLogin(LPCXSTR lpszUserName, LPCXSTR lpszUse { return m_DBSQLite.DBModule_SQLite_QueryLogin(lpszUserName, lpszUserAddr); } -extern "C" bool DBModule_SQLite_SerialInsert(LPCXSTR lpszSerialNumber, LPCXSTR lpszExpiredTime) +extern "C" bool DBModule_SQLite_SerialInsert(AUTHREG_SERIALTABLE* pSt_SerialTable) { - return m_DBSQLite.DBModule_SQLite_SerialInsert(lpszSerialNumber, lpszExpiredTime); + return m_DBSQLite.DBModule_SQLite_SerialInsert(pSt_SerialTable); } extern "C" bool DBModule_SQLite_SerialDelete(LPCXSTR lpszSerialNumber) { @@ -107,7 +107,7 @@ extern "C" bool DBModule_SQLite_TryDelete(LPCXSTR lpszSerial) { return m_DBSQLite.DBModule_SQLite_TryDelete(lpszSerial); } -extern "C" bool DBModule_SQLite_TryClear(int nThanValue, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enVerMode) +extern "C" bool DBModule_SQLite_TryClear(int nThanValue, ENUM_VERIFICATION_MODULE_SERIAL_TYPE enVerMode) { return m_DBSQLite.DBModule_SQLite_TryClear(nThanValue, enVerMode); } @@ -190,9 +190,9 @@ extern "C" bool DBModule_MySQL_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int { return m_DBMySQL.DBModule_MySQL_UserList(pppSt_UserInfo, pInt_ListCount, nPosStart, nPosEnd); } -extern "C" bool DBModule_MySQL_SerialInsert(LPCXSTR lpszSerialNumber, LPCXSTR lpszExpiredTime) +extern "C" bool DBModule_MySQL_SerialInsert(AUTHREG_SERIALTABLE* pSt_SerialTable) { - return m_DBMySQL.DBModule_MySQL_SerialInsert(lpszSerialNumber, lpszExpiredTime); + return m_DBMySQL.DBModule_MySQL_SerialInsert(pSt_SerialTable); } extern "C" bool DBModule_MySQL_SerialDelete(LPCXSTR lpszSerialNumber) { @@ -222,7 +222,7 @@ extern "C" bool DBModule_MySQL_TryDelete(LPCXSTR lpszSerial) { return m_DBMySQL.DBModule_MySQL_TryDelete(lpszSerial); } -extern "C" bool DBModule_MySQL_TryClear(int nThanValue, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enVerMode) +extern "C" bool DBModule_MySQL_TryClear(int nThanValue, ENUM_VERIFICATION_MODULE_SERIAL_TYPE enVerMode) { return m_DBMySQL.DBModule_MySQL_TryClear(nThanValue, enVerMode); } diff --git a/XEngine_Source/AuthorizeModule_Database/pch.h b/XEngine_Source/AuthorizeModule_Database/pch.h index 3172cd7..ec24bc2 100644 --- a/XEngine_Source/AuthorizeModule_Database/pch.h +++ b/XEngine_Source/AuthorizeModule_Database/pch.h @@ -25,10 +25,8 @@ using namespace std; #include #include #include -#include "../XAuth_BuildSwitch.h" +#include "../XEngine_OPenSource/XEngine_Module/XEngine_Verification/Verification_Define.h" #include "../XAuth_Protocol.h" -#include "../AuthorizeModule_CDKey/CDKey_Define.h" -#include "../AuthorizeModule_CDKey/CDKey_Error.h" #include "Database_Define.h" #include "Database_Error.h" /******************************************************************** @@ -46,24 +44,7 @@ extern bool SQLPacket_IsErrorOccur; extern XLONG SQLPacket_dwErrorCode; -#ifdef _WINDOWS +#ifdef _MSC_BUILD #pragma comment(lib,"XEngine_BaseLib/XEngine_BaseLib.lib") #pragma comment(lib,"XEngine_HelpComponents/HelpComponents_DataBase.lib") -#ifdef _DEBUG -#ifdef _M_X64 -#pragma comment(lib,"../x64/Debug/AuthorizeModule_CDKey") -#elif _M_ARM64 -#pragma comment(lib,"../ARM64/Debug/AuthorizeModule_CDKey") -#elif _M_IX86 -#pragma comment(lib,"../Debug/AuthorizeModule_CDKey") -#endif -#else -#ifdef _M_X64 -#pragma comment(lib,"../x64/Release/AuthorizeModule_CDKey") -#elif _M_ARM64 -#pragma comment(lib,"../ARM64/Release/AuthorizeModule_CDKey") -#elif _M_IX86 -#pragma comment(lib,"../Release/AuthorizeModule_CDKey") -#endif -#endif #endif \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Help/pch.h b/XEngine_Source/AuthorizeModule_Help/pch.h index 642d520..b5325f3 100644 --- a/XEngine_Source/AuthorizeModule_Help/pch.h +++ b/XEngine_Source/AuthorizeModule_Help/pch.h @@ -31,7 +31,6 @@ using namespace std; #include #include #include -#include "../XAuth_BuildSwitch.h" #include "AuthHelp_Define.h" #include "AuthHelp_Error.h" /******************************************************************** diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h index dfb945b..7a12a80 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h @@ -98,7 +98,7 @@ extern "C" bool Protocol_Packet_HttpComm(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Protocol_Packet_HttpUserPass(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, AUTHORIZE_PROTOCOL_USERAUTHEX* pSt_UserAuth); +extern "C" bool Protocol_Packet_HttpUserPass(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, XENGINE_PROTOCOL_USERAUTHEX* pSt_UserAuth); /******************************************************************** 函数名称:Protocol_Packet_UserTime 函数功能:用户时间打包函数 @@ -473,7 +473,7 @@ extern "C" bool Protocol_Parse_HttpParseToken(LPCXSTR lpszMsgBuffer, int nMsgLen 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Protocol_Parse_HttpParseAuth(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHORIZE_PROTOCOL_USERAUTHEX* pSt_UserAuth); +extern "C" bool Protocol_Parse_HttpParseAuth(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_PROTOCOL_USERAUTHEX* pSt_UserAuth); /******************************************************************** 函数名称:Protocol_Parse_HttpParseUser 函数功能:解析用户信息 @@ -642,7 +642,7 @@ extern "C" bool Protocol_Parse_HttpParseSerial(LPCXSTR lpszMsgBuffer, int nMsgLe 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE * penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR * ptszHasTime, XCHAR* ptszExpiredTime); +extern "C" bool Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_VERIFICATION_MODULE_SERIAL_TYPE * penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR * ptszHasTime, XCHAR* ptszExpiredTime); /******************************************************************** 函数名称:Protocol_Parse_HttpParseOnline 函数功能:解析在线列表 @@ -820,7 +820,7 @@ extern "C" bool Protocol_Parse_HttpParseBanned2(LPCXSTR lpszMsgBuffer, int nMsgL 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AUTHORIZE_LOCAL* pSt_Authorize); +extern "C" bool Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, VERIFICATION_XAUTHKEY* pSt_Authorize); /******************************************************************** 函数名称:Protocol_Parse_HttpParseAnnouncement 函数功能:解析公告信息 diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.cpp b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.cpp index af12123..9e14420 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.cpp +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.cpp @@ -159,7 +159,7 @@ bool CProtocol_Packet::Protocol_Packet_HttpComm(XCHAR* ptszMsgBuffer, int* pInt_ 意思:是否成功 备注: *********************************************************************/ -bool CProtocol_Packet::Protocol_Packet_HttpUserPass(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, AUTHORIZE_PROTOCOL_USERAUTHEX* pSt_UserAuth) +bool CProtocol_Packet::Protocol_Packet_HttpUserPass(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, XENGINE_PROTOCOL_USERAUTHEX* pSt_UserAuth) { Protocol_IsErrorOccur = false; @@ -860,7 +860,7 @@ bool CProtocol_Packet::Protocol_Packet_HttpTryList(XCHAR* ptszMsgBuffer, int* pI st_JsonObject["nID"] = (Json::Value::Int64)(*pppSt_TryList)[i]->nID; st_JsonObject["nVTime"] = (*pppSt_TryList)[i]->nVTime; st_JsonObject["enVMode"] = (*pppSt_TryList)[i]->enVMode; - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY == (*pppSt_TryList)[i]->enVMode) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY == (*pppSt_TryList)[i]->enVMode) { XENGINE_LIBTIME st_TimeStart = {}; XENGINE_LIBTIME st_TimeEnd = {}; diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.h b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.h index 229c446..ce4e0e9 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.h +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.h @@ -20,7 +20,7 @@ class CProtocol_Packet bool Protocol_Packet_HDRComm(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, XENGINE_PROTOCOLHDR* pSt_ProtocolHdr, int enDeviceType); public: bool Protocol_Packet_HttpComm(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, int nCode = 0, LPCXSTR lpszMsgBuffer = NULL); - bool Protocol_Packet_HttpUserPass(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, AUTHORIZE_PROTOCOL_USERAUTHEX* pSt_UserAuth); + bool Protocol_Packet_HttpUserPass(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, XENGINE_PROTOCOL_USERAUTHEX* pSt_UserAuth); bool Protocol_Packet_UserTime(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, AUTHSESSION_NETCLIENT*** pppSt_ListClient, int nListCount); bool Protocol_Packet_HttpUserTime(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, AUTHREG_PROTOCOL_TIME* pSt_ProtocolTime); bool Protocol_Packet_HttpClientInfo(XCHAR* ptszMsgBuffer, int* pInt_MsgLen, AUTHREG_USERTABLE* pSt_UserTable); diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp index 536774d..ab31697 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp @@ -154,7 +154,7 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseToken(LPCXSTR lpszMsgBuffer, int n 意思:是否成功 备注: *********************************************************************/ -bool CProtocol_Parse::Protocol_Parse_HttpParseAuth(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHORIZE_PROTOCOL_USERAUTHEX* pSt_UserAuth) +bool CProtocol_Parse::Protocol_Parse_HttpParseAuth(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_PROTOCOL_USERAUTHEX* pSt_UserAuth) { Protocol_IsErrorOccur = false; @@ -390,7 +390,7 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseTry(LPCXSTR lpszMsgBuffer, int nMs if (!st_JsonProtocol["enVMode"].isNull()) { - pSt_NETTry->enVMode = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)st_JsonProtocol["enVMode"].asInt(); + pSt_NETTry->enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_JsonProtocol["enVMode"].asInt(); } if (!st_JsonProtocol["nID"].isNull()) { @@ -463,7 +463,7 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseTable(LPCXSTR lpszMsgBuffer, int n if (!st_UserTable["enSerialType"].isNull()) { - pSt_UserTable->enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)st_UserTable["enSerialType"].asInt(); + pSt_UserTable->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_UserTable["enSerialType"].asInt(); } if (!st_UserTable["enDeviceType"].isNull()) { @@ -576,7 +576,7 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseSerial(LPCXSTR lpszMsgBuffer, int } if (!st_JsonArray[i]["enSerialType"].isNull()) { - (*pppSt_SerialTable)[i]->enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)st_JsonArray[i]["enSerialType"].asInt(); + (*pppSt_SerialTable)[i]->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_JsonArray[i]["enSerialType"].asInt(); } if (!st_JsonArray[i]["tszCreateTime"].isNull()) { @@ -644,7 +644,7 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseSerial(LPCXSTR lpszMsgBuffer, int 意思:是否成功 备注: *********************************************************************/ -bool CProtocol_Parse::Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE* penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR* ptszHasTime, XCHAR* ptszExpiredTime) +bool CProtocol_Parse::Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_VERIFICATION_MODULE_SERIAL_TYPE* penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR* ptszHasTime, XCHAR* ptszExpiredTime) { Protocol_IsErrorOccur = false; @@ -667,7 +667,7 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int } Json::Value st_JsonObject = st_JsonRoot["st_SerialInfo"]; - *penSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)st_JsonObject["enSerialType"].asInt(); + *penSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_JsonObject["enSerialType"].asInt(); *pInt_NumberCount = st_JsonObject["nNumberCount"].asInt(); *pInt_SerialCount = st_JsonObject["nSerialCount"].asInt(); _tcsxcpy(ptszHasTime, st_JsonObject["tszHasTime"].asCString()); @@ -774,7 +774,7 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseTime(LPCXSTR lpszMsgBuffer, int nM if (!st_JsonProtocol["enSerialType"].isNull()) { - pSt_ProtocolTime->enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)st_JsonProtocol["enSerialType"].asInt(); + pSt_ProtocolTime->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_JsonProtocol["enSerialType"].asInt(); } if (!st_JsonProtocol["enDeviceType"].isNull()) { @@ -1078,7 +1078,7 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseBanned2(LPCXSTR lpszMsgBuffer, int 意思:是否成功 备注: *********************************************************************/ -bool CProtocol_Parse::Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AUTHORIZE_LOCAL* pSt_Authorize) +bool CProtocol_Parse::Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, VERIFICATION_XAUTHKEY* pSt_Authorize) { Protocol_IsErrorOccur = false; @@ -1158,19 +1158,19 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int n } if (!st_JsonREGInfo["enSerialType"].isNull()) { - pSt_Authorize->st_AuthRegInfo.enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)st_JsonREGInfo["enSerialType"].asInt(); + pSt_Authorize->st_AuthRegInfo.enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_JsonREGInfo["enSerialType"].asInt(); } if (!st_JsonREGInfo["enRegType"].isNull()) { - pSt_Authorize->st_AuthRegInfo.enRegType = (ENUM_AUTHORIZE_MODULE_CDKEY_TYPE)st_JsonREGInfo["enRegType"].asInt(); + pSt_Authorize->st_AuthRegInfo.enRegType = (ENUM_VERIFICATION_MODULE_CDKEY_TYPE)st_JsonREGInfo["enRegType"].asInt(); } if (!st_JsonREGInfo["enHWType"].isNull()) { - pSt_Authorize->st_AuthRegInfo.enHWType = (ENUM_AUTHORIZE_MODULE_HW_TYPE)st_JsonREGInfo["enHWType"].asInt(); + pSt_Authorize->st_AuthRegInfo.enHWType = (ENUM_VERIFICATION_MODULE_HW_TYPE)st_JsonREGInfo["enHWType"].asInt(); } if (!st_JsonREGInfo["enVModeType"].isNull()) { - pSt_Authorize->st_AuthRegInfo.enVModeType = (ENUM_AUTHORIZE_MODULE_VERMODE_TYPE)st_JsonREGInfo["enVModeType"].asInt(); + pSt_Authorize->st_AuthRegInfo.enVModeType = (ENUM_VERIFICATION_MODULE_VERMODE_TYPE)st_JsonREGInfo["enVModeType"].asInt(); } //临时序列号 Json::Value st_JsonSerialInfo = st_JsonRoot["st_AuthSerial"]; diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h index b3ff682..4a8f997 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h @@ -20,20 +20,20 @@ class CProtocol_Parse bool Protocol_Parse_WSHdr(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_PROTOCOLHDR* pSt_ProtocolHdr); public: bool Protocol_Parse_HttpParseToken(LPCXSTR lpszMsgBuffer, int nMsgLen, XNETHANDLE* pxhToken); - bool Protocol_Parse_HttpParseAuth(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHORIZE_PROTOCOL_USERAUTHEX* pSt_UserAuth); + bool Protocol_Parse_HttpParseAuth(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_PROTOCOL_USERAUTHEX* pSt_UserAuth); bool Protocol_Parse_HttpParseUser(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_PROTOCOL_USERINFO* pSt_UserInfo); bool Protocol_Parse_HttpParsePay(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_PROTOCOL_USERPAY* pSt_UserPay); bool Protocol_Parse_HttpParseTry(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_TEMPVER* pSt_NETTry); bool Protocol_Parse_HttpParseTable(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_USERTABLE* pSt_UserTable); bool Protocol_Parse_HttpParseSerial(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount); - bool Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE* penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR* ptszHasTime, XCHAR* ptszExpiredTime); + bool Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_VERIFICATION_MODULE_SERIAL_TYPE* penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR* ptszHasTime, XCHAR* ptszExpiredTime); bool Protocol_Parse_HttpParseOnline(LPCXSTR lpszMsgBuffer, int nMsgLen, bool* pbOnline); bool Protocol_Parse_HttpParseTime(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_PROTOCOL_TIME* pSt_ProtocolTime); bool Protocol_Parse_HttpParseSwitch(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_FUNCTIONSWITCH* pSt_FunSwitch); bool Protocol_Parse_HttpParsePos(LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_PosStart, int* pInt_PosEnd); bool Protocol_Parse_HttpParseBanned(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_BANNED* pSt_AuthBanned); bool Protocol_Parse_HttpParseBanned2(LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_POSStart, int* pInt_POSEnd); - bool Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AUTHORIZE_LOCAL* pSt_Authorize); + bool Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, VERIFICATION_XAUTHKEY* pSt_Authorize); bool Protocol_Parse_HttpParseAnnouncement(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_ANNOUNCEMENT* pSt_Announcement); protected: private: diff --git a/XEngine_Source/AuthorizeModule_Protocol/pch.cpp b/XEngine_Source/AuthorizeModule_Protocol/pch.cpp index fe25099..6267236 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/pch.cpp +++ b/XEngine_Source/AuthorizeModule_Protocol/pch.cpp @@ -39,7 +39,7 @@ extern "C" bool Protocol_Packet_HttpComm(XCHAR * ptszMsgBuffer, int* pInt_MsgLen { return m_ProtocolPacket.Protocol_Packet_HttpComm(ptszMsgBuffer, pInt_MsgLen, nCode, lpszMsgBuffer); } -extern "C" bool Protocol_Packet_HttpUserPass(XCHAR * ptszMsgBuffer, int* pInt_MsgLen, AUTHORIZE_PROTOCOL_USERAUTHEX* pSt_UserAuth) +extern "C" bool Protocol_Packet_HttpUserPass(XCHAR * ptszMsgBuffer, int* pInt_MsgLen, XENGINE_PROTOCOL_USERAUTHEX* pSt_UserAuth) { return m_ProtocolPacket.Protocol_Packet_HttpUserPass(ptszMsgBuffer, pInt_MsgLen, pSt_UserAuth); } @@ -94,7 +94,7 @@ extern "C" bool Protocol_Parse_HttpParseToken(LPCXSTR lpszMsgBuffer, int nMsgLen { return m_ProtocolParse.Protocol_Parse_HttpParseToken(lpszMsgBuffer, nMsgLen, pxhToken); } -extern "C" bool Protocol_Parse_HttpParseAuth(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHORIZE_PROTOCOL_USERAUTHEX* pSt_UserAuth) +extern "C" bool Protocol_Parse_HttpParseAuth(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_PROTOCOL_USERAUTHEX* pSt_UserAuth) { return m_ProtocolParse.Protocol_Parse_HttpParseAuth(lpszMsgBuffer, nMsgLen, pSt_UserAuth); } @@ -118,7 +118,7 @@ extern "C" bool Protocol_Parse_HttpParseSerial(LPCXSTR lpszMsgBuffer, int nMsgLe { return m_ProtocolParse.Protocol_Parse_HttpParseSerial(lpszMsgBuffer, nMsgLen, pppSt_SerialTable, pInt_ListCount); } -extern "C" bool Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE * penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR * ptszHasTime, XCHAR* ptszExpiredTime) +extern "C" bool Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_VERIFICATION_MODULE_SERIAL_TYPE * penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR * ptszHasTime, XCHAR* ptszExpiredTime) { return m_ProtocolParse.Protocol_Parse_HttpParseSerial2(lpszMsgBuffer, nMsgLen, penSerialType, pInt_NumberCount, pInt_SerialCount, ptszHasTime, ptszExpiredTime); } @@ -146,7 +146,7 @@ extern "C" bool Protocol_Parse_HttpParseBanned2(LPCXSTR lpszMsgBuffer, int nMsgL { return m_ProtocolParse.Protocol_Parse_HttpParseBanned2(lpszMsgBuffer, nMsgLen, pInt_POSStart, pInt_POSEnd); } -extern "C" bool Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AUTHORIZE_LOCAL * pSt_Authorize) +extern "C" bool Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, VERIFICATION_XAUTHKEY * pSt_Authorize) { return m_ProtocolParse.Protocol_Parse_HttpParseCDKey(lpszMsgBuffer, nMsgLen, pSt_Authorize); } diff --git a/XEngine_Source/AuthorizeModule_Protocol/pch.h b/XEngine_Source/AuthorizeModule_Protocol/pch.h index 7da04b0..47ca0dd 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/pch.h +++ b/XEngine_Source/AuthorizeModule_Protocol/pch.h @@ -24,10 +24,8 @@ using namespace std; #include #include #include -#include "../XAuth_BuildSwitch.h" +#include "../XEngine_OPenSource/XEngine_Module/XEngine_Verification/Verification_Define.h" #include "../XAuth_Protocol.h" -#include "../AuthorizeModule_CDKey/CDKey_Define.h" -#include "../AuthorizeModule_CDKey/CDKey_Error.h" #include "../AuthorizeModule_Configure/Config_Define.h" #include "../AuthorizeModule_Session/Session_Define.h" #include "../AuthorizeModule_Session/Session_Error.h" diff --git a/XEngine_Source/AuthorizeModule_Session/Session_Authorize/Session_Authorize.cpp b/XEngine_Source/AuthorizeModule_Session/Session_Authorize/Session_Authorize.cpp index 4bd8a60..9815f1b 100644 --- a/XEngine_Source/AuthorizeModule_Session/Session_Authorize/Session_Authorize.cpp +++ b/XEngine_Source/AuthorizeModule_Session/Session_Authorize/Session_Authorize.cpp @@ -412,7 +412,7 @@ XHTHREAD CSession_Authorize::Session_Authorize_ActiveThread(XPVOID lParam) //登陆成功的。我们要处理他过期 switch (stl_ListIterator->st_UserTable.enSerialType) { - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND: { bMultiTime = true; //秒钟处理 @@ -428,7 +428,7 @@ XHTHREAD CSession_Authorize::Session_Authorize_ActiveThread(XPVOID lParam) _tcsxcpy(st_ProtocolTimer.tszUserName, stl_ListIterator->st_UserTable.st_UserInfo.tszUserName); break; } - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME: { //次数处理 stl_ListIterator->nOnlineTime = nOnlineSpan; @@ -444,7 +444,7 @@ XHTHREAD CSession_Authorize::Session_Authorize_ActiveThread(XPVOID lParam) _tcsxcpy(st_ProtocolTimer.tszUserName, stl_ListIterator->st_UserTable.st_UserInfo.tszUserName); break; } - case ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY: + case ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY: { stl_ListIterator->nOnlineTime = nOnlineSpan; _xstprintf(stl_ListIterator->tszLeftTime, _X("%lld"), stl_ListIterator->nLeftTime); diff --git a/XEngine_Source/AuthorizeModule_Session/Session_Define.h b/XEngine_Source/AuthorizeModule_Session/Session_Define.h index 0274311..8192c68 100644 --- a/XEngine_Source/AuthorizeModule_Session/Session_Define.h +++ b/XEngine_Source/AuthorizeModule_Session/Session_Define.h @@ -25,7 +25,7 @@ typedef struct // 导出的回调函数 ////////////////////////////////////////////////////////////////////////// //用户在线时间事件回调处理函数,用户名 在线时间 剩余时间(分,天) 注册的卡类型 自定义参数 -typedef void(XCALLBACK* CALLBACK_XENGIEN_AUTHORIZE_SESSION_CLIENT_EVENTS)(LPCXSTR lpszUserAddr, LPCXSTR lpszUserName, __int64x nOnlineTimer, __int64x nLeftTimer, LPCXSTR lpszLeftDate, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType, ENUM_PROTOCOLDEVICE_TYPE enDeviceType, int nNetType, XPVOID lParam); +typedef void(XCALLBACK* CALLBACK_XENGIEN_AUTHORIZE_SESSION_CLIENT_EVENTS)(LPCXSTR lpszUserAddr, LPCXSTR lpszUserName, __int64x nOnlineTimer, __int64x nLeftTimer, LPCXSTR lpszLeftDate, ENUM_VERIFICATION_MODULE_SERIAL_TYPE enSerialType, ENUM_PROTOCOLDEVICE_TYPE enDeviceType, int nNetType, XPVOID lParam); typedef void(XCALLBACK* CALLBACK_XENGIEN_AUTHORIZE_SESSION_TOKEN_EVENTS)(XNETHANDLE xhToken, XPVOID lParam); ////////////////////////////////////////////////////////////////////////// // 导出的函数 diff --git a/XEngine_Source/AuthorizeModule_Session/pch.h b/XEngine_Source/AuthorizeModule_Session/pch.h index 91eb09a..7c185f4 100644 --- a/XEngine_Source/AuthorizeModule_Session/pch.h +++ b/XEngine_Source/AuthorizeModule_Session/pch.h @@ -27,10 +27,8 @@ using namespace std; #include #include #include -#include "../XAuth_BuildSwitch.h" +#include "../XEngine_OPenSource/XEngine_Module/XEngine_Verification/Verification_Define.h" #include "../XAuth_Protocol.h" -#include "../AuthorizeModule_CDKey/CDKey_Define.h" -#include "../AuthorizeModule_CDKey/CDKey_Error.h" #include "Session_Define.h" #include "Session_Error.h" /******************************************************************** diff --git a/XEngine_Source/XAuth_Protocol.h b/XEngine_Source/XAuth_Protocol.h index eb47b6f..880a3ab 100644 --- a/XEngine_Source/XAuth_Protocol.h +++ b/XEngine_Source/XAuth_Protocol.h @@ -14,23 +14,20 @@ ////////////////////////////////////////////////////////////////////////// // 导出的协议定义 ////////////////////////////////////////////////////////////////////////// -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQDEL 0x2001 //删除用户 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPDEL 0x2002 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQREGISTER 0x2003 //注册 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPREGISTER 0x2004 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQLOGIN 0x2005 //登陆 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPLOGIN 0x2006 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQPAY 0x2007 //充值 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPPAY 0x2008 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQGETPASS 0x2009 //找回密码 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPGETPASS 0x200A -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQGETTIME 0x200B //获取剩余时间 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPGETTIME 0x200C -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQTRYVER 0x200D //临时验证协议请求 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPTRYVER 0x200E -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQDCODE 0x2010 //动态验证码请求 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPDCODE 0x2011 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_TIMEDOUT 0x2FFF //通知客户端时间到期 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQDEL 0x2010 //删除用户 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPDEL 0x2011 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQREGISTER 0x2012 //注册 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPREGISTER 0x2013 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQPAY 0x2014 //充值 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPPAY 0x2015 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQGETPASS 0x2016 //找回密码 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPGETPASS 0x2017 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQGETTIME 0x2018 //获取剩余时间 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPGETTIME 0x2019 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQTRYVER 0x2020 //临时验证协议请求 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPTRYVER 0x2021 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQDCODE 0x2022 //动态验证码请求 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPDCODE 0x2023 ////////////////////////////////////////////////////////////////////////// // 导出的错误码 ////////////////////////////////////////////////////////////////////////// @@ -69,98 +66,9 @@ static LPCXSTR lpszXVerType[6] = { "UNKNOW","LOCAL","NETWORK" }; #ifndef _MSC_BUILD #pragma GCC diagnostic pop #endif -typedef enum -{ - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW = 0, //无法识别的充值卡 - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND = 1, //秒钟,本地使用在read和write的时候更新 - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY = 2, //天数,本地使用天数卡,不使用不减天数. - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME = 3, //次数卡 - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM = 4 //自定义过期日期 -}ENUM_AUTHORIZE_MODULE_SERIAL_TYPE, * LPENUM_AUTHORIZE_MODULE_SERIAL_TYPE; -typedef enum -{ - ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_UNKNOW = 0, //未注册,Authorize_CDKey_GetLeftTimer将返回失败 - ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_TEMP = 1, //临时,Authorize_CDKey_GetLeftTimer一次后过期,需要Write - ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_TRY = 2, //试用 - ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_OFFICIAL = 3, //正式版 - ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_UNLIMIT = 4, //无限制版,永不过期.CDKEY不做任何验证 - ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_EXPIRED = 5 //已过期的版本,Authorize_CDKey_GetLeftTimer将返回失败 -}ENUM_AUTHORIZE_MODULE_CDKEY_TYPE, * LPENUM_AUTHORIZE_MODULE_CDKEY_TYPE; -typedef enum -{ - ENUM_AUTHORIZE_MODULE_HW_TYPE_UNKNOW = 0, //未指定 - ENUM_AUTHORIZE_MODULE_HW_TYPE_CPU = 1, //CPU序列号 - ENUM_AUTHORIZE_MODULE_HW_TYPE_DISK = 2, //硬盘序列号 - ENUM_AUTHORIZE_MODULE_HW_TYPE_BOARD = 3, //主板序列号 - ENUM_AUTHORIZE_MODULE_HW_TYPE_MAC = 4, //网卡MAC地址 - ENUM_AUTHORIZE_MODULE_HW_TYPE_BIOS = 5 //BIOS序列号 -}ENUM_AUTHORIZE_MODULE_HW_TYPE, * LPENUM_AUTHORIZE_MODULE_HW_TYPE; -typedef enum -{ - ENUM_AUTHORIZE_MODULE_VERMODE_TYPE_UNKNOW = 0, //未知 - ENUM_AUTHORIZE_MODULE_VERMODE_TYPE_LOCAL = 0x01, //本地 - ENUM_AUTHORIZE_MODULE_VERMODE_TYPE_NETWORK = 0x02, //网络 -}ENUM_AUTHORIZE_MODULE_VERMODE_TYPE, * LPENUM_AUTHORIZE_MODULE_VERMODE_TYPE; ////////////////////////////////////////////////////////////////////////// // 导出的结构体 ////////////////////////////////////////////////////////////////////////// -typedef struct -{ - XCHAR tszAddr[XPATH_MAX]; //服务器或者域名地址 - int nPort; //端口号码,如果>0表示CDKEY验证失败后改为网络验证 - //版本信息 - struct - { - XCHAR tszAppName[128]; //应用程序名称 - XCHAR tszAppVer[128]; //应用程序版本号 - __int64x nExecTime; //程序已经执行次数,调用Authorize_CDKey_GetLeftTimer会更新 - bool bInit; //是否初始化,由用户控制 - }st_AuthAppInfo; - //CDKEY信息 - struct - { - XCHAR tszHardware[1024]; //硬件码 - XCHAR tszCreateTime[64]; //CDKEY创建日期,年/月/日-小时:分钟:秒 - XCHAR tszRegisterTime[64]; //注册时间,年/月/日-小时:分钟:秒 - XCHAR tszLeftTime[64]; //总的剩余时间,过期日期,根据nLeftType决定此值的意义 - XCHAR tszStartTime[64]; //当前启动时间,由系统读取CDKEY的时候自动更新,天数和分钟有效 - XCHAR tszExpiryTime[64]; //过期的时间,需要调用Authorize_CDKey_GetLeftTimer并且Write才生效 - __int64x nHasTime; //当前还拥有时间,根据nLeftType决定此值的意义,调用Authorize_CDKey_GetLeftTimer会更新 - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType; //过期类型,参考:ENUM_AUTHORIZE_MODULE_SERIAL_TYPE - ENUM_AUTHORIZE_MODULE_CDKEY_TYPE enRegType; //注册类型,参考:ENUM_AUTHORIZE_MODULE_CDKEY_TYPE - ENUM_AUTHORIZE_MODULE_HW_TYPE enHWType; //硬件类型,参考:ENUM_AUTHORIZE_MODULE_HW_TYPE - ENUM_AUTHORIZE_MODULE_VERMODE_TYPE enVModeType; //验证方式,参考:ENUM_AUTHORIZE_MODULE_VERMODE_TYPE - }st_AuthRegInfo; - //临时序列号 - struct - { - //次数限制 - struct - { - XCHAR tszTimeSerial[128]; - int nTimeCount; //使用次数 - }st_TimeLimit; - //时间限制 - struct - { - XCHAR tszDataTime[128]; //过期时间 - XCHAR tszDataSerial[128]; //序列号 - bool bTimeAdd; //真,过期时间是设置的日期-创建日期.假过期日期就是设定的日期 - }st_DataLimit; - //无限制 - struct - { - XCHAR tszUNLimitSerial[128]; //无限制序列号 - }st_UNLimit; - }st_AuthSerial; - //注册的用户信息,可以不填 - struct - { - XCHAR tszUserName[64]; //注册的用户 - XCHAR tszUserContact[64]; //联系方式,电子邮件或者手机等 - XCHAR tszCustom[1024]; //自定义数据 - }st_AuthUserInfo; -}XENGINE_AUTHORIZE_LOCAL, * LPXENGINE_AUTHORIZE_LOCAL; //充值协议 typedef struct { @@ -176,7 +84,7 @@ typedef struct __int64x nTimeLeft; //剩余时间 __int64x nTimeONLine; //在线时间 int nNetType; //连接类型 - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType; + ENUM_VERIFICATION_MODULE_SERIAL_TYPE enSerialType; ENUM_PROTOCOLDEVICE_TYPE enDeviceType; }AUTHREG_PROTOCOL_TIME, * LPAUTHREG_PROTOCOL_TIME; //用户表 @@ -186,7 +94,7 @@ typedef struct tag_AuthReg_UserTable XCHAR tszADDInfo[2048]; //附加信息 XCHAR tszLeftTime[64]; //剩余日期 XCHAR tszHardCode[32]; //硬件码 - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType; //充值卡类型 + ENUM_VERIFICATION_MODULE_SERIAL_TYPE enSerialType; //充值卡类型 ENUM_PROTOCOLDEVICE_TYPE enDeviceType; //设备类型 }AUTHREG_USERTABLE, * LPAUTHREG_USERTABLE; //注册序列号表 @@ -195,7 +103,7 @@ typedef struct tag_AuthReg_SerialTable XCHAR tszUserName[XENGINE_AUTHREG_SERVICE_SQL_MAX_USERNAME]; //使用者是谁 XCHAR tszSerialNumber[128]; //序列号 XCHAR tszMaxTime[64]; //使用时间 - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType; //充值卡类型 + ENUM_VERIFICATION_MODULE_SERIAL_TYPE enSerialType; //充值卡类型 int bIsUsed; //是否已经使用 XCHAR tszCreateTime[64]; //创建时间 XCHAR tszExpiredTime[64]; //过期时间 @@ -208,7 +116,7 @@ typedef struct __int64x nID; //ID int nVTime; //试用时间 int nLTime; //剩余时间 - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enVMode; //验证方式 + ENUM_VERIFICATION_MODULE_SERIAL_TYPE enVMode; //验证方式 }AUTHREG_TEMPVER; //禁止列表 typedef struct @@ -226,8 +134,4 @@ typedef struct XCHAR tszContext[4096]; //信息 XCHAR tszCreateTime[64]; //创建时间 __int64x nID; //ID -}AUTHREG_ANNOUNCEMENT, * LPAUTHREG_ANNOUNCEMENT; -//扩展登录协议 -struct AUTHORIZE_PROTOCOL_USERAUTHEX : public XENGINE_PROTOCOL_USERAUTH { - XCHAR tszHWCode[64]; -}; \ No newline at end of file +}AUTHREG_ANNOUNCEMENT, * LPAUTHREG_ANNOUNCEMENT; \ No newline at end of file diff --git a/XEngine_Source/XEngine.sln b/XEngine_Source/XEngine.sln index 8ad426b..37d3d4f 100644 --- a/XEngine_Source/XEngine.sln +++ b/XEngine_Source/XEngine.sln @@ -5,7 +5,6 @@ VisualStudioVersion = 17.2.32519.379 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "XEngine_HDRFile", "XEngine_HDRFile", "{D3A33095-8584-4EFB-9411-EBC38407E7B9}" ProjectSection(SolutionItems) = preProject - XAuth_BuildSwitch.h = XAuth_BuildSwitch.h XAuth_Protocol.h = XAuth_Protocol.h EndProjectSection EndProject @@ -28,28 +27,23 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthorizeModule_Session", " EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthorizeModule_Database", "AuthorizeModule_Database\AuthorizeModule_Database.vcxproj", "{5FA1874A-32F4-4176-9C23-4E22BE183660}" ProjectSection(ProjectDependencies) = postProject - {02A75BD0-416E-4AEF-BF34-BD85BD86384F} = {02A75BD0-416E-4AEF-BF34-BD85BD86384F} {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} = {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_AuthorizeService", "XEngine_APPService\XEngine_AuthorizeService\XEngine_AuthorizeService.vcxproj", "{A29DFD8D-2818-4BE3-A2DB-07F241B4BFC9}" ProjectSection(ProjectDependencies) = postProject - {02A75BD0-416E-4AEF-BF34-BD85BD86384F} = {02A75BD0-416E-4AEF-BF34-BD85BD86384F} {1391B739-713B-4A3A-9233-FEAB92E0566C} = {1391B739-713B-4A3A-9233-FEAB92E0566C} - {51DCBDC7-50CB-4A44-B10B-FCF90309914D} = {51DCBDC7-50CB-4A44-B10B-FCF90309914D} {5FA1874A-32F4-4176-9C23-4E22BE183660} = {5FA1874A-32F4-4176-9C23-4E22BE183660} {6B926D00-DCD2-49E3-86A9-3230C9872E65} = {6B926D00-DCD2-49E3-86A9-3230C9872E65} {A8E43EC0-698A-4807-8A61-B2BE5FAB7256} = {A8E43EC0-698A-4807-8A61-B2BE5FAB7256} {AB3DB24C-E1B3-41CF-B2F4-6C12E13C2894} = {AB3DB24C-E1B3-41CF-B2F4-6C12E13C2894} {CB9138DF-789D-459F-AD43-4095B22A487F} = {CB9138DF-789D-459F-AD43-4095B22A487F} - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14} = {DD8CB5F1-980F-48C3-BA2F-3CF534903B14} {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} = {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} {F6520D2C-BB8E-45BB-964B-F5D6A4318A89} = {F6520D2C-BB8E-45BB-964B-F5D6A4318A89} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_AuthorizeApp", "XEngine_APPService\XEngine_AuthorizeApp\XEngine_AuthorizeApp.vcxproj", "{51DCBDC7-50CB-4A44-B10B-FCF90309914D}" ProjectSection(ProjectDependencies) = postProject - {02A75BD0-416E-4AEF-BF34-BD85BD86384F} = {02A75BD0-416E-4AEF-BF34-BD85BD86384F} {1391B739-713B-4A3A-9233-FEAB92E0566C} = {1391B739-713B-4A3A-9233-FEAB92E0566C} {AB3DB24C-E1B3-41CF-B2F4-6C12E13C2894} = {AB3DB24C-E1B3-41CF-B2F4-6C12E13C2894} {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} = {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} @@ -61,18 +55,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthorizeModule_Help", "Aut {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} = {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthorizeModule_Client", "AuthorizeModule_Client\AuthorizeModule_Client.vcxproj", "{DD8CB5F1-980F-48C3-BA2F-3CF534903B14}" - ProjectSection(ProjectDependencies) = postProject - {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} = {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} - EndProjectSection -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "XEngine_DependLibrary", "XEngine_DependLibrary", "{6444F125-63DE-4120-98B3-DF097A9758FA}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthorizeModule_CDKey", "AuthorizeModule_CDKey\AuthorizeModule_CDKey.vcxproj", "{02A75BD0-416E-4AEF-BF34-BD85BD86384F}" - ProjectSection(ProjectDependencies) = postProject - {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} = {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsoncpp", "XEngine_DependLibrary\XEngine_Module\jsoncpp\jsoncpp.vcxproj", "{F1736B3F-03A2-4FC7-B045-A12BA8D724FB}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_InfoReport", "XEngine_DependLibrary\XEngine_Module\XEngine_InfoReport\XEngine_InfoReport.vcxproj", "{F6520D2C-BB8E-45BB-964B-F5D6A4318A89}" @@ -176,30 +160,6 @@ Global {AB3DB24C-E1B3-41CF-B2F4-6C12E13C2894}.Release|x64.Build.0 = Release|x64 {AB3DB24C-E1B3-41CF-B2F4-6C12E13C2894}.Release|x86.ActiveCfg = Release|Win32 {AB3DB24C-E1B3-41CF-B2F4-6C12E13C2894}.Release|x86.Build.0 = Release|Win32 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Debug|ARM64.Build.0 = Debug|ARM64 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Debug|x64.ActiveCfg = Debug|x64 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Debug|x64.Build.0 = Debug|x64 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Debug|x86.ActiveCfg = Debug|Win32 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Debug|x86.Build.0 = Debug|Win32 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Release|ARM64.ActiveCfg = Release|ARM64 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Release|ARM64.Build.0 = Release|ARM64 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Release|x64.ActiveCfg = Release|x64 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Release|x64.Build.0 = Release|x64 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Release|x86.ActiveCfg = Release|Win32 - {DD8CB5F1-980F-48C3-BA2F-3CF534903B14}.Release|x86.Build.0 = Release|Win32 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Debug|ARM64.Build.0 = Debug|ARM64 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Debug|x64.ActiveCfg = Debug|x64 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Debug|x64.Build.0 = Debug|x64 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Debug|x86.ActiveCfg = Debug|Win32 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Debug|x86.Build.0 = Debug|Win32 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Release|ARM64.ActiveCfg = Release|ARM64 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Release|ARM64.Build.0 = Release|ARM64 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Release|x64.ActiveCfg = Release|x64 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Release|x64.Build.0 = Release|x64 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Release|x86.ActiveCfg = Release|Win32 - {02A75BD0-416E-4AEF-BF34-BD85BD86384F}.Release|x86.Build.0 = Release|Win32 {F1736B3F-03A2-4FC7-B045-A12BA8D724FB}.Debug|ARM64.ActiveCfg = Debug|ARM64 {F1736B3F-03A2-4FC7-B045-A12BA8D724FB}.Debug|ARM64.Build.0 = Debug|ARM64 {F1736B3F-03A2-4FC7-B045-A12BA8D724FB}.Debug|x64.ActiveCfg = Debug|x64 diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.cpp index ad91aa7..20edfe7 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.cpp @@ -122,14 +122,16 @@ bool CDialog_CDKey::Dialog_CDKey_Init() m_EditRegHaveTime.SetWindowText(_T("5")); m_EditRegLeftTime.SetWindowText(_T("5")); - int nSerialCount = 3; - XCHAR** pptszSerialList; USES_CONVERSION; - Authorize_Serial_Create(&pptszSerialList, _X("XAUTH"), nSerialCount, 9); - m_EditSerialTimeNumber.SetWindowText(A2W(pptszSerialList[0])); - m_EditSerialDataNumber.SetWindowText(A2W(pptszSerialList[1])); - m_EditSerialUnlimitNumber.SetWindowText(A2W(pptszSerialList[2])); - BaseLib_Memory_Free((XPPPMEM)&pptszSerialList, nSerialCount); + XCHAR tszSerialStr[XPATH_MIN] = {}; + Verification_XAuthKey_KeySerial(tszSerialStr, 9, 0); + m_EditSerialTimeNumber.SetWindowText(A2W(tszSerialStr)); + Verification_XAuthKey_KeySerial(tszSerialStr, 9, 0); + memset(tszSerialStr, 0, XPATH_MIN); + m_EditSerialTimeNumber.SetWindowText(A2W(tszSerialStr)); + memset(tszSerialStr, 0, XPATH_MIN); + Verification_XAuthKey_KeySerial(tszSerialStr, 9, 0); + m_EditSerialTimeNumber.SetWindowText(A2W(tszSerialStr)); m_EditSerialTimeCount.SetWindowText(_T("9999")); m_CheckSerialDataAdd.SetCheck(BST_CHECKED); @@ -151,7 +153,7 @@ bool CDialog_CDKey::Dialog_CDKey_Init() m_EditUserContact.SetWindowText(_T("www.xyry.org")); return true; } -bool CDialog_CDKey::Dialog_CDKey_Read(XENGINE_AUTHORIZE_LOCAL* pSt_AuthorizeCDKey) +bool CDialog_CDKey::Dialog_CDKey_Read(VERIFICATION_XAUTHKEY* pSt_AuthorizeCDKey) { //网络信息 CString m_StrIPAddr; @@ -192,10 +194,10 @@ bool CDialog_CDKey::Dialog_CDKey_Read(XENGINE_AUTHORIZE_LOCAL* pSt_AuthorizeCDKe m_StrRegInfo.ReleaseBuffer(); m_DateTimeStart.GetWindowText(m_StrRegInfo); strcpy(pSt_AuthorizeCDKey->st_AuthRegInfo.tszStartTime, W2A(m_StrRegInfo.GetBuffer())); - pSt_AuthorizeCDKey->st_AuthRegInfo.enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)m_ComboRegSerial.GetCurSel(); - pSt_AuthorizeCDKey->st_AuthRegInfo.enRegType = (ENUM_AUTHORIZE_MODULE_CDKEY_TYPE)m_ComboRegType.GetCurSel(); - pSt_AuthorizeCDKey->st_AuthRegInfo.enHWType = (ENUM_AUTHORIZE_MODULE_HW_TYPE)m_ComboRegHard.GetCurSel(); - pSt_AuthorizeCDKey->st_AuthRegInfo.enVModeType = (ENUM_AUTHORIZE_MODULE_VERMODE_TYPE)m_ComboRegVer.GetCurSel(); + pSt_AuthorizeCDKey->st_AuthRegInfo.enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)m_ComboRegSerial.GetCurSel(); + pSt_AuthorizeCDKey->st_AuthRegInfo.enRegType = (ENUM_VERIFICATION_MODULE_CDKEY_TYPE)m_ComboRegType.GetCurSel(); + pSt_AuthorizeCDKey->st_AuthRegInfo.enHWType = (ENUM_VERIFICATION_MODULE_HW_TYPE)m_ComboRegHard.GetCurSel(); + pSt_AuthorizeCDKey->st_AuthRegInfo.enVModeType = (ENUM_VERIFICATION_MODULE_VERMODE_TYPE)m_ComboRegVer.GetCurSel(); //序列信息 CString m_StrSerialInfo; m_EditSerialTimeCount.GetWindowText(m_StrSerialInfo); @@ -229,7 +231,7 @@ bool CDialog_CDKey::Dialog_CDKey_Read(XENGINE_AUTHORIZE_LOCAL* pSt_AuthorizeCDKe strcpy(pSt_AuthorizeCDKey->st_AuthUserInfo.tszCustom, W2A(m_StrUserInfo.GetBuffer())); return true; } -bool CDialog_CDKey::Dialog_CDKey_Write(XENGINE_AUTHORIZE_LOCAL* pSt_AuthorizeCDKey) +bool CDialog_CDKey::Dialog_CDKey_Write(VERIFICATION_XAUTHKEY* pSt_AuthorizeCDKey) { CString m_StrFormat; //网络信息 @@ -317,27 +319,18 @@ void CDialog_CDKey::OnBnClickedButton1() AfxMessageBox(_T("密码必须设置")); return; } - XENGINE_AUTHORIZE_LOCAL st_AuthorizeCDKey = {}; + VERIFICATION_XAUTHKEY st_AuthorizeCDKey = {}; Dialog_CDKey_Read(&st_AuthorizeCDKey); CFileDialog m_FileDlg(false, _T(".key"),_T("CDKey"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("CDKey文件(*.key)|*.key|")); if (IDOK == m_FileDlg.DoModal()) { - int nMSGLen = 0; - XCHAR tszDEBuffer[4096] = {}; - XBYTE tszENBuffer[4096] = {}; - Authorize_CDKey_WriteMemory(tszDEBuffer, &nMSGLen, &st_AuthorizeCDKey); - USES_CONVERSION; - Cryption_XCrypto_Encoder(tszDEBuffer, &nMSGLen, tszENBuffer, W2A(m_StrPass.GetBuffer())); - FILE* pSt_File = _tfopen(m_FileDlg.GetPathName(), _T("wb")); - if (NULL == pSt_File) + if (!Verification_XAuthKey_FileWrite(&st_AuthorizeCDKey, W2A(m_FileDlg.GetPathName()), W2A(m_StrPass.GetBuffer()))) { AfxMessageBox(_T("创建CDKEY文件失败")); return; } - fwrite(tszENBuffer, 1, nMSGLen, pSt_File); - fclose(pSt_File); } } @@ -351,27 +344,13 @@ void CDialog_CDKey::OnBnClickedButton9() AfxMessageBox(_T("密码必须设置")); return; } - XENGINE_AUTHORIZE_LOCAL st_AuthorizeCDKey = {}; + VERIFICATION_XAUTHKEY st_AuthorizeCDKey = {}; CFileDialog m_FileDlg(true, _T(".key"), _T("CDKey"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("CDKey文件(*.key)|*.key|")); if (IDOK == m_FileDlg.DoModal()) { - int nMSGLen = 0; - XCHAR tszDEBuffer[4096] = {}; - XCHAR tszENBuffer[4096] = {}; - - FILE* pSt_File = _tfopen(m_FileDlg.GetPathName(), _T("rb")); - nMSGLen = fread(tszENBuffer, 1, sizeof(tszENBuffer), pSt_File); - fclose(pSt_File); - USES_CONVERSION; - if (!Cryption_XCrypto_Decoder(tszENBuffer, &nMSGLen, tszDEBuffer, W2A(m_StrPass.GetBuffer()))) - { - AfxMessageBox(_T("解密CDKEY失败")); - return; - } - - if (!Authorize_CDKey_ReadMemory(tszDEBuffer, nMSGLen, &st_AuthorizeCDKey)) + if (!Verification_XAuthKey_FileRead(&st_AuthorizeCDKey, W2A(m_FileDlg.GetPathName()), W2A(m_StrPass.GetBuffer()))) { AfxMessageBox(_T("CDKEY读取失败")); return; @@ -397,7 +376,7 @@ void CDialog_CDKey::OnBnClickedButton11() AfxMessageBox(_T("没有打开要授权的文件")); return; } - XENGINE_AUTHORIZE_LOCAL st_AuthorizeCDKey = {}; + VERIFICATION_XAUTHKEY st_AuthorizeCDKey = {}; Dialog_CDKey_Read(&st_AuthorizeCDKey); CString m_StrLeftTime; @@ -405,14 +384,14 @@ void CDialog_CDKey::OnBnClickedButton11() if (3 == m_ComboRegSerial.GetCurSel()) { - Authorize_CDKey_BuildKeyTime(&st_AuthorizeCDKey, _ttoi64(m_StrLeftTime.GetBuffer())); + //Authorize_CDKey_BuildKeyTime(&st_AuthorizeCDKey, _ttoi64(m_StrLeftTime.GetBuffer())); } else if (4 == m_ComboRegSerial.GetCurSel()) { XENGINE_LIBTIME st_LibTime = {}; USES_CONVERSION; BaseLib_Time_StrToTime(W2A(m_StrLeftTime.GetBuffer()), &st_LibTime); - Authorize_CDKey_BuildKeyTime(&st_AuthorizeCDKey, 0, &st_LibTime); + //Authorize_CDKey_BuildKeyTime(&st_AuthorizeCDKey, 0, &st_LibTime); } else { @@ -433,7 +412,7 @@ void CDialog_CDKey::OnBnClickedButton11() int nMSGLen = 0; XCHAR tszDEBuffer[4096] = {}; XBYTE tszENBuffer[4096] = {}; - Authorize_CDKey_WriteMemory(tszDEBuffer, &nMSGLen, &st_AuthorizeCDKey); + //Authorize_CDKey_WriteMemory(tszDEBuffer, &nMSGLen, &st_AuthorizeCDKey); USES_CONVERSION; Cryption_XCrypto_Encoder(tszDEBuffer, &nMSGLen, tszENBuffer, W2A(m_StrPass.GetBuffer())); FILE* pSt_File = _tfopen(m_FileDlg.GetPathName(), _T("wb")); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.h b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.h index 89c5dbf..aa30b29 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.h +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.h @@ -24,8 +24,8 @@ class CDialog_CDKey : public CDialogEx public: bool bOPenCDKey = false; bool Dialog_CDKey_Init(); - bool Dialog_CDKey_Read(XENGINE_AUTHORIZE_LOCAL* pSt_AuthorizeCDKey); - bool Dialog_CDKey_Write(XENGINE_AUTHORIZE_LOCAL* pSt_AuthorizeCDKey); + bool Dialog_CDKey_Read(VERIFICATION_XAUTHKEY* pSt_AuthorizeCDKey); + bool Dialog_CDKey_Write(VERIFICATION_XAUTHKEY* pSt_AuthorizeCDKey); public: virtual BOOL OnInitDialog(); afx_msg void OnBnClickedButton1(); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Modify.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Modify.cpp index 8e2050e..7a17f64 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Modify.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Modify.cpp @@ -214,7 +214,7 @@ void CDialog_Modify::OnBnClickedButton2() m_EditLeftTime.GetWindowText(m_StrUserInfo); strcpy(st_UserTable.tszLeftTime, W2A(m_StrUserInfo.GetBuffer())); - st_UserTable.enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)m_ComboSerial.GetCurSel(); + st_UserTable.enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)m_ComboSerial.GetCurSel(); st_UserTable.st_UserInfo.nUserLevel = m_ComboLeave.GetCurSel() - 1; Json::Value st_JsonRoot; diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Try.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Try.cpp index 7ae7440..d745884 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Try.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Try.cpp @@ -328,7 +328,7 @@ void CDialog_Try::OnBnClickedButton3() m_EditDate.GetWindowText(m_StrDate); st_JsonObject["nID"] = _ttoi64(m_StrID.GetBuffer()); - st_JsonObject["enVMode"] = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)m_ComboType.GetCurSel(); + st_JsonObject["enVMode"] = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)m_ComboType.GetCurSel(); st_JsonObject["nVTime"] = _ttoi(m_StrTime.GetBuffer()); st_JsonObject["nLTime"] = _ttoi(m_StrLeft.GetBuffer()); st_JsonObject["tszVSerial"] = W2A(m_StrSerail.GetBuffer()); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/pch.h b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/pch.h index 63e464f..89ba10c 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/pch.h +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/pch.h @@ -24,14 +24,13 @@ using namespace std; #include #include #include -#include "../../XAuth_BuildSwitch.h" +#include "../../XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Define.h" +#include "../../XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Error.h" #include "../../XAuth_Protocol.h" #include "../../AuthorizeModule_Configure/Config_Define.h" #include "../../AuthorizeModule_Configure/Config_Error.h" #include "../../AuthorizeModule_Help/AuthHelp_Define.h" #include "../../AuthorizeModule_Help/AuthHelp_Error.h" -#include "../../AuthorizeModule_CDKey/CDKey_Define.h" -#include "../../AuthorizeModule_CDKey/CDKey_Error.h" #include "Authorize_Dialog/Dialog_Config.h" #include "Authorize_Dialog/Dialog_User.h" #include "Authorize_Dialog/Dialog_Serial.h" @@ -57,30 +56,30 @@ extern LPCTSTR lpszStuType[2]; #ifdef _DEBUG #ifdef _M_X64 #pragma comment(lib,"../../x64/Debug/jsoncpp") +#pragma comment(lib,"../../x64/Debug/XEngine_Verification") #pragma comment(lib,"../../x64/Debug/AuthorizeModule_Help") -#pragma comment(lib,"../../x64/Debug/AuthorizeModule_CDKey") #elif _M_ARM64 #pragma comment(lib,"../../ARM64/Debug/jsoncpp") +#pragma comment(lib,"../../ARM64/Debug/XEngine_Verification") #pragma comment(lib,"../../ARM64/Debug/AuthorizeModule_Help") -#pragma comment(lib,"../../ARM64/Debug/AuthorizeModule_CDKey") #elif _M_IX86 #pragma comment(lib,"../../Debug/jsoncpp") +#pragma comment(lib,"../../Debug/XEngine_Verification") #pragma comment(lib,"../../Debug/AuthorizeModule_Help") -#pragma comment(lib,"../../Debug/AuthorizeModule_CDKey") #endif #else #ifdef _M_X64 #pragma comment(lib,"../../x64/Release/jsoncpp") +#pragma comment(lib,"../../x64/Release/XEngine_Verification") #pragma comment(lib,"../../x64/Release/AuthorizeModule_Help") -#pragma comment(lib,"../../x64/Release/AuthorizeModule_CDKey") #elif _M_ARM64 #pragma comment(lib,"../../ARM64/Release/jsoncpp") +#pragma comment(lib,"../../ARM64/Release/XEngine_Verification") #pragma comment(lib,"../../ARM64/Release/AuthorizeModule_Help") -#pragma comment(lib,"../../ARM64/Release/AuthorizeModule_CDKey") #elif _M_IX86 #pragma comment(lib,"../../Release/jsoncpp") +#pragma comment(lib,"../../Release/XEngine_Verification") #pragma comment(lib,"../../Release/AuthorizeModule_Help") -#pragma comment(lib,"../../Release/AuthorizeModule_CDKey") #endif #endif #endif \ No newline at end of file diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp index 3574881..e7141a3 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp @@ -19,39 +19,42 @@ bool XEngine_AuthorizeHTTP_CDKey(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LP } if (0 == _tcsxnicmp(lpszAPICreate, lpszAPIName, _tcsxlen(lpszAPICreate))) { - XENGINE_AUTHORIZE_LOCAL st_Authorize; - memset(&st_Authorize, '\0', sizeof(XENGINE_AUTHORIZE_LOCAL)); + VERIFICATION_XAUTHKEY st_Authorize; + memset(&st_Authorize, '\0', sizeof(VERIFICATION_XAUTHKEY)); Protocol_Parse_HttpParseCDKey(lpszMsgBuffer, nMsgLen, &st_Authorize); if (_tcsxlen(st_Authorize.st_AuthSerial.st_TimeLimit.tszTimeSerial) <= 0) { - int nSerialCount = 3; - XCHAR** pptszSerialList; - Authorize_Serial_Create(&pptszSerialList, _X("XAUTH"), nSerialCount, 9); + XCHAR tszSerialStr[XPATH_MIN] = {}; + Verification_XAuthKey_KeySerial(tszSerialStr, 8, 0); st_Authorize.st_AuthSerial.st_TimeLimit.nTimeCount = 9999; - _tcsxcpy(st_Authorize.st_AuthSerial.st_TimeLimit.tszTimeSerial, pptszSerialList[0]); + _tcsxcpy(st_Authorize.st_AuthSerial.st_TimeLimit.tszTimeSerial, tszSerialStr); + memset(tszSerialStr, '\0', sizeof(tszSerialStr)); + Verification_XAuthKey_KeySerial(tszSerialStr, 8, 0); st_Authorize.st_AuthSerial.st_DataLimit.bTimeAdd = false; - _tcsxcpy(st_Authorize.st_AuthSerial.st_DataLimit.tszDataSerial, pptszSerialList[1]); + _tcsxcpy(st_Authorize.st_AuthSerial.st_DataLimit.tszDataSerial, tszSerialStr); + XCHAR tszTimeStr[128] = {}; XENGINE_LIBTIME st_LibTime = {}; BaseLib_Time_GetSysTime(&st_LibTime); st_LibTime.wYear += 1; //一年后过期 BaseLib_Time_TimeToStr(tszTimeStr, NULL, true, &st_LibTime); - _tcsxcpy(st_Authorize.st_AuthSerial.st_DataLimit.tszDataTime, tszTimeStr); + memset(tszSerialStr, '\0', sizeof(tszSerialStr)); + Verification_XAuthKey_KeySerial(tszSerialStr, 8, 0); - _tcsxcpy(st_Authorize.st_AuthSerial.st_UNLimit.tszUNLimitSerial, pptszSerialList[2]); - BaseLib_Memory_Free((XPPPMEM)&pptszSerialList, nSerialCount); + _tcsxcpy(st_Authorize.st_AuthSerial.st_DataLimit.tszDataTime, tszTimeStr); + _tcsxcpy(st_Authorize.st_AuthSerial.st_UNLimit.tszUNLimitSerial, tszSerialStr); } - if (!Authorize_CDKey_WriteMemory(m_MemoryPoolRecv.get(), &nRVLen, &st_Authorize)) + if (!Verification_XAuthKey_WriteMemory(m_MemoryPoolRecv.get(), &nRVLen, &st_Authorize)) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_SERVER, "Not Acceptable,write key failed"); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求创建CDKEY协议失败,服务器内部错误:%lX"), lpszClientAddr, Authorize_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求创建CDKEY协议失败,服务器内部错误:%lX"), lpszClientAddr, Verification_GetLastError()); return false; } XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolRecv.get(), nRVLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -59,49 +62,37 @@ bool XEngine_AuthorizeHTTP_CDKey(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LP } else if (0 == _tcsxnicmp(lpszAPIAuth, lpszAPIName, _tcsxlen(lpszAPIAuth))) { - XENGINE_AUTHORIZE_LOCAL st_Authorize; - memset(&st_Authorize, '\0', sizeof(XENGINE_AUTHORIZE_LOCAL)); + VERIFICATION_XAUTHKEY st_Authorize; + memset(&st_Authorize, '\0', sizeof(VERIFICATION_XAUTHKEY)); - Authorize_CDKey_ReadMemory(lpszMsgBuffer, nMsgLen, &st_Authorize); + Verification_XAuthKey_ReadMemory(lpszMsgBuffer, nMsgLen, &st_Authorize); //授权 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM == st_Authorize.st_AuthRegInfo.enSerialType) - { - XENGINE_LIBTIME st_LibTime; - memset(&st_LibTime, '\0', sizeof(XENGINE_LIBTIME)); - - BaseLib_Time_StrToTime(st_Authorize.st_AuthRegInfo.tszLeftTime, &st_LibTime); - Authorize_CDKey_BuildKeyTime(&st_Authorize, 0, &st_LibTime); - } - else - { - Authorize_CDKey_BuildKeyTime(&st_Authorize, _ttxoll(st_Authorize.st_AuthRegInfo.tszLeftTime)); - } - Authorize_CDKey_WriteMemory(m_MemoryPoolRecv.get(), &nRVLen, &st_Authorize); + XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolRecv.get(), nRVLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求授权CDKEY成功,APP名:%s,APP版本:%s,授权期限:%s"), lpszClientAddr, st_Authorize.st_AuthAppInfo.tszAppName, st_Authorize.st_AuthAppInfo.tszAppVer, st_Authorize.st_AuthRegInfo.tszLeftTime); } else if (0 == _tcsxnicmp(lpszAPIVer, lpszAPIName, _tcsxlen(lpszAPIVer))) { - XENGINE_AUTHORIZE_LOCAL st_Authorize; - memset(&st_Authorize, '\0', sizeof(XENGINE_AUTHORIZE_LOCAL)); + VERIFICATION_XAUTHKEY st_Authorize; + memset(&st_Authorize, '\0', sizeof(VERIFICATION_XAUTHKEY)); - Authorize_CDKey_ReadMemory(lpszMsgBuffer, nMsgLen, &st_Authorize); + Verification_XAuthKey_ReadMemory(lpszMsgBuffer, nMsgLen, &st_Authorize); - if (ENUM_AUTHORIZE_MODULE_VERMODE_TYPE_NETWORK != st_Authorize.st_AuthRegInfo.enVModeType) + if (ENUM_VERIFICATION_MODULE_VERMODE_TYPE_NETWORK != st_Authorize.st_AuthRegInfo.enVModeType) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_UNAUTHORIZE, "unsupport,cdkey is not authorized"); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求验证CDKEY失败,cdkey未授权或者已超时,错误:%lX"), lpszClientAddr, Authorize_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求验证CDKEY失败,cdkey未授权或者已超时,错误:%lX"), lpszClientAddr, Verification_GetLastError()); return false; } - if (!Authorize_CDKey_GetLeftTimer(&st_Authorize)) + if (!Verification_XAuthKey_KeyParse(&st_Authorize)) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_UNAUTHORIZE, "Unauthorized,cdkey is not authorized"); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求验证CDKEY失败,cdkey未授权或者已超时,错误:%lX"), lpszClientAddr, Authorize_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求验证CDKEY失败,cdkey未授权或者已超时,错误:%lX"), lpszClientAddr, Verification_GetLastError()); return false; } - Authorize_CDKey_WriteMemory(m_MemoryPoolRecv.get(), &nRVLen, &st_Authorize); + Verification_XAuthKey_WriteMemory(m_MemoryPoolRecv.get(), &nRVLen, &st_Authorize); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolRecv.get(), nRVLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求验证CDKEY成功,APP名:%s,APP版本:%s,授权期限:%s"), lpszClientAddr, st_Authorize.st_AuthAppInfo.tszAppName, st_Authorize.st_AuthAppInfo.tszAppVer, st_Authorize.st_AuthRegInfo.tszLeftTime); } diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Pass.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Pass.cpp index 244dcf8..69646fa 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Pass.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Pass.cpp @@ -12,10 +12,10 @@ bool XEngine_AuthorizeHTTP_Pass(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC if (0 == _tcsxnicmp(lpszAPIName, lpszAPILogin, _tcsxlen(lpszAPIName))) { - AUTHORIZE_PROTOCOL_USERAUTHEX st_UserAuth; + XENGINE_PROTOCOL_USERAUTHEX st_UserAuth; AUTHREG_USERTABLE st_UserTable; - memset(&st_UserAuth, '\0', sizeof(AUTHORIZE_PROTOCOL_USERAUTHEX)); + memset(&st_UserAuth, '\0', sizeof(XENGINE_PROTOCOL_USERAUTHEX)); memset(&st_UserTable, '\0', sizeof(AUTHREG_USERTABLE)); Protocol_Parse_HttpParseAuth(lpszMsgBuffer, nMsgLen, &st_UserAuth); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp index 9bb881b..1c0b50a 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp @@ -52,23 +52,23 @@ bool XEngine_AuthorizeHTTP_Serial(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L XCHAR tszHasTime[128] = {}; XCHAR tszExpiredTime[128] = {}; XENGINE_LIBTIME st_AuthTimer = {}; - ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType = {}; + ENUM_VERIFICATION_MODULE_SERIAL_TYPE enSerialType = {}; Protocol_Parse_HttpParseSerial2(lpszMsgBuffer, nMsgLen, &enSerialType, &nNumberCount, &nSerialCount, tszHasTime, tszExpiredTime); //解析类型 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == enSerialType) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND == enSerialType) { st_AuthTimer.wSecond = _ttxoi(tszHasTime); } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY == enSerialType) + else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY == enSerialType) { st_AuthTimer.wDay = _ttxoi(tszHasTime); } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME == enSerialType) + else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME == enSerialType) { st_AuthTimer.wFlags = _ttxoi(tszHasTime); } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM == enSerialType) + else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_CUSTOM == enSerialType) { if (6 != _stxscanf(tszHasTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), &st_AuthTimer.wYear, &st_AuthTimer.wMonth, &st_AuthTimer.wDay, &st_AuthTimer.wHour, &st_AuthTimer.wMinute, &st_AuthTimer.wSecond)) { @@ -88,28 +88,6 @@ bool XEngine_AuthorizeHTTP_Serial(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L //生成卡 XCHAR** pptszSerialNumber; LPCXSTR lpszUserHdr = _X("XAUTH"); - if (!Authorize_Serial_Creator(&pptszSerialNumber, lpszUserHdr, nSerialCount, nNumberCount, &st_AuthTimer, enSerialType)) - { - Protocol_Packet_HttpComm(m_MemoryPool.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_SERVER, "Internal Server Error"); - XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPool.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,创建序列卡失败,错误码:%lX"), lpszClientAddr, Authorize_GetLastError()); - return false; - } - //导入序列卡 - if (0 == st_AuthConfig.st_XSql.nDBType) - { - for (int i = 0; i < nSerialCount; i++) //导入序列卡 - { - DBModule_SQLite_SerialInsert(pptszSerialNumber[i], tszExpiredTime); - } - } - else - { - for (int i = 0; i < nSerialCount; i++) - { - DBModule_MySQL_SerialInsert(pptszSerialNumber[i], tszExpiredTime); - } - } BaseLib_Memory_Free((XPPPMEM)&pptszSerialNumber, nSerialCount); Protocol_Packet_HttpComm(m_MemoryPool.get(), &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPool.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp index ed41d86..d756e4c 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp @@ -109,10 +109,10 @@ bool XEngine_AuthorizeHTTP_User(XNETHANDLE xhToken, LPCXSTR lpszClientAddr, LPCX return false; } //填充写入数据 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW == st_UserTable.enSerialType) + if (ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW == st_UserTable.enSerialType) { _xstprintf(st_UserTable.tszLeftTime, _X("%d"), st_AuthConfig.st_XVerification.nTryTime); - st_UserTable.enSerialType = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)st_AuthConfig.st_XVerification.nTryMode; + st_UserTable.enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_AuthConfig.st_XVerification.nTryMode; } //禁止权限0和1注册 if (st_UserTable.st_UserInfo.nUserLevel < 10) @@ -288,7 +288,7 @@ bool XEngine_AuthorizeHTTP_User(XNETHANDLE xhToken, LPCXSTR lpszClientAddr, LPCX return false; } - AUTHORIZE_PROTOCOL_USERAUTHEX st_AuthProtocol = {}; + XENGINE_PROTOCOL_USERAUTHEX st_AuthProtocol = {}; _tcsxcpy(st_AuthProtocol.tszUserName, st_UserTable.st_UserInfo.tszUserName); _tcsxcpy(st_AuthProtocol.tszUserPass, st_UserTable.st_UserInfo.tszUserPass); Protocol_Packet_HttpUserPass(tszSDBuffer, &nSDLen, &st_AuthProtocol); @@ -329,7 +329,7 @@ bool XEngine_AuthorizeHTTP_User(XNETHANDLE xhToken, LPCXSTR lpszClientAddr, LPCX { __int64x nTimeSpan = 0; //根据方式来计算剩余时间 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME == st_VERTemp.enVMode) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME == st_VERTemp.enVMode) { //次数卡需要更新才可以 st_VERTemp.nLTime--; @@ -379,9 +379,9 @@ bool XEngine_AuthorizeHTTP_User(XNETHANDLE xhToken, LPCXSTR lpszClientAddr, LPCX { //填充写入数据 st_VERTemp.nVTime = st_AuthConfig.st_XVerification.nVerTime; - st_VERTemp.enVMode = (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE)st_AuthConfig.st_XVerification.nVerMode; + st_VERTemp.enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_AuthConfig.st_XVerification.nVerMode; //看下是否启用了此功能,不支持分钟,因为不登录 - if ((ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW == st_VERTemp.enVMode) || (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == st_VERTemp.enVMode) || (st_VERTemp.nVTime <= 0)) + if ((ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW == st_VERTemp.enVMode) || (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND == st_VERTemp.enVMode) || (st_VERTemp.nVTime <= 0)) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, ERROR_AUTHORIZE_PROTOCOL_CLOSED, "the function server unavailable"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Hdr.h b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Hdr.h index c7a1964..44ced79 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Hdr.h +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Hdr.h @@ -3,11 +3,13 @@ #include #include #include +#include #include #else #include #include #include +#include #endif #include #include @@ -44,7 +46,10 @@ using namespace std; #include #include #include -#include "../../XAuth_BuildSwitch.h" +#include "../../XEngine_DependLibrary/XEngine_Module/XEngine_InfoReport/InfoReport_Define.h" +#include "../../XEngine_DependLibrary/XEngine_Module/XEngine_InfoReport/InfoReport_Error.h" +#include "../../XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Define.h" +#include "../../XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Error.h" #include "../../XAuth_Protocol.h" #include "../../AuthorizeModule_Configure/Config_Define.h" #include "../../AuthorizeModule_Configure/Config_Error.h" @@ -56,12 +61,6 @@ using namespace std; #include "../../AuthorizeModule_Protocol/Protocol_Error.h" #include "../../AuthorizeModule_Help/AuthHelp_Define.h" #include "../../AuthorizeModule_Help/AuthHelp_Error.h" -#include "../../AuthorizeModule_CDKey/CDKey_Define.h" -#include "../../AuthorizeModule_CDKey/CDKey_Error.h" -#include "../../XEngine_DependLibrary/XEngine_Module/XEngine_InfoReport/InfoReport_Define.h" -#include "../../XEngine_DependLibrary/XEngine_Module/XEngine_InfoReport/InfoReport_Error.h" -#include "../../XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Define.h" -#include "../../XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Error.h" extern bool bIsRun; extern bool bIsTest; @@ -129,7 +128,6 @@ extern XENGINE_FUNCTIONSWITCH st_FunSwitch; #pragma comment(lib,"../../x64/Debug/AuthorizeModule_Session.lib") #pragma comment(lib,"../../x64/Debug/AuthorizeModule_Database.lib") #pragma comment(lib,"../../x64/Debug/AuthorizeModule_Help.lib") -#pragma comment(lib,"../../x64/Debug/AuthorizeModule_CDKey.lib") #pragma comment(lib,"../../x64/Debug/XEngine_InfoReport.lib") #pragma comment(lib,"../../x64/Debug/XEngine_Verification.lib") #elif _M_ARM64 @@ -138,7 +136,6 @@ extern XENGINE_FUNCTIONSWITCH st_FunSwitch; #pragma comment(lib,"../../ARM64/Debug/AuthorizeModule_Session.lib") #pragma comment(lib,"../../ARM64/Debug/AuthorizeModule_Database.lib") #pragma comment(lib,"../../ARM64/Debug/AuthorizeModule_Help.lib") -#pragma comment(lib,"../../ARM64/Debug/AuthorizeModule_CDKey.lib") #pragma comment(lib,"../../ARM64/Debug/XEngine_InfoReport.lib") #pragma comment(lib,"../../ARM64/Debug/XEngine_Verification.lib") #elif _M_IX86 @@ -147,7 +144,6 @@ extern XENGINE_FUNCTIONSWITCH st_FunSwitch; #pragma comment(lib,"../../Debug/AuthorizeModule_Session.lib") #pragma comment(lib,"../../Debug/AuthorizeModule_Database.lib") #pragma comment(lib,"../../Debug/AuthorizeModule_Help.lib") -#pragma comment(lib,"../../Debug/AuthorizeModule_CDKey.lib") #pragma comment(lib,"../../Debug/XEngine_InfoReport.lib") #pragma comment(lib,"../../Debug/XEngine_Verification.lib") #endif @@ -158,7 +154,6 @@ extern XENGINE_FUNCTIONSWITCH st_FunSwitch; #pragma comment(lib,"../../x64/Release/AuthorizeModule_Session.lib") #pragma comment(lib,"../../x64/Release/AuthorizeModule_Database.lib") #pragma comment(lib,"../../x64/Release/AuthorizeModule_Help.lib") -#pragma comment(lib,"../../x64/Release/AuthorizeModule_CDKey.lib") #pragma comment(lib,"../../x64/Release/XEngine_InfoReport.lib") #pragma comment(lib,"../../x64/Release/XEngine_Verification.lib") #elif _M_ARM64 @@ -167,7 +162,6 @@ extern XENGINE_FUNCTIONSWITCH st_FunSwitch; #pragma comment(lib,"../../ARM64/Release/AuthorizeModule_Session.lib") #pragma comment(lib,"../../ARM64/Release/AuthorizeModule_Database.lib") #pragma comment(lib,"../../ARM64/Release/AuthorizeModule_Help.lib") -#pragma comment(lib,"../../ARM64/Release/AuthorizeModule_CDKey.lib") #pragma comment(lib,"../../ARM64/Release/XEngine_InfoReport.lib") #pragma comment(lib,"../../ARM64/Release/XEngine_Verification.lib") #elif _M_IX86 @@ -176,7 +170,6 @@ extern XENGINE_FUNCTIONSWITCH st_FunSwitch; #pragma comment(lib,"../../Release/AuthorizeModule_Session.lib") #pragma comment(lib,"../../Release/AuthorizeModule_Database.lib") #pragma comment(lib,"../../Release/AuthorizeModule_Help.lib") -#pragma comment(lib,"../../Release/AuthorizeModule_CDKey.lib") #pragma comment(lib,"../../Release/XEngine_InfoReport.lib") #pragma comment(lib,"../../Release/XEngine_Verification.lib") #endif diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp index 77c2beb..302caf2 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp @@ -143,7 +143,7 @@ bool XEngine_Client_HttpTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,GET请求验证服务:%s 失败,错误:%d"), lpszClientAddr, st_AuthConfig.st_XApiVer.tszAPIUrl, nHTTPCode); return false; } - AUTHORIZE_PROTOCOL_USERAUTHEX st_UserAuth = {}; + XENGINE_PROTOCOL_USERAUTHEX st_UserAuth = {}; if (!Protocol_Parse_HttpParseAuth(ptszMSGBuffer, nMsgLen, &st_UserAuth)) { st_HDRParam.nHttpCode = 500; diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp index 3ddbfd2..6da06d9 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp @@ -73,17 +73,17 @@ bool XEngine_Client_TCPTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int n else if (XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQLOGIN == pSt_ProtocolHdr->unOperatorCode) { AUTHREG_USERTABLE st_UserTable; - AUTHORIZE_PROTOCOL_USERAUTHEX st_AuthProtocol; + XENGINE_PROTOCOL_USERAUTHEX st_AuthProtocol; memset(&st_UserTable, '\0', sizeof(AUTHREG_USERTABLE)); - memset(&st_AuthProtocol, '\0', sizeof(AUTHORIZE_PROTOCOL_USERAUTHEX)); + memset(&st_AuthProtocol, '\0', sizeof(XENGINE_PROTOCOL_USERAUTHEX)); if (nMsgLen == sizeof(XENGINE_PROTOCOL_USERAUTH)) { memcpy(&st_AuthProtocol, lpszMsgBuffer, sizeof(XENGINE_PROTOCOL_USERAUTH)); } else { - memcpy(&st_AuthProtocol, lpszMsgBuffer, sizeof(AUTHORIZE_PROTOCOL_USERAUTHEX)); + memcpy(&st_AuthProtocol, lpszMsgBuffer, sizeof(XENGINE_PROTOCOL_USERAUTHEX)); } _tcsxcpy(st_Banned.tszIPAddr, lpszClientAddr); _tcsxcpy(st_Banned.tszUserName, st_AuthProtocol.tszUserName); @@ -277,28 +277,28 @@ bool XEngine_Client_TCPTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int n //对多端登录的类型进行验证 if (bLogin && st_FunSwitch.bSwitchMulti) { - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_SECOND == st_UserTable.enSerialType) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND == st_UserTable.enSerialType) { if (st_AuthConfig.st_XLogin.st_MulitLogin.bSecond) { bLogin = false; } } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME == st_UserTable.enSerialType) + else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME == st_UserTable.enSerialType) { if (st_AuthConfig.st_XLogin.st_MulitLogin.bTime) { bLogin = false; } } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY == st_UserTable.enSerialType) + else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY == st_UserTable.enSerialType) { if (st_AuthConfig.st_XLogin.st_MulitLogin.bDay) { bLogin = false; } } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_CUSTOM == st_UserTable.enSerialType) + else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_CUSTOM == st_UserTable.enSerialType) { if (st_AuthConfig.st_XLogin.st_MulitLogin.bCustom) { @@ -320,7 +320,7 @@ bool XEngine_Client_TCPTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int n return false; } //分析充值类型 - if ((ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_UNKNOW == st_UserTable.enSerialType) || ('0' == st_UserTable.tszLeftTime[0])) + if ((ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW == st_UserTable.enSerialType) || ('0' == st_UserTable.tszLeftTime[0])) { pSt_ProtocolHdr->wReserve = ERROR_AUTHORIZE_PROTOCOL_TIMELEFT; Protocol_Packet_HDRComm(tszSDBuffer, &nSDLen, pSt_ProtocolHdr, nNetType); @@ -329,7 +329,7 @@ bool XEngine_Client_TCPTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int n return false; } //如果是次数卡,需要优先处理 - if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME == st_UserTable.enSerialType) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME == st_UserTable.enSerialType) { __int64x nTime = _ttxoll(st_UserTable.tszLeftTime) - 1; _xstprintf(st_UserTable.tszLeftTime, _X("%lld"), nTime); @@ -344,7 +344,7 @@ bool XEngine_Client_TCPTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int n } } - else if (ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_DAY == st_UserTable.enSerialType) + else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY == st_UserTable.enSerialType) { bool bSuccess = false; XCHAR tszIPAddr[128] = {}; diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.cpp index 751971f..ab1114b 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.cpp @@ -1,6 +1,6 @@ #include "Authorize_Hdr.h" -void XCALLBACK XEngine_TaskEvent_Client(LPCXSTR lpszUserAddr, LPCXSTR lpszUserName, __int64x nOnlineTimer, __int64x nLeftTimer, LPCXSTR lpszLeftDate, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType, ENUM_PROTOCOLDEVICE_TYPE enDeviceType, int nNetType, XPVOID lParam) +void XCALLBACK XEngine_TaskEvent_Client(LPCXSTR lpszUserAddr, LPCXSTR lpszUserName, __int64x nOnlineTimer, __int64x nLeftTimer, LPCXSTR lpszLeftDate, ENUM_VERIFICATION_MODULE_SERIAL_TYPE enSerialType, ENUM_PROTOCOLDEVICE_TYPE enDeviceType, int nNetType, XPVOID lParam) { if (nLeftTimer <= 0) { @@ -13,7 +13,7 @@ void XCALLBACK XEngine_TaskEvent_Client(LPCXSTR lpszUserAddr, LPCXSTR lpszUserNa st_ProtocolHdr.wHeader = XENGIEN_COMMUNICATION_PACKET_PROTOCOL_HEADER; st_ProtocolHdr.unOperatorType = ENUM_XENGINE_COMMUNICATION_PROTOCOL_TYPE_AUTH; - st_ProtocolHdr.unOperatorCode = XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_TIMEDOUT; + st_ProtocolHdr.unOperatorCode = XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_EXPIRED; st_ProtocolHdr.wTail = XENGIEN_COMMUNICATION_PACKET_PROTOCOL_TAIL; if (st_AuthConfig.st_XLogin.bPassAuth) diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.h b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.h index 61d4ba0..c71acac 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.h +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.h @@ -1,4 +1,4 @@ #pragma once -void XCALLBACK XEngine_TaskEvent_Client(LPCXSTR lpszUserAddr, LPCXSTR lpszUserName, __int64x nOnlineTimer, __int64x nLeftTimer, LPCXSTR lpszLeftDate, ENUM_AUTHORIZE_MODULE_SERIAL_TYPE enSerialType, ENUM_PROTOCOLDEVICE_TYPE enDeviceType, int nNetType, XPVOID lParam); +void XCALLBACK XEngine_TaskEvent_Client(LPCXSTR lpszUserAddr, LPCXSTR lpszUserName, __int64x nOnlineTimer, __int64x nLeftTimer, LPCXSTR lpszLeftDate, ENUM_VERIFICATION_MODULE_SERIAL_TYPE enSerialType, ENUM_PROTOCOLDEVICE_TYPE enDeviceType, int nNetType, XPVOID lParam); void XCALLBACK XEngine_TaskEvent_Token(XNETHANDLE xhToken, XPVOID lParam); \ No newline at end of file diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_WSTask.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_WSTask.cpp index e1f7caf..ebf0eb0 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_WSTask.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_WSTask.cpp @@ -76,11 +76,11 @@ bool XEngine_Client_WSTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nM if (XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQLOGIN == st_ProtocolHdr.unOperatorCode) { - AUTHORIZE_PROTOCOL_USERAUTHEX st_UserAuth; - memset(&st_UserAuth, '\0', sizeof(AUTHORIZE_PROTOCOL_USERAUTHEX)); + XENGINE_PROTOCOL_USERAUTHEX st_UserAuth; + memset(&st_UserAuth, '\0', sizeof(XENGINE_PROTOCOL_USERAUTHEX)); Protocol_Parse_HttpParseAuth(lpszMsgBuffer, nMsgLen, &st_UserAuth); - XEngine_Client_TCPTask(lpszClientAddr, (LPCXSTR)&st_UserAuth, sizeof(AUTHORIZE_PROTOCOL_USERAUTHEX), &st_ProtocolHdr, XENGINE_AUTH_APP_NETTYPE_WS); + XEngine_Client_TCPTask(lpszClientAddr, (LPCXSTR)&st_UserAuth, sizeof(XENGINE_PROTOCOL_USERAUTHEX), &st_ProtocolHdr, XENGINE_AUTH_APP_NETTYPE_WS); } if (XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_HB_SYN == st_ProtocolHdr.unOperatorCode) { diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/XEngine_AuthorizeService.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/XEngine_AuthorizeService.cpp index 6f4c645..a5e7ba4 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/XEngine_AuthorizeService.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/XEngine_AuthorizeService.cpp @@ -136,7 +136,6 @@ int main(int argc, char** argv) #endif bIsRun = true; int nRet = -1; - FILE* pSt_File = NULL; HELPCOMPONENTS_XLOG_CONFIGURE st_XLogConfig; THREADPOOL_PARAMENT** ppSt_ListTCPThread; THREADPOOL_PARAMENT** ppSt_ListWSThread; @@ -382,47 +381,24 @@ int main(int argc, char** argv) XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,加密传输设置为关闭,采用明文传输")); } - pSt_File = _xtfopen(st_AuthConfig.st_XVerification.st_XCDKey.tszKeyFile, _X("rb")); - if (NULL == pSt_File) - { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("启动服务中,授权文件验证失败,授权文件没有找到")); - } - else + if (0 == _xtaccess(st_AuthConfig.st_XVerification.st_XCDKey.tszKeyFile, 0)) { + VERIFICATION_XAUTHKEY st_AuthLocal = {}; //一个简单的示例,没有验证硬件码 - XCHAR tszENCodecBuffer[4096] = {}; - XCHAR tszDECodecBuffer[4096] = {}; - XENGINE_AUTHORIZE_LOCAL st_AuthLocal = {}; - - int nRet = fread(tszENCodecBuffer, 1, sizeof(tszENCodecBuffer), pSt_File); - fclose(pSt_File); - - if (Cryption_XCrypto_Decoder(tszENCodecBuffer, &nRet, tszDECodecBuffer, st_AuthConfig.st_XVerification.st_XCDKey.tszKeyPass)) + if (Verification_XAuthKey_FileRead(&st_AuthLocal, st_AuthConfig.st_XVerification.st_XCDKey.tszKeyFile, st_AuthConfig.st_XVerification.st_XCDKey.tszKeyPass)) { - Authorize_CDKey_ReadMemory(tszDECodecBuffer, nRet, &st_AuthLocal); - bool bRet = Authorize_CDKey_GetLeftTimer(&st_AuthLocal); - //无论成功失败需要重写CDKEY - memset(tszENCodecBuffer, '\0', sizeof(tszENCodecBuffer)); - memset(tszDECodecBuffer, '\0', sizeof(tszDECodecBuffer)); - Authorize_CDKey_WriteMemory(tszDECodecBuffer, &nRet, &st_AuthLocal); - Cryption_XCrypto_Encoder(tszDECodecBuffer, &nRet, (XBYTE*)tszENCodecBuffer, st_AuthConfig.st_XVerification.st_XCDKey.tszKeyPass); - pSt_File = _xtfopen(st_AuthConfig.st_XVerification.st_XCDKey.tszKeyFile, _X("wb")); - fwrite(tszENCodecBuffer, 1, nRet, pSt_File); - fclose(pSt_File); - if (bRet) - { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,授权文件验证成功,总可运行次数:%s,剩余可运行次数:%lld"), st_AuthLocal.st_AuthRegInfo.tszLeftTime, st_AuthLocal.st_AuthRegInfo.nHasTime); - } - else - { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("启动服务中,授权文件验证失败,总可运行次数:%s,剩余可运行次数:%lld,错误码:%lX"), st_AuthLocal.st_AuthRegInfo.tszLeftTime, st_AuthLocal.st_AuthRegInfo.nHasTime, Authorize_GetLastError()); - } + Verification_XAuthKey_FileWrite(&st_AuthLocal, st_AuthConfig.st_XVerification.st_XCDKey.tszKeyFile, st_AuthConfig.st_XVerification.st_XCDKey.tszKeyPass); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,授权文件验证成功,总可运行次数:%s,剩余可运行次数:%lld"), st_AuthLocal.st_AuthRegInfo.tszLeftTime, st_AuthLocal.st_AuthRegInfo.nHasTime); } else { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("启动服务中,授权文件失败,解密失败,数据不正确")); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("启动服务中,授权文件验证失败,总可运行次数:%s,剩余可运行次数:%lld,错误码:%lX"), st_AuthLocal.st_AuthRegInfo.tszLeftTime, st_AuthLocal.st_AuthRegInfo.nHasTime, Verification_GetLastError()); } } + else + { + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("启动服务中,授权文件验证失败,授权文件没有找到")); + } #ifndef _DEBUG //发送信息报告 if (st_AuthConfig.st_XReport.bEnable && !bIsTest) diff --git a/XEngine_Source/XEngine_DependLibrary b/XEngine_Source/XEngine_DependLibrary index 8970bcc..da4c1c3 160000 --- a/XEngine_Source/XEngine_DependLibrary +++ b/XEngine_Source/XEngine_DependLibrary @@ -1 +1 @@ -Subproject commit 8970bcc172a44e943e01921ffd398594e58c8d6f +Subproject commit da4c1c30f9c7667e86b8e816560306b0882931a7 From 8c29103fbdf84f7d8317f54246ab2de4d30145d6 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 15 Oct 2025 14:17:29 +0800 Subject: [PATCH 06/22] update:vs copy file fixed:cd key serial init --- XEngine_Source/VSCopy_Arm64.bat | 4 +++- XEngine_Source/VSCopy_Debug.bat | 4 +++- XEngine_Source/VSCopy_x64.bat | 4 +++- XEngine_Source/VSCopy_x86.bat | 4 +++- .../Authorize_Dialog/Dialog_CDKey.cpp | 22 +++++++----------- .../XEngineAuthorizeApp.rc | Bin 49846 -> 49846 bytes 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/XEngine_Source/VSCopy_Arm64.bat b/XEngine_Source/VSCopy_Arm64.bat index b589fba..9171e7e 100644 --- a/XEngine_Source/VSCopy_Arm64.bat +++ b/XEngine_Source/VSCopy_Arm64.bat @@ -5,6 +5,9 @@ copy /y "%XEngine_LibArm64%\XEngine_Core\XEngine_Core.dll" "./" copy /y "%XEngine_LibArm64%\XEngine_Core\XEngine_ManagePool.dll" "./" copy /y "%XEngine_LibArm64%\XEngine_Core\XEngine_Cryption.dll" "./" +copy /y "%XEngine_LibArm64%\XEngine_Client\XClient_Socket.dll" "./" +copy /y "%XEngine_LibArm64%\XEngine_Client\XClient_APIHelp.dll" "./" + copy /y "%XEngine_LibArm64%\XEngine_NetHelp\NetHelp_APIHelp.dll" "./" copy /y "%XEngine_LibArm64%\XEngine_NetHelp\NetHelp_APIAddr.dll" "./" copy /y "%XEngine_LibArm64%\XEngine_NetHelp\NetHelp_XSocket.dll" "./" @@ -16,6 +19,5 @@ copy /y "%XEngine_LibArm64%\XEngine_HelpComponents\HelpComponents_XLog.dll" "./" copy /y "%XEngine_LibArm64%\XEngine_RfcComponents\RfcComponents_WSProtocol.dll" "./" copy /y "%XEngine_LibArm64%\XEngine_RfcComponents\RfcComponents_HttpProtocol.dll" "./" -copy /y "%XEngine_LibArm64%\XEngine_Client\XClient_APIHelp.dll" "./" copy /y "%XEngine_LibArm64%\XEngine_SystemSdk\XEngine_SystemApi.dll" "./" copy /y "%XEngine_LibArm64%\XEngine_SystemSdk\XEngine_SystemConfig.dll" "./" \ No newline at end of file diff --git a/XEngine_Source/VSCopy_Debug.bat b/XEngine_Source/VSCopy_Debug.bat index b813a8b..b200edb 100644 --- a/XEngine_Source/VSCopy_Debug.bat +++ b/XEngine_Source/VSCopy_Debug.bat @@ -5,6 +5,9 @@ copy /y "D:\XEngine\XEngine_SourceCode\Debug\XEngine_Core.dll" "./" copy /y "D:\XEngine\XEngine_SourceCode\Debug\XEngine_ManagePool.dll" "./" copy /y "D:\XEngine\XEngine_SourceCode\Debug\XEngine_Cryption.dll" "./" +copy /y "D:\XEngine\XEngine_SourceCode\Debug\XClient_Socket.dll" "./" +copy /y "D:\XEngine\XEngine_SourceCode\Debug\XClient_APIHelp.dll" "./" + copy /y "D:\XEngine\XEngine_SourceCode\Debug\NetHelp_APIHelp.dll" "./" copy /y "D:\XEngine\XEngine_SourceCode\Debug\NetHelp_APIAddr.dll" "./" copy /y "D:\XEngine\XEngine_SourceCode\Debug\NetHelp_XSocket.dll" "./" @@ -16,6 +19,5 @@ copy /y "D:\XEngine\XEngine_SourceCode\Debug\HelpComponents_XLog.dll" "./" copy /y "D:\XEngine\XEngine_SourceCode\Debug\RfcComponents_WSProtocol.dll" "./" copy /y "D:\XEngine\XEngine_SourceCode\Debug\RfcComponents_HttpProtocol.dll" "./" -copy /y "D:\XEngine\XEngine_SourceCode\Debug\XClient_APIHelp.dll" "./" copy /y "D:\XEngine\XEngine_SourceCode\Debug\XEngine_SystemApi.dll" "./" copy /y "D:\XEngine\XEngine_SourceCode\Debug\XEngine_SystemConfig.dll" "./" \ No newline at end of file diff --git a/XEngine_Source/VSCopy_x64.bat b/XEngine_Source/VSCopy_x64.bat index af2923e..f7b08fb 100644 --- a/XEngine_Source/VSCopy_x64.bat +++ b/XEngine_Source/VSCopy_x64.bat @@ -5,6 +5,9 @@ copy /y "%XEngine_Lib64%\XEngine_Core\XEngine_Core.dll" "./" copy /y "%XEngine_Lib64%\XEngine_Core\XEngine_ManagePool.dll" "./" copy /y "%XEngine_Lib64%\XEngine_Core\XEngine_Cryption.dll" "./" +copy /y "%XEngine_Lib64%\XEngine_Client\XClient_Socket.dll" "./" +copy /y "%XEngine_Lib64%\XEngine_Client\XClient_APIHelp.dll" "./" + copy /y "%XEngine_Lib64%\XEngine_NetHelp\NetHelp_APIHelp.dll" "./" copy /y "%XEngine_Lib64%\XEngine_NetHelp\NetHelp_APIAddr.dll" "./" copy /y "%XEngine_Lib64%\XEngine_NetHelp\NetHelp_XSocket.dll" "./" @@ -16,6 +19,5 @@ copy /y "%XEngine_Lib64%\XEngine_HelpComponents\HelpComponents_XLog.dll" "./" copy /y "%XEngine_Lib64%\XEngine_RfcComponents\RfcComponents_WSProtocol.dll" "./" copy /y "%XEngine_Lib64%\XEngine_RfcComponents\RfcComponents_HttpProtocol.dll" "./" -copy /y "%XEngine_Lib64%\XEngine_Client\XClient_APIHelp.dll" "./" copy /y "%XEngine_Lib64%\XEngine_SystemSdk\XEngine_SystemApi.dll" "./" copy /y "%XEngine_Lib64%\XEngine_SystemSdk\XEngine_SystemConfig.dll" "./" \ No newline at end of file diff --git a/XEngine_Source/VSCopy_x86.bat b/XEngine_Source/VSCopy_x86.bat index e37f3b1..4f31596 100644 --- a/XEngine_Source/VSCopy_x86.bat +++ b/XEngine_Source/VSCopy_x86.bat @@ -5,6 +5,9 @@ copy /y "%XEngine_Lib32%\XEngine_Core\XEngine_Core.dll" "./" copy /y "%XEngine_Lib32%\XEngine_Core\XEngine_ManagePool.dll" "./" copy /y "%XEngine_Lib32%\XEngine_Core\XEngine_Cryption.dll" "./" +copy /y "%XEngine_Lib32%\XEngine_Client\XClient_Socket.dll" "./" +copy /y "%XEngine_Lib32%\XEngine_Client\XClient_APIHelp.dll" "./" + copy /y "%XEngine_Lib32%\XEngine_NetHelp\NetHelp_APIHelp.dll" "./" copy /y "%XEngine_Lib32%\XEngine_NetHelp\NetHelp_APIAddr.dll" "./" copy /y "%XEngine_Lib32%\XEngine_NetHelp\NetHelp_XSocket.dll" "./" @@ -16,6 +19,5 @@ copy /y "%XEngine_Lib32%\XEngine_HelpComponents\HelpComponents_XLog.dll" "./" copy /y "%XEngine_Lib32%\XEngine_RfcComponents\RfcComponents_WSProtocol.dll" "./" copy /y "%XEngine_Lib32%\XEngine_RfcComponents\RfcComponents_HttpProtocol.dll" "./" -copy /y "%XEngine_Lib32%\XEngine_Client\XClient_APIHelp.dll" "./" copy /y "%XEngine_Lib32%\XEngine_SystemSdk\XEngine_SystemApi.dll" "./" copy /y "%XEngine_Lib32%\XEngine_SystemSdk\XEngine_SystemConfig.dll" "./" \ No newline at end of file diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.cpp index 20edfe7..e087615 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_CDKey.cpp @@ -124,14 +124,17 @@ bool CDialog_CDKey::Dialog_CDKey_Init() USES_CONVERSION; XCHAR tszSerialStr[XPATH_MIN] = {}; - Verification_XAuthKey_KeySerial(tszSerialStr, 9, 0); + Verification_XAuthKey_KeySerial(tszSerialStr, 8, 0); m_EditSerialTimeNumber.SetWindowText(A2W(tszSerialStr)); - Verification_XAuthKey_KeySerial(tszSerialStr, 9, 0); + memset(tszSerialStr, 0, XPATH_MIN); - m_EditSerialTimeNumber.SetWindowText(A2W(tszSerialStr)); + Verification_XAuthKey_KeySerial(tszSerialStr, 8, 0); + m_EditSerialDataNumber.SetWindowText(A2W(tszSerialStr)); + memset(tszSerialStr, 0, XPATH_MIN); - Verification_XAuthKey_KeySerial(tszSerialStr, 9, 0); - m_EditSerialTimeNumber.SetWindowText(A2W(tszSerialStr)); + Verification_XAuthKey_KeySerial(tszSerialStr, 8, 0); + m_EditSerialUnlimitNumber.SetWindowText(A2W(tszSerialStr)); + m_EditSerialTimeCount.SetWindowText(_T("9999")); m_CheckSerialDataAdd.SetCheck(BST_CHECKED); @@ -409,15 +412,8 @@ void CDialog_CDKey::OnBnClickedButton11() CFileDialog m_FileDlg(false, _T(".key"), _T("CDKey"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("CDKey文件(*.key)|*.key|")); if (IDOK == m_FileDlg.DoModal()) { - int nMSGLen = 0; - XCHAR tszDEBuffer[4096] = {}; - XBYTE tszENBuffer[4096] = {}; - //Authorize_CDKey_WriteMemory(tszDEBuffer, &nMSGLen, &st_AuthorizeCDKey); USES_CONVERSION; - Cryption_XCrypto_Encoder(tszDEBuffer, &nMSGLen, tszENBuffer, W2A(m_StrPass.GetBuffer())); - FILE* pSt_File = _tfopen(m_FileDlg.GetPathName(), _T("wb")); - fwrite(tszENBuffer, 1, nMSGLen, pSt_File); - fclose(pSt_File); + Verification_XAuthKey_FileWrite(&st_AuthorizeCDKey, W2A(m_FileDlg.GetPathName()), W2A(m_StrPass.GetBuffer())); } AfxMessageBox(_T("授权CDKEY成功")); } diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/XEngineAuthorizeApp.rc b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/XEngineAuthorizeApp.rc index d13598135be86f0a8fda3f11ec8af72dcb4b0854..fbb7a2ad64107cf6d554bd551bd0b68781e33606 100644 GIT binary patch delta 68 zcmdni%Dk(#M XGUzZ^Fc U2RQ&V04xAFlY5LCvyh%9B<$f9-v9sr From 8f875962c57fa3bd96986fbae317e9eac46fd96f Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 15 Oct 2025 14:29:32 +0800 Subject: [PATCH 07/22] fixed:build error --- XEngine_Source/AuthorizeModule_Database/Makefile | 4 ++-- XEngine_Source/Makefile | 8 +------- .../XEngine_APPService/XEngine_AuthorizeService/Makefile | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/XEngine_Source/AuthorizeModule_Database/Makefile b/XEngine_Source/AuthorizeModule_Database/Makefile index cd52a3b..e722ec2 100644 --- a/XEngine_Source/AuthorizeModule_Database/Makefile +++ b/XEngine_Source/AuthorizeModule_Database/Makefile @@ -3,8 +3,8 @@ PLATVER = FILEEXT = LIBFLAG = LOADHDR = -I ./ -LOADSO = -L ../AuthorizeModule_CDKey -LIB = -lXEngine_BaseLib -lHelpComponents_DataBase -lAuthorizeModule_CDKey +LOADSO = +LIB = -lXEngine_BaseLib -lHelpComponents_DataBase LIBEX = OBJECTS = DBModule_SQLite.o DBModule_MySQL.o pch.o diff --git a/XEngine_Source/Makefile b/XEngine_Source/Makefile index 6844f24..9137128 100644 --- a/XEngine_Source/Makefile +++ b/XEngine_Source/Makefile @@ -7,13 +7,11 @@ DEPEND_JSONCPP_PATH = ./XEngine_DependLibrary/XEngine_Module/jsoncpp DEPEND_REPORT_PATH = ./XEngine_DependLibrary/XEngine_Module/XEngine_InfoReport DEPEND_VERIFICATION_PATH = ./XEngine_DependLibrary/XEngine_Module/XEngine_Verification -AUTH_CDKEY_PATH = ./AuthorizeModule_CDKey AUTH_SESSION_PATH = ./AuthorizeModule_Session AUTH_DATABASE_PATH = ./AuthorizeModule_Database AUTH_PROTOCOL_PATH = ./AuthorizeModule_Protocol AUTH_CONFIGURE_PATH = ./AuthorizeModule_Configure AUTH_HELP_PATH = ./AuthorizeModule_Help -AUTH_CLIENT_PATH = ./AuthorizeModule_Client AUTH_APP_PATH = ./XEngine_APPService/XEngine_AuthorizeService @@ -24,7 +22,7 @@ else ifeq ($(PLATFORM),mac) endif XENGINE_MODULES = libjsoncpp.so libXEngine_InfoReport.so libXEngine_Verification.so \ - libAuthorizeModule_CDKey.so libAuthorizeModule_Session.so libAuthorizeModule_Database.so libAuthorizeModule_Protocol.so libAuthorizeModule_Configure.so libAuthorizeModule_Help.so libAuthorizeModule_Client.so \ + libAuthorizeModule_Session.so libAuthorizeModule_Database.so libAuthorizeModule_Protocol.so libAuthorizeModule_Configure.so libAuthorizeModule_Help.so \ XEngine_AuthorizeApp.exe .PHONY:MakeAll @@ -50,8 +48,6 @@ else make -C $(DEPEND_VERIFICATION_PATH) PLATFORM=$(PLATFORM) $(FLAGS) endif -libAuthorizeModule_CDKey.so: - make -C $(AUTH_CDKEY_PATH) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) $(FLAGS) libAuthorizeModule_Session.so: make -C $(AUTH_SESSION_PATH) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) $(FLAGS) libAuthorizeModule_Database.so: @@ -62,8 +58,6 @@ libAuthorizeModule_Configure.so: make -C $(AUTH_CONFIGURE_PATH) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) $(FLAGS) libAuthorizeModule_Help.so: make -C $(AUTH_HELP_PATH) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) $(FLAGS) -libAuthorizeModule_Client.so: - make -C $(AUTH_CLIENT_PATH) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) $(FLAGS) XEngine_AuthorizeApp.exe: make -C $(AUTH_APP_PATH) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) $(FLAGS) \ No newline at end of file diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Makefile b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Makefile index 9422394..9f499f1 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Makefile +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Makefile @@ -7,7 +7,7 @@ LOADSO = -L ../../XEngine_DependLibrary/XEngine_Module/jsoncpp -L ../../XEngine_ -L ../../AuthorizeModule_Session -L ../../AuthorizeModule_Database -L ../../AuthorizeModule_Protocol -L ../../AuthorizeModule_Configure -L ../../AuthorizeModule_Help -L ../../AuthorizeModule_CDKey LIB = -lXEngine_InfoReport -ljsoncpp -lXEngine_Verification \ -lXEngine_BaseLib -lXEngine_Algorithm -lXEngine_Core -lXEngine_ManagePool -lXEngine_Cryption -lXClient_APIHelp -lNetHelp_APIAddr -lHelpComponents_Packets -lHelpComponents_DataBase -lHelpComponents_XLog -lRfcComponents_WSProtocol -lRfcComponents_HttpProtocol -lXEngine_ProcFile -lXEngine_SystemApi \ - -lAuthorizeModule_Session -lAuthorizeModule_Database -lAuthorizeModule_Protocol -lAuthorizeModule_Configure -lAuthorizeModule_Help -lAuthorizeModule_CDKey + -lAuthorizeModule_Session -lAuthorizeModule_Database -lAuthorizeModule_Protocol -lAuthorizeModule_Configure -lAuthorizeModule_Help LIBEX = OBJECTS = Authorize_Config.o Authorize_Net.o Authorize_Task.o Authorize_TCPTask.o Authorize_WSTask.o Authorize_HttpTask.o XEngine_AuthorizeService.o \ AuthorizeHTTP_Client.o AuthorizeHTTP_Serial.o AuthorizeHTTP_User.o AuthorizeHTTP_Pass.o AuthorizeHTTP_Switch.o AuthorizeHTTP_Banned.o AuthorizeHTTP_CDKey.o AuthorizeHTTP_Announcement.o AuthorizeHTTP_Try.o\ From 8c61980ed93ef43698b2cca5ef7b4fc419145361 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 15 Oct 2025 15:18:56 +0800 Subject: [PATCH 08/22] fixed:build error --- .../DBModule_MySQL/DBModule_MySQL.cpp | 16 ++++++++-------- .../DBModule_SQLite/DBModule_SQLite.cpp | 16 ++++++++-------- XEngine_Source/AuthorizeModule_Database/pch.h | 2 +- .../Protocol_Packet/Protocol_Packet.cpp | 4 ++-- .../Protocol_Parse/Protocol_Parse.cpp | 2 +- XEngine_Source/AuthorizeModule_Protocol/pch.h | 2 +- XEngine_Source/AuthorizeModule_Session/pch.h | 2 +- XEngine_Source/XAuth_Protocol.h | 4 ++-- .../AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp | 10 +++++----- .../Authorize_TCPTask.cpp | 2 +- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp index 5cbe3ec..5906b7a 100644 --- a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp @@ -957,7 +957,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer) return false; } //插入数据库 - _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_TempVer`(tszVSerial,nVMode,nVTime,nLTime,CreateTime) VALUES('%s',%d,%d,%d,NOW())"), pSt_AuthVer->tszVSerial, pSt_AuthVer->enVMode, pSt_AuthVer->nVTime, pSt_AuthVer->nVTime); + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_TempVer`(tszVSerial,nVMode,nVTime,nLTime,CreateTime) VALUES('%s',%d,%d,%d,NOW())"), pSt_AuthVer->tszVSerial, pSt_AuthVer->enSerialType, pSt_AuthVer->nVTime, pSt_AuthVer->nLTime); if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) { @@ -1025,7 +1025,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer) //试用类型 if (NULL != ppszResult[nFliedValue]) { - pSt_AuthVer->enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + pSt_AuthVer->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); } //试用时间 @@ -1142,7 +1142,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TryClear(int nThanValue, ENUM_VERIFICATION_ _tcsxcpy(st_AuthVer.tszVSerial, ppszResult[nFliedValue]); nFliedValue++; //模式 - st_AuthVer.enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + st_AuthVer.enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //测试时间 st_AuthVer.nVTime = _ttxoi(ppszResult[nFliedValue]); @@ -1161,7 +1161,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TryClear(int nThanValue, ENUM_VERIFICATION_ for (; stl_ListIterator != stl_ListVer.end(); stl_ListIterator++) { //判断是不是不关心注册的模式直接清理 - if (ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW == enVerMode) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW == enVerMode) { if (nThanValue > stl_ListIterator->nVTime) { @@ -1178,7 +1178,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TryClear(int nThanValue, ENUM_VERIFICATION_ } else { - if (enVerMode == stl_ListIterator->enVMode) + if (enVerMode == stl_ListIterator->enSerialType) { memset(tszSQLStatement, '\0', 1024); _xstprintf(tszSQLStatement, _X("DELETE FROM `Authorize_TempVer` WHERE tszVSerial = '%s'"), stl_ListIterator->tszVSerial); @@ -1215,7 +1215,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TrySet(AUTHREG_TEMPVER* pSt_AuthVer) XCHAR tszSQLStatement[1024]; memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_TempVer` SET nVMode = '%d',nVTime = '%d',nLTime = '%d',CreateTime = '%s' WHERE tszVSerial = '%s'"), pSt_AuthVer->enVMode, pSt_AuthVer->nVTime, pSt_AuthVer->nLTime, pSt_AuthVer->tszVDate, pSt_AuthVer->tszVSerial); + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_TempVer` SET nVMode = '%d',nVTime = '%d',nLTime = '%d',CreateTime = '%s' WHERE tszVSerial = '%s'"), pSt_AuthVer->enSerialType, pSt_AuthVer->nVTime, pSt_AuthVer->nLTime, pSt_AuthVer->tszVDate, pSt_AuthVer->tszVSerial); //更新用户表 if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) { @@ -1288,7 +1288,7 @@ bool CDBModule_MySQL::DBModule_MySQL_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, i _tcsxcpy((*pppSt_AuthVer)[i]->tszVSerial, ppszResult[nFliedValue]); nFliedValue++; //类型 - (*pppSt_AuthVer)[i]->enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + (*pppSt_AuthVer)[i]->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //时间 (*pppSt_AuthVer)[i]->nVTime = _ttxoi(ppszResult[nFliedValue]); @@ -1948,7 +1948,7 @@ bool CDBModule_MySQL::DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR l if (en_AuthSerialType != en_AuthUserType) { //如果不等于,需要重写 - if (ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW != en_AuthUserType) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW != en_AuthUserType) { //判断是否允许改写。 if (!m_bChange) diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp index 140684d..60678a9 100644 --- a/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp @@ -898,7 +898,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer) return false; } //插入数据库 - _xstprintf(tszSQLStatement, _X("INSERT INTO Authorize_TempVer(tszVSerial,nVMode,nVTime,nLTime,CreateTime) VALUES('%s',%d,%d,%d,datetime('now', 'localtime'))"), pSt_AuthVer->tszVSerial, pSt_AuthVer->enVMode, pSt_AuthVer->nVTime, pSt_AuthVer->nVTime); + _xstprintf(tszSQLStatement, _X("INSERT INTO Authorize_TempVer(tszVSerial,nVMode,nVTime,nLTime,CreateTime) VALUES('%s',%d,%d,%d,datetime('now', 'localtime'))"), pSt_AuthVer->tszVSerial, pSt_AuthVer->enSerialType, pSt_AuthVer->nVTime, pSt_AuthVer->nVTime); if (!DataBase_SQLite_Exec(xhData, tszSQLStatement)) { SQLPacket_IsErrorOccur = true; @@ -956,7 +956,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer) //序列号 nFliedValue++; //试用类型 - pSt_AuthVer->enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + pSt_AuthVer->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //试用时间 pSt_AuthVer->nVTime = _ttxoi(ppszResult[nFliedValue]); @@ -1054,7 +1054,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TryClear(int nThanValue, ENUM_VERIFICATIO _tcsxcpy(st_AuthVer.tszVSerial, ppszResult[nFliedValue]); nFliedValue++; //模式 - st_AuthVer.enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + st_AuthVer.enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //测试时间 st_AuthVer.nVTime = _ttxoi(ppszResult[nFliedValue]); @@ -1073,7 +1073,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TryClear(int nThanValue, ENUM_VERIFICATIO for (; stl_ListIterator != stl_ListVer.end(); stl_ListIterator++) { //判断是不是不关心注册的模式直接清理 - if (ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW == enVMode) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW == enVMode) { if (nThanValue > stl_ListIterator->nVTime) { @@ -1090,7 +1090,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TryClear(int nThanValue, ENUM_VERIFICATIO } else { - if (enVMode == stl_ListIterator->enVMode) + if (enVMode == stl_ListIterator->enSerialType) { memset(tszSQLStatement, '\0', 1024); _xstprintf(tszSQLStatement, _X("DELETE FROM Authorize_TempVer WHERE tszVSerial = '%s'"), stl_ListIterator->tszVSerial); @@ -1127,7 +1127,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TrySet(AUTHREG_TEMPVER* pSt_AuthVer) XCHAR tszSQLStatement[1024]; memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - _xstprintf(tszSQLStatement, _X("UPDATE Authorize_TempVer SET nVMode = '%d',nVTime = '%d',nLTime = '%d',CreateTime = '%s' WHERE tszVSerial = '%s'"), pSt_AuthVer->enVMode, pSt_AuthVer->nVTime, pSt_AuthVer->nLTime, pSt_AuthVer->tszVDate, pSt_AuthVer->tszVSerial); + _xstprintf(tszSQLStatement, _X("UPDATE Authorize_TempVer SET nVMode = '%d',nVTime = '%d',nLTime = '%d',CreateTime = '%s' WHERE tszVSerial = '%s'"), pSt_AuthVer->enSerialType, pSt_AuthVer->nVTime, pSt_AuthVer->nLTime, pSt_AuthVer->tszVDate, pSt_AuthVer->tszVSerial); //更新用户表 if (!DataBase_SQLite_Exec(xhData, tszSQLStatement)) { @@ -1195,7 +1195,7 @@ bool CDBModule_SQLite::DBModule_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, _tcsxcpy((*pppSt_AuthVer)[i]->tszVSerial, ppszResult[nFliedValue]); nFliedValue++; //类型 - (*pppSt_AuthVer)[i]->enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + (*pppSt_AuthVer)[i]->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); nFliedValue++; //时间 (*pppSt_AuthVer)[i]->nVTime = _ttxoi(ppszResult[nFliedValue]); @@ -1809,7 +1809,7 @@ bool CDBModule_SQLite::DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR if (en_AuthSerialType != en_AuthUserType) { //如果不等于,需要重写 - if (ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW != en_AuthUserType) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW != en_AuthUserType) { //判断是否允许改写。 if (!m_bChange) diff --git a/XEngine_Source/AuthorizeModule_Database/pch.h b/XEngine_Source/AuthorizeModule_Database/pch.h index ec24bc2..d123f71 100644 --- a/XEngine_Source/AuthorizeModule_Database/pch.h +++ b/XEngine_Source/AuthorizeModule_Database/pch.h @@ -25,7 +25,7 @@ using namespace std; #include #include #include -#include "../XEngine_OPenSource/XEngine_Module/XEngine_Verification/Verification_Define.h" +#include "../XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Define.h" #include "../XAuth_Protocol.h" #include "Database_Define.h" #include "Database_Error.h" diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.cpp b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.cpp index 9e14420..157fc90 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.cpp +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Packet/Protocol_Packet.cpp @@ -859,8 +859,8 @@ bool CProtocol_Packet::Protocol_Packet_HttpTryList(XCHAR* ptszMsgBuffer, int* pI Json::Value st_JsonObject; st_JsonObject["nID"] = (Json::Value::Int64)(*pppSt_TryList)[i]->nID; st_JsonObject["nVTime"] = (*pppSt_TryList)[i]->nVTime; - st_JsonObject["enVMode"] = (*pppSt_TryList)[i]->enVMode; - if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY == (*pppSt_TryList)[i]->enVMode) + st_JsonObject["enVMode"] = (*pppSt_TryList)[i]->enSerialType; + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY == (*pppSt_TryList)[i]->enSerialType) { XENGINE_LIBTIME st_TimeStart = {}; XENGINE_LIBTIME st_TimeEnd = {}; diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp index ab31697..8b1dc7f 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp @@ -390,7 +390,7 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseTry(LPCXSTR lpszMsgBuffer, int nMs if (!st_JsonProtocol["enVMode"].isNull()) { - pSt_NETTry->enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_JsonProtocol["enVMode"].asInt(); + pSt_NETTry->enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_JsonProtocol["enVMode"].asInt(); } if (!st_JsonProtocol["nID"].isNull()) { diff --git a/XEngine_Source/AuthorizeModule_Protocol/pch.h b/XEngine_Source/AuthorizeModule_Protocol/pch.h index 47ca0dd..ac92c00 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/pch.h +++ b/XEngine_Source/AuthorizeModule_Protocol/pch.h @@ -24,7 +24,7 @@ using namespace std; #include #include #include -#include "../XEngine_OPenSource/XEngine_Module/XEngine_Verification/Verification_Define.h" +#include "../XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Define.h" #include "../XAuth_Protocol.h" #include "../AuthorizeModule_Configure/Config_Define.h" #include "../AuthorizeModule_Session/Session_Define.h" diff --git a/XEngine_Source/AuthorizeModule_Session/pch.h b/XEngine_Source/AuthorizeModule_Session/pch.h index 7c185f4..4564ce3 100644 --- a/XEngine_Source/AuthorizeModule_Session/pch.h +++ b/XEngine_Source/AuthorizeModule_Session/pch.h @@ -27,7 +27,7 @@ using namespace std; #include #include #include -#include "../XEngine_OPenSource/XEngine_Module/XEngine_Verification/Verification_Define.h" +#include "../XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Define.h" #include "../XAuth_Protocol.h" #include "Session_Define.h" #include "Session_Error.h" diff --git a/XEngine_Source/XAuth_Protocol.h b/XEngine_Source/XAuth_Protocol.h index 880a3ab..2635573 100644 --- a/XEngine_Source/XAuth_Protocol.h +++ b/XEngine_Source/XAuth_Protocol.h @@ -116,13 +116,13 @@ typedef struct __int64x nID; //ID int nVTime; //试用时间 int nLTime; //剩余时间 - ENUM_VERIFICATION_MODULE_SERIAL_TYPE enVMode; //验证方式 + ENUM_VERIFICATION_MODULE_SERIAL_TYPE enSerialType; //验证方式 }AUTHREG_TEMPVER; //禁止列表 typedef struct { __int64x nID; //ID - XCHAR tszUserName[XPATH_MAX]; //用户名 + XCHAR tszUserName[XENGINE_AUTHREG_SERVICE_SQL_MAX_USERNAME]; //用户名 XCHAR tszIPAddr[128]; //IP XCHAR tszLeftTime[64]; //过期时间 XCHAR tszCreateTime[64]; //创建时间 diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp index d756e4c..dc5ea38 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp @@ -109,7 +109,7 @@ bool XEngine_AuthorizeHTTP_User(XNETHANDLE xhToken, LPCXSTR lpszClientAddr, LPCX return false; } //填充写入数据 - if (ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW == st_UserTable.enSerialType) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW == st_UserTable.enSerialType) { _xstprintf(st_UserTable.tszLeftTime, _X("%d"), st_AuthConfig.st_XVerification.nTryTime); st_UserTable.enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_AuthConfig.st_XVerification.nTryMode; @@ -329,7 +329,7 @@ bool XEngine_AuthorizeHTTP_User(XNETHANDLE xhToken, LPCXSTR lpszClientAddr, LPCX { __int64x nTimeSpan = 0; //根据方式来计算剩余时间 - if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME == st_VERTemp.enVMode) + if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME == st_VERTemp.enSerialType) { //次数卡需要更新才可以 st_VERTemp.nLTime--; @@ -366,7 +366,7 @@ bool XEngine_AuthorizeHTTP_User(XNETHANDLE xhToken, LPCXSTR lpszClientAddr, LPCX } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,序列号:%s,类型:%s,临时验证成功,剩余时间:%lld"), lpszClientAddr, st_VERTemp.tszVSerial, lpszXSerialType[st_VERTemp.enVMode], nTimeSpan); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,序列号:%s,类型:%s,临时验证成功,剩余时间:%lld"), lpszClientAddr, st_VERTemp.tszVSerial, lpszXSerialType[st_VERTemp.enSerialType], nTimeSpan); } else { @@ -379,9 +379,9 @@ bool XEngine_AuthorizeHTTP_User(XNETHANDLE xhToken, LPCXSTR lpszClientAddr, LPCX { //填充写入数据 st_VERTemp.nVTime = st_AuthConfig.st_XVerification.nVerTime; - st_VERTemp.enVMode = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_AuthConfig.st_XVerification.nVerMode; + st_VERTemp.enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_AuthConfig.st_XVerification.nVerMode; //看下是否启用了此功能,不支持分钟,因为不登录 - if ((ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW == st_VERTemp.enVMode) || (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND == st_VERTemp.enVMode) || (st_VERTemp.nVTime <= 0)) + if ((ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW == st_VERTemp.enSerialType) || (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND == st_VERTemp.enSerialType) || (st_VERTemp.nVTime <= 0)) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, ERROR_AUTHORIZE_PROTOCOL_CLOSED, "the function server unavailable"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp index 6da06d9..a64bc61 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp @@ -320,7 +320,7 @@ bool XEngine_Client_TCPTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int n return false; } //分析充值类型 - if ((ENUM_VERIFICATION_MODULE_CDKEY_TYPE_UNKNOW == st_UserTable.enSerialType) || ('0' == st_UserTable.tszLeftTime[0])) + if ((ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW == st_UserTable.enSerialType) || ('0' == st_UserTable.tszLeftTime[0])) { pSt_ProtocolHdr->wReserve = ERROR_AUTHORIZE_PROTOCOL_TIMELEFT; Protocol_Packet_HDRComm(tszSDBuffer, &nSDLen, pSt_ProtocolHdr, nNetType); From cb5e2191500b9807550d22cfbcdaabc945fe4cf2 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 15 Oct 2025 15:44:40 +0800 Subject: [PATCH 09/22] ci:centos and alma linux and debian 13 system support --- .github/workflows/Alma_build.yml | 95 ++++++++++++++++++++++++++++ .github/workflows/Centos_build.yml | 99 ++++++++++++++++++++++++++++++ .github/workflows/debian_build.yml | 18 ++++-- .github/workflows/release.yml | 18 ++++++ 4 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/Alma_build.yml create mode 100644 .github/workflows/Centos_build.yml diff --git a/.github/workflows/Alma_build.yml b/.github/workflows/Alma_build.yml new file mode 100644 index 0000000..11127b1 --- /dev/null +++ b/.github/workflows/Alma_build.yml @@ -0,0 +1,95 @@ +name: alma build workflows + +on: + push: + branches: + - 'develop' + paths: + - 'XEngine_Source/**' + - 'XEngine_Release/**' + - '.github/**' + +permissions: + contents: read + +jobs: + build: + runs-on: ${{ matrix.runner }} + container: + image: almalinux:${{ matrix.version }} + options: --platform ${{ matrix.platform }} + strategy: + matrix: + include: + - arch: amd64 + runner: ubuntu-24.04 + platform: linux/amd64 + artifact: x86-64 + version: 9 + - arch: amd64 + runner: ubuntu-24.04 + platform: linux/amd64 + artifact: x86-64 + version: 10 + - arch: arm64 + runner: ubuntu-24.04-arm + platform: linux/arm64 + artifact: Arm64 + version: 9 + - arch: arm64 + runner: ubuntu-24.04-arm + platform: linux/arm64 + artifact: Arm64 + version: 10 + + steps: + - name: Checkout main repository code + uses: actions/checkout@v4 + + - name: Checkout dependency repository (xengine) + uses: actions/checkout@v4 + with: + repository: libxengine/libxengine + path: libxengine + + - name: sub module checkout (opensource) + uses: actions/checkout@v4 + with: + repository: libxengine/XEngine_OPenSource + path: XEngine_Source/XEngine_DependLibrary + + - name: Set TERM variable + run: echo "TERM=xterm" >> $GITHUB_ENV + + - name: install system package + run: | + dnf update -y + dnf install gcc g++ make git jq unzip wget -y + + - name: install xengine library + run: | + latest_tag=$(curl -s https://api.github.com/repos/libxengine/libxengine/releases/latest | jq -r .tag_name) + wget https://github.com/libxengine/libxengine/releases/download/$latest_tag/XEngine_RockyLinux_${{ matrix.version }}_${{ matrix.artifact }}.zip + unzip ./XEngine_RockyLinux_${{ matrix.version }}_${{ matrix.artifact }}.zip -d ./XEngine_RockyLinux_${{ matrix.version }}_${{ matrix.artifact }} + cd XEngine_RockyLinux_${{ matrix.version }}_${{ matrix.artifact }} + + chmod 777 * + ./XEngine_LINEnv.sh -i 3 + + - name: make + run: | + cd XEngine_Source + make RELEASE=1 + make FLAGS=InstallAll + make FLAGS=CleanAll + cd .. + - name: test + run: | + cd XEngine_Release + ./XEngine_AuthorizeService -t + + - name: Upload folder as artifact + uses: actions/upload-artifact@v4 + with: + name: XEngine_AuthorizeService-AlmaLinux_${{ matrix.version }}_${{ matrix.artifact }} + path: XEngine_Release/ \ No newline at end of file diff --git a/.github/workflows/Centos_build.yml b/.github/workflows/Centos_build.yml new file mode 100644 index 0000000..e3c4ddb --- /dev/null +++ b/.github/workflows/Centos_build.yml @@ -0,0 +1,99 @@ +name: centos build workflows + +on: + push: + branches: + - 'develop' + paths: + - 'XEngine_Source/**' + - 'XEngine_Release/**' + - '.github/**' + +permissions: + contents: read + +jobs: + build: + runs-on: ${{ matrix.runner }} + container: + image: quay.io/centos/centos:${{ matrix.stream }} + options: --platform ${{ matrix.platform }} + strategy: + matrix: + include: + - arch: amd64 + runner: ubuntu-24.04 + platform: linux/amd64 + artifact: x86-64 + version: 9 + stream: stream9 + - arch: amd64 + runner: ubuntu-24.04 + platform: linux/amd64 + artifact: x86-64 + version: 10 + stream: stream10 + - arch: arm64 + runner: ubuntu-24.04-arm + platform: linux/arm64 + artifact: Arm64 + version: 9 + stream: stream9 + - arch: arm64 + runner: ubuntu-24.04-arm + platform: linux/arm64 + artifact: Arm64 + version: 10 + stream: stream10 + + steps: + - name: Checkout main repository code + uses: actions/checkout@v4 + + - name: Checkout dependency repository (xengine) + uses: actions/checkout@v4 + with: + repository: libxengine/libxengine + path: libxengine + + - name: sub module checkout (opensource) + uses: actions/checkout@v4 + with: + repository: libxengine/XEngine_OPenSource + path: XEngine_Source/XEngine_DependLibrary + + - name: Set TERM variable + run: echo "TERM=xterm" >> $GITHUB_ENV + + - name: install system package + run: | + dnf update -y + dnf install gcc g++ make git jq unzip wget -y + + - name: install xengine library + run: | + latest_tag=$(curl -s https://api.github.com/repos/libxengine/libxengine/releases/latest | jq -r .tag_name) + wget https://github.com/libxengine/libxengine/releases/download/$latest_tag/XEngine_RockyLinux_${{ matrix.version }}_${{ matrix.artifact }}.zip + unzip ./XEngine_RockyLinux_${{ matrix.version }}_${{ matrix.artifact }}.zip -d ./XEngine_RockyLinux_${{ matrix.version }}_${{ matrix.artifact }} + cd XEngine_RockyLinux_${{ matrix.version }}_${{ matrix.artifact }} + + chmod 777 * + ./XEngine_LINEnv.sh -i 3 + + - name: make + run: | + cd XEngine_Source + make RELEASE=1 + make FLAGS=InstallAll + make FLAGS=CleanAll + cd .. + - name: test + run: | + cd XEngine_Release + ./XEngine_AuthorizeService -t + + - name: Upload folder as artifact + uses: actions/upload-artifact@v4 + with: + name: XEngine_AuthorizeService-CentOS_${{ matrix.version }}_${{ matrix.artifact }} + path: XEngine_Release/ \ No newline at end of file diff --git a/.github/workflows/debian_build.yml b/.github/workflows/debian_build.yml index c2be054..702ad83 100644 --- a/.github/workflows/debian_build.yml +++ b/.github/workflows/debian_build.yml @@ -16,7 +16,7 @@ jobs: build: runs-on: ${{ matrix.runner }} container: - image: debian:bookworm + image: debian:${{ matrix.name }} options: --platform ${{ matrix.platform }} strategy: matrix: @@ -25,6 +25,14 @@ jobs: runner: ubuntu-24.04 platform: linux/amd64 artifact: x86-64 + name: bookworm + version: 12 + - arch: amd64 + runner: ubuntu-24.04 + platform: linux/amd64 + artifact: x86-64 + name: trixie + version: 13 steps: - name: Checkout main repository code @@ -53,9 +61,9 @@ jobs: - name: install xengine library run: | latest_tag=$(curl -s https://api.github.com/repos/libxengine/libxengine/releases/latest | jq -r .tag_name) - wget https://github.com/libxengine/libxengine/releases/download/$latest_tag/XEngine_Debian_12_${{ matrix.artifact }}.zip - unzip ./XEngine_Debian_12_${{ matrix.artifact }}.zip -d ./XEngine_Debian_12_${{ matrix.artifact }} - cd XEngine_Debian_12_${{ matrix.artifact }} + wget https://github.com/libxengine/libxengine/releases/download/$latest_tag/XEngine_Debian_${{ matrix.version }}_${{ matrix.artifact }}.zip + unzip ./XEngine_Debian_${{ matrix.version }}_${{ matrix.artifact }}.zip -d ./XEngine_Debian_${{ matrix.version }}_${{ matrix.artifact }} + cd XEngine_Debian_${{ matrix.version }}_${{ matrix.artifact }} chmod 777 * ./XEngine_LINEnv.sh -i 3 @@ -79,6 +87,6 @@ jobs: - name: Upload folder as artifact uses: actions/upload-artifact@v4 with: - name: XEngine_AuthorizeService-Debian_12_x86-64 + name: XEngine_AuthorizeService-Debian_${{ matrix.version }}_x86-64 path: XEngine_Release/ retention-days: 1 \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 03cc0ee..8cac7be 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -70,6 +70,24 @@ jobs: skip_unpack: true if_no_artifact_found: fail path: ./XRelease/ + - name: Download Alma Linux + uses: dawidd6/action-download-artifact@v6 + with: + workflow: Alma_build.yml + workflow_conclusion: success + check_artifacts: false + skip_unpack: true + if_no_artifact_found: fail + path: ./XRelease/ + - name: Download CentOS + uses: dawidd6/action-download-artifact@v6 + with: + workflow: Centos_build.yml + workflow_conclusion: success + check_artifacts: false + skip_unpack: true + if_no_artifact_found: fail + path: ./XRelease/ - name: Display structure of downloaded files run: ls -al ./XRelease/ From ff79ea532722d1c9a535d27ecea0e37071a477ad Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 15 Oct 2025 15:51:43 +0800 Subject: [PATCH 10/22] modify:delete push serial and use custom serial insert instead --- .../AuthorizeModule_Database.def | 2 - .../DBModule_MySQL/DBModule_MySQL.cpp | 38 +-------- .../DBModule_MySQL/DBModule_MySQL.h | 1 - .../DBModule_SQLite/DBModule_SQLite.cpp | 38 +-------- .../DBModule_SQLite/DBModule_SQLite.h | 1 - .../Database_Define.h | 28 ------- .../AuthorizeModule_Database/pch.cpp | 8 -- .../AuthorizeModule_Protocol.def | 1 - .../Protocol_Define.h | 44 ----------- .../Protocol_Parse/Protocol_Parse.cpp | 77 ------------------- .../Protocol_Parse/Protocol_Parse.h | 1 - .../AuthorizeModule_Protocol/pch.cpp | 4 - .../Authorize_Dialog/Dialog_Serial.cpp | 33 ++++++-- .../AuthorizeHTTP_Serial.cpp | 57 +------------- 14 files changed, 31 insertions(+), 302 deletions(-) diff --git a/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.def b/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.def index 8ccb2a1..07a2227 100644 --- a/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.def +++ b/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.def @@ -20,7 +20,6 @@ EXPORTS DBModule_SQLite_SerialDelete DBModule_SQLite_SerialQuery DBModule_SQLite_SerialQueryAll - DBModule_SQLite_SerialPush DBModule_SQLite_TryInsert DBModule_SQLite_TryQuery @@ -56,7 +55,6 @@ EXPORTS DBModule_MySQL_SerialDelete DBModule_MySQL_SerialQuery DBModule_MySQL_SerialQueryAll - DBModule_MySQL_SerialPush DBModule_MySQL_TryInsert DBModule_MySQL_TryQuery diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp index 5906b7a..800e847 100644 --- a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp @@ -672,7 +672,7 @@ bool CDBModule_MySQL::DBModule_MySQL_SerialInsert(AUTHREG_SERIALTABLE* pSt_Seria SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; return false; } - _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s','%s','%d',0,NOW(),'%s')"), pSt_SerialTable->tszSerialNumber, pSt_SerialTable->tszMaxTime, pSt_SerialTable->enSerialType, pSt_SerialTable->tszExpiredTime); + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'%s','%s','%s',%d,%d,'%s','%s')"), pSt_SerialTable->tszUserName, pSt_SerialTable->tszSerialNumber, pSt_SerialTable->tszMaxTime, pSt_SerialTable->enSerialType, pSt_SerialTable->bIsUsed, pSt_SerialTable->tszCreateTime, pSt_SerialTable->tszExpiredTime); if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) { @@ -885,42 +885,6 @@ bool CDBModule_MySQL::DBModule_MySQL_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt return true; } /******************************************************************** -函数名称:DBModule_MySQL_SerialPush -函数功能:插入一条指定的序列号信息到服务器 - 参数.一:pSt_SerialTable - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:输入要插入的信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CDBModule_MySQL::DBModule_MySQL_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable) -{ - SQLPacket_IsErrorOccur = false; - - XCHAR tszSQLStatement[1024]; //SQL语句 - memset(tszSQLStatement, '\0', 1024); - - if (DBModule_MySQL_SerialQuery(pSt_SerialTable->tszSerialNumber)) - { - SQLPacket_IsErrorOccur = true; - SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; - return false; - } - _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'%s','%s','%s',%d,%d,'%s','%s')"), pSt_SerialTable->tszUserName, pSt_SerialTable->tszSerialNumber, pSt_SerialTable->tszMaxTime, pSt_SerialTable->enSerialType, pSt_SerialTable->bIsUsed, pSt_SerialTable->tszCreateTime, pSt_SerialTable->tszExpiredTime); - - if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) - { - SQLPacket_IsErrorOccur = true; - SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_ISFAILED; - return false; - } - return true; -} -/******************************************************************** 函数名称:DBModule_MySQL_TryInsert 函数功能:网络使用模式插入一条数据 参数.一:pSt_AuthVer diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h index f134755..71f8553 100644 --- a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h @@ -37,7 +37,6 @@ class CDBModule_MySQL bool DBModule_MySQL_SerialDelete(LPCXSTR lpszSerialNumber); //删除一个序列号 bool DBModule_MySQL_SerialQuery(LPCXSTR lpszSerialNumber, LPAUTHREG_SERIALTABLE pSt_SerialTable = NULL); //按照卡号或者用户查询 bool DBModule_MySQL_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd);//查询所有序列卡 - bool DBModule_MySQL_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable);//插入一条指定的序列号信息到服务器 public: bool DBModule_MySQL_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer); //网络使用模式插入一条数据 bool DBModule_MySQL_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer); //试用序列号查询函数 diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp index 60678a9..2de361b 100644 --- a/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp @@ -623,7 +623,7 @@ bool CDBModule_SQLite::DBModule_SQLite_SerialInsert(AUTHREG_SERIALTABLE *pSt_Ser SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; return false; } - _xstprintf(tszSQLStatement, _X("INSERT INTO Authorize_Serial values(NULL,'NOT','%s','%s','%d',0,datetime('now', 'localtime'),'%s')"), pSt_SerialTable->tszSerialNumber, pSt_SerialTable->tszMaxTime, pSt_SerialTable->enSerialType, pSt_SerialTable->tszExpiredTime); + _xstprintf(tszSQLStatement, _X("INSERT INTO Authorize_Serial values(NULL,'%s','%s','%s',%d,%d,'%s','%s')"), pSt_SerialTable->tszUserName, pSt_SerialTable->tszSerialNumber, pSt_SerialTable->tszMaxTime, pSt_SerialTable->enSerialType, pSt_SerialTable->bIsUsed, pSt_SerialTable->tszCreateTime, pSt_SerialTable->tszExpiredTime); if (!DataBase_SQLite_Exec(xhData, tszSQLStatement)) { @@ -825,42 +825,6 @@ bool CDBModule_SQLite::DBModule_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE*** ppp return true; } /******************************************************************** -函数名称:DBModule_SQLite_SerialPush -函数功能:插入一条指定的序列号信息到服务器 - 参数.一:pSt_SerialTable - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:输入要插入的信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CDBModule_SQLite::DBModule_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable) -{ - SQLPacket_IsErrorOccur = false; - - XCHAR tszSQLStatement[1024]; //SQL语句 - memset(tszSQLStatement, '\0', 1024); - - if (DBModule_SQLite_SerialQuery(pSt_SerialTable->tszSerialNumber)) - { - SQLPacket_IsErrorOccur = true; - SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; - return false; - } - _xstprintf(tszSQLStatement, _X("INSERT INTO Authorize_Serial values(NULL,'%s','%s','%s',%d,%d,'%s','%s')"), pSt_SerialTable->tszUserName, pSt_SerialTable->tszSerialNumber, pSt_SerialTable->tszMaxTime, pSt_SerialTable->enSerialType, pSt_SerialTable->bIsUsed, pSt_SerialTable->tszCreateTime, pSt_SerialTable->tszExpiredTime); - - if (!DataBase_SQLite_Exec(xhData, tszSQLStatement)) - { - SQLPacket_IsErrorOccur = true; - SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_ISFAILED; - return false; - } - return true; -} -/******************************************************************** 函数名称:DBModule_SQLite_TryInsert 函数功能:网络使用模式插入一条数据 参数.一:pSt_AuthVer diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.h b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.h index a7822cb..7ce8482 100644 --- a/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.h +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.h @@ -37,7 +37,6 @@ class CDBModule_SQLite bool DBModule_SQLite_SerialDelete(LPCXSTR lpszSerialNumber); //删除一个序列号 bool DBModule_SQLite_SerialQuery(LPCXSTR lpszSerialNumber,LPAUTHREG_SERIALTABLE pSt_SerialTable = NULL); //按照卡号或者用户查询 bool DBModule_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE ***pppSt_SerialTable,int *pInt_ListCount, int nPosStart, int nPosEnd);//查询所有序列卡 - bool DBModule_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable); public: bool DBModule_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer); bool DBModule_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer); diff --git a/XEngine_Source/AuthorizeModule_Database/Database_Define.h b/XEngine_Source/AuthorizeModule_Database/Database_Define.h index 464343c..4b3aa74 100644 --- a/XEngine_Source/AuthorizeModule_Database/Database_Define.h +++ b/XEngine_Source/AuthorizeModule_Database/Database_Define.h @@ -288,20 +288,6 @@ extern "C" bool DBModule_SQLite_SerialQuery(LPCXSTR lpszSerialNumber,LPAUTHREG_S *********************************************************************/ extern "C" bool DBModule_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE * **pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd); /******************************************************************** -函数名称:DBModule_SQLite_SerialPush -函数功能:插入一条指定的序列号信息到服务器 - 参数.一:pSt_SerialTable - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:输入要插入的信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool DBModule_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable); -/******************************************************************** 函数名称:DBModule_SQLite_TryInsert 函数功能:网络使用模式插入一条数据 参数.一:pSt_AuthVer @@ -781,20 +767,6 @@ extern "C" bool DBModule_MySQL_SerialQuery(LPCXSTR lpszSerialNumber, LPAUTHREG_S *********************************************************************/ extern "C" bool DBModule_MySQL_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd); /******************************************************************** -函数名称:DBModule_MySQL_SerialPush -函数功能:插入一条指定的序列号信息到服务器 - 参数.一:pSt_SerialTable - In/Out:In - 类型:数据结构指针 - 可空:N - 意思:输入要插入的信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool DBModule_MySQL_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable); -/******************************************************************** 函数名称:DBModule_MySQL_TryInsert 函数功能:网络使用模式插入一条数据 参数.一:pSt_AuthVer diff --git a/XEngine_Source/AuthorizeModule_Database/pch.cpp b/XEngine_Source/AuthorizeModule_Database/pch.cpp index de26270..4260df9 100644 --- a/XEngine_Source/AuthorizeModule_Database/pch.cpp +++ b/XEngine_Source/AuthorizeModule_Database/pch.cpp @@ -91,10 +91,6 @@ extern "C" bool DBModule_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE * **pppSt_Ser { return m_DBSQLite.DBModule_SQLite_SerialQueryAll(pppSt_SerialTable, pInt_ListCount, nPosStart, nPosEnd); } -extern "C" bool DBModule_SQLite_SerialPush(AUTHREG_SERIALTABLE * pSt_SerialTable) -{ - return m_DBSQLite.DBModule_SQLite_SerialPush(pSt_SerialTable); -} extern "C" bool DBModule_SQLite_TryInsert(AUTHREG_TEMPVER * pSt_AuthVer) { return m_DBSQLite.DBModule_SQLite_TryInsert(pSt_AuthVer); @@ -206,10 +202,6 @@ extern "C" bool DBModule_MySQL_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt_Seria { return m_DBMySQL.DBModule_MySQL_SerialQueryAll(pppSt_SerialTable, pInt_ListCount, nPosStart, nPosEnd); } -extern "C" bool DBModule_MySQL_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable) -{ - return m_DBMySQL.DBModule_MySQL_SerialPush(pSt_SerialTable); -} extern "C" bool DBModule_MySQL_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer) { return m_DBMySQL.DBModule_MySQL_TryInsert(pSt_AuthVer); diff --git a/XEngine_Source/AuthorizeModule_Protocol/AuthorizeModule_Protocol.def b/XEngine_Source/AuthorizeModule_Protocol/AuthorizeModule_Protocol.def index bc2f769..42a33d5 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/AuthorizeModule_Protocol.def +++ b/XEngine_Source/AuthorizeModule_Protocol/AuthorizeModule_Protocol.def @@ -25,7 +25,6 @@ EXPORTS Protocol_Parse_HttpParseTry Protocol_Parse_HttpParseTable Protocol_Parse_HttpParseSerial - Protocol_Parse_HttpParseSerial2 Protocol_Parse_HttpParseOnline Protocol_Parse_HttpParseTime Protocol_Parse_HttpParseSwitch diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h index 7a12a80..0df07c3 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h @@ -600,50 +600,6 @@ extern "C" bool Protocol_Parse_HttpParseTable(LPCXSTR lpszMsgBuffer, int nMsgLen *********************************************************************/ extern "C" bool Protocol_Parse_HttpParseSerial(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount); /******************************************************************** -函数名称:Protocol_Parse_HttpParseSerial2 -函数功能:解析HTTP序列号 - 参数.一:lpszMsgBuffer - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要解析的缓冲区 - 参数.二:nMsgLen - In/Out:In - 类型:整数型 - 可空:N - 意思:输入要解析的大小 - 参数.三:penSerialType - In/Out:Out - 类型:枚举型指针 - 可空:N - 意思:导出序列卡类型 - 参数.四:pInt_NumberCount - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:导出序列卡长度 - 参数.五:pInt_SerialCount - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:导出序列卡个数 - 参数.六:ptszHasTime - In/Out:Out - 类型:字符指针 - 可空:N - 意思:导出拥有时间 - 参数.七:ptszExpiredTime - In/Out:Out - 类型:字符指针 - 可空:N - 意思:导出过期时间 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_VERIFICATION_MODULE_SERIAL_TYPE * penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR * ptszHasTime, XCHAR* ptszExpiredTime); -/******************************************************************** 函数名称:Protocol_Parse_HttpParseOnline 函数功能:解析在线列表 参数.一:lpszMsgBuffer diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp index 8b1dc7f..b4c69eb 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp @@ -602,83 +602,6 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseSerial(LPCXSTR lpszMsgBuffer, int return true; } /******************************************************************** -函数名称:Protocol_Parse_HttpParseSerial2 -函数功能:解析HTTP序列号 - 参数.一:lpszMsgBuffer - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要解析的缓冲区 - 参数.二:nMsgLen - In/Out:In - 类型:整数型 - 可空:N - 意思:输入要解析的大小 - 参数.三:penSerialType - In/Out:Out - 类型:枚举型指针 - 可空:N - 意思:导出序列卡类型 - 参数.四:pInt_NumberCount - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:导出序列卡长度 - 参数.五:pInt_SerialCount - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:导出序列卡个数 - 参数.六:ptszHasTime - In/Out:Out - 类型:字符指针 - 可空:N - 意思:导出拥有时间 - 参数.七:ptszExpiredTime - In/Out:Out - 类型:字符指针 - 可空:N - 意思:导出过期时间 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CProtocol_Parse::Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_VERIFICATION_MODULE_SERIAL_TYPE* penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR* ptszHasTime, XCHAR* ptszExpiredTime) -{ - Protocol_IsErrorOccur = false; - - if ((NULL == lpszMsgBuffer) || (NULL == penSerialType)) - { - Protocol_IsErrorOccur = true; - Protocol_dwErrorCode = ERROR_AUTHORIZE_MODULE_PROTOCOL_PARAMENT; - return false; - } - Json::Value st_JsonRoot; - JSONCPP_STRING st_JsonError; - Json::CharReaderBuilder st_ReaderBuilder; - - std::unique_ptr const pSt_JsonReader(st_ReaderBuilder.newCharReader()); - if (!pSt_JsonReader->parse(lpszMsgBuffer, lpszMsgBuffer + nMsgLen, &st_JsonRoot, &st_JsonError)) - { - Protocol_IsErrorOccur = true; - Protocol_dwErrorCode = ERROR_AUTHORIZE_MODULE_PROTOCOL_PARSE; - return false; - } - Json::Value st_JsonObject = st_JsonRoot["st_SerialInfo"]; - - *penSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_JsonObject["enSerialType"].asInt(); - *pInt_NumberCount = st_JsonObject["nNumberCount"].asInt(); - *pInt_SerialCount = st_JsonObject["nSerialCount"].asInt(); - _tcsxcpy(ptszHasTime, st_JsonObject["tszHasTime"].asCString()); - - if (!st_JsonObject["tszExpiredTime"].isNull()) - { - _tcsxcpy(ptszExpiredTime, st_JsonObject["tszExpiredTime"].asCString()); - } - return true; -} -/******************************************************************** 函数名称:Protocol_Parse_HttpParseOnline 函数功能:解析在线列表 参数.一:lpszMsgBuffer diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h index 4a8f997..14944a0 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h @@ -26,7 +26,6 @@ class CProtocol_Parse bool Protocol_Parse_HttpParseTry(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_TEMPVER* pSt_NETTry); bool Protocol_Parse_HttpParseTable(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_USERTABLE* pSt_UserTable); bool Protocol_Parse_HttpParseSerial(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount); - bool Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_VERIFICATION_MODULE_SERIAL_TYPE* penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR* ptszHasTime, XCHAR* ptszExpiredTime); bool Protocol_Parse_HttpParseOnline(LPCXSTR lpszMsgBuffer, int nMsgLen, bool* pbOnline); bool Protocol_Parse_HttpParseTime(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_PROTOCOL_TIME* pSt_ProtocolTime); bool Protocol_Parse_HttpParseSwitch(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_FUNCTIONSWITCH* pSt_FunSwitch); diff --git a/XEngine_Source/AuthorizeModule_Protocol/pch.cpp b/XEngine_Source/AuthorizeModule_Protocol/pch.cpp index 6267236..bcd6d3e 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/pch.cpp +++ b/XEngine_Source/AuthorizeModule_Protocol/pch.cpp @@ -118,10 +118,6 @@ extern "C" bool Protocol_Parse_HttpParseSerial(LPCXSTR lpszMsgBuffer, int nMsgLe { return m_ProtocolParse.Protocol_Parse_HttpParseSerial(lpszMsgBuffer, nMsgLen, pppSt_SerialTable, pInt_ListCount); } -extern "C" bool Protocol_Parse_HttpParseSerial2(LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_VERIFICATION_MODULE_SERIAL_TYPE * penSerialType, int* pInt_NumberCount, int* pInt_SerialCount, XCHAR * ptszHasTime, XCHAR* ptszExpiredTime) -{ - return m_ProtocolParse.Protocol_Parse_HttpParseSerial2(lpszMsgBuffer, nMsgLen, penSerialType, pInt_NumberCount, pInt_SerialCount, ptszHasTime, ptszExpiredTime); -} extern "C" bool Protocol_Parse_HttpParseOnline(LPCXSTR lpszMsgBuffer, int nMsgLen, bool * pbOnline) { return m_ProtocolParse.Protocol_Parse_HttpParseOnline(lpszMsgBuffer, nMsgLen, pbOnline); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Serial.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Serial.cpp index e95fec3..6224306 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Serial.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeApp/Authorize_Dialog/Dialog_Serial.cpp @@ -186,6 +186,11 @@ void CDialog_Serial::OnBnClickedButton1() void CDialog_Serial::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 + if (m_ComboSerialType.GetCurSel() == ENUM_VERIFICATION_MODULE_SERIAL_TYPE_UNKNOW) + { + AfxMessageBox(_T("没有选择序列卡类型")); + return; + } CString m_StrIPAddr; CString m_StrIPPort; CString m_StrToken; @@ -202,20 +207,32 @@ void CDialog_Serial::OnBnClickedButton2() CString m_StrNumberCount; CString m_StrExpiredTime; Json::Value st_JsonRoot; + Json::Value st_JsonArray; Json::Value st_JsonObject; m_EditExpiredTime.GetWindowText(m_StrExpiredTime); m_EditHasTime.GetWindowText(m_StrHasTime); m_EditSerialCount.GetWindowText(m_StrSerialCount); m_ComboNumber.GetLBText(m_ComboNumber.GetCurSel(), m_StrNumberCount); - USES_CONVERSION; - st_JsonObject["enSerialType"] = m_ComboSerialType.GetCurSel(); - st_JsonObject["nNumberCount"] = _ttoi(m_StrNumberCount.GetBuffer()); - st_JsonObject["nSerialCount"] = _ttoi(m_StrSerialCount.GetBuffer()); - st_JsonObject["tszHasTime"] = W2A(m_StrHasTime.GetBuffer()); - st_JsonObject["tszExpiredTime"] = W2A(m_StrExpiredTime.GetBuffer()); - st_JsonRoot["st_SerialInfo"] = st_JsonObject; + XCHAR tszTimeStr[XPATH_MIN] = {}; + BaseLib_Time_TimeToStr(tszTimeStr); + for (int i = 0; i < _ttoi(m_StrSerialCount.GetBuffer()); i++) + { + Json::Value st_JsonObject; + XCHAR tszSerialStr[XPATH_MIN] = {}; + Verification_XAuthKey_KeySerial(tszSerialStr, _ttoi(m_StrNumberCount.GetBuffer()), 0); + + st_JsonObject["bIsUsed"] = false; + st_JsonObject["enSerialType"] = m_ComboSerialType.GetCurSel(); + st_JsonObject["tszCreateTime"] = tszTimeStr; + st_JsonObject["tszExpiredTime"] = W2A(m_StrExpiredTime.GetBuffer()); + st_JsonObject["tszMaxTime"] = W2A(m_StrHasTime.GetBuffer()); + st_JsonObject["tszSerialNumber"] = tszSerialStr; + st_JsonObject["tszUserName"] = "NOT"; + st_JsonArray.append(st_JsonObject); + } + st_JsonRoot["Array"] = st_JsonArray; st_JsonRoot["xhToken"] = _ttoll(m_StrToken.GetBuffer()); int nMsgLen = 0; @@ -475,7 +492,7 @@ void CDialog_Serial::OnBnClickedButton6() int nMsgLen = 0; XCHAR* ptszMsgBuffer = NULL; USES_CONVERSION; - _xstprintf(tszUrlAddr, _X("http://%s:%s/auth/serial/push"), W2A(m_StrIPAddr.GetBuffer()), W2A(m_StrIPPort.GetBuffer())); + _xstprintf(tszUrlAddr, _X("http://%s:%s/auth/serial/insert"), W2A(m_StrIPAddr.GetBuffer()), W2A(m_StrIPPort.GetBuffer())); //是否加密 TCHAR tszPassBuffer[64]; memset(tszPassBuffer, '\0', sizeof(tszPassBuffer)); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp index 1c0b50a..2c82136 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp @@ -6,7 +6,6 @@ bool XEngine_AuthorizeHTTP_Serial(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L LPCXSTR lpszAPIList = _X("list"); LPCXSTR lpszAPIInsert = _X("insert"); LPCXSTR lpszAPIDelete = _X("delete"); - LPCXSTR lpszAPIPush = _X("push"); CHttpMemory_PoolEx m_MemoryPool(XENGINE_MEMORY_SIZE_MAX); if (0 == _tcsxnicmp(lpszAPIList, lpszAPIName, _tcsxlen(lpszAPIList))) @@ -45,54 +44,6 @@ bool XEngine_AuthorizeHTTP_Serial(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L ptszMsgBuffer = NULL; XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,请求序列号列表成功,个数:%d"), lpszClientAddr, nListCount); } - else if (0 == _tcsxnicmp(lpszAPIInsert, lpszAPIName, _tcsxlen(lpszAPIInsert))) - { - int nNumberCount = 0; - int nSerialCount = 0; - XCHAR tszHasTime[128] = {}; - XCHAR tszExpiredTime[128] = {}; - XENGINE_LIBTIME st_AuthTimer = {}; - ENUM_VERIFICATION_MODULE_SERIAL_TYPE enSerialType = {}; - - Protocol_Parse_HttpParseSerial2(lpszMsgBuffer, nMsgLen, &enSerialType, &nNumberCount, &nSerialCount, tszHasTime, tszExpiredTime); - //解析类型 - if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_SECOND == enSerialType) - { - st_AuthTimer.wSecond = _ttxoi(tszHasTime); - } - else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_DAY == enSerialType) - { - st_AuthTimer.wDay = _ttxoi(tszHasTime); - } - else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_TIME == enSerialType) - { - st_AuthTimer.wFlags = _ttxoi(tszHasTime); - } - else if (ENUM_VERIFICATION_MODULE_SERIAL_TYPE_CUSTOM == enSerialType) - { - if (6 != _stxscanf(tszHasTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), &st_AuthTimer.wYear, &st_AuthTimer.wMonth, &st_AuthTimer.wDay, &st_AuthTimer.wHour, &st_AuthTimer.wMinute, &st_AuthTimer.wSecond)) - { - Protocol_Packet_HttpComm(m_MemoryPool.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_REQUEST, "time request is failed"); - XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPool.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求插入序列卡失败,时间格式错误"), lpszClientAddr); - return false; - } - } - else - { - Protocol_Packet_HttpComm(m_MemoryPool.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_NOTSUPPORT, "not support serial types"); - XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPool.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求插入序列卡失败,不支持的类型格式:%d"), lpszClientAddr, enSerialType); - return false; - } - //生成卡 - XCHAR** pptszSerialNumber; - LPCXSTR lpszUserHdr = _X("XAUTH"); - BaseLib_Memory_Free((XPPPMEM)&pptszSerialNumber, nSerialCount); - Protocol_Packet_HttpComm(m_MemoryPool.get(), &nSDLen); - XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPool.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,请求插入序列号成功,个数:%d"), lpszClientAddr, nSerialCount); - } else if (0 == _tcsxnicmp(lpszAPIDelete, lpszAPIName, _tcsxlen(lpszAPIDelete))) { int nListCount = 0; @@ -118,7 +69,7 @@ bool XEngine_AuthorizeHTTP_Serial(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPool.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,请求删除序列号成功,删除个数:%d"), lpszClientAddr, nListCount); } - else if (0 == _tcsxnicmp(lpszAPIPush, lpszAPIName, _tcsxlen(lpszAPIPush))) + else if (0 == _tcsxnicmp(lpszAPIInsert, lpszAPIName, _tcsxlen(lpszAPIInsert))) { int nListCount = 0; AUTHREG_SERIALTABLE** ppSt_SerialTable; @@ -128,20 +79,20 @@ bool XEngine_AuthorizeHTTP_Serial(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L { for (int i = 0; i < nListCount; i++) { - DBModule_SQLite_SerialPush(ppSt_SerialTable[i]); + DBModule_SQLite_SerialInsert(ppSt_SerialTable[i]); } } else { for (int i = 0; i < nListCount; i++) { - DBModule_MySQL_SerialPush(ppSt_SerialTable[i]); + DBModule_SQLite_SerialInsert(ppSt_SerialTable[i]); } } BaseLib_Memory_Free((XPPPMEM)&ppSt_SerialTable, nListCount); Protocol_Packet_HttpComm(m_MemoryPool.get(), &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPool.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,请求推送自定义序列号成功,个数:%d"), lpszClientAddr, nListCount); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,请求插入自定义序列号成功,个数:%d"), lpszClientAddr, nListCount); } return true; } \ No newline at end of file From f29a34c00634b58ee66d340bad698e3d1e3d7d05 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 15 Oct 2025 15:52:46 +0800 Subject: [PATCH 11/22] ci:update macos build --- .github/workflows/macbuild.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/macbuild.yml b/.github/workflows/macbuild.yml index 71f0537..3b5fdc9 100644 --- a/.github/workflows/macbuild.yml +++ b/.github/workflows/macbuild.yml @@ -14,8 +14,8 @@ jobs: strategy: matrix: include: - - os: macos-13 - - os: macos-14 + - os: macos-15-intel + - os: macos-15 runs-on: ${{ matrix.os }} steps: @@ -43,13 +43,13 @@ jobs: run: echo "TERM=xterm" >> $GITHUB_ENV - name: Set up Dependency x86_64 Environment - if: matrix.os == 'macos-13' + if: matrix.os == 'macos-15-intel' run: | cd libxengine chmod 777 * ./XEngine_LINEnv.sh -i 3 - name: Set up Dependency Arm64 Environment - if: matrix.os == 'macos-14' + if: matrix.os == 'macos-15' run: | cd libxengine chmod 777 * @@ -84,14 +84,14 @@ jobs: ./XEngine_AuthorizeService -t - name: Upload folder as artifact with mac x64 - if: matrix.os == 'macos-13' + if: matrix.os == 'macos-15-intel' uses: actions/upload-artifact@v4 with: name: XEngine_AuthorizeService-Mac_x86-64 path: XEngine_Release/ retention-days: 1 - name: Upload folder as artifact with mac arm - if: matrix.os == 'macos-14' + if: matrix.os == 'macos-15' uses: actions/upload-artifact@v4 with: name: XEngine_AuthorizeService-Mac_Arm64 From b2d62f64faf32b38aa9ac56489879c8757a10db8 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 20 Oct 2025 14:29:07 +0800 Subject: [PATCH 12/22] delete:more protocol define --- .github/workflows/debian_build.yml | 4 ---- XEngine_Source/XAuth_Protocol.h | 22 ++++++++-------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/.github/workflows/debian_build.yml b/.github/workflows/debian_build.yml index 702ad83..7fc58f5 100644 --- a/.github/workflows/debian_build.yml +++ b/.github/workflows/debian_build.yml @@ -71,10 +71,6 @@ jobs: - name: make run: | cd XEngine_Source - make - make FLAGS=InstallAll - make FLAGS=CleanAll - make RELEASE=1 make FLAGS=InstallAll make FLAGS=CleanAll diff --git a/XEngine_Source/XAuth_Protocol.h b/XEngine_Source/XAuth_Protocol.h index 2635573..13c1058 100644 --- a/XEngine_Source/XAuth_Protocol.h +++ b/XEngine_Source/XAuth_Protocol.h @@ -14,20 +14,14 @@ ////////////////////////////////////////////////////////////////////////// // 导出的协议定义 ////////////////////////////////////////////////////////////////////////// -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQDEL 0x2010 //删除用户 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPDEL 0x2011 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQREGISTER 0x2012 //注册 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPREGISTER 0x2013 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQPAY 0x2014 //充值 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPPAY 0x2015 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQGETPASS 0x2016 //找回密码 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPGETPASS 0x2017 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQGETTIME 0x2018 //获取剩余时间 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPGETTIME 0x2019 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQTRYVER 0x2020 //临时验证协议请求 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPTRYVER 0x2021 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQDCODE 0x2022 //动态验证码请求 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPDCODE 0x2023 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQPAY 0x2001 //充值 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPPAY 0x2002 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQGETPASS 0x2003 //找回密码 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPGETPASS 0x2004 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQGETTIME 0x2005 //获取剩余时间 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPGETTIME 0x2006 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQDCODE 0x2007 //动态验证码请求 +#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REPDCODE 0x2008 ////////////////////////////////////////////////////////////////////////// // 导出的错误码 ////////////////////////////////////////////////////////////////////////// From 94eae1a154eb9b548d53d7d25cf29ec2d86b0a0a Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 23 Oct 2025 13:40:40 +0800 Subject: [PATCH 13/22] modify:re generator serial key when cdkey network create --- .../AuthorizeHTTP_CDKey.cpp | 36 +++++++------------ XEngine_Source/XEngine_DependLibrary | 2 +- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp index e7141a3..afc9553 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp @@ -24,32 +24,21 @@ bool XEngine_AuthorizeHTTP_CDKey(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LP Protocol_Parse_HttpParseCDKey(lpszMsgBuffer, nMsgLen, &st_Authorize); - if (_tcsxlen(st_Authorize.st_AuthSerial.st_TimeLimit.tszTimeSerial) <= 0) - { - XCHAR tszSerialStr[XPATH_MIN] = {}; - Verification_XAuthKey_KeySerial(tszSerialStr, 8, 0); - - st_Authorize.st_AuthSerial.st_TimeLimit.nTimeCount = 9999; - _tcsxcpy(st_Authorize.st_AuthSerial.st_TimeLimit.tszTimeSerial, tszSerialStr); - - memset(tszSerialStr, '\0', sizeof(tszSerialStr)); - Verification_XAuthKey_KeySerial(tszSerialStr, 8, 0); - st_Authorize.st_AuthSerial.st_DataLimit.bTimeAdd = false; - _tcsxcpy(st_Authorize.st_AuthSerial.st_DataLimit.tszDataSerial, tszSerialStr); + st_Authorize.st_AuthSerial.st_TimeLimit.nTimeCount = 9999; + memset(st_Authorize.st_AuthSerial.st_TimeLimit.tszTimeSerial, 0, XPATH_MIN); + Verification_XAuthKey_KeySerial(st_Authorize.st_AuthSerial.st_TimeLimit.tszTimeSerial, 8, 0); - XCHAR tszTimeStr[128] = {}; - XENGINE_LIBTIME st_LibTime = {}; - BaseLib_Time_GetSysTime(&st_LibTime); - st_LibTime.wYear += 1; //一年后过期 - BaseLib_Time_TimeToStr(tszTimeStr, NULL, true, &st_LibTime); + memset(st_Authorize.st_AuthSerial.st_DataLimit.tszDataSerial, 0, XPATH_MIN); + XENGINE_LIBTIME st_LibTime = {}; + BaseLib_Time_GetSysTime(&st_LibTime); + st_LibTime.wYear += 1; //一年后过期 + st_Authorize.st_AuthSerial.st_DataLimit.bTimeAdd = false; + BaseLib_Time_TimeToStr(st_Authorize.st_AuthSerial.st_DataLimit.tszDataTime, NULL, true, &st_LibTime); + Verification_XAuthKey_KeySerial(st_Authorize.st_AuthSerial.st_DataLimit.tszDataSerial, 8, 0); - memset(tszSerialStr, '\0', sizeof(tszSerialStr)); - Verification_XAuthKey_KeySerial(tszSerialStr, 8, 0); + memset(st_Authorize.st_AuthSerial.st_UNLimit.tszUNLimitSerial, 0, XPATH_MIN); + Verification_XAuthKey_KeySerial(st_Authorize.st_AuthSerial.st_UNLimit.tszUNLimitSerial, 8, 0); - _tcsxcpy(st_Authorize.st_AuthSerial.st_DataLimit.tszDataTime, tszTimeStr); - _tcsxcpy(st_Authorize.st_AuthSerial.st_UNLimit.tszUNLimitSerial, tszSerialStr); - } - if (!Verification_XAuthKey_WriteMemory(m_MemoryPoolRecv.get(), &nRVLen, &st_Authorize)) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_SERVER, "Not Acceptable,write key failed"); @@ -77,7 +66,6 @@ bool XEngine_AuthorizeHTTP_CDKey(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LP memset(&st_Authorize, '\0', sizeof(VERIFICATION_XAUTHKEY)); Verification_XAuthKey_ReadMemory(lpszMsgBuffer, nMsgLen, &st_Authorize); - if (ENUM_VERIFICATION_MODULE_VERMODE_TYPE_NETWORK != st_Authorize.st_AuthRegInfo.enVModeType) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_UNAUTHORIZE, "unsupport,cdkey is not authorized"); diff --git a/XEngine_Source/XEngine_DependLibrary b/XEngine_Source/XEngine_DependLibrary index da4c1c3..ad7cbdc 160000 --- a/XEngine_Source/XEngine_DependLibrary +++ b/XEngine_Source/XEngine_DependLibrary @@ -1 +1 @@ -Subproject commit da4c1c30f9c7667e86b8e816560306b0882931a7 +Subproject commit ad7cbdcd7727b0bd4817bd6b40d48b1eb2ef105e From 05b5f4dcef386a9bbb70be85ee3480e2332cba3a Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 23 Oct 2025 14:03:44 +0800 Subject: [PATCH 14/22] delete:parse cdkey protocol and use verification read instead --- .../AuthorizeModule_Protocol.def | 1 - .../Protocol_Define.h | 24 --- .../Protocol_Parse/Protocol_Parse.cpp | 162 ------------------ .../Protocol_Parse/Protocol_Parse.h | 1 - .../AuthorizeModule_Protocol/pch.cpp | 4 - XEngine_Source/XAuth_Protocol.h | 1 + XEngine_Source/XEngine.sln | 4 + .../AuthorizeHTTP_CDKey.cpp | 59 +++---- .../Authorize_HttpTask.cpp | 3 +- 9 files changed, 34 insertions(+), 225 deletions(-) diff --git a/XEngine_Source/AuthorizeModule_Protocol/AuthorizeModule_Protocol.def b/XEngine_Source/AuthorizeModule_Protocol/AuthorizeModule_Protocol.def index 42a33d5..cde4e4c 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/AuthorizeModule_Protocol.def +++ b/XEngine_Source/AuthorizeModule_Protocol/AuthorizeModule_Protocol.def @@ -31,5 +31,4 @@ EXPORTS Protocol_Parse_HttpParsePos Protocol_Parse_HttpParseBanned Protocol_Parse_HttpParseBanned2 - Protocol_Parse_HttpParseCDKey Protocol_Parse_HttpParseAnnouncement \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h index 0df07c3..366ad8c 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Define.h @@ -754,30 +754,6 @@ extern "C" bool Protocol_Parse_HttpParseBanned(LPCXSTR lpszMsgBuffer, int nMsgLe *********************************************************************/ extern "C" bool Protocol_Parse_HttpParseBanned2(LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_POSStart, int* pInt_POSEnd); /******************************************************************** -函数名称:Protocol_Parse_HttpParseCDKey -函数功能:解析CDKEY - 参数.一:lpszMsgBuffer - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要解析的缓冲区 - 参数.二:nMsgLen - In/Out:In - 类型:整数型 - 可空:N - 意思:输入缓冲区大小 - 参数.三:pSt_Authorize - In/Out:Out - 类型:数据结构指针 - 可空:N - 意思:输出解析后的信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, VERIFICATION_XAUTHKEY* pSt_Authorize); -/******************************************************************** 函数名称:Protocol_Parse_HttpParseAnnouncement 函数功能:解析公告信息 参数.一:lpszMsgBuffer diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp index b4c69eb..fd9095d 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp @@ -979,168 +979,6 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseBanned2(LPCXSTR lpszMsgBuffer, int return true; } /******************************************************************** -函数名称:Protocol_Parse_HttpParseCDKey -函数功能:解析CDKEY - 参数.一:lpszMsgBuffer - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要解析的缓冲区 - 参数.二:nMsgLen - In/Out:In - 类型:整数型 - 可空:N - 意思:输入缓冲区大小 - 参数.三:pSt_Authorize - In/Out:Out - 类型:数据结构指针 - 可空:N - 意思:输出解析后的信息 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CProtocol_Parse::Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, VERIFICATION_XAUTHKEY* pSt_Authorize) -{ - Protocol_IsErrorOccur = false; - - if ((NULL == lpszMsgBuffer) || (NULL == pSt_Authorize)) - { - Protocol_IsErrorOccur = true; - Protocol_dwErrorCode = ERROR_AUTHORIZE_MODULE_PROTOCOL_PARAMENT; - return false; - } - Json::Value st_JsonRoot; - JSONCPP_STRING st_JsonError; - Json::CharReaderBuilder st_ReaderBuilder; - //解析JSON - std::unique_ptr const pSt_JsonReader(st_ReaderBuilder.newCharReader()); - if (!pSt_JsonReader->parse(lpszMsgBuffer, lpszMsgBuffer + nMsgLen, &st_JsonRoot, &st_JsonError)) - { - Protocol_IsErrorOccur = true; - Protocol_dwErrorCode = ERROR_AUTHORIZE_MODULE_PROTOCOL_PARSE; - return false; - } - - if (!st_JsonRoot["tszAddr"].isNull()) - { - _tcsxcpy(pSt_Authorize->tszAddr, st_JsonRoot["tszAddr"].asCString()); - } - if (!st_JsonRoot["nPort"].isNull()) - { - pSt_Authorize->nPort = st_JsonRoot["nPort"].asInt(); - } - //应用信息 - Json::Value st_JsonAPPInfo = st_JsonRoot["st_AuthAppInfo"]; - if (!st_JsonAPPInfo["nExecTime"].isNull()) - { - pSt_Authorize->st_AuthAppInfo.nExecTime = st_JsonAPPInfo["nExecTime"].asInt(); - } - if (!st_JsonAPPInfo["bInit"].isNull()) - { - pSt_Authorize->st_AuthAppInfo.bInit = st_JsonAPPInfo["bInit"].asBool(); - } - if (!st_JsonAPPInfo["tszAppName"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthAppInfo.tszAppName, st_JsonAPPInfo["tszAppName"].asCString()); - } - if (!st_JsonAPPInfo["tszAppVer"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthAppInfo.tszAppVer, st_JsonAPPInfo["tszAppVer"].asCString()); - } - //注册信息 - Json::Value st_JsonREGInfo = st_JsonRoot["st_AuthRegInfo"]; - if (!st_JsonREGInfo["tszHardware"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthRegInfo.tszHardware, st_JsonREGInfo["tszHardware"].asCString()); - } - if (!st_JsonREGInfo["tszCreateTime"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthRegInfo.tszCreateTime, st_JsonREGInfo["tszCreateTime"].asCString()); - } - if (!st_JsonREGInfo["tszRegisterTime"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthRegInfo.tszRegisterTime, st_JsonREGInfo["tszRegisterTime"].asCString()); - } - if (!st_JsonREGInfo["tszLeftTime"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthRegInfo.tszLeftTime, st_JsonREGInfo["tszLeftTime"].asCString()); - } - if (!st_JsonREGInfo["tszStartTime"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthRegInfo.tszStartTime, st_JsonREGInfo["tszStartTime"].asCString()); - } - if (!st_JsonREGInfo["tszExpiryTime"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthRegInfo.tszExpiryTime, st_JsonREGInfo["tszExpiryTime"].asCString()); - } - if (!st_JsonREGInfo["nHasTime"].isNull()) - { - pSt_Authorize->st_AuthRegInfo.nHasTime = st_JsonREGInfo["nHasTime"].asInt(); - } - if (!st_JsonREGInfo["enSerialType"].isNull()) - { - pSt_Authorize->st_AuthRegInfo.enSerialType = (ENUM_VERIFICATION_MODULE_SERIAL_TYPE)st_JsonREGInfo["enSerialType"].asInt(); - } - if (!st_JsonREGInfo["enRegType"].isNull()) - { - pSt_Authorize->st_AuthRegInfo.enRegType = (ENUM_VERIFICATION_MODULE_CDKEY_TYPE)st_JsonREGInfo["enRegType"].asInt(); - } - if (!st_JsonREGInfo["enHWType"].isNull()) - { - pSt_Authorize->st_AuthRegInfo.enHWType = (ENUM_VERIFICATION_MODULE_HW_TYPE)st_JsonREGInfo["enHWType"].asInt(); - } - if (!st_JsonREGInfo["enVModeType"].isNull()) - { - pSt_Authorize->st_AuthRegInfo.enVModeType = (ENUM_VERIFICATION_MODULE_VERMODE_TYPE)st_JsonREGInfo["enVModeType"].asInt(); - } - //临时序列号 - Json::Value st_JsonSerialInfo = st_JsonRoot["st_AuthSerial"]; - if (!st_JsonSerialInfo.isNull()) - { - if (!st_JsonSerialInfo["tszTimeSerial"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthSerial.st_TimeLimit.tszTimeSerial, st_JsonSerialInfo["tszTimeSerial"].asCString()); - } - if (!st_JsonSerialInfo["nTimeCount"].isNull()) - { - pSt_Authorize->st_AuthSerial.st_TimeLimit.nTimeCount = st_JsonSerialInfo["nTimeCount"].asInt(); - } - if (!st_JsonSerialInfo["tszTimeSerial"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthSerial.st_DataLimit.tszDataSerial, st_JsonSerialInfo["tszTimeSerial"].asCString()); - } - if (!st_JsonSerialInfo["tszDataTime"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthSerial.st_DataLimit.tszDataTime, st_JsonSerialInfo["tszDataTime"].asCString()); - } - if (!st_JsonSerialInfo["bTimeAdd"].isNull()) - { - pSt_Authorize->st_AuthSerial.st_DataLimit.bTimeAdd = st_JsonSerialInfo["bTimeAdd"].asBool(); - } - if (!st_JsonSerialInfo["tszUNLimitSerial"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthSerial.st_UNLimit.tszUNLimitSerial, st_JsonSerialInfo["tszUNLimitSerial"].asCString()); - } - } - //CDKEY用户信息 - Json::Value st_JsonUserInfo = st_JsonRoot["st_AuthUserInfo"]; - if (!st_JsonUserInfo["tszUserName"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthUserInfo.tszUserName, st_JsonUserInfo["tszUserName"].asCString()); - } - if (!st_JsonUserInfo["tszUserContact"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthUserInfo.tszUserContact, st_JsonUserInfo["tszUserContact"].asCString()); - } - if (!st_JsonUserInfo["tszCustom"].isNull()) - { - _tcsxcpy(pSt_Authorize->st_AuthUserInfo.tszCustom, st_JsonUserInfo["tszCustom"].asCString()); - } - return true; -} -/******************************************************************** 函数名称:Protocol_Parse_HttpParseAnnouncement 函数功能:解析公告信息 参数.一:lpszMsgBuffer diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h index 14944a0..d1d16f5 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.h @@ -32,7 +32,6 @@ class CProtocol_Parse bool Protocol_Parse_HttpParsePos(LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_PosStart, int* pInt_PosEnd); bool Protocol_Parse_HttpParseBanned(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_BANNED* pSt_AuthBanned); bool Protocol_Parse_HttpParseBanned2(LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_POSStart, int* pInt_POSEnd); - bool Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, VERIFICATION_XAUTHKEY* pSt_Authorize); bool Protocol_Parse_HttpParseAnnouncement(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_ANNOUNCEMENT* pSt_Announcement); protected: private: diff --git a/XEngine_Source/AuthorizeModule_Protocol/pch.cpp b/XEngine_Source/AuthorizeModule_Protocol/pch.cpp index bcd6d3e..05fe44a 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/pch.cpp +++ b/XEngine_Source/AuthorizeModule_Protocol/pch.cpp @@ -142,10 +142,6 @@ extern "C" bool Protocol_Parse_HttpParseBanned2(LPCXSTR lpszMsgBuffer, int nMsgL { return m_ProtocolParse.Protocol_Parse_HttpParseBanned2(lpszMsgBuffer, nMsgLen, pInt_POSStart, pInt_POSEnd); } -extern "C" bool Protocol_Parse_HttpParseCDKey(LPCXSTR lpszMsgBuffer, int nMsgLen, VERIFICATION_XAUTHKEY * pSt_Authorize) -{ - return m_ProtocolParse.Protocol_Parse_HttpParseCDKey(lpszMsgBuffer, nMsgLen, pSt_Authorize); -} extern "C" bool Protocol_Parse_HttpParseAnnouncement(LPCXSTR lpszMsgBuffer, int nMsgLen, AUTHREG_ANNOUNCEMENT * pSt_Announcement) { return m_ProtocolParse.Protocol_Parse_HttpParseAnnouncement(lpszMsgBuffer, nMsgLen, pSt_Announcement); diff --git a/XEngine_Source/XAuth_Protocol.h b/XEngine_Source/XAuth_Protocol.h index 13c1058..0da92d9 100644 --- a/XEngine_Source/XAuth_Protocol.h +++ b/XEngine_Source/XAuth_Protocol.h @@ -43,6 +43,7 @@ #define ERROR_AUTHORIZE_PROTOCOL_TIMEOUT 0x115 //超时 #define ERROR_AUTHORIZE_PROTOCOL_PERMISSION 0x116 //用户权限错误 #define ERROR_AUTHORIZE_PROTOCOL_EXPIRED 0x117 //已经过期 +#define ERROR_AUTHORIZE_PROTOCOL_CDKEY 0x118 //CDKEY错误 #define ERROR_AUTHORIZE_PROTOCOL_SERVER 0x201 //服务端内部错误 #define ERROR_AUTHORIZE_PROTOCOL_LIMIT 0x202 //服务端内部限制,数据过大后者过小 diff --git a/XEngine_Source/XEngine.sln b/XEngine_Source/XEngine.sln index 37d3d4f..0368e73 100644 --- a/XEngine_Source/XEngine.sln +++ b/XEngine_Source/XEngine.sln @@ -33,6 +33,7 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_AuthorizeService", "XEngine_APPService\XEngine_AuthorizeService\XEngine_AuthorizeService.vcxproj", "{A29DFD8D-2818-4BE3-A2DB-07F241B4BFC9}" ProjectSection(ProjectDependencies) = postProject {1391B739-713B-4A3A-9233-FEAB92E0566C} = {1391B739-713B-4A3A-9233-FEAB92E0566C} + {51DCBDC7-50CB-4A44-B10B-FCF90309914D} = {51DCBDC7-50CB-4A44-B10B-FCF90309914D} {5FA1874A-32F4-4176-9C23-4E22BE183660} = {5FA1874A-32F4-4176-9C23-4E22BE183660} {6B926D00-DCD2-49E3-86A9-3230C9872E65} = {6B926D00-DCD2-49E3-86A9-3230C9872E65} {A8E43EC0-698A-4807-8A61-B2BE5FAB7256} = {A8E43EC0-698A-4807-8A61-B2BE5FAB7256} @@ -65,6 +66,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_InfoReport", "XEngi EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_Verification", "XEngine_DependLibrary\XEngine_Module\XEngine_Verification\XEngine_Verification.vcxproj", "{A8E43EC0-698A-4807-8A61-B2BE5FAB7256}" + ProjectSection(ProjectDependencies) = postProject + {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} = {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp index afc9553..11b196e 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp @@ -19,31 +19,14 @@ bool XEngine_AuthorizeHTTP_CDKey(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LP } if (0 == _tcsxnicmp(lpszAPICreate, lpszAPIName, _tcsxlen(lpszAPICreate))) { - VERIFICATION_XAUTHKEY st_Authorize; - memset(&st_Authorize, '\0', sizeof(VERIFICATION_XAUTHKEY)); - - Protocol_Parse_HttpParseCDKey(lpszMsgBuffer, nMsgLen, &st_Authorize); - - st_Authorize.st_AuthSerial.st_TimeLimit.nTimeCount = 9999; - memset(st_Authorize.st_AuthSerial.st_TimeLimit.tszTimeSerial, 0, XPATH_MIN); - Verification_XAuthKey_KeySerial(st_Authorize.st_AuthSerial.st_TimeLimit.tszTimeSerial, 8, 0); - - memset(st_Authorize.st_AuthSerial.st_DataLimit.tszDataSerial, 0, XPATH_MIN); - XENGINE_LIBTIME st_LibTime = {}; - BaseLib_Time_GetSysTime(&st_LibTime); - st_LibTime.wYear += 1; //一年后过期 - st_Authorize.st_AuthSerial.st_DataLimit.bTimeAdd = false; - BaseLib_Time_TimeToStr(st_Authorize.st_AuthSerial.st_DataLimit.tszDataTime, NULL, true, &st_LibTime); - Verification_XAuthKey_KeySerial(st_Authorize.st_AuthSerial.st_DataLimit.tszDataSerial, 8, 0); - - memset(st_Authorize.st_AuthSerial.st_UNLimit.tszUNLimitSerial, 0, XPATH_MIN); - Verification_XAuthKey_KeySerial(st_Authorize.st_AuthSerial.st_UNLimit.tszUNLimitSerial, 8, 0); + VERIFICATION_XAUTHKEY st_Authorize = {}; + Verification_XAuthKey_KeyInit(&st_Authorize); if (!Verification_XAuthKey_WriteMemory(m_MemoryPoolRecv.get(), &nRVLen, &st_Authorize)) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_SERVER, "Not Acceptable,write key failed"); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求创建CDKEY协议失败,服务器内部错误:%lX"), lpszClientAddr, Verification_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求创建CDKEY协议失败,读取CDKEY失败:%lX"), lpszClientAddr, Verification_GetLastError()); return false; } XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolRecv.get(), nRVLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -51,33 +34,47 @@ bool XEngine_AuthorizeHTTP_CDKey(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LP } else if (0 == _tcsxnicmp(lpszAPIAuth, lpszAPIName, _tcsxlen(lpszAPIAuth))) { - VERIFICATION_XAUTHKEY st_Authorize; - memset(&st_Authorize, '\0', sizeof(VERIFICATION_XAUTHKEY)); - - Verification_XAuthKey_ReadMemory(lpszMsgBuffer, nMsgLen, &st_Authorize); + VERIFICATION_XAUTHKEY st_Authorize = {}; + if (!Verification_XAuthKey_ReadMemory(lpszMsgBuffer, nMsgLen, &st_Authorize)) + { + Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_CDKEY, "Not Acceptable,read key failed"); + XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求创建授权CDKEY协议失败,读取CDKEY失败:%lX"), lpszClientAddr, Verification_GetLastError()); + return false; + } //授权 - + if (!Verification_XAuthKey_UserRegister(&st_Authorize, st_Authorize.st_AuthSerial.st_TimeLimit.tszTimeSerial)) + { + Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_SERVER, "Not Acceptable,read key failed"); + XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求创建授权CDKEY协议失败,读取CDKEY失败:%lX"), lpszClientAddr, Verification_GetLastError()); + return false; + } XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolRecv.get(), nRVLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求授权CDKEY成功,APP名:%s,APP版本:%s,授权期限:%s"), lpszClientAddr, st_Authorize.st_AuthAppInfo.tszAppName, st_Authorize.st_AuthAppInfo.tszAppVer, st_Authorize.st_AuthRegInfo.tszLeftTime); } else if (0 == _tcsxnicmp(lpszAPIVer, lpszAPIName, _tcsxlen(lpszAPIVer))) { - VERIFICATION_XAUTHKEY st_Authorize; - memset(&st_Authorize, '\0', sizeof(VERIFICATION_XAUTHKEY)); - - Verification_XAuthKey_ReadMemory(lpszMsgBuffer, nMsgLen, &st_Authorize); + VERIFICATION_XAUTHKEY st_Authorize = {}; + if (!Verification_XAuthKey_ReadMemory(lpszMsgBuffer, nMsgLen, &st_Authorize)) + { + Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_CDKEY, "Not Acceptable,read key failed"); + XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求创建授权CDKEY协议失败,读取CDKEY失败:%lX"), lpszClientAddr, Verification_GetLastError()); + return false; + } if (ENUM_VERIFICATION_MODULE_VERMODE_TYPE_NETWORK != st_Authorize.st_AuthRegInfo.enVModeType) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_UNAUTHORIZE, "unsupport,cdkey is not authorized"); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求验证CDKEY失败,cdkey未授权或者已超时,错误:%lX"), lpszClientAddr, Verification_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求验证CDKEY失败,cdkey未授权或者已超时,错误:%lX"), lpszClientAddr, Verification_GetLastError()); return false; } if (!Verification_XAuthKey_KeyParse(&st_Authorize)) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_UNAUTHORIZE, "Unauthorized,cdkey is not authorized"); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求验证CDKEY失败,cdkey未授权或者已超时,错误:%lX"), lpszClientAddr, Verification_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求验证CDKEY失败,cdkey未授权或者已超时,错误:%lX"), lpszClientAddr, Verification_GetLastError()); return false; } Verification_XAuthKey_WriteMemory(m_MemoryPoolRecv.get(), &nRVLen, &st_Authorize); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp index 302caf2..d09675d 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp @@ -215,8 +215,7 @@ bool XEngine_Client_HttpTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求的API:%s 不支持"), lpszClientAddr, pSt_HTTPParament->tszHttpUri); return false; } - AUTHREG_USERTABLE st_UserTable; - memset(&st_UserTable, '\0', sizeof(AUTHREG_USERTABLE)); + AUTHREG_USERTABLE st_UserTable = {}; //得到TOKEN if (Protocol_Parse_HttpParseToken(lpszMsgBuffer, nMsgLen, &xhToken)) { From e69db03956623823070c4c1fd1b8e0daf64f96c5 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 23 Oct 2025 16:14:28 +0800 Subject: [PATCH 15/22] fixed:example build failure --- XEngine_Apps/Authorize_APPClient.sln | 20 +-- .../Authorize_APPClient.cpp | 48 +---- .../Authorize_APPLocal/Authorize_APPLocal.cpp | 164 +++--------------- .../Authorize_CDKeyNetVer.cpp | 130 +++----------- .../Authorize_ClientModule.cpp | 23 ++- XEngine_Apps/VSCopy_Client_x64.bat | 6 +- XEngine_Apps/VSCopy_Client_x86.bat | 6 +- 7 files changed, 87 insertions(+), 310 deletions(-) diff --git a/XEngine_Apps/Authorize_APPClient.sln b/XEngine_Apps/Authorize_APPClient.sln index c2e56bc..93b8467 100644 --- a/XEngine_Apps/Authorize_APPClient.sln +++ b/XEngine_Apps/Authorize_APPClient.sln @@ -7,10 +7,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Authorize_APPClient", "Auth EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Authorize_APPLocal", "Authorize_APPLocal\Authorize_APPLocal.vcxproj", "{767151F7-230E-431B-AC6D-683F19F43C13}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Authorize_ClientModule", "Authorize_ClientModule\Authorize_ClientModule.vcxproj", "{82B923A9-2F4A-4784-A245-BAA6ABF5A358}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Authorize_CDKeyNetVer", "Authorize_CDKeyNetVer\Authorize_CDKeyNetVer.vcxproj", "{1D584651-5E93-43BA-9A48-E7D199DC587F}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Authorize_ClientModule", "Authorize_ClientModule\Authorize_ClientModule.vcxproj", "{82B923A9-2F4A-4784-A245-BAA6ABF5A358}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -35,14 +35,6 @@ Global {767151F7-230E-431B-AC6D-683F19F43C13}.Release|x64.Build.0 = Release|x64 {767151F7-230E-431B-AC6D-683F19F43C13}.Release|x86.ActiveCfg = Release|Win32 {767151F7-230E-431B-AC6D-683F19F43C13}.Release|x86.Build.0 = Release|Win32 - {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Debug|x64.ActiveCfg = Debug|x64 - {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Debug|x64.Build.0 = Debug|x64 - {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Debug|x86.ActiveCfg = Debug|Win32 - {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Debug|x86.Build.0 = Debug|Win32 - {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Release|x64.ActiveCfg = Release|x64 - {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Release|x64.Build.0 = Release|x64 - {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Release|x86.ActiveCfg = Release|Win32 - {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Release|x86.Build.0 = Release|Win32 {1D584651-5E93-43BA-9A48-E7D199DC587F}.Debug|x64.ActiveCfg = Debug|x64 {1D584651-5E93-43BA-9A48-E7D199DC587F}.Debug|x64.Build.0 = Debug|x64 {1D584651-5E93-43BA-9A48-E7D199DC587F}.Debug|x86.ActiveCfg = Debug|Win32 @@ -51,6 +43,14 @@ Global {1D584651-5E93-43BA-9A48-E7D199DC587F}.Release|x64.Build.0 = Release|x64 {1D584651-5E93-43BA-9A48-E7D199DC587F}.Release|x86.ActiveCfg = Release|Win32 {1D584651-5E93-43BA-9A48-E7D199DC587F}.Release|x86.Build.0 = Release|Win32 + {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Debug|x64.ActiveCfg = Debug|x64 + {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Debug|x64.Build.0 = Debug|x64 + {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Debug|x86.ActiveCfg = Debug|Win32 + {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Debug|x86.Build.0 = Debug|Win32 + {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Release|x64.ActiveCfg = Release|x64 + {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Release|x64.Build.0 = Release|x64 + {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Release|x86.ActiveCfg = Release|Win32 + {82B923A9-2F4A-4784-A245-BAA6ABF5A358}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/XEngine_Apps/Authorize_APPClient/Authorize_APPClient.cpp b/XEngine_Apps/Authorize_APPClient/Authorize_APPClient.cpp index c161059..8834b95 100644 --- a/XEngine_Apps/Authorize_APPClient/Authorize_APPClient.cpp +++ b/XEngine_Apps/Authorize_APPClient/Authorize_APPClient.cpp @@ -29,6 +29,7 @@ using namespace std; #include #include #include +#include "../../XEngine_Source/XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Define.h" #include "../../XEngine_Source/XAuth_Protocol.h" //Windows::vs2022 x86 debug 编译即可 @@ -48,7 +49,7 @@ XSOCKET m_Socket = 0; LPCXSTR lpszUser = _X("123123aa"); LPCXSTR lpszPass = _X("123123"); LPCXSTR lpszHWCode = _X("2FDWAD02JD2091"); -LPCXSTR lpszSerial = _X("XAUTH-XYRYS-JKG60-N510G-ZUFDH-54-V7I3H"); +LPCXSTR lpszSerial = _X("Y5V0Y-03O2L-E7G8Y-NX1DR-3EGVO-UDIRQ-GBBKO-FGX0C"); LPCXSTR lpszEmail = _X("486179@qq.com"); __int64x nPhoneNumber = 1366666666; __int64x nIDNumber = 511025111111111111; @@ -91,7 +92,7 @@ XHTHREAD AuthClient_Thread() printf(_X("登录失败,错误:%d\n"), st_ProtocolHdr.wReserve); } } - else if (XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_TIMEDOUT == st_ProtocolHdr.unOperatorCode) + else if (XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_EXPIRED == st_ProtocolHdr.unOperatorCode) { bTimeOut = false; printf(_X("用户过期\n")); @@ -258,16 +259,16 @@ int AuthClient_Login() { XCHAR tszMsgBuffer[2048]; XENGINE_PROTOCOLHDR st_ProtocolHdr; //协议头 - AUTHORIZE_PROTOCOL_USERAUTHEX st_AuthUser; + XENGINE_PROTOCOL_USERAUTHEX st_AuthUser; memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer)); memset(&st_ProtocolHdr, '\0', sizeof(XENGINE_PROTOCOLHDR)); - memset(&st_AuthUser, '\0', sizeof(AUTHORIZE_PROTOCOL_USERAUTHEX)); + memset(&st_AuthUser, '\0', sizeof(XENGINE_PROTOCOL_USERAUTHEX)); st_ProtocolHdr.wHeader = XENGIEN_COMMUNICATION_PACKET_PROTOCOL_HEADER; st_ProtocolHdr.unOperatorType = ENUM_XENGINE_COMMUNICATION_PROTOCOL_TYPE_AUTH; st_ProtocolHdr.unOperatorCode = XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQLOGIN; - st_ProtocolHdr.unPacketSize = sizeof(AUTHORIZE_PROTOCOL_USERAUTHEX); + st_ProtocolHdr.unPacketSize = sizeof(XENGINE_PROTOCOL_USERAUTHEX); st_ProtocolHdr.wTail = XENGIEN_COMMUNICATION_PACKET_PROTOCOL_TAIL; st_AuthUser.enDeviceType = ENUM_PROTOCOL_FOR_DEVICE_TYPE_PC_WINDOWS; @@ -308,7 +309,7 @@ int AuthClient_Login() memcpy(tszMsgBuffer, &st_ProtocolHdr, sizeof(XENGINE_PROTOCOLHDR)); memcpy(tszMsgBuffer + sizeof(XENGINE_PROTOCOLHDR), &st_AuthUser, st_ProtocolHdr.unPacketSize); - nMsgLen = sizeof(XENGINE_PROTOCOLHDR) + sizeof(AUTHORIZE_PROTOCOL_USERAUTHEX); + nMsgLen = sizeof(XENGINE_PROTOCOLHDR) + sizeof(XENGINE_PROTOCOL_USERAUTHEX); } if (!XClient_TCPSelect_SendMsg(m_Socket, tszMsgBuffer, nMsgLen)) @@ -516,40 +517,6 @@ int AuthClient_Delete() } return 0; } -int AuthClient_Try() -{ - Json::Value st_JsonRoot; - Json::Value st_JsonObject; - LPCXSTR lpszSerialNet = _X("cpuid:112233"); //通过此可以做临时网络验证,安全性比本地临时验证高 - LPCXSTR lpszUrl = _X("http://127.0.0.1:5302/auth/user/try"); - - st_JsonObject["tszVSerial"] = lpszSerialNet; - st_JsonRoot["st_VERTemp"] = st_JsonObject; - - int nMsgLen = 0; - XCHAR* ptszMsgBuffer = NULL; - - if (bEncrypto) - { - XCHAR tszENBuffer[2048] = {}; - XCHAR tszDEBuffer[2048] = {}; - - nMsgLen = st_JsonRoot.toStyledString().length(); - Cryption_XCrypto_Encoder(st_JsonRoot.toStyledString().c_str(), &nMsgLen, (XBYTE*)tszENBuffer, lpszPass); - APIClient_Http_Request(_X("POST"), lpszUrl, tszENBuffer, NULL, &ptszMsgBuffer, &nMsgLen); - - Cryption_XCrypto_Decoder(ptszMsgBuffer, &nMsgLen, tszDEBuffer, lpszPass); - printf("AuthClient_Try:\n%s\n", tszDEBuffer); - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMsgBuffer); - } - else - { - APIClient_Http_Request(_X("POST"), lpszUrl, st_JsonRoot.toStyledString().c_str(), NULL, &ptszMsgBuffer, &nMsgLen); - printf("AuthClient_Try:\n%s\n", ptszMsgBuffer); - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMsgBuffer); - } - return 0; -} int main() { #ifdef _MSC_BUILD @@ -578,7 +545,6 @@ int main() std::this_thread::sleep_for(std::chrono::seconds(10)); AuthClient_Delete(); - AuthClient_Try(); bRun = false; XClient_TCPSelect_Close(m_Socket); diff --git a/XEngine_Apps/Authorize_APPLocal/Authorize_APPLocal.cpp b/XEngine_Apps/Authorize_APPLocal/Authorize_APPLocal.cpp index 23fad03..7f60dbd 100644 --- a/XEngine_Apps/Authorize_APPLocal/Authorize_APPLocal.cpp +++ b/XEngine_Apps/Authorize_APPLocal/Authorize_APPLocal.cpp @@ -7,10 +7,10 @@ #pragma comment(lib,"XEngine_SystemSdk/XEngine_SystemApi") #ifdef _WIN64 #pragma comment(lib,"../../XEngine_Source/x64/Debug/jsoncpp") -#pragma comment(lib,"../../XEngine_Source/x64/Debug/AuthorizeModule_CDKey") +#pragma comment(lib,"../../XEngine_Source/x64/Debug/XEngine_Verification") #else #pragma comment(lib,"../../XEngine_Source/Debug/jsoncpp") -#pragma comment(lib,"../../XEngine_Source/Debug/AuthorizeModule_CDKey") +#pragma comment(lib,"../../XEngine_Source/Debug/XEngine_Verification") #endif #endif #include @@ -27,173 +27,65 @@ #include #include #include +#include "../../XEngine_Source/XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Define.h" +#include "../../XEngine_Source/XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Error.h" #include "../../XEngine_Source/XAuth_Protocol.h" -#include "../../XEngine_Source/AuthorizeModule_CDKey/CDKey_Define.h" -#include "../../XEngine_Source/AuthorizeModule_CDKey/CDKey_Error.h" //需要优先配置XEngine //WINDOWS支持VS2022 x86 debug 编译调试 -//g++ -std=c++17 -Wall -g Authorize_APPLocal.cpp -o Authorize_APPLocal.exe -I ../../XEngine_Source/XEngine_DependLibrary/XEngine_Module/jsoncpp -L ../../XEngine_Release -lXEngine_BaseLib -lXEngine_Cryption -lXEngine_SystemApi -lAuthorizeModule_CDKey -ljsoncpp -Wl,-rpath=../../XEngine_Release +//g++ -std=c++17 -Wall -g Authorize_APPLocal.cpp -o Authorize_APPLocal.exe -I ../../XEngine_Source/XEngine_DependLibrary/XEngine_Module/jsoncpp -L ../../XEngine_Release -lXEngine_BaseLib -lXEngine_Cryption -lXEngine_SystemApi -lXEngine_Verification -ljsoncpp -Wl,-rpath=../../XEngine_Release XCHAR tszSerialStr[XPATH_MAX] = {}; //1.创建CDKEY.或者由管理员创建. bool Authorize_APPLocal_Create(LPCXSTR lpszKeyFile, LPCXSTR lpszPasswd) { - int nRet = 0; - XCHAR tszENCodecBuffer[4096] = {}; - XCHAR tszDECodecBuffer[4096] = {}; - XENGINE_AUTHORIZE_LOCAL st_AuthLocal = {}; - SYSTEMAPI_SERIAL_INFOMATION st_SDKSerial = {}; + VERIFICATION_XAUTHKEY st_AuthLocal = {}; - SystemApi_HardWare_GetSerial(&st_SDKSerial); - //网络信息 - st_AuthLocal.nPort = 5302; - _tcsxcpy(st_AuthLocal.tszAddr, _X("http://app.xyry.org")); - //软件信息 - st_AuthLocal.st_AuthAppInfo.bInit = false; - st_AuthLocal.st_AuthAppInfo.nExecTime = 0; - _xstprintf(st_AuthLocal.st_AuthAppInfo.tszAppName, _X("XEngine_Authorize")); - _xstprintf(st_AuthLocal.st_AuthAppInfo.tszAppVer, _X("V1.0.0.1")); - //注册信息 - st_AuthLocal.st_AuthRegInfo.enHWType = ENUM_AUTHORIZE_MODULE_HW_TYPE_BIOS; - st_AuthLocal.st_AuthRegInfo.enRegType = ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_TRY; - st_AuthLocal.st_AuthRegInfo.enSerialType = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME; - st_AuthLocal.st_AuthRegInfo.enVModeType = ENUM_AUTHORIZE_MODULE_VERMODE_TYPE_LOCAL; - st_AuthLocal.st_AuthRegInfo.nHasTime = 0; - BaseLib_Time_TimeToStr(st_AuthLocal.st_AuthRegInfo.tszCreateTime); - _tcsxcpy(st_AuthLocal.st_AuthRegInfo.tszHardware, st_SDKSerial.tszBoardSerial); - _xstprintf(st_AuthLocal.st_AuthRegInfo.tszLeftTime, _X("0")); //0次试用 - //序列号信息.可以不写,如果不想启用用户自己注册.或者交给管理员填充 - int nSerialCount = 3; - XCHAR** pptszSerialList; - Authorize_Serial_Create(&pptszSerialList, _X("XAUTH"), nSerialCount, 9); - _tcsxcpy(tszSerialStr, pptszSerialList[0]); - - st_AuthLocal.st_AuthSerial.st_TimeLimit.nTimeCount = 5; - _tcsxcpy(st_AuthLocal.st_AuthSerial.st_TimeLimit.tszTimeSerial, pptszSerialList[0]); - - st_AuthLocal.st_AuthSerial.st_DataLimit.bTimeAdd = false; - _tcsxcpy(st_AuthLocal.st_AuthSerial.st_DataLimit.tszDataSerial, pptszSerialList[1]); - XCHAR tszTimeStr[128] = {}; - XENGINE_LIBTIME st_LibTime = {}; - BaseLib_Time_GetSysTime(&st_LibTime); - st_LibTime.wYear += 1; //一年后过期 - BaseLib_Time_TimeToStr(tszTimeStr, NULL, true, &st_LibTime); - - _tcsxcpy(st_AuthLocal.st_AuthSerial.st_DataLimit.tszDataTime, tszTimeStr); - - _tcsxcpy(st_AuthLocal.st_AuthSerial.st_UNLimit.tszUNLimitSerial, pptszSerialList[2]); - //用户信息 - _xstprintf(st_AuthLocal.st_AuthUserInfo.tszUserName, _X("qyt")); - _xstprintf(st_AuthLocal.st_AuthUserInfo.tszUserContact, _X("486179@qq.com")); - - Authorize_CDKey_WriteMemory(tszDECodecBuffer, &nRet, &st_AuthLocal); - Cryption_XCrypto_Encoder(tszDECodecBuffer, &nRet, (XBYTE*)tszENCodecBuffer, lpszPasswd); - FILE* pSt_File = _xtfopen(lpszKeyFile, _X("wb")); - if (NULL == pSt_File) + if (!Verification_XAuthKey_KeyInit(&st_AuthLocal)) { - printf("create key file is failed\n"); + printf("Verification_XAuthKey_KeyInit is failed\n"); return false; } - fwrite(tszENCodecBuffer, 1, nRet, pSt_File); - fclose(pSt_File); + _tcsxcpy(tszSerialStr, st_AuthLocal.st_AuthSerial.st_TimeLimit.tszTimeSerial); + //用户信息 + _xstprintf(st_AuthLocal.st_AuthUserInfo.tszUserName, _X("qyt")); + _xstprintf(st_AuthLocal.st_AuthUserInfo.tszUserContact, _X("486179@qq.com")); + Verification_XAuthKey_FileWrite(&st_AuthLocal, lpszKeyFile, lpszPasswd); return true; } //2.打开CDKEY并且授权(授权只能通过自我授权或者由管理员授权,用户不应该可以自己随意授权) -bool Authorize_APPLocal_Auth(LPCXSTR lpszKeyFile, LPCXSTR lpszPasswd, LPCXSTR lpszSerialStr) +bool Authorize_APPLocal_Auth(LPCXSTR lpszKeyFile, LPCXSTR lpszPasswd) { - XCHAR tszENCodecBuffer[4096] = {}; - XCHAR tszDECodecBuffer[4096] = {}; - XENGINE_AUTHORIZE_LOCAL st_AuthLocal = {}; + VERIFICATION_XAUTHKEY st_AuthLocal = {}; - FILE* pSt_File = _xtfopen(lpszKeyFile, _X("rb")); - if (NULL == pSt_File) + if (!Verification_XAuthKey_FileRead(&st_AuthLocal, lpszKeyFile, lpszPasswd)) { - printf("open key file is failed\n"); + printf("Verification_XAuthKey_FileRead is failed\n"); return false; } - int nRet = fread(tszENCodecBuffer, 1, sizeof(tszENCodecBuffer), pSt_File); - fclose(pSt_File); - - Cryption_XCrypto_Decoder(tszENCodecBuffer, &nRet, tszDECodecBuffer, lpszPasswd); - //printf("大小:%d,内容:\n%s\n", nRet, tszDECodecBuffer); - - Authorize_CDKey_ReadMemory(tszDECodecBuffer, nRet, &st_AuthLocal); - if (!Authorize_CDKey_UserRegister(&st_AuthLocal, lpszSerialStr)) + if (!Verification_XAuthKey_UserRegister(&st_AuthLocal, tszSerialStr)) { - printf("serila verifacation is failed,error code:%lX\n", Authorize_GetLastError()); + printf("serila verifacation is failed,error code:%lX\n", Verification_GetLastError()); return false; } - - memset(tszENCodecBuffer, '\0', sizeof(tszENCodecBuffer)); - memset(tszDECodecBuffer, '\0', sizeof(tszDECodecBuffer)); - Authorize_CDKey_WriteMemory(tszDECodecBuffer, &nRet, &st_AuthLocal); - Cryption_XCrypto_Encoder(tszDECodecBuffer, &nRet, (XBYTE*)tszENCodecBuffer, lpszPasswd); - pSt_File = _xtfopen(lpszKeyFile, _X("wb")); - fwrite(tszENCodecBuffer, 1, nRet, pSt_File); - fclose(pSt_File); + Verification_XAuthKey_FileWrite(&st_AuthLocal, lpszKeyFile, lpszPasswd); return true; } //3.验证CDkey -bool Authorize_APPLocal_Auth(LPCXSTR lpszKeyFile, LPCXSTR lpszPasswd) +bool Authorize_APPLocal_Ver(LPCXSTR lpszKeyFile, LPCXSTR lpszPasswd) { - XCHAR tszENCodecBuffer[4096] = {}; - XCHAR tszDECodecBuffer[4096] = {}; - XENGINE_AUTHORIZE_LOCAL st_AuthLocal = {}; - - FILE* pSt_File = _xtfopen(lpszKeyFile, _X("rb")); - if (NULL == pSt_File) + VERIFICATION_XAUTHKEY st_AuthLocal = {}; + if (!Verification_XAuthKey_FileRead(&st_AuthLocal, lpszKeyFile, lpszPasswd)) { - printf("open key file is failed\n"); + printf("Verification_XAuthKey_FileRead is failed\n"); return false; } - int nRet = fread(tszENCodecBuffer, 1, sizeof(tszENCodecBuffer), pSt_File); - fclose(pSt_File); - - Cryption_XCrypto_Decoder(tszENCodecBuffer, &nRet, tszDECodecBuffer, lpszPasswd); - //printf("大小:%d,内容:\n%s\n", nRet, tszDECodecBuffer); - Authorize_CDKey_ReadMemory(tszDECodecBuffer, nRet, &st_AuthLocal); - if (!Authorize_CDKey_GetLeftTimer(&st_AuthLocal)) + if (!Verification_XAuthKey_KeyParse(&st_AuthLocal)) { - //失败也需要重写CDKEY - memset(tszENCodecBuffer, '\0', sizeof(tszENCodecBuffer)); - memset(tszDECodecBuffer, '\0', sizeof(tszDECodecBuffer)); - Authorize_CDKey_WriteMemory(tszDECodecBuffer, &nRet, &st_AuthLocal); - Cryption_XCrypto_Encoder(tszDECodecBuffer, &nRet, (XBYTE*)tszENCodecBuffer, lpszPasswd); - pSt_File = _xtfopen(lpszKeyFile, _X("wb")); - fwrite(tszENCodecBuffer, 1, nRet, pSt_File); - fclose(pSt_File); - printf("verifaction is failed\n"); - return false; - } - SYSTEMAPI_SERIAL_INFOMATION st_SDKSerial = {}; - SystemApi_HardWare_GetSerial(&st_SDKSerial); - - if (ENUM_AUTHORIZE_MODULE_VERMODE_TYPE_LOCAL != st_AuthLocal.st_AuthRegInfo.enVModeType) - { - printf("cdkey does not support local verification\n"); - return false; } - if (ENUM_AUTHORIZE_MODULE_HW_TYPE_BIOS != st_AuthLocal.st_AuthRegInfo.enHWType) - { - printf("cdkey serial type is incorrect\n"); - return false; - } - if (0 != _tcsxnicmp(st_SDKSerial.tszBoardSerial, st_AuthLocal.st_AuthRegInfo.tszHardware, _tcsxlen(st_SDKSerial.tszBoardSerial))) - { - printf("cdkey serial verification is failed\n"); - return false; - } - - memset(tszENCodecBuffer, '\0', sizeof(tszENCodecBuffer)); - memset(tszDECodecBuffer, '\0', sizeof(tszDECodecBuffer)); - Authorize_CDKey_WriteMemory(tszDECodecBuffer, &nRet, &st_AuthLocal); - Cryption_XCrypto_Encoder(tszDECodecBuffer, &nRet, (XBYTE*)tszENCodecBuffer, lpszPasswd); - pSt_File = _xtfopen(lpszKeyFile, _X("wb")); - fwrite(tszENCodecBuffer, 1, nRet, pSt_File); - fclose(pSt_File); + Verification_XAuthKey_FileWrite(&st_AuthLocal, lpszKeyFile, lpszPasswd); return true; } int main() @@ -213,14 +105,14 @@ int main() } Authorize_APPLocal_Auth(lpszFileStr, lpszPasswd); - if (!Authorize_APPLocal_Auth(lpszFileStr, lpszPasswd, tszSerialStr)) + if (!Authorize_APPLocal_Ver(lpszFileStr, lpszPasswd)) { return -1; } for (int i = 0; i < 10; i++) { - if (!Authorize_APPLocal_Auth(lpszFileStr, lpszPasswd)) + if (!Authorize_APPLocal_Ver(lpszFileStr, lpszPasswd)) { break; } diff --git a/XEngine_Apps/Authorize_CDKeyNetVer/Authorize_CDKeyNetVer.cpp b/XEngine_Apps/Authorize_CDKeyNetVer/Authorize_CDKeyNetVer.cpp index 1bc0f65..65e4d66 100644 --- a/XEngine_Apps/Authorize_CDKeyNetVer/Authorize_CDKeyNetVer.cpp +++ b/XEngine_Apps/Authorize_CDKeyNetVer/Authorize_CDKeyNetVer.cpp @@ -1,4 +1,5 @@ #ifdef _MSC_BUILD +#define _CRT_SECURE_NO_WARNINGS #include #include #pragma comment(lib,"Ws2_32") @@ -8,10 +9,10 @@ #pragma comment(lib,"XEngine_SystemSdk/XEngine_SystemConfig") #ifdef _WIN64 #pragma comment(lib,"../../XEngine_Source/x64/Debug/jsoncpp") -#pragma comment(lib,"../../XEngine_Source/x64/Debug/AuthorizeModule_CDKey") +#pragma comment(lib,"../../XEngine_Source/x64/Debug/XEngine_Verification") #else #pragma comment(lib,"../../XEngine_Source/Debug/jsoncpp") -#pragma comment(lib,"../../XEngine_Source/Debug/AuthorizeModule_CDKey") +#pragma comment(lib,"../../XEngine_Source/Debug/XEngine_Verification") #endif #endif #include @@ -29,15 +30,13 @@ #include #include #include +#include "../../XEngine_Source/XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Define.h" +#include "../../XEngine_Source/XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Error.h" #include "../../XEngine_Source/XAuth_Protocol.h" -#include "../../XEngine_Source/AuthorizeModule_CDKey/CDKey_Define.h" -#include "../../XEngine_Source/AuthorizeModule_CDKey/CDKey_Error.h" //需要优先配置XEngine //WINDOWS支持VS2022 x64 debug 编译调试 -//g++ -std=c++17 -Wall -g Authorize_CDKeyNetVer.cpp -o Authorize_CDKeyNetVer.exe -I ../../XEngine_Source/XEngine_DependLibrary/XEngine_Module/jsoncpp -lXEngine_BaseLib -L ../../XEngine_Release -lXEngine_Cryption -lXClient_APIHelp -lXEngine_SystemConfig -lAuthorizeModule_CDKey -ljsoncpp -Wl,-rpath=../../XEngine_Release - -//#define XENGINE_AUTHORIZE_CDKEY_CRYPTO +//g++ -std=c++17 -Wall -g Authorize_CDKeyNetVer.cpp -o Authorize_CDKeyNetVer.exe -I ../../XEngine_Source/XEngine_DependLibrary/XEngine_Module/jsoncpp -lXEngine_BaseLib -L ../../XEngine_Release -lXEngine_Cryption -lXClient_APIHelp -lXEngine_SystemConfig -lXEngine_Verification -ljsoncpp -Wl,-rpath=../../XEngine_Release LPCXSTR lpszPasswd = _X("123123"); @@ -47,135 +46,48 @@ int main() WSADATA st_WSAData; WSAStartup(MAKEWORD(2, 2), &st_WSAData); #endif - int nLen = 0; - int nCode = 0; - Json::Value st_JsonRoot; - Json::Value st_JsonAPPInfo; - Json::Value st_JsonREGInfo; - Json::Value st_JsonUserInfo; - st_JsonRoot["tszAddr"] = "http://app.xyry.org"; - st_JsonRoot["nPort"] = 5501; - - st_JsonAPPInfo["tszAppName"] = "XEngine"; - st_JsonAPPInfo["tszAppVer"] = "1.0.0.1001"; - - st_JsonREGInfo["tszHardware"] = "5501012NE21N"; - st_JsonREGInfo["enSerialType"] = ENUM_AUTHORIZE_MODULE_SERIAL_TYPE_TIME; - st_JsonREGInfo["enRegType"] = ENUM_AUTHORIZE_MODULE_CDKEY_TYPE_TRY; - st_JsonREGInfo["enHWType"] = ENUM_AUTHORIZE_MODULE_HW_TYPE_CPU; - st_JsonREGInfo["enVModeType"] = ENUM_AUTHORIZE_MODULE_VERMODE_TYPE_LOCAL; - - st_JsonUserInfo["tszUserName"] = "qyt"; - st_JsonUserInfo["tszUserContact"] = "486179@qq.com"; - - st_JsonRoot["st_AuthAppInfo"] = st_JsonAPPInfo; - st_JsonRoot["st_AuthRegInfo"] = st_JsonREGInfo; - st_JsonRoot["st_AuthUserInfo"] = st_JsonUserInfo; + int nMSGLen = 0; + XCHAR tszMSGBuffer[2048] = {}; + VERIFICATION_XAUTHKEY st_AuthLocal = {}; XCHAR* ptszCreateBuffer = NULL; LPCXSTR lpszCreateUrl = _X("http://127.0.0.1:5302/auth/cdkey/create"); //1. 创建CDKEY -#ifdef XENGINE_AUTHORIZE_CDKEY_CRYPTO - //加密 - CHAR tszCodecBuffer[4096]; - memset(tszCodecBuffer, '\0', sizeof(tszCodecBuffer)); - - nLen = st_JsonRoot.toStyledString().length(); - Cryption_XCrypto_Encoder(st_JsonRoot.toStyledString().c_str(), &nLen, (XBYTE*)tszCodecBuffer, lpszPasswd); - if (!APIClient_Http_Request(_X("POST"), lpszCreateUrl, tszCodecBuffer, &nCode, &ptszCreateBuffer, &nLen)) -#else - if (!APIClient_Http_Request(_X("POST"), lpszCreateUrl, st_JsonRoot.toStyledString().c_str(), &nCode, &ptszCreateBuffer, &nLen)) -#endif + if (!APIClient_Http_Request(_X("POST"), lpszCreateUrl, NULL, NULL, &ptszCreateBuffer, &nMSGLen)) { printf("发送投递失败!\n"); return 0; } - - XCHAR tszMsgBuffer[4096]; - memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer)); -#ifdef XENGINE_AUTHORIZE_CDKEY_CRYPTO - //解密 - memset(tszCodecBuffer, '\0', sizeof(tszCodecBuffer)); - - Cryption_XCrypto_Decoder(ptszCreateBuffer, &nLen, tszCodecBuffer, lpszPasswd); - printf("接受到数据,大小:%d,内容:\n%s\n", nLen, tszCodecBuffer); - //你也可以通过授权模块的API函数来读内存,都一回事,这里为了方便直接写了,请求分钟卡,拥有10分钟,也可以写自定义时间格式 - SystemConfig_File_WriteProfileFromMemory(tszCodecBuffer, nLen, "AuthReg", "tszLeftTime", "10", tszMsgBuffer, &nLen); -#else - SystemConfig_File_WriteProfileFromMemory(ptszCreateBuffer, nLen, "AuthReg", "tszLeftTime", "10", tszMsgBuffer, &nLen); - printf("接受到数据,大小:%d,内容:\n%s\n", nLen, ptszCreateBuffer); -#endif + Verification_XAuthKey_ReadMemory(ptszCreateBuffer, nMSGLen, &st_AuthLocal); + sprintf(st_AuthLocal.st_AuthUserInfo.tszUserName, _X("qyt")); + sprintf(st_AuthLocal.st_AuthUserInfo.tszUserContact, _X("486179@qq.com")); BaseLib_Memory_FreeCStyle((XPPMEM)&ptszCreateBuffer); + //2. 授权CDKEY XCHAR* ptszAuthBuffer = NULL; LPCXSTR lpszAuthUrl = _X("http://127.0.0.1:5302/auth/cdkey/auth"); -#ifdef XENGINE_AUTHORIZE_CDKEY_CRYPTO - //加密 - memset(tszCodecBuffer, '\0', sizeof(tszCodecBuffer)); - nLen = nLen; - Cryption_XCrypto_Encoder(tszMsgBuffer, &nLen, (XBYTE*)tszCodecBuffer, lpszPasswd); - if (!APIClient_Http_Request(_X("POST"), lpszAuthUrl, tszCodecBuffer, &nCode, &ptszAuthBuffer, &nLen)) -#else - if (!APIClient_Http_Request(_X("POST"), lpszAuthUrl, tszMsgBuffer, &nCode, &ptszAuthBuffer, &nLen)) -#endif + Verification_XAuthKey_WriteMemory(tszMSGBuffer, &nMSGLen, &st_AuthLocal); + if (!APIClient_Http_Request(_X("POST"), lpszAuthUrl, tszMSGBuffer, NULL, &ptszAuthBuffer, &nMSGLen)) { printf("发送投递失败!\n"); return 0; } -#ifdef XENGINE_AUTHORIZE_CDKEY_CRYPTO - //解密 - memset(tszCodecBuffer, '\0', sizeof(tszCodecBuffer)); - - Cryption_XCrypto_Decoder(ptszAuthBuffer, &nLen, tszCodecBuffer, lpszPasswd); - printf("接受到数据,大小:%d,内容:\n%s\n", nLen, tszCodecBuffer); - //你也可以通过授权模块的API函数来读内存,都一回事,这里为了方便直接写了,请求分钟卡,拥有10分钟,也可以写自定义时间格式 - SystemConfig_File_WriteProfileFromMemory(tszCodecBuffer, nLen, "AuthReg", "tszLeftTime", "10", tszMsgBuffer, &nLen); -#else - printf("接受到数据,大小:%d,内容:\n%s\n", nLen, ptszAuthBuffer); - SystemConfig_File_WriteProfileFromMemory(ptszAuthBuffer, nLen, "AuthReg", "tszLeftTime", "10", tszMsgBuffer, &nLen); -#endif + printf("接受到数据,大小:%d,内容:\n%s\n", nMSGLen, ptszAuthBuffer); + memset(tszMSGBuffer, 0, sizeof(tszMSGBuffer)); + Verification_XAuthKey_WriteMemory(tszMSGBuffer, &nMSGLen, &st_AuthLocal); BaseLib_Memory_FreeCStyle((XPPMEM)&ptszAuthBuffer); //3. 验证CDKEY XCHAR* ptszVerBuffer = NULL; LPCXSTR lpszVerUrl = _X("http://127.0.0.1:5302/auth/cdkey/ver"); - XENGINE_AUTHORIZE_LOCAL st_Authorize; - memset(&st_Authorize, '\0', sizeof(XENGINE_AUTHORIZE_LOCAL)); - -#ifdef XENGINE_AUTHORIZE_CDKEY_CRYPTO - //加密 - memset(tszCodecBuffer, '\0', sizeof(tszCodecBuffer)); - Cryption_XCrypto_Encoder(tszMsgBuffer, &nLen, (XBYTE*)tszCodecBuffer, lpszPasswd); - if (!APIClient_Http_Request(_X("POST"), lpszVerUrl, tszCodecBuffer, &nCode, &ptszVerBuffer, &nLen)) -#else - if (!APIClient_Http_Request(_X("POST"), lpszVerUrl, tszMsgBuffer, &nCode, &ptszVerBuffer, &nLen)) -#endif + VERIFICATION_XAUTHKEY st_Authorize = {}; + if (!APIClient_Http_Request(_X("POST"), lpszVerUrl, tszMSGBuffer, NULL, &ptszVerBuffer, &nMSGLen)) { printf("发送投递失败!\n"); return 0; } -#ifdef XENGINE_AUTHORIZE_CDKEY_CRYPTO - //解密 - memset(tszCodecBuffer, '\0', sizeof(tszCodecBuffer)); - - Cryption_XCrypto_Decoder(ptszVerBuffer, &nLen, tszCodecBuffer, lpszPasswd); - printf("接受到数据,大小:%d,内容:\n%s\n", nLen, tszCodecBuffer); - Authorize_CDKey_ReadMemory(tszCodecBuffer, nLen, &st_Authorize); -#else - printf("接受到数据,大小:%d,内容:\n%s\n", nLen, ptszVerBuffer); - Authorize_CDKey_ReadMemory(ptszVerBuffer, nLen, &st_Authorize); -#endif BaseLib_Memory_FreeCStyle((XPPMEM)&ptszVerBuffer); - //4. 也可以本地验证 - if (Authorize_CDKey_GetLeftTimer(&st_Authorize)) - { - printf("ok\n"); - } - else - { - printf("timeout\n"); - } #ifdef _MSC_BUILD WSACleanup(); #endif diff --git a/XEngine_Apps/Authorize_ClientModule/Authorize_ClientModule.cpp b/XEngine_Apps/Authorize_ClientModule/Authorize_ClientModule.cpp index 5e7422c..6131e49 100644 --- a/XEngine_Apps/Authorize_ClientModule/Authorize_ClientModule.cpp +++ b/XEngine_Apps/Authorize_ClientModule/Authorize_ClientModule.cpp @@ -3,9 +3,9 @@ #include #pragma comment(lib,"Ws2_32.lib") #ifdef _WIN64 -#pragma comment(lib,"../../XEngine_Source/x64/Debug/AuthorizeModule_Client") +#pragma comment(lib,"../../XEngine_Source/x64/Debug/XEngine_Verification") #else -#pragma comment(lib,"../../XEngine_Source/Debug/AuthorizeModule_Client") +#pragma comment(lib,"../../XEngine_Source/Debug/XEngine_Verification") #endif #endif #include @@ -14,27 +14,26 @@ #include using namespace std; #include -#include "../../XEngine_Source/XAuth_BuildSwitch.h" -#include "../../XEngine_Source/AuthorizeModule_Client/AuthClient_Define.h" -#include "../../XEngine_Source/AuthorizeModule_Client/AuthClient_Error.h" +#include "../../XEngine_Source/XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Define.h" +#include "../../XEngine_Source/XEngine_DependLibrary/XEngine_Module/XEngine_Verification/Verification_Error.h" //Windows::vs2022 x86 debug 编译即可 -//Linux MACOS::g++ -std=c++17 -Wall -g Authorize_ClientModule.cpp -o Authorize_ClientModule.exe -L ../../XEngine_Release/ -lAuthorizeModule_Client -ljsoncpp -Wl,-rpath=../../XEngine_Release +//Linux MACOS::g++ -std=c++17 -Wall -g Authorize_ClientModule.cpp -o Authorize_ClientModule.exe -L ../../XEngine_Release/ -lXEngine_Verification -ljsoncpp -Wl,-rpath=../../XEngine_Release int TestClient_HardLogin() { - if (!AuthClient_Connector_Connect(_X("127.0.0.1"), 5300)) + if (!Verification_XAuthNet_Connect(_X("127.0.0.1"), 5300)) { - printf("AuthClient_Connector_Connect:%lX\n", AuthClient_GetLastError()); + printf("Verification_XAuthNet_Connect:%lX\n", Verification_GetLastError()); return -1; } - if (!AuthClient_Connector_Login("2FDWAD02JD2091", "")) + if (!Verification_XAuthNet_Login("2FDWAD02JD2091", "")) { - printf("AuthClient_Connector_Login:%lX\n", AuthClient_GetLastError()); + printf("AuthClient_Connector_Login:%lX\n", Verification_GetLastError()); return -1; } - AuthClient_Connector_Close(); + Verification_XAuthNet_Close(); return 0; } @@ -43,7 +42,7 @@ int TestClient_TryLogin() //插入查询 LPCXSTR lpszTryInsert = _X("http://127.0.0.1:5302/auth/user/try"); - if (AuthClient_HTTPVer_TryRequest(lpszTryInsert)) + if (Verification_XAuthNet_TryRequest(lpszTryInsert)) { printf("ok\n"); } diff --git a/XEngine_Apps/VSCopy_Client_x64.bat b/XEngine_Apps/VSCopy_Client_x64.bat index fc40d03..3ea232d 100644 --- a/XEngine_Apps/VSCopy_Client_x64.bat +++ b/XEngine_Apps/VSCopy_Client_x64.bat @@ -1,10 +1,14 @@ copy /y "%XEngine_Lib64%\XEngine_BaseLib\XEngine_BaseLib.dll" "./" copy /y "%XEngine_Lib64%\XEngine_BaseLib\XEngine_BaseSafe.dll" "./" copy /y "%XEngine_Lib64%\XEngine_BaseLib\XEngine_Algorithm.dll" "./" + copy /y "%XEngine_Lib64%\XEngine_Core\XEngine_Cryption.dll" "./" +copy /y "%XEngine_Lib64%\XEngine_Core\XEngine_ManagePool.dll" "./" copy /y "%XEngine_Lib64%\XEngine_Client\XClient_Socket.dll" "./" copy /y "%XEngine_Lib64%\XEngine_Client\XClient_APIHelp.dll" "./" copy /y "%XEngine_Lib64%\XEngine_SystemSdk\XEngine_SystemApi.dll" "./" -copy /y "%XEngine_Lib64%\XEngine_SystemSdk\XEngine_SystemConfig.dll" "./" \ No newline at end of file +copy /y "%XEngine_Lib64%\XEngine_SystemSdk\XEngine_SystemConfig.dll" "./" + +copy /y "%XEngine_Lib64%\XEngine_RfcComponents\RfcComponents_HttpProtocol.dll" "./" \ No newline at end of file diff --git a/XEngine_Apps/VSCopy_Client_x86.bat b/XEngine_Apps/VSCopy_Client_x86.bat index ae37887..cf107ca 100644 --- a/XEngine_Apps/VSCopy_Client_x86.bat +++ b/XEngine_Apps/VSCopy_Client_x86.bat @@ -1,10 +1,14 @@ copy /y "%XEngine_Lib32%\XEngine_BaseLib\XEngine_BaseLib.dll" "./" copy /y "%XEngine_Lib32%\XEngine_BaseLib\XEngine_BaseSafe.dll" "./" copy /y "%XEngine_Lib32%\XEngine_BaseLib\XEngine_Algorithm.dll" "./" + copy /y "%XEngine_Lib32%\XEngine_Core\XEngine_Cryption.dll" "./" +copy /y "%XEngine_Lib32%\XEngine_Core\XEngine_ManagePool.dll" "./" copy /y "%XEngine_Lib32%\XEngine_Client\XClient_Socket.dll" "./" copy /y "%XEngine_Lib32%\XEngine_Client\XClient_APIHelp.dll" "./" copy /y "%XEngine_Lib32%\XEngine_SystemSdk\XEngine_SystemApi.dll" "./" -copy /y "%XEngine_Lib32%\XEngine_SystemSdk\XEngine_SystemConfig.dll" "./" \ No newline at end of file +copy /y "%XEngine_Lib32%\XEngine_SystemSdk\XEngine_SystemConfig.dll" "./" + +copy /y "%XEngine_Lib32%\XEngine_RfcComponents\RfcComponents_HttpProtocol.dll" "./" \ No newline at end of file From d86a248709fe7299ac0c69b1b54817490a891615 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 23 Oct 2025 16:17:08 +0800 Subject: [PATCH 16/22] delete:unused cdkey process code --- .../AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp | 17 ++++++++--------- XEngine_Source/XEngine_DependLibrary | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp index 11b196e..c48bf28 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_CDKey.cpp @@ -3,13 +3,11 @@ bool XEngine_AuthorizeHTTP_CDKey(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPCXSTR lpszMsgBuffer, int nMsgLen) { int nSDLen = 0; - int nRVLen = 0; LPCXSTR lpszAPICreate = _X("create"); LPCXSTR lpszAPIAuth = _X("auth"); LPCXSTR lpszAPIVer = _X("ver"); CHttpMemory_PoolEx m_MemoryPoolSend(XENGINE_MEMORY_SIZE_MAX); - CHttpMemory_PoolEx m_MemoryPoolRecv(XENGINE_MEMORY_SIZE_MAX); if (!st_FunSwitch.bSwitchCDKey) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_CLOSED, "the function is closed"); @@ -22,20 +20,20 @@ bool XEngine_AuthorizeHTTP_CDKey(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LP VERIFICATION_XAUTHKEY st_Authorize = {}; Verification_XAuthKey_KeyInit(&st_Authorize); - if (!Verification_XAuthKey_WriteMemory(m_MemoryPoolRecv.get(), &nRVLen, &st_Authorize)) + if (!Verification_XAuthKey_MemoryWrite(&st_Authorize, m_MemoryPoolSend.get(), &nSDLen)) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_SERVER, "Not Acceptable,write key failed"); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求创建CDKEY协议失败,读取CDKEY失败:%lX"), lpszClientAddr, Verification_GetLastError()); return false; } - XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolRecv.get(), nRVLen, XENGINE_AUTH_APP_NETTYPE_HTTP); + XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求创建CDKEY成功,APP名:%s,APP版本:%s"), lpszClientAddr, st_Authorize.st_AuthAppInfo.tszAppName, st_Authorize.st_AuthAppInfo.tszAppVer); } else if (0 == _tcsxnicmp(lpszAPIAuth, lpszAPIName, _tcsxlen(lpszAPIAuth))) { VERIFICATION_XAUTHKEY st_Authorize = {}; - if (!Verification_XAuthKey_ReadMemory(lpszMsgBuffer, nMsgLen, &st_Authorize)) + if (!Verification_XAuthKey_MemoryRead(&st_Authorize, lpszMsgBuffer, nMsgLen)) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_CDKEY, "Not Acceptable,read key failed"); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -50,13 +48,14 @@ bool XEngine_AuthorizeHTTP_CDKey(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LP XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求创建授权CDKEY协议失败,读取CDKEY失败:%lX"), lpszClientAddr, Verification_GetLastError()); return false; } - XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolRecv.get(), nRVLen, XENGINE_AUTH_APP_NETTYPE_HTTP); + Verification_XAuthKey_MemoryWrite(&st_Authorize, m_MemoryPoolSend.get(), &nSDLen); + XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求授权CDKEY成功,APP名:%s,APP版本:%s,授权期限:%s"), lpszClientAddr, st_Authorize.st_AuthAppInfo.tszAppName, st_Authorize.st_AuthAppInfo.tszAppVer, st_Authorize.st_AuthRegInfo.tszLeftTime); } else if (0 == _tcsxnicmp(lpszAPIVer, lpszAPIName, _tcsxlen(lpszAPIVer))) { VERIFICATION_XAUTHKEY st_Authorize = {}; - if (!Verification_XAuthKey_ReadMemory(lpszMsgBuffer, nMsgLen, &st_Authorize)) + if (!Verification_XAuthKey_MemoryRead(&st_Authorize, lpszMsgBuffer, nMsgLen)) { Protocol_Packet_HttpComm(m_MemoryPoolSend.get(), &nSDLen, ERROR_AUTHORIZE_PROTOCOL_CDKEY, "Not Acceptable,read key failed"); XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -77,8 +76,8 @@ bool XEngine_AuthorizeHTTP_CDKey(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LP XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求验证CDKEY失败,cdkey未授权或者已超时,错误:%lX"), lpszClientAddr, Verification_GetLastError()); return false; } - Verification_XAuthKey_WriteMemory(m_MemoryPoolRecv.get(), &nRVLen, &st_Authorize); - XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolRecv.get(), nRVLen, XENGINE_AUTH_APP_NETTYPE_HTTP); + Verification_XAuthKey_MemoryWrite(&st_Authorize, m_MemoryPoolSend.get(), &nSDLen); + XEngine_Client_TaskSend(lpszClientAddr, m_MemoryPoolSend.get(), nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,请求验证CDKEY成功,APP名:%s,APP版本:%s,授权期限:%s"), lpszClientAddr, st_Authorize.st_AuthAppInfo.tszAppName, st_Authorize.st_AuthAppInfo.tszAppVer, st_Authorize.st_AuthRegInfo.tszLeftTime); } else diff --git a/XEngine_Source/XEngine_DependLibrary b/XEngine_Source/XEngine_DependLibrary index ad7cbdc..b6bed0e 160000 --- a/XEngine_Source/XEngine_DependLibrary +++ b/XEngine_Source/XEngine_DependLibrary @@ -1 +1 @@ -Subproject commit ad7cbdcd7727b0bd4817bd6b40d48b1eb2ef105e +Subproject commit b6bed0eeb6e91426ff1a9bbe31e40fcdcdf0a184 From f9cff4a0d10fd0f440da92498d5c10d31a3fa765 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 23 Oct 2025 16:33:15 +0800 Subject: [PATCH 17/22] modify:adjust vs generator order --- XEngine_Source/XEngine.sln | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/XEngine_Source/XEngine.sln b/XEngine_Source/XEngine.sln index 0368e73..33e44b3 100644 --- a/XEngine_Source/XEngine.sln +++ b/XEngine_Source/XEngine.sln @@ -33,7 +33,6 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_AuthorizeService", "XEngine_APPService\XEngine_AuthorizeService\XEngine_AuthorizeService.vcxproj", "{A29DFD8D-2818-4BE3-A2DB-07F241B4BFC9}" ProjectSection(ProjectDependencies) = postProject {1391B739-713B-4A3A-9233-FEAB92E0566C} = {1391B739-713B-4A3A-9233-FEAB92E0566C} - {51DCBDC7-50CB-4A44-B10B-FCF90309914D} = {51DCBDC7-50CB-4A44-B10B-FCF90309914D} {5FA1874A-32F4-4176-9C23-4E22BE183660} = {5FA1874A-32F4-4176-9C23-4E22BE183660} {6B926D00-DCD2-49E3-86A9-3230C9872E65} = {6B926D00-DCD2-49E3-86A9-3230C9872E65} {A8E43EC0-698A-4807-8A61-B2BE5FAB7256} = {A8E43EC0-698A-4807-8A61-B2BE5FAB7256} @@ -46,7 +45,11 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_AuthorizeApp", "XEngine_APPService\XEngine_AuthorizeApp\XEngine_AuthorizeApp.vcxproj", "{51DCBDC7-50CB-4A44-B10B-FCF90309914D}" ProjectSection(ProjectDependencies) = postProject {1391B739-713B-4A3A-9233-FEAB92E0566C} = {1391B739-713B-4A3A-9233-FEAB92E0566C} + {5FA1874A-32F4-4176-9C23-4E22BE183660} = {5FA1874A-32F4-4176-9C23-4E22BE183660} + {6B926D00-DCD2-49E3-86A9-3230C9872E65} = {6B926D00-DCD2-49E3-86A9-3230C9872E65} + {A8E43EC0-698A-4807-8A61-B2BE5FAB7256} = {A8E43EC0-698A-4807-8A61-B2BE5FAB7256} {AB3DB24C-E1B3-41CF-B2F4-6C12E13C2894} = {AB3DB24C-E1B3-41CF-B2F4-6C12E13C2894} + {CB9138DF-789D-459F-AD43-4095B22A487F} = {CB9138DF-789D-459F-AD43-4095B22A487F} {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} = {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} {F6520D2C-BB8E-45BB-964B-F5D6A4318A89} = {F6520D2C-BB8E-45BB-964B-F5D6A4318A89} EndProjectSection From fb9a2542616416a5633ba638cc1f0cc6eb22ec9a Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 3 Nov 2025 16:30:21 +0800 Subject: [PATCH 18/22] update:depend library --- XEngine_Source/XEngine_DependLibrary | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XEngine_Source/XEngine_DependLibrary b/XEngine_Source/XEngine_DependLibrary index b6bed0e..9ee4f67 160000 --- a/XEngine_Source/XEngine_DependLibrary +++ b/XEngine_Source/XEngine_DependLibrary @@ -1 +1 @@ -Subproject commit b6bed0eeb6e91426ff1a9bbe31e40fcdcdf0a184 +Subproject commit 9ee4f67755748e7780b75cf98282c2d4935613dd From 5e316933da530e402695a2109f17c82fc7534614 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 3 Nov 2025 16:36:39 +0800 Subject: [PATCH 19/22] fixed:build --- .../XEngine_APPService/XEngine_AuthorizeService/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Makefile b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Makefile index 9f499f1..e953eb1 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Makefile +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Makefile @@ -6,7 +6,7 @@ LOADHDR = -I ./ LOADSO = -L ../../XEngine_DependLibrary/XEngine_Module/jsoncpp -L ../../XEngine_DependLibrary/XEngine_Module/XEngine_InfoReport -L ../../XEngine_DependLibrary/XEngine_Module/XEngine_Verification \ -L ../../AuthorizeModule_Session -L ../../AuthorizeModule_Database -L ../../AuthorizeModule_Protocol -L ../../AuthorizeModule_Configure -L ../../AuthorizeModule_Help -L ../../AuthorizeModule_CDKey LIB = -lXEngine_InfoReport -ljsoncpp -lXEngine_Verification \ - -lXEngine_BaseLib -lXEngine_Algorithm -lXEngine_Core -lXEngine_ManagePool -lXEngine_Cryption -lXClient_APIHelp -lNetHelp_APIAddr -lHelpComponents_Packets -lHelpComponents_DataBase -lHelpComponents_XLog -lRfcComponents_WSProtocol -lRfcComponents_HttpProtocol -lXEngine_ProcFile -lXEngine_SystemApi \ + -lXEngine_BaseLib -lXEngine_Algorithm -lXEngine_Core -lXEngine_ManagePool -lXEngine_Cryption -lXClient_APIHelp -lNetHelp_APIAddr -lHelpComponents_Packets -lHelpComponents_DataBase -lHelpComponents_XLog -lRfcComponents_WSProtocol -lRfcComponents_HttpProtocol -lXEngine_SystemApi \ -lAuthorizeModule_Session -lAuthorizeModule_Database -lAuthorizeModule_Protocol -lAuthorizeModule_Configure -lAuthorizeModule_Help LIBEX = OBJECTS = Authorize_Config.o Authorize_Net.o Authorize_Task.o Authorize_TCPTask.o Authorize_WSTask.o Authorize_HttpTask.o XEngine_AuthorizeService.o \ From 58c9aec2fb316f3b2e807cfc54af53ac37f0e2e9 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 4 Nov 2025 10:31:20 +0800 Subject: [PATCH 20/22] update:depend library --- XEngine_Source/XEngine_DependLibrary | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XEngine_Source/XEngine_DependLibrary b/XEngine_Source/XEngine_DependLibrary index 9ee4f67..dc2e4b3 160000 --- a/XEngine_Source/XEngine_DependLibrary +++ b/XEngine_Source/XEngine_DependLibrary @@ -1 +1 @@ -Subproject commit 9ee4f67755748e7780b75cf98282c2d4935613dd +Subproject commit dc2e4b3af5b666e888166ef1e7567475f6f03904 From 1d2d21fd45cf30ee143341adba203867f86cdf18 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 4 Nov 2025 10:31:50 +0800 Subject: [PATCH 21/22] fixed:websocket size lost modify:verification type string from module --- .../Protocol_Parse/Protocol_Parse.cpp | 9 +++++---- XEngine_Source/XAuth_Protocol.h | 16 +--------------- .../Authorize_WSTask.cpp | 4 +--- 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp index fd9095d..b61170a 100644 --- a/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp +++ b/XEngine_Source/AuthorizeModule_Protocol/Protocol_Parse/Protocol_Parse.cpp @@ -72,6 +72,7 @@ bool CProtocol_Parse::Protocol_Parse_WSHdr(LPCXSTR lpszMsgBuffer, int nMsgLen, X pSt_ProtocolHdr->unOperatorCode = st_JsonRoot["unOperatorCode"].asInt(); pSt_ProtocolHdr->byIsReply = st_JsonRoot["byIsReply"].asInt(); pSt_ProtocolHdr->wCrypto = st_JsonRoot["wCrypto"].asInt(); + pSt_ProtocolHdr->unPacketSize = sizeof(XENGINE_PROTOCOL_USERAUTHEX); if (!st_JsonRoot["xhToken"].isNull()) { pSt_ProtocolHdr->xhToken = st_JsonRoot["xhToken"].asUInt64(); @@ -185,10 +186,6 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseAuth(LPCXSTR lpszMsgBuffer, int nM { _tcsxcpy(pSt_UserAuth->tszUserPass, st_JsonProtocol["tszUserPass"].asCString()); } - if (!st_JsonProtocol["tszDCode"].isNull()) - { - _tcsxcpy(pSt_UserAuth->tszDCode, st_JsonProtocol["tszDCode"].asCString()); - } if (!st_JsonProtocol["enClientType"].isNull()) { pSt_UserAuth->enClientType = (ENUM_PROTOCOLCLIENT_TYPE)st_JsonProtocol["enClientType"].asInt(); @@ -197,6 +194,10 @@ bool CProtocol_Parse::Protocol_Parse_HttpParseAuth(LPCXSTR lpszMsgBuffer, int nM { pSt_UserAuth->enDeviceType = (ENUM_PROTOCOLDEVICE_TYPE)st_JsonProtocol["enDeviceType"].asInt(); } + if (!st_JsonProtocol["tszDCode"].isNull()) + { + _tcsxcpy(pSt_UserAuth->tszDCode, st_JsonProtocol["tszDCode"].asCString()); + } if (!st_JsonProtocol["tszHWCode"].isNull()) { _tcsxcpy(pSt_UserAuth->tszHWCode, st_JsonProtocol["tszHWCode"].asCString()); diff --git a/XEngine_Source/XAuth_Protocol.h b/XEngine_Source/XAuth_Protocol.h index 0da92d9..48ca685 100644 --- a/XEngine_Source/XAuth_Protocol.h +++ b/XEngine_Source/XAuth_Protocol.h @@ -44,24 +44,10 @@ #define ERROR_AUTHORIZE_PROTOCOL_PERMISSION 0x116 //用户权限错误 #define ERROR_AUTHORIZE_PROTOCOL_EXPIRED 0x117 //已经过期 #define ERROR_AUTHORIZE_PROTOCOL_CDKEY 0x118 //CDKEY错误 - +////////////////////////////////////////////////////////////////////////// #define ERROR_AUTHORIZE_PROTOCOL_SERVER 0x201 //服务端内部错误 #define ERROR_AUTHORIZE_PROTOCOL_LIMIT 0x202 //服务端内部限制,数据过大后者过小 ////////////////////////////////////////////////////////////////////////// -// 导出的枚举型 -////////////////////////////////////////////////////////////////////////// -#ifndef _MSC_BUILD -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" -#endif -static LPCXSTR lpszXSerialType[5] = { "UNKNOW","SECOND","DAY","TIME","CUSTOM" }; -static LPCXSTR lpszXRegType[6] = { "UNKNOW","TEMP","TRY","OFFICIAL","UNLIMIT","EXPIRED" }; -static LPCXSTR lpszXHDType[6] = { "UNKNOW","CPU","DISK","BOARD","MAC","BIOS" }; -static LPCXSTR lpszXVerType[6] = { "UNKNOW","LOCAL","NETWORK" }; -#ifndef _MSC_BUILD -#pragma GCC diagnostic pop -#endif -////////////////////////////////////////////////////////////////////////// // 导出的结构体 ////////////////////////////////////////////////////////////////////////// //充值协议 diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_WSTask.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_WSTask.cpp index ebf0eb0..982e9cd 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_WSTask.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_WSTask.cpp @@ -76,9 +76,7 @@ bool XEngine_Client_WSTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nM if (XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQLOGIN == st_ProtocolHdr.unOperatorCode) { - XENGINE_PROTOCOL_USERAUTHEX st_UserAuth; - memset(&st_UserAuth, '\0', sizeof(XENGINE_PROTOCOL_USERAUTHEX)); - + XENGINE_PROTOCOL_USERAUTHEX st_UserAuth = {}; Protocol_Parse_HttpParseAuth(lpszMsgBuffer, nMsgLen, &st_UserAuth); XEngine_Client_TCPTask(lpszClientAddr, (LPCXSTR)&st_UserAuth, sizeof(XENGINE_PROTOCOL_USERAUTHEX), &st_ProtocolHdr, XENGINE_AUTH_APP_NETTYPE_WS); } From 3f92a7e0fe2ee5393030ee780416e0fc32dc1950 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 4 Nov 2025 10:58:57 +0800 Subject: [PATCH 22/22] update:document and configure and CHANGELOG --- CHANGELOG | 26 ++++++++++++++++++ XEngine_Docment/Docment_en.docx | Bin 151007 -> 151839 bytes XEngine_Docment/Docment_zh.docx | Bin 157216 -> 158054 bytes .../XEngine_Config/XEngine_VersionConfig.json | 1 + 4 files changed, 27 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index ab2bd72..0d3579f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,29 @@ +XEngine_Authorize V3.20.0.1001 + +ci:centos and alma linux and debian 13 system support +modify:cdkey module to verification module from depend library +modify:delete push serial and use custom serial insert instead +modify:re generator serial key when cdkey network create +fixed:http verification status incorrect +fixed:sometimes memory leak when read configure +update:depend library +delete:client module +delete:cd key module +delete:more protocol define +delete:parse cdkey protocol and use verification read instead + +工作流:支持centos和alma以及debian13系统支持 +修改:cdkey模块功能使用了依赖库的验证模块替换 +修改:序列号现在使用自定义序列号替换了 +修改:网络验证创建的CDKEY现在需要通过服务器重新生成的序列号 +修正:http验证状态错误 +修正:某些时候读取配置内存溢出 +更新:依赖库 +删除:客户端模块 +删除:cdkey模块 +删除:多余的协议定义 +删除:解析CDKEY协议并且使用验证模块读取替换 +================================================================ XEngine_Authorize V3.19.0.1001 added:more system support diff --git a/XEngine_Docment/Docment_en.docx b/XEngine_Docment/Docment_en.docx index dc7d0543e19ec1ce7730625ca987bfbb1d3e48a8..4d50a50871381dd73f0728d9a92e3ffa775f36fe 100644 GIT binary patch delta 131021 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 q3kjRt+_@I(gW}b40Q;!DRzNlpC5B5eS444$q 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

$GbU-XzZp?EH$0R?`TuM4c7yLmJ!h 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%0DS?nC$1n`;K|h>x+Z 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 delta 130206 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

Z!I>61* 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 B91Z{g diff --git a/XEngine_Docment/Docment_zh.docx b/XEngine_Docment/Docment_zh.docx index d567a42930d37e93f60d7c241798bbc1f97be23f..da425312137de5f669e72bdf541aae5c797b69fa 100644 GIT binary patch delta 134364 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

TKe#Td*apYJHjkQNfEu3hoR3=OXU0n)LFydCE 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 ZBBw2}~O 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

nqRBG(NmryY+ee-^|Od0s5A}A;y#3!+}iwq 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 uc|x0i}C7zV~rl1 za`5je^XKRhNjfpwdWCj?C>nl}v>r1%p&KeMI)j8{(@CX*LWNo2o17@RENmEfD|K^e z61JKusIR;?X9y0q>tS?f{pmq6C63RzL_!O~!8SGDtzvZhtlw{^oVfsXale8q_fyJ* zHLxvS+y}u$FgUPHSb5u3ueoR#hE~Qmeot#wd!P;H;#Tb&P{!Cdcx01*X`6ecBgrBq zVj1!AO^Fcy9q!mYeXM|E{Wfs`%8?|GHN(QDnd)lIu9Y;K`|H@4`sg>%8~=oKCeM(k z04qv%Y9GcsNZLT%*Buq0I{%-q|K+FXdy9Ymn54$GV57eeuRzIp5my0mE;H4T>o>kdYQO7%8{5I$xn0daT??FR z8TiH9BOI;t;Kv!6;?Szq z{r{`y_RFocdPxA#VthBzQ(dL+ABnnh`~$IltlNs?>4O1*fb8Q0tlsMVW52BD-^aJR zCE{&D@Q#^(DM#J0PCflrzLw)7>eiLnI|Wqu$}I=g8>S47b$PsaG{HVxepa-f8#}Au ze_DT%sVyZ7Gx8R=hY2?{;s^+TuTwcp(w}D4iE=dvrkDZ}z)oKTEy}zzw8xhqghw~q z3B?wS=#>i+lB~U>?glFBU*Rbqyt;Lw7$(KD#U&vcZ-IjODSXMMaHPI74nmQ0tJGMp zhVN{fWcqtj#AFI(m>O{8CtGau7^z*Qn#v*X)EgtJvC}A+?LfflUiF;DP4kkNLwuH%_s{~fa9X#LCxYx(m|H@gN7On2 zn`|VZG6RIZ>1;>+u5TtbdiPKVI>M%LzZ#yCZ60E6|5v9|^Xs&%XGb9CI|P;Aifa;* z6gtm(gj&q5RhJQdqi{jE(XR*+MB~3ogQ4h+>SFtSYyy?UFbt|I0?xh(s_5PG7NnV&it1 ze5$Q~aSpx5?}36Sta<5FCg(ce)Olj)+#F|Fz;eN2$r_D4ff3JN+`Z5pty)0}_gn%R z>v(lUZ!mnO&IH}?Z85AWT8S?ilr|1ms{s`LLEe$ig+gw`4&bhxJqppbDB@hltaS7x zGxpw7{ZI*QLbg`x5C+dn(d^p1*Zod^-GL(6 zH$w{cLOy)QF~>dz^Lus;!SGY|-l|F|c^L(ZD7O>vXK|Zrkj@a(UR(d%Z%S6P1OfGb zUWh8c{^ zb)&p;EHJO;dgM+YB`YaRs6~%S#sTx$*e$d*%G@}l!pDnQq)=rS9W!Bumd{NmB{xce`+mcOxn%}r&h2fIvmiG(1{3>nsmycDB)1A@jb z&?igVT;Q;DdN3@}-B<87`&lbRT<(x=tkf9uPTHHz(zwU99+i2e_RG&PCt#O@@tK^_?&77O02-?*nJxICqk(q@ueNM?K--x{B7v(3)>`N%EC#s@eXm@2*hPPN&`$;UOUk6g@ z9r-bc-gBR?>2kc~)4Vu}XY{JOube@>5tc?L7rlIZHxK(GJvu>odO{(J1;1=`tU63% zaeh^Mei_d*b4Ms{h6#8}FbfQSX6BMdTwiI6?xIndQ@ZM%^?MntZa`pb1% z$e+?2XMT-h%n2ukTxw0q!_q!V2IG~mTGZIZC%8Z-6AI7UV3Mt#r5Quavs)~awl8pu zO0}qrM%>h9i#N~@BT)%mvaD#Om$)Ia8sdzDUxZ$-xarva&J&8c5RsUN1-ZVV&HINx zES-{3Y#+SEWehM}$SkI#v{!$5sZ=yE-g8rCFKV%-9rT}~EV&w82o)))YC|bxlMbKg zT2VnThmiC93WX&rh#<1^U21#SRmX?6|Etz}f*F46V62Te1ltTflH~aR-8yr|(qx@I^I~lUoH5USsfMoQ1)ndKF*%wUxttoGzPlM~>lsu|>+wa%W1SCF)kp7U_YPg64 zjz;H6Rr*T$(qc#zjx`2z>Wv#sAe&B{Jl;~qUN<6+9>@q zQ3oimm*lFcmM~P#l^o5|VR+Gd!-s6*FQW|v=OB=eYkRD@6@K{2Ja@YJx1E*WMqr)R zFz=*4w`NqP#;Sg1sc9W6jecjs!?R?78=kViIk3(;9`*%UEh2B>*MwuRoiO>vRi2w9 zm|jOf-mILZht(?_dU3bQ{rV!A4N;mXA^t!$~?MA34q77epkEDVK`N>*QXdVZ*mKxthvi;4%#Glnu= zUSDMBws@_RAxLRwmgF_Z(Jo$YS6IB+FIwy7b;Jyo6GJ$nRT{EEGz@w4<^4}r;dRX< zIcaXc&)Ji=AHZMJW_0i}T@sYX7KO~+(T?g1Io@oFJF^pW^81V&;Ggtv8SU^^jQGxN zn6V$}4`Cz~YXmq+rfiJRfPDaI{e>Dm{5dwWGE!ox^Pt?HRPR817-2XEh=@buV^uyi zL!>->jlbS~+izTDz2mIJvnrhd3aMRVat^cazX|Gwj<;FTV`Cp1%x!W=nzd?h@RXtm zXumM;>2Pwe+xC(VwQ#YShMX$GHD|5jZmnANhEj0)oOE;rPKwfWg@F@HjE&s|F{T{k z!}7&z$d-v%){d&orq#w45*WawY4^J94<4Rp6O`K=76JXr^-nSj7Wd>%W7O>~+(JXxnpp`EZJ&># zrHg5=aFJ7$7!)l_765W?JalQwNhvj@Cb##SN_PSur8-F6<_whm_|uxQ`6J%S=X${! z$lQDI!XgViC3>>$y~b8`j3k%HCp>92^|0xj71O*;QLDN5;0^Xrq$RG}abQY-Bwl}F zfZSFCRGGEovXw-3C+#Xw@GGGR=A)!twsig(0|@1Dgqm)x0gZJ=rqvlY?se328_x0T zo-;9Dc#}!lQh6b`o%9Kl6>q=EB<~hzYz2nLGZyQFPva@;?)ji3NCaKd7jJjs|4qF7 z_L<6N2k$yi(>3>(W3s8(JLq6Pfiq=m6ZoH$;*3=mH@`Mp=$mu*Z`(0c)U#yx!jpVPA;GxhE(?6W<7<;I#{XsPtsBp5uoDi6(0mV$>AESriahDp2;7X&jJJ;Z zOZjpZ&Hip|MVM;q=8-1K){9ML5u>G{>n z56Y8;Cc12@WxwVK&wzD-b#b~@ZMhbM8XpunBRzM z3oPmGh-nlH|LhrF^*$O!TWSETUjy^t;Qj(^{rF!YmhE|ZlX-w^>}isybUweAXYXM3J+DWUfp6M*OLM5qJ~1GQt^hGauemkGcVaS3~gar*${j@!WwXm9(V>r*>2Q=uxFLm8$+!*m7g-h*b-F%`Y`(F_P^L+oS78vFd3WULE2Y?q z!{rzU^E@z>wFnyG&7d)e#tj~6+N3gd(dXy3{me7`ijO&8^uLHJ#_pd`~j;Js0oC!D3xXg!~ zgh4%lcb{awSqM_F=t}ATMQf#i24z$XeUX)MDKo})sI=vWg;Fm&cinV`@)2OpvMtCE z`G{ABpg6r}6RONse`s(!e96MpfAm6Gm;vHSs$)MTat>?zXY8eRl+^GLwE0g@xT15R9bf_{(Z*GGHl13U*=PM z5v?qcv!Nl%a%ZTR&ZmwOolcX;joowU`AQ*zS3c7uJPj+qs^>?eav%WJ<+% z8$A~AbU)e7yUCHU5x%Eb0#vNB_oq$X@|N~nmMivCRc+*BuM9qCk;6SyAW=FMlVbo zcF6YzzGE=bc^~pRcEf4SUZv0L^axBQ)AH&C2%c~2inB%jYBu>A@P0*%%p3-k*K zo!%d3bWt0LXA{QgQxh>|r5H3nZDKcU-JWN+ok>^}&hU41i^OC(8Lg9I@|e{&r`=?prz)^MvO>m8K&;n~+HFg46L21ddiK*{%BO9Iq#;e4sc15LG=di_ruZ>tY0l^;na z-)Et79TIOS+zy{vl^5n8>LyTbzz3$}jZ%~7nI*Zytl3yHc0_c}N`6i=&$bw`w$3=e zcHYNa%ShrUZm(2NI^=X8*QZCKkC+-ggMu?`)3-AULi+7KpgsDi=jTa?ddXf*k+m+guAC5sqm@o;Qlx593jAuF~@kI zc4T{~K-cY)iwz54ysOoW-$iS4y$x!4;ya-*L+)DH%rEDsN|En{y(KQuYnJB|Twq^E zJe`hMwK@S|i)!n)-0BZI9eTTbm#;Gm_*40i1?45mhbv8T>n%UTw=_S7QO+3WMB5nm=wr;J8U54ZuR9Joz{+P}8 z1NAi&-vxT6yYp&;B%5}iSIuS+5>SiwHhFLTNtxl9V7+Y&Car`T-nVHnUL(G)<%#EA z(`KT$zwGv46PyjQG#HkY^6@xd5A>I{ydamITND%ElcD0&vH!=~4#0+MIw)O?PJfG)2Bi`ISj6QEIyPsra08g2jZBGY&9?uWW?)q(&8Sux`z2V6dBz5*k z`=srDZ8CEw^;#b|qt<)g>nfN9qI{kQvGqIb+aF*0_+2Bejvf(+4fR!1N4W3x{_sxJ z{bi=!)8kc?Vy55SQB(U<590%3`at~gx?T66Z}ucpAGj;e6nj7>r0xDG`xwWGKJXX?+#{+K+Sx|++q|D{FPmrU z#GcO)PX*=0cXyBV&jiZ4l~-iXITQ{(%5@Asp>CVb42yE+^%H5ABPmr}7iOo71ZU;pb8PjDw@p(b1Lm zryIoH-fdSw`5fTY;WMG~e1mc%`gpMAoK9ZgQ_6gKYwz&%@;TG>T*&guUZwE;+2Us6 zeckd@`*069nWtCj;rY?^z|ZgTfz|N;i|IvdM}^aVm z|819eLEAz$&QsQN)HLlj$*n07m;QB%Q?oUnH^znkXyZLA!v^2WDrZ-?JO2}@KNolJ zS77qOU9pA^p$8++=>)9L-I`b1=zs3+yR27#bkJ((zeq<2nP`ku!(J0E`9YkpI@ZN=QX&z>$iVZ7y%X726We-ZcR%y}N^ zb4V+3&e7bu12f`3Jyx#ZIG5}pmFy;DmiJjtwf zPuZuf?z1C8MYP-A*K@9QDt)AWuqI?rh4+5ZP(QwZkAiDIEIGdL*gffq6aLGpopsuI zg?VStLx3Smsjg?@F&lIKg*JhuUy1~<^ z{l0gaQsALK{nHM*USIO&-{mqh4TjnBj8UompG;qrJYd~W$z6VHQv0U*sLAs;sx>=q zar}{YVEXEV&sh${aWz|aHJKlBVfiNCF!%M|4JxOWb*aQZTD<=5*9oV9$LT-FxtTt9 z*Iw~SF*@D8l~(c9#}3X52-$KxC5h?5w7LL;!@MTh(IN5abwbV){2zNieVP?`;rq-x z;%>A3{X6Oz7#RNlXJ!cSW@Zs#V4HkyBm4CB3?{zq8)KN<*tuk06>Qg7#J~{7HJveq z$)BZQB?H6c+%+=O3sRT_WCG&nAKS*nz;KG2fk6mp5CSl-nLa0lNk!&T(%y+%fhvvw zRR|)afvlJ7rr$|nvSm8Eak_LWlMU0yEz=`Gbk>pS(^Hw$Wt8r}{UMvl$PjM8j;536 z)bv}aK%EiB(ES*UOl9{LTXE2E}iG@s8%V1KL0j0)PMh1qPKz9qExOqz0 p^wbQX8~r1vFU|m3A{{f`Ad^XK`mYQo6DGwt5XXQ`JprhX0RVLbeS-i1 diff --git a/XEngine_Release/XEngine_Config/XEngine_VersionConfig.json b/XEngine_Release/XEngine_Config/XEngine_VersionConfig.json index 91c8a4c..3ed0431 100644 --- a/XEngine_Release/XEngine_Config/XEngine_VersionConfig.json +++ b/XEngine_Release/XEngine_Config/XEngine_VersionConfig.json @@ -1,5 +1,6 @@ { "XVer":[ + "V3.20.0.1001 Build20251104", "V3.19.0.1001 Build20250821", "V3.18.0.1001 Build20250510", "V3.17.0.1001 Build20250305",