From 4c242ec12983193860aec7ae31f0695a1a329037 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 16 Oct 2025 11:39:08 +0800 Subject: [PATCH 01/20] update:CHANGELOG --- CHANGELOG | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index b12f369..7c3f857 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,41 @@ +XEngine_APIService V3.13.0.1001 + +ci:增加centos和rockylinux以及debian13支持 +ci:MACOS仅支持arm64 +增加:http验证启动日志 +增加:dns协议服务支持 +增加:http验证的基本和摘要支持 +修改:ntp 协议服务单独提取 +修改:测试api消息输出 +修改:不在限制api请求的key名称 +修改:守护进程和后台管理验证方法 +修改:avformat模块替换了xstream模块 +修改:屏幕推流方法 +修改:系统声音推流方法 +更新:依赖库 +更新:启动参数不区分大小写 +修正:ntp宏错误 +修正:启动日志插件索引错误 +删除:不使用的代码 + +ci:added Centos_build.yml and improved Rocky_build.yml and debian 13 +ci:only support arm64 macos build +added:http verification start log +added:dns protocol service support +added:http basic and digest authorize support +modify:ntp protocol service extract individually +modify:print message for d-test api +modify:dont limit api key name +modify:deamon and back verification method +modify:avformat instead xstream +modify:screen stream push support +modify:system sound capture support for back service +update:depend library +update:start parameter are not case sensitive +fixed:ntp macro error +fixed:start log plugin index +delete:not use return +====================================================================================== XEngine_APIService V3.12.0.1001 增加:rockylinux 10 支持 From 55d022bf9a211d82a45f7a0d81cfb855438e555c Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 16 Oct 2025 13:46:15 +0800 Subject: [PATCH 02/20] fixed:verification reply status is incorrect --- XEngine_Release/XEngine_Config/XEngine_Config.json | 4 ++-- XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource | 2 +- .../XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp | 6 ++++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/XEngine_Release/XEngine_Config/XEngine_Config.json b/XEngine_Release/XEngine_Config/XEngine_Config.json index 2c14e61..d77af21 100644 --- a/XEngine_Release/XEngine_Config/XEngine_Config.json +++ b/XEngine_Release/XEngine_Config/XEngine_Config.json @@ -69,8 +69,8 @@ "nVType": 1, "bEnable": false, "st_VerSwitch": { - "bBackService": false, - "bDeamon": false + "bBackService": true, + "bDeamon": true } }, "XReport": { diff --git a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource index da4c1c3..24bde9d 160000 --- a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource +++ b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource @@ -1 +1 @@ -Subproject commit da4c1c30f9c7667e86b8e816560306b0882931a7 +Subproject commit 24bde9d212cd48b822ad8aab90956033972ee46b diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp index 96b0d8b..cc3b1e0 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp @@ -342,6 +342,9 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST if (st_ServiceConfig.st_XVerifcation.st_VerSwitch.bBackService && !bVerification) { + st_HDRParam.nHttpCode = 401; + st_HDRParam.bAuth = true; + st_HDRParam.bIsClose = true; ModuleProtocol_Packet_Common(tszRVBuffer, &nSDLen, 403, _X("User verification required")); HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); @@ -361,6 +364,9 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST //守护进程接口:http://app.xyry.org:5501/api?function=deamon¶ms1=0 if (st_ServiceConfig.st_XVerifcation.st_VerSwitch.bDeamon && !bVerification) { + st_HDRParam.nHttpCode = 401; + st_HDRParam.bAuth = true; + st_HDRParam.bIsClose = true; ModuleProtocol_Packet_Common(tszRVBuffer, &nSDLen, 403, _X("User verification required")); HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); From 64afbfa1c51b923eab04face0ecfb1c7a06dce54 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 16 Oct 2025 13:54:21 +0800 Subject: [PATCH 03/20] fixed:HTTP authentication switch does not support individual verification --- .../XEngine_HttpApp/XEngine_HTTPTask.cpp | 233 +++++++++--------- .../XEngine_HttpApp/XEngine_HTTPTask.h | 1 + 2 files changed, 120 insertions(+), 114 deletions(-) diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp index cc3b1e0..e8cebc3 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp @@ -55,6 +55,114 @@ XHTHREAD XCALLBACK HTTPTask_TastPost_Thread(XPVOID lParam) } return 0; } +bool HTTPTask_TastPost_Verification(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXSTR lpszClientAddr, XCHAR** pptszHDRList, int nHDRCount) +{ + //http验证 + int nVType = 0; + int nSDLen = 0; + XCHAR tszSDBuffer[XPATH_MAX] = {}; + RFCCOMPONENTS_HTTP_HDRPARAM st_HDRParam = {}; + + st_HDRParam.nHttpCode = 401; + st_HDRParam.bIsClose = true; + st_HDRParam.bAuth = true; + //打包验证信息 + int nHDRLen = 0; + XCHAR tszHDRBuffer[XPATH_MAX] = {}; + if (1 == st_ServiceConfig.st_XVerifcation.nVType) + { + Verification_HTTP_BasicServerPacket(tszHDRBuffer, &nHDRLen); + } + else + { + XCHAR tszNonceStr[64] = {}; + XCHAR tszOpaqueStr[64] = {}; + Verification_HTTP_DigestServerPacket(tszHDRBuffer, &nHDRLen, tszNonceStr, tszOpaqueStr); + } + //后去验证方法 + if (!Verification_HTTP_GetType(pptszHDRList, nHDRCount, &nVType)) + { + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); + XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,验证方式:%d,错误:%lX"), lpszClientAddr, st_ServiceConfig.st_XVerifcation.nVType, Verification_GetLastError()); + return false; + } + //验证方式是否一致 + if (st_ServiceConfig.st_XVerifcation.nVType != nVType) + { + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); + XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,验证方式错误,请求:%d,需求:%d"), lpszClientAddr, nVType, st_ServiceConfig.st_XVerifcation.nVType); + return false; + } + bool bRet = false; + + if (_tcsxlen(st_ServiceConfig.st_XVerifcation.tszAPIAuth) > 0) + { + int nHTTPCode = 0; + int nMSGLen = 0; + XCLIENT_APIHTTP st_APIHttp = {}; + XCHAR* ptszMSGBuffer = NULL; + if (!APIClient_Http_Request(_X("GET"), st_ServiceConfig.st_XVerifcation.tszAPIAuth, NULL, &nHTTPCode, &ptszMSGBuffer, &nMSGLen, NULL, NULL, &st_APIHttp)) + { + st_HDRParam.nHttpCode = 500; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); + XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,GET请求验证服务:%s 失败,错误码:%lX"), lpszClientAddr, st_ServiceConfig.st_XVerifcation.tszAPIAuth, APIClient_GetLastError()); + return false; + } + if (200 != nHTTPCode) + { + st_HDRParam.nHttpCode = 500; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); + XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,GET请求验证服务:%s 失败,错误:%d"), lpszClientAddr, st_ServiceConfig.st_XVerifcation.tszAPIAuth, nHTTPCode); + return false; + } + XENGINE_PROTOCOL_USERAUTH st_UserAuth = {}; + if (!ModuleProtocol_Parse_Verifcation(ptszMSGBuffer, nSDLen, st_UserAuth.tszUserName, st_UserAuth.tszUserPass)) + { + st_HDRParam.nHttpCode = 500; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); + XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,返回内容:%s 错误,无法继续"), lpszClientAddr, ptszMSGBuffer); + BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMSGBuffer); + return false; + } + BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMSGBuffer); + + if (1 == nVType) + { + bRet = Verification_HTTP_Basic(st_UserAuth.tszUserName, st_UserAuth.tszUserPass, pptszHDRList, nHDRCount); + } + else if (2 == nVType) + { + bRet = Verification_HTTP_Digest(st_UserAuth.tszUserName, st_UserAuth.tszUserPass, pSt_HTTPParam->tszHttpMethod, pptszHDRList, nHDRCount); + } + } + else + { + if (1 == nVType) + { + bRet = Verification_HTTP_Basic(st_ServiceConfig.st_XVerifcation.tszUserName, st_ServiceConfig.st_XVerifcation.tszUserPass, pptszHDRList, nHDRCount); + } + else if (2 == nVType) + { + bRet = Verification_HTTP_Digest(st_ServiceConfig.st_XVerifcation.tszUserName, st_ServiceConfig.st_XVerifcation.tszUserPass, pSt_HTTPParam->tszHttpMethod, pptszHDRList, nHDRCount); + } + } + + if (!bRet) + { + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); + XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,验证处理错误,可能用户密码登信息不匹配,类型:%d"), lpszClientAddr, nVType); + return false; + } + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,HTTP验证类型:%d 通过"), lpszClientAddr, nVType); + return true; +} + bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXSTR lpszClientAddr, LPCXSTR lpszMSGBuffer, int nMSGLen, XCHAR** pptszHDRList, int nHDRCount) { bool bVerification = false; @@ -103,107 +211,12 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST //http验证 if (st_ServiceConfig.st_XVerifcation.bEnable) { - int nVType = 0; - RFCCOMPONENTS_HTTP_HDRPARAM st_HDRParam = {}; - - st_HDRParam.nHttpCode = 401; - st_HDRParam.bIsClose = true; - st_HDRParam.bAuth = true; - //打包验证信息 - int nHDRLen = 0; - XCHAR tszHDRBuffer[XPATH_MAX] = {}; - if (1 == st_ServiceConfig.st_XVerifcation.nVType) - { - Verification_HTTP_BasicServerPacket(tszHDRBuffer, &nHDRLen); - } - else - { - XCHAR tszNonceStr[64] = {}; - XCHAR tszOpaqueStr[64] = {}; - Verification_HTTP_DigestServerPacket(tszHDRBuffer, &nHDRLen, tszNonceStr, tszOpaqueStr); - } - //后去验证方法 - if (!Verification_HTTP_GetType(pptszHDRList, nHDRCount, &nVType)) - { - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); - XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,验证方式:%d,错误:%lX"), lpszClientAddr, st_ServiceConfig.st_XVerifcation.nVType, Verification_GetLastError()); - return false; - } - //验证方式是否一致 - if (st_ServiceConfig.st_XVerifcation.nVType != nVType) - { - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); - XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,验证方式错误,请求:%d,需求:%d"), lpszClientAddr, nVType, st_ServiceConfig.st_XVerifcation.nVType); - return false; - } - bool bRet = false; - - if (_tcsxlen(st_ServiceConfig.st_XVerifcation.tszAPIAuth) > 0) - { - int nHTTPCode = 0; - int nMSGLen = 0; - XCLIENT_APIHTTP st_APIHttp = {}; - XCHAR* ptszMSGBuffer = NULL; - if (!APIClient_Http_Request(_X("GET"), st_ServiceConfig.st_XVerifcation.tszAPIAuth, NULL, &nHTTPCode, &ptszMSGBuffer, &nMSGLen, NULL, NULL, &st_APIHttp)) - { - st_HDRParam.nHttpCode = 500; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); - XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,GET请求验证服务:%s 失败,错误码:%lX"), lpszClientAddr, st_ServiceConfig.st_XVerifcation.tszAPIAuth, APIClient_GetLastError()); - return false; - } - if (200 != nHTTPCode) - { - st_HDRParam.nHttpCode = 500; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); - XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,GET请求验证服务:%s 失败,错误:%d"), lpszClientAddr, st_ServiceConfig.st_XVerifcation.tszAPIAuth, nHTTPCode); - return false; - } - XENGINE_PROTOCOL_USERAUTH st_UserAuth = {}; - if (!ModuleProtocol_Parse_Verifcation(ptszMSGBuffer, nSDLen, st_UserAuth.tszUserName, st_UserAuth.tszUserPass)) - { - st_HDRParam.nHttpCode = 500; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); - XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,返回内容:%s 错误,无法继续"), lpszClientAddr, ptszMSGBuffer); - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMSGBuffer); - return false; - } - BaseLib_Memory_FreeCStyle((XPPMEM)&ptszMSGBuffer); - - if (1 == nVType) - { - bRet = Verification_HTTP_Basic(st_UserAuth.tszUserName, st_UserAuth.tszUserPass, pptszHDRList, nHDRCount); - } - else if (2 == nVType) - { - bRet = Verification_HTTP_Digest(st_UserAuth.tszUserName, st_UserAuth.tszUserPass, pSt_HTTPParam->tszHttpMethod, pptszHDRList, nHDRCount); - } - } - else + //全面验证 + if (!HTTPTask_TastPost_Verification(pSt_HTTPParam, lpszClientAddr, pptszHDRList, nHDRCount)) { - if (1 == nVType) - { - bRet = Verification_HTTP_Basic(st_ServiceConfig.st_XVerifcation.tszUserName, st_ServiceConfig.st_XVerifcation.tszUserPass, pptszHDRList, nHDRCount); - } - else if (2 == nVType) - { - bRet = Verification_HTTP_Digest(st_ServiceConfig.st_XVerifcation.tszUserName, st_ServiceConfig.st_XVerifcation.tszUserPass, pSt_HTTPParam->tszHttpMethod, pptszHDRList, nHDRCount); - } - } - - if (!bRet) - { - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHDRBuffer); - XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户验证失败,验证处理错误,可能用户密码登信息不匹配,类型:%d"), lpszClientAddr, nVType); return false; } bVerification = true; - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,HTTP验证类型:%d 通过"), lpszClientAddr, nVType); } XCHAR tszKey[XPATH_MAX]; @@ -339,17 +352,13 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST //后台管理接口:http://app.xyry.org:5501/api?function=back¶ms1=0 XCHAR tszType[64]; memset(tszType, '\0', sizeof(tszType)); - + //单独验证 if (st_ServiceConfig.st_XVerifcation.st_VerSwitch.bBackService && !bVerification) { - st_HDRParam.nHttpCode = 401; - st_HDRParam.bAuth = true; - st_HDRParam.bIsClose = true; - ModuleProtocol_Packet_Common(tszRVBuffer, &nSDLen, 403, _X("User verification required")); - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); - XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求后台协议失败,此模式需要进行验证,但是请求未验证"), lpszClientAddr); - return false; + if (!HTTPTask_TastPost_Verification(pSt_HTTPParam, lpszClientAddr, pptszHDRList, nHDRCount)) + { + return false; + } } BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszType); HTTPTask_TaskPost_BackService(lpszClientAddr, lpszMSGBuffer, nMSGLen, _ttxoi(tszType)); @@ -364,14 +373,10 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST //守护进程接口:http://app.xyry.org:5501/api?function=deamon¶ms1=0 if (st_ServiceConfig.st_XVerifcation.st_VerSwitch.bDeamon && !bVerification) { - st_HDRParam.nHttpCode = 401; - st_HDRParam.bAuth = true; - st_HDRParam.bIsClose = true; - ModuleProtocol_Packet_Common(tszRVBuffer, &nSDLen, 403, _X("User verification required")); - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); - XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求守护进程协议失败,此模式需要进行验证,但是请求未验证"), lpszClientAddr); - return false; + if (!HTTPTask_TastPost_Verification(pSt_HTTPParam, lpszClientAddr, pptszHDRList, nHDRCount)) + { + return false; + } } HTTPTask_TaskPost_Deamon(lpszClientAddr, lpszMSGBuffer, nMSGLen); } diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.h b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.h index 5ace63a..901189c 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.h +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.h @@ -13,4 +13,5 @@ //任务处理池,用来获取一个完整包 XHTHREAD XCALLBACK HTTPTask_TastPost_Thread(XPVOID lParam); //任务处理相关函数,处理包的内容 +bool HTTPTask_TastPost_Verification(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXSTR lpszClientAddr, XCHAR** pptszHDRList, int nHDRCount); bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXSTR lpszClientAddr, LPCXSTR lpszMSGBuffer, int nMSGLen, XCHAR** pptszHDRList, int nHDRCount); \ No newline at end of file From 4c3b133668a8e841101b9d5585e2e86cff8ec4d9 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 3 Nov 2025 16:42:09 +0800 Subject: [PATCH 04/20] update:depend library fixed:build --- XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource | 2 +- XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource index 24bde9d..9ee4f67 160000 --- a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource +++ b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource @@ -1 +1 @@ -Subproject commit 24bde9d212cd48b822ad8aab90956033972ee46b +Subproject commit 9ee4f67755748e7780b75cf98282c2d4935613dd diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile index 44780e3..cc23fd7 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile @@ -6,7 +6,7 @@ LOADHDR = -I ./ LOADSO = -L ../../XEngine_ModuleConfigure -L ../../XEngine_ModuleDatabase -L ../../XEngine_ModuleProtocol -L ../../XEngine_ModuleSystem -L ../../XEngine_ModuleHelp -L ../../XEngine_ModulePlugin \ -L ../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/jsoncpp -L ../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_InfoReport -L ../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_Verification \ -L ../../XEngine_DependLibrary/XEngine_IPMacData/XEngine_Source/XEngine_APIModuleIPMac -L ../../XEngine_DependLibrary/XEngine_PhoneData/XEngine_Source/XEngine_APIModulePhone -LIB = -lXEngine_BaseSafe -lXEngine_BaseLib -lXEngine_Algorithm -lXEngine_Core -lXEngine_ManagePool -lXEngine_Cryption -lXClient_APIHelp -lXClient_Socket -lNetHelp_APIAddr -lNetHelp_XSocket -lHelpComponents_XLog -lRfcComponents_HttpProtocol -lRfcComponents_NatProtocol -lRfcComponents_NTPProtocol -lRfcComponents_DNSProtocol -lXEngine_ProcFile -lXEngine_SystemApi -lXEngine_AVHelp -lXEngine_VideoCodec -lXEngine_AudioCodec -lXEngine_AVFilter -lXEngine_AVCollect -lXEngine_AVFormat \ +LIB = -lXEngine_BaseSafe -lXEngine_BaseLib -lXEngine_Algorithm -lXEngine_Core -lXEngine_ManagePool -lXEngine_Cryption -lXClient_APIHelp -lXClient_Socket -lNetHelp_APIAddr -lNetHelp_XSocket -lHelpComponents_XLog -lRfcComponents_HttpProtocol -lRfcComponents_NatProtocol -lRfcComponents_NTPProtocol -lRfcComponents_DNSProtocol -lXEngine_SystemApi -lXEngine_AVHelp -lXEngine_VideoCodec -lXEngine_AudioCodec -lXEngine_AVFilter -lXEngine_AVCollect -lXEngine_AVFormat \ -lXEngine_ModuleConfigure -lXEngine_ModuleDatabase -lXEngine_ModuleProtocol -lXEngine_ModuleSystem -lXEngine_ModuleHelp -lXEngine_ModulePlugin \ -ljsoncpp -lXEngine_InfoReport -lXEngine_Verification \ -lXEngine_APIModuleIPMac -lXEngine_APIModulePhone From c59474e0f5a5e39967070f86cbde463cdb6e50f6 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 3 Nov 2025 17:36:42 +0800 Subject: [PATCH 05/20] fixed:build failure --- XEngine_Source/XEngine_ModuleProtocol/pch.h | 1 - 1 file changed, 1 deletion(-) diff --git a/XEngine_Source/XEngine_ModuleProtocol/pch.h b/XEngine_Source/XEngine_ModuleProtocol/pch.h index c529200..f65ef43 100644 --- a/XEngine_Source/XEngine_ModuleProtocol/pch.h +++ b/XEngine_Source/XEngine_ModuleProtocol/pch.h @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include "../XEngine_DependLibrary/XEngine_IPMacData/XEngine_Source/XIPMac_CommHdr.h" From 8b9594e7fb9cb3404de7d24403152fcc273559a2 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 14 Jan 2026 17:16:56 +0800 Subject: [PATCH 06/20] update:depend library --- XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource index 9ee4f67..984e60d 160000 --- a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource +++ b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource @@ -1 +1 @@ -Subproject commit 9ee4f67755748e7780b75cf98282c2d4935613dd +Subproject commit 984e60d9e1cb7c8736d31d0f2b798756afb9399a From e4f531c767aa02fd71b4cc42e3d5a5d6560e400e Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 14 Jan 2026 17:17:17 +0800 Subject: [PATCH 07/20] fixed:build error and remove audio fifo --- .../XEngine_TaskPost/TaskPost_BackService.cpp | 54 ++++++------------- .../XEngine_TaskPost/TaskPost_BackService.h | 4 +- 2 files changed, 17 insertions(+), 41 deletions(-) diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.cpp index 7ef2024..2cd076e 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.cpp @@ -6,50 +6,36 @@ static XHANDLE xhAudio = NULL; static XHANDLE xhSound = NULL; static XHANDLE xhScreen = NULL; static XHANDLE xhPacket = NULL; -static XHANDLE xhAudioFifo = NULL; static XHANDLE xhFilter = 0; -void XCALLBACK HTTPTask_TaskPost_CBVideo(AVCODEC_VIDEO_MSGBUFFER* pSt_MSGBuffer, XPVOID lParam) +void XCALLBACK HTTPTask_TaskPost_CBVideo(XHANDLE*** pppSt_AVBuffer, XPVOID lParam) { int nListCount = 0; - AVCODEC_VIDEO_MSGBUFFER** ppSt_MSGBuffer; - pSt_MSGBuffer->st_TimeStamp = {}; - VideoCodec_Stream_EnCodec(xhVideo, pSt_MSGBuffer, &ppSt_MSGBuffer, &nListCount); + XHANDLE** ppSt_AVPacket; + VideoCodec_Stream_EnCodec(xhVideo, pppSt_AVBuffer, &ppSt_AVPacket, &nListCount); for (int i = 0; i < nListCount; i++) { - AVFormat_Packet_StreamWrite(xhPacket, 0, ppSt_MSGBuffer[i]->st_MSGBuffer.unData.ptszMSGBuffer, ppSt_MSGBuffer[i]->st_MSGBuffer.nMSGLen[0], &ppSt_MSGBuffer[i]->st_TimeStamp); - BaseLib_Memory_MSGFree(&ppSt_MSGBuffer[i]->st_MSGBuffer); + AVFormat_Packet_StreamWrite(xhPacket, 0, ppSt_AVPacket[i]); } - BaseLib_Memory_Free((XPPPMEM)&ppSt_MSGBuffer, nListCount); + AVHelp_Memory_FreeAVList(&ppSt_AVPacket, nListCount); } -void XCALLBACK HTTPTask_TaskPost_CBAudio(AVCODEC_AUDIO_MSGBUFFER* pSt_MSGBuffer, XPVOID lParam) +void XCALLBACK HTTPTask_TaskPost_CBAudio(XHANDLE*** pppSt_AVBuffer, XPVOID lParam) { int nListCount = 0; - AVCODEC_AUDIO_MSGBUFFER** ppSt_MSGBuffer; - AVFilter_Audio_Cvt(xhFilter, pSt_MSGBuffer, &ppSt_MSGBuffer, &nListCount); + XHANDLE** ppSt_MSGBuffer; + AVFilter_Audio_Cvt(xhFilter, pppSt_AVBuffer, &ppSt_MSGBuffer, &nListCount); for (int i = 0; i < nListCount; i++) { - AudioCodec_Help_FifoSend(xhAudioFifo, ppSt_MSGBuffer[i]); - while (true) + int nAudioCount = 0; + XHANDLE** ppSt_AVPacket; + AudioCodec_Stream_EnCodec(xhAudio, ppSt_MSGBuffer[i], &ppSt_AVPacket, &nAudioCount); + for (int j = 0; j < nAudioCount; j++) { - AVCODEC_AUDIO_MSGBUFFER st_MSGBuffer = {}; - if (!AudioCodec_Help_FifoRecv(xhAudioFifo, &st_MSGBuffer)) - { - break; - } - int nAudioCount = 0; - AVCODEC_AUDIO_MSGBUFFER** ppSt_AudioBuffer; - AudioCodec_Stream_EnCodec(xhAudio, &st_MSGBuffer, &ppSt_AudioBuffer, &nAudioCount); - for (int j = 0; j < nAudioCount; j++) - { - AVFormat_Packet_StreamWrite(xhPacket, 1, ppSt_AudioBuffer[j]->st_MSGBuffer.unData.ptszMSGArray[0], ppSt_AudioBuffer[j]->st_MSGBuffer.nMSGLen[0], &ppSt_AudioBuffer[j]->st_TimeStamp); - BaseLib_Memory_MSGFree(&ppSt_AudioBuffer[j]->st_MSGBuffer); - } - BaseLib_Memory_Free((XPPPMEM)&ppSt_AudioBuffer, nAudioCount); + AVFormat_Packet_StreamWrite(xhPacket, 1, ppSt_AVPacket[j]); } - BaseLib_Memory_MSGFree(&ppSt_MSGBuffer[i]->st_MSGBuffer); + AVHelp_Memory_FreeAVList(&ppSt_AVPacket, nAudioCount); } - BaseLib_Memory_Free((XPPPMEM)&ppSt_MSGBuffer, nListCount); + AVHelp_Memory_FreeAVList(&ppSt_MSGBuffer, nListCount, false); } bool HTTPTask_TaskPost_BackService(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, int nType) @@ -411,15 +397,6 @@ bool HTTPTask_TaskPost_BackService(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,初始化音频采集器请求失败,错误码:%lX"), lpszClientAddr, AudioCodec_GetLastError()); return false; } - xhAudioFifo = AudioCodec_Help_FifoInit(ENUM_AVCODEC_AUDIO_SAMPLEFMT_FLTP, 2); - if (NULL == xhAudioFifo) - { - st_HDRParam.nHttpCode = 400; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,初始化音频采集器请求失败,错误码:%lX"), lpszClientAddr, AudioCodec_GetLastError()); - return false; - } XHANDLE xhAudioCodec = NULL; AudioCodec_Stream_GetAVCodec(xhAudio, &xhAudioCodec); AVFormat_Packet_StreamCreate(xhPacket, xhAudioCodec); @@ -448,7 +425,6 @@ bool HTTPTask_TaskPost_BackService(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer VideoCodec_Stream_Destroy(xhVideo); AudioCodec_Stream_Destroy(xhAudio); - AudioCodec_Help_FifoClose(xhAudioFifo); AVFilter_Audio_Destroy(xhFilter); diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.h b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.h index d47cb87..438f901 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.h +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.h @@ -1,5 +1,5 @@ #pragma once -void XCALLBACK HTTPTask_TaskPost_CBVideo(XENGINE_MSGBUFFER* pSt_MSGBuffer, AVCODEC_TIMESTAMP* pSt_TimeInfo, int nNBSample, int nSampleFmt, XPVOID lParam); -void XCALLBACK HTTPTask_TaskPost_CBAudio(XENGINE_MSGBUFFER* pSt_MSGBuffer, AVCODEC_TIMESTAMP* pSt_TimeInfo, int nNBSample, int nSampleFmt, XPVOID lParam); +void XCALLBACK HTTPTask_TaskPost_CBVideo(XHANDLE*** pppSt_AVBuffer, XPVOID lParam); +void XCALLBACK HTTPTask_TaskPost_CBAudio(XHANDLE*** pppSt_AVBuffer, XPVOID lParam); bool HTTPTask_TaskPost_BackService(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, int nType); \ No newline at end of file From 0dc036ea1aee997bd85c4092a9b3ad4070ef89d5 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 27 Jan 2026 17:05:15 +0800 Subject: [PATCH 08/20] delete:plugin module and use depend library plugin module instead --- .../APPClient_ImageExample.cpp | 1 - XEngine_Source/Makefile | 14 +- XEngine_Source/XEngine.sln | 32 +- .../XEngine_DependLibrary/XEngine_OPenSource | 2 +- XEngine_Source/XEngine_ModulePlugin/Makefile | 81 ---- .../ModulePlugin_Define.h | 443 ------------------ .../XEngine_ModulePlugin/ModulePlugin_Error.h | 27 -- .../ModulePlugin_LibCore.cpp | 370 --------------- .../ModulePlugin_LibCore.h | 58 --- .../ModulePlugin_Loader.cpp | 383 --------------- .../ModulePlugin_Loader/ModulePlugin_Loader.h | 43 -- .../ModulePlugin_LuaCore.cpp | 390 --------------- .../ModulePlugin_LuaCore.h | 42 -- .../XEngine_ModulePlugin.def | 24 - .../XEngine_ModulePlugin.vcxproj | 270 ----------- .../XEngine_ModulePlugin.vcxproj.filters | 80 ---- .../XEngine_ModulePlugin.vcxproj.user | 4 - .../XEngine_ModulePlugin/dllmain.cpp | 19 - .../XEngine_ModulePlugin/framework.h | 5 - XEngine_Source/XEngine_ModulePlugin/pch.cpp | 109 ----- XEngine_Source/XEngine_ModulePlugin/pch.h | 61 --- .../ModulePlugin_BMIndex/pch.h | 2 +- .../ModulePlugin_Meter/pch.h | 2 +- .../ModulePlugin_Password/pch.h | 2 +- .../ModulePlugin_Timezone/pch.h | 2 +- .../ModulePlugin_Zodiac/pch.h | 2 +- .../XEngine_HttpApp/XEngine_HTTPTask.cpp | 2 +- .../XEngine_HttpApp/XEngine_Hdr.h | 16 +- .../XEngine_HttpApp/XEngine_HttpApp.cpp | 20 +- .../XEngine_HttpApp/XEngine_PluginTask.cpp | 4 +- .../XEngine_TaskGet/TaskGet_Reload.cpp | 8 +- XEngine_Source/XEngine_UserProtocol.h | 6 - 32 files changed, 56 insertions(+), 2468 deletions(-) delete mode 100644 XEngine_Source/XEngine_ModulePlugin/Makefile delete mode 100644 XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Define.h delete mode 100644 XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Error.h delete mode 100644 XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LibCore/ModulePlugin_LibCore.cpp delete mode 100644 XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LibCore/ModulePlugin_LibCore.h delete mode 100644 XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Loader/ModulePlugin_Loader.cpp delete mode 100644 XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Loader/ModulePlugin_Loader.h delete mode 100644 XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LuaCore/ModulePlugin_LuaCore.cpp delete mode 100644 XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LuaCore/ModulePlugin_LuaCore.h delete mode 100644 XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.def delete mode 100644 XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj delete mode 100644 XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj.filters delete mode 100644 XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj.user delete mode 100644 XEngine_Source/XEngine_ModulePlugin/dllmain.cpp delete mode 100644 XEngine_Source/XEngine_ModulePlugin/framework.h delete mode 100644 XEngine_Source/XEngine_ModulePlugin/pch.cpp delete mode 100644 XEngine_Source/XEngine_ModulePlugin/pch.h diff --git a/XEngine_APPClient/APPClient_ImageExample/APPClient_ImageExample.cpp b/XEngine_APPClient/APPClient_ImageExample/APPClient_ImageExample.cpp index 5ab682d..b1392f1 100644 --- a/XEngine_APPClient/APPClient_ImageExample/APPClient_ImageExample.cpp +++ b/XEngine_APPClient/APPClient_ImageExample/APPClient_ImageExample.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/XEngine_Source/Makefile b/XEngine_Source/Makefile index 57c3811..2414e8f 100644 --- a/XEngine_Source/Makefile +++ b/XEngine_Source/Makefile @@ -9,7 +9,6 @@ MODULE_DATABASE_PATH = ./XEngine_ModuleDatabase MODULE_PROTOCOL_PATH = ./XEngine_ModuleProtocol MODULE_SYSTEM_PATH = ./XEngine_ModuleSystem MODULE_HELP_PATH = ./XEngine_ModuleHelp -MODULE_PLUGIN_PATH = ./XEngine_ModulePlugin PLUGIN_MODULE_ZODIAC = ./XEngine_PluginModule/ModulePlugin_Zodiac PLUGIN_MODULE_PASSWORD = ./XEngine_PluginModule/ModulePlugin_Password @@ -20,6 +19,7 @@ PLUGIN_MODULE_METER = ./XEngine_PluginModule/ModulePlugin_Meter THIRDPART_MODULE_JSONCPP = ./XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/jsoncpp THIRDPART_MODULE_REPORT = ./XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_InfoReport THIRDPART_MODULE_VERIFICATION = ./XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_Verification +THIRDPART_MODULE_PLUGIN = ./XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_PluginExtension APIMODULE_PHONE_PATH = ./XEngine_DependLibrary/XEngine_PhoneData/XEngine_Source/XEngine_APIModulePhone APIMODULE_IPMAC_PATH = ./XEngine_DependLibrary/XEngine_IPMacData/XEngine_Source/XEngine_APIModuleIPMac @@ -31,8 +31,8 @@ else ifeq ($(PLATFORM),mac) FILEEXT = dylib endif -XENGINE_MODULES = libjsoncpp.so libXEngine_InfoReport.so libXEngine_Verification.so \ - libXEngine_ModuleConfigure.so libXEngine_ModuleDatabase.so libXEngine_ModuleProtocol.so libXEngine_ModuleSystem.so libXEngine_ModuleHelp.so libXEngine_ModulePlugin.so \ +XENGINE_MODULES = libjsoncpp.so libXEngine_InfoReport.so libXEngine_Verification.so libXEngine_PluginExtension.so \ + libXEngine_ModuleConfigure.so libXEngine_ModuleDatabase.so libXEngine_ModuleProtocol.so libXEngine_ModuleSystem.so libXEngine_ModuleHelp.so \ libModulePlugin_Zodiac.so libModulePlugin_Password.so libModulePlugin_Timezone.so libModulePlugin_BMIndex.so libModulePlugin_Meter.so \ libXEngine_APIModulePhone.so libXEngine_APIModuleIPMac.so \ XEngine_HttpApp.exe @@ -58,6 +58,12 @@ ifeq ($(FLAGS), InstallAll) else make -C $(THIRDPART_MODULE_VERIFICATION) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) RELEASE=$(RELEASE) $(FLAGS) endif +libXEngine_PluginExtension.so: +ifeq ($(FLAGS), InstallAll) + cp $(THIRDPART_MODULE_PLUGIN)/libXEngine_PluginExtension.$(FILEEXT) ../XEngine_Release/ +else + make -C $(THIRDPART_MODULE_PLUGIN) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) RELEASE=$(RELEASE) $(FLAGS) +endif libXEngine_APIModulePhone.so: ifeq ($(FLAGS), InstallAll) cp $(APIMODULE_PHONE_PATH)/libXEngine_APIModulePhone.$(FILEEXT) ../XEngine_Release/ @@ -81,8 +87,6 @@ libXEngine_ModuleSystem.so: make -C $(MODULE_SYSTEM_PATH) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) RELEASE=$(RELEASE) $(FLAGS) libXEngine_ModuleHelp.so: make -C $(MODULE_HELP_PATH) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) RELEASE=$(RELEASE) $(FLAGS) -libXEngine_ModulePlugin.so: - make -C $(MODULE_PLUGIN_PATH) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) RELEASE=$(RELEASE) $(FLAGS) libModulePlugin_Zodiac.so: make -C $(PLUGIN_MODULE_ZODIAC) PLATFORM=$(PLATFORM) UNICODE=$(UNICODE) RELEASE=$(RELEASE) $(FLAGS) diff --git a/XEngine_Source/XEngine.sln b/XEngine_Source/XEngine.sln index a4746dd..7d5df08 100644 --- a/XEngine_Source/XEngine.sln +++ b/XEngine_Source/XEngine.sln @@ -29,7 +29,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_HttpApp", "XEngine_ {A13B72E7-FC40-4A27-81C3-26DF3C8F4C0A} = {A13B72E7-FC40-4A27-81C3-26DF3C8F4C0A} {A8E43EC0-698A-4807-8A61-B2BE5FAB7256} = {A8E43EC0-698A-4807-8A61-B2BE5FAB7256} {BBC4B2B4-1143-45DF-8890-47CE26A61D0E} = {BBC4B2B4-1143-45DF-8890-47CE26A61D0E} - {CB443280-E283-44CD-B956-52C404A51DB6} = {CB443280-E283-44CD-B956-52C404A51DB6} + {D76B9C99-D002-4770-BB33-C24A91ED97E9} = {D76B9C99-D002-4770-BB33-C24A91ED97E9} {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} = {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} {F54F152C-594F-4465-A44E-2DB915B39760} = {F54F152C-594F-4465-A44E-2DB915B39760} {F6520D2C-BB8E-45BB-964B-F5D6A4318A89} = {F6520D2C-BB8E-45BB-964B-F5D6A4318A89} @@ -45,8 +45,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_ModuleProtocol", "X EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_ModuleHelp", "XEngine_ModuleHelp\XEngine_ModuleHelp.vcxproj", "{6D0FCB40-D544-4AB2-A239-2FEBC4B98F6D}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_ModulePlugin", "XEngine_ModulePlugin\XEngine_ModulePlugin.vcxproj", "{CB443280-E283-44CD-B956-52C404A51DB6}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "XEngine_PluginModule", "XEngine_PluginModule", "{D0473C03-9464-4C44-818A-AE212680CD05}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libModulePlugin_Zodiac", "XEngine_PluginModule\ModulePlugin_Zodiac\ModulePlugin_Zodiac.vcxproj", "{32BB166A-3D3D-45EF-8BED-2E0471274159}" @@ -88,7 +86,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_APIServiceApp", "XE {92F971AB-CAC9-4D9B-A9CA-AFD9CA17E505} = {92F971AB-CAC9-4D9B-A9CA-AFD9CA17E505} {A13B72E7-FC40-4A27-81C3-26DF3C8F4C0A} = {A13B72E7-FC40-4A27-81C3-26DF3C8F4C0A} {BBC4B2B4-1143-45DF-8890-47CE26A61D0E} = {BBC4B2B4-1143-45DF-8890-47CE26A61D0E} - {CB443280-E283-44CD-B956-52C404A51DB6} = {CB443280-E283-44CD-B956-52C404A51DB6} {E756B7D2-D40D-4106-9C14-1D90F20A712E} = {E756B7D2-D40D-4106-9C14-1D90F20A712E} {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} = {F1736B3F-03A2-4FC7-B045-A12BA8D724FB} {F54F152C-594F-4465-A44E-2DB915B39760} = {F54F152C-594F-4465-A44E-2DB915B39760} @@ -114,6 +111,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_APIModulePhone", "X EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_Verification", "XEngine_DependLibrary\XEngine_OPenSource\XEngine_Module\XEngine_Verification\XEngine_Verification.vcxproj", "{A8E43EC0-698A-4807-8A61-B2BE5FAB7256}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XEngine_PluginExtension", "XEngine_DependLibrary\XEngine_OPenSource\XEngine_Module\XEngine_PluginExtension\XEngine_PluginExtension.vcxproj", "{D76B9C99-D002-4770-BB33-C24A91ED97E9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM64 = Debug|ARM64 @@ -184,18 +183,6 @@ Global {6D0FCB40-D544-4AB2-A239-2FEBC4B98F6D}.Release|x64.Build.0 = Release|x64 {6D0FCB40-D544-4AB2-A239-2FEBC4B98F6D}.Release|x86.ActiveCfg = Release|Win32 {6D0FCB40-D544-4AB2-A239-2FEBC4B98F6D}.Release|x86.Build.0 = Release|Win32 - {CB443280-E283-44CD-B956-52C404A51DB6}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {CB443280-E283-44CD-B956-52C404A51DB6}.Debug|ARM64.Build.0 = Debug|ARM64 - {CB443280-E283-44CD-B956-52C404A51DB6}.Debug|x64.ActiveCfg = Debug|x64 - {CB443280-E283-44CD-B956-52C404A51DB6}.Debug|x64.Build.0 = Debug|x64 - {CB443280-E283-44CD-B956-52C404A51DB6}.Debug|x86.ActiveCfg = Debug|Win32 - {CB443280-E283-44CD-B956-52C404A51DB6}.Debug|x86.Build.0 = Debug|Win32 - {CB443280-E283-44CD-B956-52C404A51DB6}.Release|ARM64.ActiveCfg = Release|ARM64 - {CB443280-E283-44CD-B956-52C404A51DB6}.Release|ARM64.Build.0 = Release|ARM64 - {CB443280-E283-44CD-B956-52C404A51DB6}.Release|x64.ActiveCfg = Release|x64 - {CB443280-E283-44CD-B956-52C404A51DB6}.Release|x64.Build.0 = Release|x64 - {CB443280-E283-44CD-B956-52C404A51DB6}.Release|x86.ActiveCfg = Release|Win32 - {CB443280-E283-44CD-B956-52C404A51DB6}.Release|x86.Build.0 = Release|Win32 {32BB166A-3D3D-45EF-8BED-2E0471274159}.Debug|ARM64.ActiveCfg = Debug|ARM64 {32BB166A-3D3D-45EF-8BED-2E0471274159}.Debug|ARM64.Build.0 = Debug|ARM64 {32BB166A-3D3D-45EF-8BED-2E0471274159}.Debug|x64.ActiveCfg = Debug|x64 @@ -340,6 +327,18 @@ Global {A8E43EC0-698A-4807-8A61-B2BE5FAB7256}.Release|x64.Build.0 = Release|x64 {A8E43EC0-698A-4807-8A61-B2BE5FAB7256}.Release|x86.ActiveCfg = Release|Win32 {A8E43EC0-698A-4807-8A61-B2BE5FAB7256}.Release|x86.Build.0 = Release|Win32 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Debug|ARM64.Build.0 = Debug|ARM64 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Debug|x64.ActiveCfg = Debug|x64 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Debug|x64.Build.0 = Debug|x64 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Debug|x86.ActiveCfg = Debug|Win32 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Debug|x86.Build.0 = Debug|Win32 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Release|ARM64.ActiveCfg = Release|ARM64 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Release|ARM64.Build.0 = Release|ARM64 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Release|x64.ActiveCfg = Release|x64 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Release|x64.Build.0 = Release|x64 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Release|x86.ActiveCfg = Release|Win32 + {D76B9C99-D002-4770-BB33-C24A91ED97E9}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -357,6 +356,7 @@ Global {FFAC032D-4F8C-4C70-AF36-D79685A6961F} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} {A13B72E7-FC40-4A27-81C3-26DF3C8F4C0A} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} {A8E43EC0-698A-4807-8A61-B2BE5FAB7256} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} + {D76B9C99-D002-4770-BB33-C24A91ED97E9} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9B202F91-A601-429E-BB0F-880DDEE096FE} diff --git a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource index 984e60d..9b1c9e3 160000 --- a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource +++ b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource @@ -1 +1 @@ -Subproject commit 984e60d9e1cb7c8736d31d0f2b798756afb9399a +Subproject commit 9b1c9e3117fdf04aeff6e26b62e5bfeeaf5a9374 diff --git a/XEngine_Source/XEngine_ModulePlugin/Makefile b/XEngine_Source/XEngine_ModulePlugin/Makefile deleted file mode 100644 index 43b6e93..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/Makefile +++ /dev/null @@ -1,81 +0,0 @@ -CC = g++ -Wall -std=c++20 -fPIC -PLATVER = -FILEEXT = -LIBFLAG = -LOADHDR = -I ./ -I /usr/include/lua5.4 -I /usr/local/include/lua -LOADSO = -LIB = -lXEngine_BaseLib -LIBEX = -OBJECTS = ModulePlugin_LibCore.o ModulePlugin_LuaCore.o ModulePlugin_Loader.o pch.o - -MACRO_LUA_SUPPORT := $(shell gcc -E -dM ../XEngine_BuildSwitch.h | grep _XENGINE_BUILD_SWITCH_LUA | cut -d ' ' -f 3) - -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__ - LIB += -llua - else - PLATVER = -D __UBUNTU__ - LIB += -llua5.4 - 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 - LOADHDR += -I /opt/homebrew/opt/lua/include/lua - LOADSO += -L /opt/homebrew/opt/lua/lib - ifeq ($(MACRO_LUA_SUPPORT),1) - LIB += -llua - endif - LIBEX = -lpthread -ldl - LOADBIN = -Wl,-rpath,@loader_path/./ -endif - -all:$(OBJECTS) - $(CC) $(DEBUG) $(OBJECTS) -o libXEngine_ModulePlugin.$(FILEEXT) $(LIBFLAG) $(LIB) $(LIBEX) $(LOADSO) $(LOADBIN) - -ModulePlugin_LibCore.o:./ModulePlugin_LibCore/ModulePlugin_LibCore.cpp - $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./ModulePlugin_LibCore/ModulePlugin_LibCore.cpp -ModulePlugin_LuaCore.o:./ModulePlugin_LuaCore/ModulePlugin_LuaCore.cpp - $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./ModulePlugin_LuaCore/ModulePlugin_LuaCore.cpp -ModulePlugin_Loader.o:./ModulePlugin_Loader/ModulePlugin_Loader.cpp - $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./ModulePlugin_Loader/ModulePlugin_Loader.cpp - -pch.o:./pch.cpp - $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./pch.cpp - - -InstallAll:InstallSo -InstallSo:./libXEngine_ModulePlugin.$(FILEEXT) - cp ./libXEngine_ModulePlugin.$(FILEEXT) ../../XEngine_Release/libXEngine_ModulePlugin.$(FILEEXT) - - -CleanAll:CleanObj CleanMk -CleanObj: - rm *.o -CleanMk: - rm *.$(FILEEXT) \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Define.h b/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Define.h deleted file mode 100644 index 74fe825..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Define.h +++ /dev/null @@ -1,443 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2022/04/20 17:22:16 -// File Name: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_Define.h -// File Path: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin -// File Base: ModulePlugin_Define -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 插件导出定义 -// History: -*********************************************************************/ -////////////////////////////////////////////////////////////////////////// -// 导出函数定义 -////////////////////////////////////////////////////////////////////////// -extern "C" XLONG ModulePlugin_GetLastError(int* pInt_SysError = NULL); -/********************************************************************************* -* LIB库插件框架导出函数定义 * -*********************************************************************************/ -/******************************************************************** -函数名称:ModulePlugin_LibCore_Init -函数功能:初始化插件核心系统 -返回值 - 类型:逻辑型 - 意思:是否成功初始化 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_LibCore_Init(); -/******************************************************************** -函数名称:ModulePlugin_LibCore_Push -函数功能:添加一个标准的插件到插件框架中 - 参数.一:pxhModule - In/Out:Out - 类型:模块句柄 - 可空:N - 意思:导出一个加载成功的模块句柄 - 参数.二:lpszPluginFile - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:插件模块路径 - 参数.三:pSt_PluginParameter - In/Out:In - 类型:数据结构指针 - 可空:Y - 意思:输入插件初始化参数 -返回值 - 类型:逻辑型 - 意思:是否成功添加 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_LibCore_Push(XNETHANDLE * pxhNet, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter = NULL); -/******************************************************************** -函数名称:ModulePlugin_LibCore_Exec -函数功能:执行一次 - 参数.一:xhModule - In/Out:In - 类型:句柄 - 可空:N - 意思:输入模块句柄 - 参数.二:pppHDRList - In/Out:In - 类型:三级指针 - 可空:N - 意思:HTTP请求的URL参数列表 - 参数.三:nListCount - In/Out:In - 类型:整数型 - 可空:N - 意思:输入列表个数 - 参数.四:pInt_HTTPCode - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出返回的HTTPCODE值 - 参数.五:ptszMsgBuffer - In/Out:Out - 类型:字符指针 - 可空:N - 意思:输出负载的内容 - 参数.六:pInt_MsgLen - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出内容大小 - 参数.七:lpszMsgBufer - In/Out:Out - 类型:常量字符指针 - 可空:Y - 意思:输入负载内容 - 参数.八:nMsgLen - In/Out:Out - 类型:整数型指针 - 可空:Y - 意思:输入负载大小 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_LibCore_Exec(XNETHANDLE xhModule, XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBufer = NULL, int nMsgLen = 0); -/******************************************************************** -函数名称:ModulePlugin_LibCore_Get -函数功能:获取插件基础信息函数 - 参数.一:xhModule - In/Out:In - 类型:句柄 - 可空:N - 意思:要操作的模块句柄 - 参数.二:ptszPluginName - In/Out:Out - 类型:字符指针 - 可空:N - 意思:处理名称 - 参数.三:ptszPluginVersion - In/Out:Out - 类型:字符指针 - 可空:N - 意思:版本号.使用x.x.x.x 格式 - 参数.四:ptszPluginAuthor - In/Out:Out - 类型:字符指针 - 可空:N - 意思:作者 - 参数.五:ptszPluginDesc - In/Out:Out - 类型:字符指针 - 可空:N - 意思:插件描述 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_LibCore_Get(XNETHANDLE xhModule, XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc); -/******************************************************************** -函数名称:ModulePlugin_LibCore_Destroy -函数功能:销毁插件核心并且清理资源 -返回值 - 类型:逻辑型 - 意思:是否成功销毁 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_LibCore_Destroy(); -/********************************************************************************* -* LUA插件框架导出函数定义 * -*********************************************************************************/ -/******************************************************************** -函数名称:ModulePlugin_LuaCore_Init -函数功能:初始化LUA插件核心系统 -返回值 - 类型:逻辑型 - 意思:是否成功初始化 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_LuaCore_Init(); -/******************************************************************** -函数名称:ModulePlugin_LuaCore_Push -函数功能:添加一个标准的插件到插件框架中 - 参数.一:pxhModule - In/Out:Out - 类型:模块句柄 - 可空:N - 意思:导出一个加载成功的模块句柄 - 参数.二:lpszPluginFile - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:插件模块路径 - 参数.三:pSt_PluginParameter - In/Out:In - 类型:数据结构指针 - 可空:Y - 意思:输入插件初始化参数 -返回值 - 类型:逻辑型 - 意思:是否成功添加 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_LuaCore_Push(XNETHANDLE* pxhModule, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter = NULL); -/******************************************************************** -函数名称:ModulePlugin_LuaCore_Exec -函数功能:执行一次 - 参数.一:xhModule - In/Out:In - 类型:句柄 - 可空:N - 意思:输入模块句柄 - 参数.二:pppHDRList - In/Out:In - 类型:三级指针 - 可空:N - 意思:HTTP请求的URL参数列表 - 参数.三:nListCount - In/Out:In - 类型:整数型 - 可空:N - 意思:输入列表个数 - 参数.四:pInt_HTTPCode - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出返回的HTTPCODE值 - 参数.五:ptszMsgBuffer - In/Out:Out - 类型:字符指针 - 可空:N - 意思:输出负载的内容 - 参数.六:pInt_MsgLen - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出内容大小 - 参数.七:lpszMsgBufer - In/Out:Out - 类型:常量字符指针 - 可空:Y - 意思:输入负载内容 - 参数.八:nMsgLen - In/Out:Out - 类型:整数型指针 - 可空:Y - 意思:输入负载大小 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_LuaCore_Exec(XNETHANDLE xhModule, XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBufer = NULL, int nMsgLen = 0); -/******************************************************************** -函数名称:ModulePlugin_LuaCore_Get -函数功能:获取插件基础信息函数 - 参数.一:xhModule - In/Out:In - 类型:句柄 - 可空:N - 意思:要操作的模块句柄 - 参数.二:ptszPluginName - In/Out:Out - 类型:字符指针 - 可空:N - 意思:处理名称 - 参数.三:ptszPluginVersion - In/Out:Out - 类型:字符指针 - 可空:N - 意思:版本号.使用x.x.x.x 格式 - 参数.四:ptszPluginAuthor - In/Out:Out - 类型:字符指针 - 可空:N - 意思:作者 - 参数.五:ptszPluginDesc - In/Out:Out - 类型:字符指针 - 可空:N - 意思:插件描述 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_LuaCore_Get(XNETHANDLE xhModule, XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc); -/******************************************************************** -函数名称:ModulePlugin_LuaCore_Destroy -函数功能:销毁插件核心并且清理资源 -返回值 - 类型:逻辑型 - 意思:是否成功销毁 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_LuaCore_Destroy(); -/********************************************************************************* -* 加载器导出函数定义 * -*********************************************************************************/ -/******************************************************************** -函数名称:ModulePlugin_Loader_Init -函数功能:初始化插件加载器 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_Loader_Init(); -/******************************************************************** -函数名称:ModulePlugin_Loader_Insert -函数功能:插入一个模块到加载器 - 参数.一:lpszModuleName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:插件路径 - 参数.二:nType - In/Out:In - 类型:整数型 - 可空:N - 意思:0为lib,1为lua - 参数.三:pSt_PluginParameter - In/Out:In - 类型:数据结构指针 - 可空:Y - 意思:输入插件初始化参数 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_Loader_Insert(LPCXSTR lpszModuleName, int nType, XENGINE_PLUGINPARAM* pSt_PluginParameter = NULL); -/******************************************************************** -函数名称:ModulePlugin_Loader_Find -函数功能:查找方法是否注册 - 参数.一:lpszMethodName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要执行的方法 - 参数.二:pInt_Type - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出获取到的模块类型 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_Loader_Find(LPCXSTR lpszMethodName, int* pInt_Type); -/******************************************************************** -函数名称:ModulePlugin_LibCore_Get -函数功能:获取插件基础信息函数 - 参数.一:lpszMethodName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:要操作的模块句柄 - 参数.二:ptszPluginName - In/Out:Out - 类型:字符指针 - 可空:N - 意思:处理名称 - 参数.三:ptszPluginVersion - In/Out:Out - 类型:字符指针 - 可空:N - 意思:版本号.使用x.x.x.x 格式 - 参数.四:ptszPluginAuthor - In/Out:Out - 类型:字符指针 - 可空:N - 意思:作者 - 参数.五:ptszPluginDesc - In/Out:Out - 类型:字符指针 - 可空:N - 意思:插件描述 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_Loader_Get(LPCXSTR lpszMethodName, XCHAR* ptszPluginName = NULL, XCHAR* ptszPluginVersion = NULL, XCHAR* ptszPluginAuthor = NULL, XCHAR* ptszPluginDesc = NULL); -/******************************************************************** -函数名称:ModulePlugin_Loader_GetForModule -函数功能:通过模块名称获取模块信息 - 参数.一:lpszModuleName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:要操作的模块名称 - 参数.二:ptszPluginName - In/Out:Out - 类型:字符指针 - 可空:N - 意思:处理名称 - 参数.三:ptszPluginVersion - In/Out:Out - 类型:字符指针 - 可空:N - 意思:版本号.使用x.x.x.x 格式 - 参数.四:ptszPluginAuthor - In/Out:Out - 类型:字符指针 - 可空:N - 意思:作者 - 参数.五:ptszPluginDesc - In/Out:Out - 类型:字符指针 - 可空:N - 意思:插件描述 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_Loader_GetForModule(LPCXSTR lpszModuleName, XCHAR* ptszPluginName = NULL, XCHAR* ptszPluginVersion = NULL, XCHAR* ptszPluginAuthor = NULL, XCHAR* ptszPluginDesc = NULL); -/******************************************************************** -函数名称:ModulePlugin_Loader_Exec -函数功能:执行一次插件 - 参数.一:lpszMethodName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要执行的方法 - 参数.二:pppHDRList - In/Out:In - 类型:三级指针 - 可空:N - 意思:HTTP请求的URL参数列表 - 参数.三:nListCount - In/Out:In - 类型:整数型 - 可空:N - 意思:输入列表个数 - 参数.四:pInt_HTTPCode - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出返回的HTTPCODE值 - 参数.五:ptszMsgBuffer - In/Out:Out - 类型:字符指针 - 可空:N - 意思:输出负载的内容 - 参数.六:pInt_MsgLen - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出内容大小 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_Loader_Exec(LPCXSTR lpszMethodName, XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen); -/******************************************************************** -函数名称:ModulePlugin_Loader_Destory -函数功能:销毁加载器 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" bool ModulePlugin_Loader_Destory(); \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Error.h b/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Error.h deleted file mode 100644 index 45e487c..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Error.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2022/04/20 16:19:38 -// File Name: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_Error.h -// File Path: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin -// File Base: ModulePlugin_Error -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 插件核心错误导出定义 -// History: -*********************************************************************/ -////////////////////////////////////////////////////////////////////////// -// 错误定义 -////////////////////////////////////////////////////////////////////////// -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_PARAMENT 0xE1001 //参数错误 -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_OPENDL 0xE1002 //打开模块插件失败 -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPINIT 0xE1003 //查找初始化函数失败 -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPUNINIT 0xE1004 //查找卸载函数失败 -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPCALL 0xE1005 //查找调用执行功能函数失败 -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPERROR 0xE1006 //获取错误函数失败 -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_INIT 0xE1007 //初始化内部模块失败 -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_NOTFOUND 0xE1008 //没有找到句柄 -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_ISINITED 0xE1009 //已经初始化了,不需要再次初始化 -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_EXECTION 0xE100A //插件执行失败 -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_MALLOC 0xE100B //申请内存失败 -#define ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_GETINFO 0xE100C //获取插件信息失败 \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LibCore/ModulePlugin_LibCore.cpp b/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LibCore/ModulePlugin_LibCore.cpp deleted file mode 100644 index 2d6ab94..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LibCore/ModulePlugin_LibCore.cpp +++ /dev/null @@ -1,370 +0,0 @@ -#include "pch.h" -#include "ModulePlugin_LibCore.h" -/******************************************************************** -// Created: 2022/11/30 16:16:54 -// File Name: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_LibCore\ModulePlugin_LibCore.cpp -// File Path: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_LibCore -// File Base: ModulePlugin_LibCore -// File Ext: cpp -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 插件核心架构实现 -// History: -*********************************************************************/ -CModulePlugin_LibCore::CModulePlugin_LibCore() -{ - bIsInit = false; -} -CModulePlugin_LibCore::~CModulePlugin_LibCore() -{ -} -////////////////////////////////////////////////////////////////////////// -// 公有函数 -////////////////////////////////////////////////////////////////////////// -/******************************************************************** -函数名称:ModulePlugin_LibCore_Init -函数功能:初始化插件核心系统 -返回值 - 类型:逻辑型 - 意思:是否成功初始化 -备注: -*********************************************************************/ -bool CModulePlugin_LibCore::ModulePlugin_LibCore_Init() -{ - ModulePlugin_IsErrorOccur = false; - //判断是否初始化 - if (bIsInit) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_ISINITED; - return false; - } - //启动线程 - bIsInit = true; - return true; -} -/******************************************************************** -函数名称:ModulePlugin_LibCore_Push -函数功能:添加一个标准的插件到插件框架中 - 参数.一:pxhModule - In/Out:Out - 类型:模块句柄 - 可空:N - 意思:导出一个加载成功的模块句柄 - 参数.二:lpszPluginFile - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:插件模块路径 - 参数.三:pSt_PluginParameter - In/Out:In - 类型:数据结构指针 - 可空:Y - 意思:输入插件初始化参数 -返回值 - 类型:逻辑型 - 意思:是否成功添加 -备注: -*********************************************************************/ -bool CModulePlugin_LibCore::ModulePlugin_LibCore_Push(XNETHANDLE* pxhModule, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter) -{ - ModulePlugin_IsErrorOccur = false; - - if (!BaseLib_Handle_Create(pxhModule)) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!ModulePlugin_LibCore_Add(*pxhModule, lpszPluginFile, pSt_PluginParameter)) - { - return false; - } - return true; -} -/******************************************************************** -函数名称:ModulePlugin_LibCore_Exec -函数功能:执行一次 - 参数.一:xhModule - In/Out:In - 类型:句柄 - 可空:N - 意思:输入模块句柄 - 参数.二:pppHDRList - In/Out:In - 类型:三级指针 - 可空:N - 意思:HTTP请求的URL参数列表 - 参数.三:nListCount - In/Out:In - 类型:整数型 - 可空:N - 意思:输入列表个数 - 参数.四:pInt_HTTPCode - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出返回的HTTPCODE值 - 参数.五:ptszMsgBuffer - In/Out:Out - 类型:字符指针 - 可空:N - 意思:输出负载的内容 - 参数.六:pInt_MsgLen - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出内容大小 - 参数.七:lpszMsgBufer - In/Out:Out - 类型:常量字符指针 - 可空:Y - 意思:输入负载内容 - 参数.八:nMsgLen - In/Out:Out - 类型:整数型指针 - 可空:Y - 意思:输入负载大小 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CModulePlugin_LibCore::ModulePlugin_LibCore_Exec(XNETHANDLE xhModule, XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBufer /* = NULL */, int nMsgLen /* = 0 */) -{ - ModulePlugin_IsErrorOccur = false; - - st_csStl.lock_shared(); - //执行指定插件函数 - unordered_map::const_iterator stl_MapIterator = stl_MapFrameWork.find(xhModule); - if (stl_MapIterator == stl_MapFrameWork.end()) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_NOTFOUND; - st_csStl.unlock_shared(); - return false; - } - if (!stl_MapIterator->second.fpCall_PluginCore_Call(pppHDRList, nListCount, pInt_HTTPCode, ptszMsgBuffer, pInt_MsgLen, lpszMsgBufer, nMsgLen)) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = stl_MapIterator->second.fpCall_PluginCore_GetLastError(); - st_csStl.unlock_shared(); - return false; - } - st_csStl.unlock_shared(); - - return true; -} -/******************************************************************** -函数名称:ModulePlugin_LibCore_Get -函数功能:获取插件基础信息函数 - 参数.一:xhModule - In/Out:In - 类型:句柄 - 可空:N - 意思:要操作的模块句柄 - 参数.二:ptszPluginName - In/Out:Out - 类型:字符指针 - 可空:N - 意思:处理名称 - 参数.三:ptszPluginVersion - In/Out:Out - 类型:字符指针 - 可空:N - 意思:版本号.使用x.x.x.x 格式 - 参数.四:ptszPluginAuthor - In/Out:Out - 类型:字符指针 - 可空:N - 意思:作者 - 参数.五:ptszPluginDesc - In/Out:Out - 类型:字符指针 - 可空:N - 意思:插件描述 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CModulePlugin_LibCore::ModulePlugin_LibCore_Get(XNETHANDLE xhModule, XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc) -{ - ModulePlugin_IsErrorOccur = false; - - st_csStl.lock_shared(); - //执行指定插件函数 - unordered_map::const_iterator stl_MapIterator = stl_MapFrameWork.find(xhModule); - if (stl_MapIterator == stl_MapFrameWork.end()) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_NOTFOUND; - st_csStl.unlock_shared(); - return false; - } - _tcsxcpy(ptszPluginName, stl_MapIterator->second.tszModuleName); - _tcsxcpy(ptszPluginVersion, stl_MapIterator->second.tszModuleVer); - _tcsxcpy(ptszPluginAuthor, stl_MapIterator->second.tszModuleAuthor); - _tcsxcpy(ptszPluginDesc, stl_MapIterator->second.tszModuleDesc); - st_csStl.unlock_shared(); - - return true; -} -/******************************************************************** -函数名称:ModulePlugin_LibCore_Destroy -函数功能:销毁插件核心并且清理资源 -返回值 - 类型:逻辑型 - 意思:是否成功销毁 -备注: -*********************************************************************/ -bool CModulePlugin_LibCore::ModulePlugin_LibCore_Destroy() -{ - ModulePlugin_IsErrorOccur = false; - - //判断是否初始化 - if (!bIsInit) - { - return true; - } - bIsInit = false; - //清理STL元素空间 - st_csStl.lock(); - unordered_map::iterator stl_MapIterator = stl_MapFrameWork.begin(); - for (; stl_MapIterator != stl_MapFrameWork.end(); stl_MapIterator++) - { - stl_MapIterator->second.fpCall_PluginCore_UnInit(); - XFreeModule(stl_MapIterator->second.mhFile); - } - stl_MapFrameWork.clear(); - st_csStl.unlock(); - return true; -} -////////////////////////////////////////////////////////////////////////// -// 保护函数 -////////////////////////////////////////////////////////////////////////// -/******************************************************************** -函数名称:ModulePlugin_LibCore_Add -函数功能:添加一个指定模块到插件核心系统当中 - 参数.一:xhNet - In/Out:In - 类型:模块句柄 - 可空:N - 意思:输入一个新的模块句柄 - 参数.二:lpszPluginFile - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:插件模块路径 - 参数.三:pSt_PluginParameter - In/Out:In - 类型:数据结构指针 - 可空:Y - 意思:输入插件初始化参数 -返回值 - 类型:逻辑型 - 意思:是否成功执行 -备注: -*********************************************************************/ -bool CModulePlugin_LibCore::ModulePlugin_LibCore_Add(XNETHANDLE xhNet, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter) -{ - ModulePlugin_IsErrorOccur = false; - - if (NULL == lpszPluginFile) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_PARAMENT; - return false; - } - PLUGINCORE_FRAMEWORK st_FrameWork = {}; - //打开一个模块 -#ifdef _MSC_BUILD - st_FrameWork.mhFile = LoadLibraryA(lpszPluginFile); -#else - st_FrameWork.mhFile = dlopen(lpszPluginFile, RTLD_LAZY); -#endif - if (NULL == st_FrameWork.mhFile) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_OPENDL; - return false; - } - //开始查找模块中的函数 -#ifdef _MSC_BUILD - st_FrameWork.fpCall_PluginCore_Init = (FPCall_PluginCore_Init)GetProcAddress(st_FrameWork.mhFile, "PluginCore_Init"); -#else - * (void**)(&st_FrameWork.fpCall_PluginCore_Init) = dlsym(st_FrameWork.mhFile, _X("PluginCore_Init")); -#endif - if (NULL == st_FrameWork.fpCall_PluginCore_Init) - { - XFreeModule(st_FrameWork.mhFile); - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPINIT; - return false; - } -#ifdef _MSC_BUILD - st_FrameWork.fpCall_PluginCore_UnInit = (FPCall_PluginCore_UnInit)GetProcAddress(st_FrameWork.mhFile, "PluginCore_UnInit"); -#else - * (void**)(&st_FrameWork.fpCall_PluginCore_UnInit) = dlsym(st_FrameWork.mhFile, _X("PluginCore_UnInit")); -#endif - if (NULL == st_FrameWork.fpCall_PluginCore_UnInit) - { - XFreeModule(st_FrameWork.mhFile); - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPUNINIT; - return false; - } -#ifdef _MSC_BUILD - st_FrameWork.fpCall_PluginCore_Call = (FPCall_PluginCore_Call)GetProcAddress(st_FrameWork.mhFile, "PluginCore_Call"); -#else - * (void**)(&st_FrameWork.fpCall_PluginCore_Call) = dlsym(st_FrameWork.mhFile, _X("PluginCore_Call")); -#endif - if (NULL == st_FrameWork.fpCall_PluginCore_Call) - { - XFreeModule(st_FrameWork.mhFile); - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPCALL; - return false; - } -#ifdef _MSC_BUILD - st_FrameWork.fpCall_PluginCore_GetLastError = (FPCall_PluginCore_GetLastError)GetProcAddress(st_FrameWork.mhFile, _X("PluginCore_GetLastError")); -#else - * (void**)(&st_FrameWork.fpCall_PluginCore_GetLastError) = dlsym(st_FrameWork.mhFile, _X("PluginCore_GetLastError")); -#endif - if (NULL == st_FrameWork.fpCall_PluginCore_GetLastError) - { - XFreeModule(st_FrameWork.mhFile); - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPERROR; - return false; - } -#ifdef _MSC_BUILD - st_FrameWork.fpCall_PluginCore_GetInfo = (FPCall_PluginCore_GetInfo)GetProcAddress(st_FrameWork.mhFile, _X("PluginCore_GetInfo")); -#else - * (void**)(&st_FrameWork.fpCall_PluginCore_GetInfo) = dlsym(st_FrameWork.mhFile, _X("PluginCore_GetInfo")); -#endif - if (NULL == st_FrameWork.fpCall_PluginCore_GetInfo) - { - XFreeModule(st_FrameWork.mhFile); - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPERROR; - return false; - } - //初始化内部模块 - if (!st_FrameWork.fpCall_PluginCore_Init(pSt_PluginParameter)) - { - XFreeModule(st_FrameWork.mhFile); - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_INIT; - return false; - } - //获得内部模块信息 - st_FrameWork.fpCall_PluginCore_GetInfo(st_FrameWork.tszModuleName, st_FrameWork.tszModuleVer, st_FrameWork.tszModuleAuthor, st_FrameWork.tszModuleDesc); - _tcsxcpy(st_FrameWork.tszModuleFile, lpszPluginFile); - - //添加模块属性到STL函数中 - st_csStl.lock(); - stl_MapFrameWork.insert(make_pair(xhNet, st_FrameWork)); - st_csStl.unlock(); - return true; -} \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LibCore/ModulePlugin_LibCore.h b/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LibCore/ModulePlugin_LibCore.h deleted file mode 100644 index c5d8c45..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LibCore/ModulePlugin_LibCore.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2022/11/30 16:16:35 -// File Name: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_LibCore\ModulePlugin_LibCore.h -// File Path: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_LibCore -// File Base: ModulePlugin_LibCore -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 插件核心架构定义 -// History: -*********************************************************************/ -typedef bool(*FPCall_PluginCore_Init)(XENGINE_PLUGINPARAM* pSt_PluginParameter); -typedef void(*FPCall_PluginCore_UnInit)(); -typedef void(*FPCall_PluginCore_GetInfo)(XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc); -typedef bool(*FPCall_PluginCore_Call)(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBufer, int nMsgLen); -typedef XLONG(*FPCall_PluginCore_GetLastError)(); - -typedef struct -{ -#ifdef _MSC_BUILD - HMODULE mhFile; -#else - void* mhFile; -#endif - XCHAR tszModuleFile[XPATH_MAX]; - XCHAR tszModuleName[128]; - XCHAR tszModuleAuthor[128]; - XCHAR tszModuleDesc[128]; - XCHAR tszModuleVer[64]; - - bool(*fpCall_PluginCore_Init)(XENGINE_PLUGINPARAM* pSt_PluginParameter); - void(*fpCall_PluginCore_UnInit)(); - void(*fpCall_PluginCore_GetInfo)(XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc); - bool(*fpCall_PluginCore_Call)(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBufer, int nMsgLen); - XLONG(*fpCall_PluginCore_GetLastError)(); -}PLUGINCORE_FRAMEWORK, * LPPLUGINCORE_FRAMEWORK; - -class CModulePlugin_LibCore -{ -public: - CModulePlugin_LibCore(); - ~CModulePlugin_LibCore(); -public: - bool ModulePlugin_LibCore_Init(); - bool ModulePlugin_LibCore_Push(XNETHANDLE* pxhModule, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter = NULL); - bool ModulePlugin_LibCore_Exec(XNETHANDLE xhModule, XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBufer = NULL, int nMsgLen = 0); - bool ModulePlugin_LibCore_Get(XNETHANDLE xhModule, XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc); - bool ModulePlugin_LibCore_Destroy(); -protected: - bool ModulePlugin_LibCore_Add(XNETHANDLE xhNet, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter = NULL); -private: - bool bIsInit; -private: - shared_mutex st_csStl; -private: - unordered_map stl_MapFrameWork; -}; diff --git a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Loader/ModulePlugin_Loader.cpp b/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Loader/ModulePlugin_Loader.cpp deleted file mode 100644 index 588bab8..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Loader/ModulePlugin_Loader.cpp +++ /dev/null @@ -1,383 +0,0 @@ -#include "pch.h" -#include "ModulePlugin_Loader.h" -/******************************************************************** -// Created: 2022/04/20 16:36:01 -// File Name: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_Loader\ModulePlugin_Loader.cpp -// File Path: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_Loader -// File Base: ModulePlugin_Loader -// File Ext: cpp -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 插件加载工具 -// History: -*********************************************************************/ -CModulePlugin_Loader::CModulePlugin_Loader() -{ -} -CModulePlugin_Loader::~CModulePlugin_Loader() -{ -} -////////////////////////////////////////////////////////////////////////// -// 公有函数 -////////////////////////////////////////////////////////////////////////// -/******************************************************************** -函数名称:ModulePlugin_Loader_Init -函数功能:初始化插件加载器 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CModulePlugin_Loader::ModulePlugin_Loader_Init() -{ - ModulePlugin_LibCore_Init(); - ModulePlugin_LuaCore_Init(); - - return true; -} -/******************************************************************** -函数名称:ModulePlugin_Loader_Insert -函数功能:插入一个模块到加载器 - 参数.一:lpszModuleName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:插件路径 - 参数.二:nType - In/Out:In - 类型:整数型 - 可空:N - 意思:0为lib,1为lua - 参数.三:pSt_PluginParameter - In/Out:In - 类型:数据结构指针 - 可空:Y - 意思:输入插件初始化参数 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CModulePlugin_Loader::ModulePlugin_Loader_Insert(LPCXSTR lpszModuleName, int nType, XENGINE_PLUGINPARAM* pSt_PluginParameter /* = NULL */) -{ - ModulePlugin_IsErrorOccur = false; - - if (NULL == lpszModuleName) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_PARAMENT; - return false; - } - PLUGINCORE_LOADER st_PluginLoader; - memset(&st_PluginLoader, '\0', sizeof(PLUGINCORE_LOADER)); - - st_PluginLoader.nType = nType; - _tcsxcpy(st_PluginLoader.tszModuleFile, lpszModuleName); - - if (0 == nType) - { - if (!ModulePlugin_LibCore_Push(&st_PluginLoader.xhToken, lpszModuleName, pSt_PluginParameter)) - { - return false; - } - ModulePlugin_LibCore_Get(st_PluginLoader.xhToken, st_PluginLoader.tszModuleName, st_PluginLoader.tszModuleVer, st_PluginLoader.tszModuleAuthor, st_PluginLoader.tszModuleDesc); - } - else - { - if (!ModulePlugin_LuaCore_Push(&st_PluginLoader.xhToken, lpszModuleName, pSt_PluginParameter)) - { - return false; - } - ModulePlugin_LuaCore_Get(st_PluginLoader.xhToken, st_PluginLoader.tszModuleName, st_PluginLoader.tszModuleVer, st_PluginLoader.tszModuleAuthor, st_PluginLoader.tszModuleDesc); - } - - st_Locker.lock(); - stl_MapLoader.insert(make_pair(st_PluginLoader.tszModuleName, st_PluginLoader)); - st_Locker.unlock(); - return true; -} -/******************************************************************** -函数名称:ModulePlugin_Loader_Find -函数功能:查找方法是否注册 - 参数.一:lpszMethodName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要执行的方法 - 参数.二:pInt_Type - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出获取到的模块类型 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CModulePlugin_Loader::ModulePlugin_Loader_Find(LPCXSTR lpszMethodName, int* pInt_Type) -{ - ModulePlugin_IsErrorOccur = false; - - if (NULL == lpszMethodName) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_PARAMENT; - return false; - } - st_Locker.lock_shared(); - unordered_map::const_iterator stl_MapIterator = stl_MapLoader.find(lpszMethodName); - if (stl_MapIterator == stl_MapLoader.end()) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_NOTFOUND; - st_Locker.unlock_shared(); - return false; - } - if (NULL != pInt_Type) - { - *pInt_Type = stl_MapIterator->second.nType; - } - st_Locker.unlock_shared(); - return true; -} -/******************************************************************** -函数名称:ModulePlugin_LibCore_Get -函数功能:获取插件基础信息函数 - 参数.一:lpszMethodName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:要操作的模块句柄 - 参数.二:ptszPluginName - In/Out:Out - 类型:字符指针 - 可空:N - 意思:处理名称 - 参数.三:ptszPluginVersion - In/Out:Out - 类型:字符指针 - 可空:N - 意思:版本号.使用x.x.x.x 格式 - 参数.四:ptszPluginAuthor - In/Out:Out - 类型:字符指针 - 可空:N - 意思:作者 - 参数.五:ptszPluginDesc - In/Out:Out - 类型:字符指针 - 可空:N - 意思:插件描述 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CModulePlugin_Loader::ModulePlugin_Loader_Get(LPCXSTR lpszMethodName, XCHAR* ptszPluginName /* = NULL */, XCHAR* ptszPluginVersion /* = NULL */, XCHAR* ptszPluginAuthor /* = NULL */, XCHAR* ptszPluginDesc /* = NULL */) -{ - ModulePlugin_IsErrorOccur = false; - - if (NULL == ptszPluginName || NULL == ptszPluginVersion || NULL == ptszPluginAuthor || NULL == ptszPluginDesc) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_PARAMENT; - return false; - } - st_Locker.lock_shared(); - unordered_map::const_iterator stl_MapIterator = stl_MapLoader.find(lpszMethodName); - if (stl_MapIterator == stl_MapLoader.end()) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_NOTFOUND; - st_Locker.unlock_shared(); - return false; - } - if (NULL != ptszPluginName) - { - _tcsxcpy(ptszPluginName, stl_MapIterator->second.tszModuleName); - } - if (NULL != ptszPluginVersion) - { - _tcsxcpy(ptszPluginVersion, stl_MapIterator->second.tszModuleVer); - } - if (NULL != ptszPluginAuthor) - { - _tcsxcpy(ptszPluginAuthor, stl_MapIterator->second.tszModuleAuthor); - } - if (NULL != ptszPluginDesc) - { - _tcsxcpy(ptszPluginDesc, stl_MapIterator->second.tszModuleDesc); - } - st_Locker.unlock_shared(); - return true; -} -/******************************************************************** -函数名称:ModulePlugin_Loader_GetForModule -函数功能:通过模块名称获取模块信息 - 参数.一:lpszModuleName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:要操作的模块名称 - 参数.二:ptszPluginName - In/Out:Out - 类型:字符指针 - 可空:N - 意思:处理名称 - 参数.三:ptszPluginVersion - In/Out:Out - 类型:字符指针 - 可空:N - 意思:版本号.使用x.x.x.x 格式 - 参数.四:ptszPluginAuthor - In/Out:Out - 类型:字符指针 - 可空:N - 意思:作者 - 参数.五:ptszPluginDesc - In/Out:Out - 类型:字符指针 - 可空:N - 意思:插件描述 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CModulePlugin_Loader::ModulePlugin_Loader_GetForModule(LPCXSTR lpszModuleName, XCHAR* ptszPluginName /* = NULL */, XCHAR* ptszPluginVersion /* = NULL */, XCHAR* ptszPluginAuthor /* = NULL */, XCHAR* ptszPluginDesc /* = NULL */) -{ - ModulePlugin_IsErrorOccur = false; - - bool bFound = false; - st_Locker.lock_shared(); - for (auto stl_MapIterator = stl_MapLoader.begin(); stl_MapIterator != stl_MapLoader.end(); stl_MapIterator++) - { - if (0 == _tcsxnicmp(lpszModuleName, stl_MapIterator->second.tszModuleFile, _tcsxlen(stl_MapIterator->second.tszModuleFile))) - { - if (NULL != ptszPluginName) - { - _tcsxcpy(ptszPluginName, stl_MapIterator->second.tszModuleName); - } - if (NULL != ptszPluginVersion) - { - _tcsxcpy(ptszPluginVersion, stl_MapIterator->second.tszModuleVer); - } - if (NULL != ptszPluginAuthor) - { - _tcsxcpy(ptszPluginAuthor, stl_MapIterator->second.tszModuleAuthor); - } - if (NULL != ptszPluginDesc) - { - _tcsxcpy(ptszPluginDesc, stl_MapIterator->second.tszModuleDesc); - } - bFound = true; - break; - } - } - st_Locker.unlock_shared(); - - if (!bFound) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_NOTFOUND; - return false; - } - return true; -} -/******************************************************************** -函数名称:ModulePlugin_Loader_Exec -函数功能:执行一次插件 - 参数.一:lpszMethodName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要执行的方法 - 参数.二:pppHDRList - In/Out:In - 类型:三级指针 - 可空:N - 意思:HTTP请求的URL参数列表 - 参数.三:nListCount - In/Out:In - 类型:整数型 - 可空:N - 意思:输入列表个数 - 参数.四:pInt_HTTPCode - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出返回的HTTPCODE值 - 参数.五:ptszMsgBuffer - In/Out:Out - 类型:字符指针 - 可空:N - 意思:输出负载的内容 - 参数.六:pInt_MsgLen - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出内容大小 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CModulePlugin_Loader::ModulePlugin_Loader_Exec(LPCXSTR lpszMethodName, XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen) -{ - ModulePlugin_IsErrorOccur = false; - - if (NULL == lpszMethodName) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_PARAMENT; - return false; - } - st_Locker.lock_shared(); - unordered_map::const_iterator stl_MapIterator = stl_MapLoader.find(lpszMethodName); - if (stl_MapIterator == stl_MapLoader.end()) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_NOTFOUND; - st_Locker.unlock_shared(); - return false; - } - - if (0 == stl_MapIterator->second.nType) - { - if (!ModulePlugin_LibCore_Exec(stl_MapIterator->second.xhToken, pppHDRList, nListCount, pInt_HTTPCode, ptszMsgBuffer, pInt_MsgLen)) - { - st_Locker.unlock_shared(); - return false; - } - } - else - { - if (!ModulePlugin_LuaCore_Exec(stl_MapIterator->second.xhToken, pppHDRList, nListCount, pInt_HTTPCode, ptszMsgBuffer, pInt_MsgLen)) - { - st_Locker.unlock_shared(); - return false; - } - } - st_Locker.unlock_shared(); - return true; -} -/******************************************************************** -函数名称:ModulePlugin_Loader_Destory -函数功能:销毁加载器 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CModulePlugin_Loader::ModulePlugin_Loader_Destory() -{ - ModulePlugin_IsErrorOccur = false; - - ModulePlugin_LibCore_Destroy(); - ModulePlugin_LuaCore_Destroy(); - - st_Locker.lock(); - stl_MapLoader.clear(); - st_Locker.unlock(); - return true; -} \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Loader/ModulePlugin_Loader.h b/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Loader/ModulePlugin_Loader.h deleted file mode 100644 index 35247ad..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_Loader/ModulePlugin_Loader.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2022/04/20 16:35:38 -// File Name: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_Loader\ModulePlugin_Loader.h -// File Path: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_Loader -// File Base: ModulePlugin_Loader -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 插件加载工具 -// History: -*********************************************************************/ -typedef struct -{ - XCHAR tszModuleFile[XPATH_MAX]; - XCHAR tszModuleName[128]; - XCHAR tszModuleAuthor[128]; - XCHAR tszModuleDesc[128]; - XCHAR tszModuleVer[128]; - - XNETHANDLE xhToken; - int nType; -}PLUGINCORE_LOADER, * LPPLUGINCORE_LOADER; - -class CModulePlugin_Loader -{ -public: - CModulePlugin_Loader(); - ~CModulePlugin_Loader(); -public: - bool ModulePlugin_Loader_Init(); - bool ModulePlugin_Loader_Insert(LPCXSTR lpszModuleName, int nType, XENGINE_PLUGINPARAM* pSt_PluginParameter = NULL); - bool ModulePlugin_Loader_Find(LPCXSTR lpszMethodName, int* pInt_Type); - bool ModulePlugin_Loader_Get(LPCXSTR lpszMethodName, XCHAR* ptszPluginName = NULL, XCHAR* ptszPluginVersion = NULL, XCHAR* ptszPluginAuthor = NULL, XCHAR* ptszPluginDesc = NULL); - bool ModulePlugin_Loader_GetForModule(LPCXSTR lpszModuleName, XCHAR* ptszPluginName = NULL, XCHAR* ptszPluginVersion = NULL, XCHAR* ptszPluginAuthor = NULL, XCHAR* ptszPluginDesc = NULL); - bool ModulePlugin_Loader_Exec(LPCXSTR lpszMethodName, XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen); - bool ModulePlugin_Loader_Destory(); -protected: -private: - shared_mutex st_Locker; -private: - unordered_map stl_MapLoader; -}; diff --git a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LuaCore/ModulePlugin_LuaCore.cpp b/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LuaCore/ModulePlugin_LuaCore.cpp deleted file mode 100644 index dd98a5b..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LuaCore/ModulePlugin_LuaCore.cpp +++ /dev/null @@ -1,390 +0,0 @@ -#include "pch.h" -#include "ModulePlugin_LuaCore.h" -/******************************************************************** -// Created: 2022/11/30 16:18:24 -// File Name: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_LuaCore\ModulePlugin_LuaCore.cpp -// File Path: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_LuaCore -// File Base: ModulePlugin_LuaCore -// File Ext: cpp -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: LUA脚本你插件 -// History: -*********************************************************************/ -CModulePlugin_LuaCore::CModulePlugin_LuaCore() -{ -} -CModulePlugin_LuaCore::~CModulePlugin_LuaCore() -{ -} -////////////////////////////////////////////////////////////////////////// -// 公有函数 -////////////////////////////////////////////////////////////////////////// -/******************************************************************** -函数名称:ModulePlugin_LuaCore_Init -函数功能:初始化插件核心系统 -返回值 - 类型:逻辑型 - 意思:是否成功初始化 -备注: -*********************************************************************/ -bool CModulePlugin_LuaCore::ModulePlugin_LuaCore_Init() -{ - ModulePlugin_IsErrorOccur = false; - return true; -} -/******************************************************************** -函数名称:ModulePlugin_LuaCore_Push -函数功能:添加一个标准的插件到插件框架中 - 参数.一:pxhModule - In/Out:Out - 类型:模块句柄 - 可空:N - 意思:导出一个加载成功的模块句柄 - 参数.二:lpszPluginFile - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:插件模块路径 - 参数.三:pSt_PluginParameter - In/Out:In - 类型:数据结构指针 - 可空:Y - 意思:输入插件初始化参数 -返回值 - 类型:逻辑型 - 意思:是否成功添加 -备注: -*********************************************************************/ -bool CModulePlugin_LuaCore::ModulePlugin_LuaCore_Push(XNETHANDLE* pxhModule, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter) -{ - ModulePlugin_IsErrorOccur = false; - - if (!BaseLib_Handle_Create(pxhModule)) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = BaseLib_GetLastError(); - return false; - } - if (!ModulePlugin_LuaCore_Add(*pxhModule, lpszPluginFile, pSt_PluginParameter)) - { - return false; - } - return true; -} -/******************************************************************** -函数名称:ModulePlugin_LuaCore_Exec -函数功能:执行一次 - 参数.一:xhModule - In/Out:In - 类型:句柄 - 可空:N - 意思:输入模块句柄 - 参数.二:pppHDRList - In/Out:In - 类型:三级指针 - 可空:N - 意思:HTTP请求的URL参数列表 - 参数.三:nListCount - In/Out:In - 类型:整数型 - 可空:N - 意思:输入列表个数 - 参数.四:pInt_HTTPCode - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出返回的HTTPCODE值 - 参数.五:ptszMsgBuffer - In/Out:Out - 类型:字符指针 - 可空:N - 意思:输出负载的内容 - 参数.六:pInt_MsgLen - In/Out:Out - 类型:整数型指针 - 可空:N - 意思:输出内容大小 - 参数.七:lpszMsgBufer - In/Out:Out - 类型:常量字符指针 - 可空:Y - 意思:输入负载内容 - 参数.八:nMsgLen - In/Out:Out - 类型:整数型指针 - 可空:Y - 意思:输入负载大小 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CModulePlugin_LuaCore::ModulePlugin_LuaCore_Exec(XNETHANDLE xhModule, XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBufer /* = NULL */, int nMsgLen /* = 0 */) -{ - ModulePlugin_IsErrorOccur = false; - - st_csStl.lock_shared(); - //执行指定插件函数 - unordered_map::const_iterator stl_MapIterator = stl_MapFrameWork.find(xhModule); - if (stl_MapIterator == stl_MapFrameWork.end()) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_NOTFOUND; - st_csStl.unlock_shared(); - return false; - } -#if (1 == _XENGINE_BUILD_SWITCH_LUA) - if (0 == lua_getglobal(stl_MapIterator->second.pSt_LuaState, "PluginCore_Call")) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPCALL; - st_csStl.unlock_shared(); - return false; - } - XCHAR tszURLParam[XPATH_MAX]; - memset(tszURLParam, '\0', XPATH_MAX); - - for (int i = 1; i < nListCount; i++) - { - if (i > 1) - { - _tcsxcat(tszURLParam, "&"); - } - _tcsxcat(tszURLParam, (*pppHDRList)[i]); - } - lua_pushstring(stl_MapIterator->second.pSt_LuaState, tszURLParam); - lua_pushinteger(stl_MapIterator->second.pSt_LuaState, nListCount - 1); - lua_pushstring(stl_MapIterator->second.pSt_LuaState, lpszMsgBufer); - lua_pushinteger(stl_MapIterator->second.pSt_LuaState, nMsgLen); - if (LUA_OK != lua_pcall(stl_MapIterator->second.pSt_LuaState, 4, 1, 0)) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_EXECTION; - st_csStl.unlock_shared(); - return false; - } - lua_getglobal(stl_MapIterator->second.pSt_LuaState, "PInt_HTTPCode"); - *pInt_HTTPCode = (int)lua_tonumber(stl_MapIterator->second.pSt_LuaState, -1); - lua_pop(stl_MapIterator->second.pSt_LuaState, -1); - - lua_getglobal(stl_MapIterator->second.pSt_LuaState, "PInt_MsgLen"); - *pInt_MsgLen = (int)lua_tonumber(stl_MapIterator->second.pSt_LuaState, -1); - lua_pop(stl_MapIterator->second.pSt_LuaState, -1); - - if (*pInt_MsgLen > 0) - { - lua_getglobal(stl_MapIterator->second.pSt_LuaState, "PtszMsgBuffer"); - _tcsxcpy(ptszMsgBuffer, lua_tostring(stl_MapIterator->second.pSt_LuaState, -1)); - lua_pop(stl_MapIterator->second.pSt_LuaState, -1); - } - st_csStl.unlock_shared(); -#endif - return true; -} -/******************************************************************** -函数名称:ModulePlugin_LuaCore_Get -函数功能:获取插件基础信息函数 - 参数.一:xhModule - In/Out:In - 类型:句柄 - 可空:N - 意思:要操作的模块句柄 - 参数.二:ptszPluginName - In/Out:Out - 类型:字符指针 - 可空:N - 意思:处理名称 - 参数.三:ptszPluginVersion - In/Out:Out - 类型:字符指针 - 可空:N - 意思:版本号.使用x.x.x.x 格式 - 参数.四:ptszPluginAuthor - In/Out:Out - 类型:字符指针 - 可空:N - 意思:作者 - 参数.五:ptszPluginDesc - In/Out:Out - 类型:字符指针 - 可空:N - 意思:插件描述 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -bool CModulePlugin_LuaCore::ModulePlugin_LuaCore_Get(XNETHANDLE xhModule, XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc) -{ - ModulePlugin_IsErrorOccur = false; - - st_csStl.lock_shared(); - unordered_map::const_iterator stl_MapIterator = stl_MapFrameWork.find(xhModule); - if (stl_MapIterator == stl_MapFrameWork.end()) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_NOTFOUND; - st_csStl.unlock_shared(); - return false; - } - _tcsxcpy(ptszPluginName, stl_MapIterator->second.tszModuleName); - _tcsxcpy(ptszPluginVersion, stl_MapIterator->second.tszModuleVer); - _tcsxcpy(ptszPluginAuthor, stl_MapIterator->second.tszModuleAuthor); - _tcsxcpy(ptszPluginDesc, stl_MapIterator->second.tszModuleDesc); - st_csStl.unlock_shared(); - return true; -} -/******************************************************************** -函数名称:ModulePlugin_LuaCore_Destroy -函数功能:销毁插件核心并且清理资源 -返回值 - 类型:逻辑型 - 意思:是否成功销毁 -备注: -*********************************************************************/ -bool CModulePlugin_LuaCore::ModulePlugin_LuaCore_Destroy() -{ - ModulePlugin_IsErrorOccur = false; - -#if (1 == _XENGINE_BUILD_SWITCH_LUA) - //清理STL元素空间 - st_csStl.lock(); - unordered_map::iterator stl_MapIterator = stl_MapFrameWork.begin(); - for (; stl_MapIterator != stl_MapFrameWork.end(); stl_MapIterator++) - { - lua_getglobal(stl_MapIterator->second.pSt_LuaState, "PluginCore_UnInit"); - lua_pcall(stl_MapIterator->second.pSt_LuaState, 0, 0, 0); - - lua_close(stl_MapIterator->second.pSt_LuaState); - } - stl_MapFrameWork.clear(); - st_csStl.unlock(); -#endif - return true; -} -////////////////////////////////////////////////////////////////////////// -// 保护函数 -////////////////////////////////////////////////////////////////////////// -/******************************************************************** -函数名称:ModulePlugin_LuaCore_Add -函数功能:添加一个指定模块到插件核心系统当中 - 参数.一:xhNet - In/Out:In - 类型:模块句柄 - 可空:N - 意思:输入一个新的模块句柄 - 参数.二:lpszPluginFile - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:插件模块路径 - 参数.三:pSt_PluginParameter - In/Out:In - 类型:数据结构指针 - 可空:Y - 意思:输入插件初始化参数 -返回值 - 类型:逻辑型 - 意思:是否成功执行 -备注: -*********************************************************************/ -bool CModulePlugin_LuaCore::ModulePlugin_LuaCore_Add(XNETHANDLE xhNet, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter /* = NULL */) -{ - ModulePlugin_IsErrorOccur = false; - - if (NULL == lpszPluginFile) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_PARAMENT; - return false; - } -#if (1 == _XENGINE_BUILD_SWITCH_LUA) - PLUGINCORE_LUAFRAMEWORK st_LuaCore; - memset(&st_LuaCore, '\0', sizeof(PLUGINCORE_LUAFRAMEWORK)); - - st_LuaCore.pSt_LuaState = luaL_newstate(); - _tcsxcpy(st_LuaCore.tszModuleFile, lpszPluginFile); - - if (NULL == st_LuaCore.pSt_LuaState) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_MALLOC; - return false; - } - luaL_openlibs(st_LuaCore.pSt_LuaState); - - if (LUA_OK != luaL_loadfile(st_LuaCore.pSt_LuaState, lpszPluginFile)) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_OPENDL; - return false; - } - if (LUA_OK != lua_pcall(st_LuaCore.pSt_LuaState, 0, 0, 0)) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_EXECTION; - return false; - } - //得到初始化函数 - if (0 == lua_getglobal(st_LuaCore.pSt_LuaState, "PluginCore_Init")) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPINIT; - return false; - } - lua_newtable(st_LuaCore.pSt_LuaState); - - lua_pushstring(st_LuaCore.pSt_LuaState, "APIVersion"); - lua_pushstring(st_LuaCore.pSt_LuaState, pSt_PluginParameter->tszAPIVersion); - lua_settable(st_LuaCore.pSt_LuaState, -3); - - lua_pushstring(st_LuaCore.pSt_LuaState, "XEngineVer"); - lua_pushstring(st_LuaCore.pSt_LuaState, pSt_PluginParameter->tszXEngineVer); - lua_settable(st_LuaCore.pSt_LuaState, -3); - - if (LUA_OK != lua_pcall(st_LuaCore.pSt_LuaState, 1, 1, 0)) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_EXECTION; - return false; - } - if (!lua_toboolean(st_LuaCore.pSt_LuaState, -1)) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_EXECTION; - return false; - } - lua_pop(st_LuaCore.pSt_LuaState, 1); - //得到信息函数 - if (0 == lua_getglobal(st_LuaCore.pSt_LuaState, "PluginCore_GetInfo")) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_FPINIT; - return false; - } - if (LUA_OK != lua_pcall(st_LuaCore.pSt_LuaState, 0, 4, 0)) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_EXECTION; - return false; - } - if (!lua_toboolean(st_LuaCore.pSt_LuaState, -1)) - { - ModulePlugin_IsErrorOccur = true; - ModulePlugin_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PLUGIN_EXECTION; - return false; - } - // Lua 栈从右到左是逆序压栈的,所以要从 -4 开始取 - _tcsxcpy(st_LuaCore.tszModuleName, lua_tostring(st_LuaCore.pSt_LuaState, -4)); - _tcsxcpy(st_LuaCore.tszModuleVer, lua_tostring(st_LuaCore.pSt_LuaState, -3)); - _tcsxcpy(st_LuaCore.tszModuleAuthor, lua_tostring(st_LuaCore.pSt_LuaState, -2)); - _tcsxcpy(st_LuaCore.tszModuleDesc, lua_tostring(st_LuaCore.pSt_LuaState, -1)); - lua_pop(st_LuaCore.pSt_LuaState, 4); - - st_csStl.lock(); - stl_MapFrameWork.insert(make_pair(xhNet, st_LuaCore)); - st_csStl.unlock(); -#endif - return true; -} \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LuaCore/ModulePlugin_LuaCore.h b/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LuaCore/ModulePlugin_LuaCore.h deleted file mode 100644 index 5e231cd..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/ModulePlugin_LuaCore/ModulePlugin_LuaCore.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -/******************************************************************** -// Created: 2022/11/30 16:18:00 -// File Name: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_LuaCore\ModulePlugin_LuaCore.h -// File Path: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\ModulePlugin_LuaCore -// File Base: ModulePlugin_LuaCore -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: LUA脚本你插件 -// History: -*********************************************************************/ -typedef struct -{ - XCHAR tszModuleFile[XPATH_MAX]; - XCHAR tszModuleName[128]; - XCHAR tszModuleAuthor[128]; - XCHAR tszModuleDesc[128]; - XCHAR tszModuleVer[64]; -#if (1 == _XENGINE_BUILD_SWITCH_LUA) - lua_State* pSt_LuaState; -#endif -}PLUGINCORE_LUAFRAMEWORK; - -class CModulePlugin_LuaCore -{ -public: - CModulePlugin_LuaCore(); - ~CModulePlugin_LuaCore(); -public: - bool ModulePlugin_LuaCore_Init(); - bool ModulePlugin_LuaCore_Push(XNETHANDLE* pxhModule, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter = NULL); - bool ModulePlugin_LuaCore_Exec(XNETHANDLE xhModule, XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBufer = NULL, int nMsgLen = 0); - bool ModulePlugin_LuaCore_Get(XNETHANDLE xhModule, XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc); - bool ModulePlugin_LuaCore_Destroy(); -protected: - bool ModulePlugin_LuaCore_Add(XNETHANDLE xhNet, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter = NULL); -private: - shared_mutex st_csStl; -private: - unordered_map stl_MapFrameWork; -}; diff --git a/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.def b/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.def deleted file mode 100644 index 8ebbc95..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.def +++ /dev/null @@ -1,24 +0,0 @@ -LIBRARY - -EXPORTS - ModulePlugin_GetLastError - - ModulePlugin_LibCore_Init - ModulePlugin_LibCore_Push - ModulePlugin_LibCore_Exec - ModulePlugin_LibCore_Get - ModulePlugin_LibCore_Destroy - - ModulePlugin_LuaCore_Init - ModulePlugin_LuaCore_Push - ModulePlugin_LuaCore_Exec - ModulePlugin_LuaCore_Get - ModulePlugin_LuaCore_Destroy - - ModulePlugin_Loader_Init - ModulePlugin_Loader_Insert - ModulePlugin_Loader_Find - ModulePlugin_Loader_Get - ModulePlugin_Loader_GetForModule - ModulePlugin_Loader_Exec - ModulePlugin_Loader_Destory \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj b/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj deleted file mode 100644 index 81d9142..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj +++ /dev/null @@ -1,270 +0,0 @@ - - - - - Debug - ARM64 - - - Debug - Win32 - - - Release - ARM64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {cb443280-e283-44cd-b956-52c404a51db6} - XEngineModulePlugin - 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - true - $(XEngine_Include);..\XEngine_ModulePlugin;$(IncludePath) - $(XEngine_Lib32);$(LibraryPath) - - - false - $(XEngine_Include);$(IncludePath) - $(XEngine_Lib32);$(LibraryPath) - - - true - $(XEngine_Include);../../XEngine_ThirdPart/jsoncpp;..\XEngine_ModulePlugin;$(IncludePath) - $(XEngine_Lib64);$(LibraryPath) - - - true - $(XEngine_Include);../../XEngine_ThirdPart/jsoncpp;..\XEngine_ModulePlugin;$(IncludePath) - $(XEngine_LibArm64);$(LibraryPath) - - - false - $(XEngine_Include);../../XEngine_ThirdPart/jsoncpp;$(IncludePath) - $(XEngine_Lib64);$(LibraryPath) - - - false - $(XEngine_Include);../../XEngine_ThirdPart/jsoncpp;$(IncludePath) - $(XEngine_LibArm64);$(LibraryPath) - - - - Level3 - true - WIN32;_DEBUG;XENGINEMODULEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - - - Windows - true - false - XEngine_ModulePlugin.def - - - - - Level3 - true - true - true - WIN32;NDEBUG;XENGINEMODULEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - /utf-8 %(AdditionalOptions) - - - Windows - true - true - true - false - XEngine_ModulePlugin.def - - - - - Level3 - true - _DEBUG;XENGINEMODULEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - - - Windows - true - false - XEngine_ModulePlugin.def - - - - - Level3 - true - _DEBUG;XENGINEMODULEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - - - Windows - true - false - XEngine_ModulePlugin.def - - - - - Level3 - true - true - true - NDEBUG;XENGINEMODULEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - /utf-8 %(AdditionalOptions) - - - Windows - true - true - true - false - XEngine_ModulePlugin.def - - - - - Level3 - true - true - true - NDEBUG;XENGINEMODULEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - Use - pch.h - /utf-8 %(AdditionalOptions) - - - Windows - true - true - true - false - XEngine_ModulePlugin.def - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj.filters b/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj.filters deleted file mode 100644 index 85756ef..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj.filters +++ /dev/null @@ -1,80 +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 - - - {5fd6b4af-2a78-499a-ab04-ab8643823743} - - - {c2bcf30b-a119-4ab5-85e5-2c16ca255b9a} - - - {716c1e27-8905-4321-a369-67cf7462cb08} - - - {c455a41d-68d1-42be-a090-0df10d4de4ed} - - - {41da9b84-643e-4284-9018-62fae573d971} - - - {8a2f82d7-3a16-438f-8533-84d44cee2ff2} - - - - - 头文件 - - - 头文件 - - - 头文件 - - - 头文件 - - - 头文件\ModulePlugin_Loader - - - 头文件\ModulePlugin_LibCore - - - 头文件\ModulePlugin_LuaCore - - - - - 源文件 - - - 源文件 - - - 源文件\ModulePlugin_Loader - - - 源文件\ModulePlugin_LibCore - - - 源文件\ModulePlugin_LuaCore - - - - - 源文件 - - - \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj.user b/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj.user deleted file mode 100644 index 88a5509..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/XEngine_ModulePlugin.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModulePlugin/dllmain.cpp b/XEngine_Source/XEngine_ModulePlugin/dllmain.cpp deleted file mode 100644 index 594ff21..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/dllmain.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// dllmain.cpp : 定义 DLL 应用程序的入口点。 -#include "pch.h" - -bool APIENTRY DllMain( HMODULE hModule, - XLONG ul_reason_for_call, - XPVOID 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/XEngine_ModulePlugin/framework.h b/XEngine_Source/XEngine_ModulePlugin/framework.h deleted file mode 100644 index 80cbbc9..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/framework.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 -// Windows 头文件 -#include diff --git a/XEngine_Source/XEngine_ModulePlugin/pch.cpp b/XEngine_Source/XEngine_ModulePlugin/pch.cpp deleted file mode 100644 index a5bd426..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/pch.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "pch.h" -#include "ModulePlugin_LibCore/ModulePlugin_LibCore.h" -#include "ModulePlugin_LuaCore/ModulePlugin_LuaCore.h" -#include "ModulePlugin_Loader/ModulePlugin_Loader.h" -/******************************************************************** -// Created: 2022/04/20 16:39:27 -// File Name: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\pch.cpp -// File Path: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin -// File Base: pch -// File Ext: cpp -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 插件核心导出函数实现 -// History: -*********************************************************************/ -bool ModulePlugin_IsErrorOccur = false; -XLONG ModulePlugin_dwErrorCode = 0; -////////////////////////////////////////////////////////////////////////// -CModulePlugin_LibCore m_PluginLib; -CModulePlugin_LuaCore m_PluginLua; -CModulePlugin_Loader m_PluginLoader; -////////////////////////////////////////////////////////////////////////// -// 导出函数实现 -////////////////////////////////////////////////////////////////////////// -extern "C" XLONG ModulePlugin_GetLastError(int* pInt_SysError) -{ - if (NULL != pInt_SysError) - { - *pInt_SysError = errno; - } - return ModulePlugin_dwErrorCode; -} -/********************************************************************************* -* 插件框架导出函数定义 * -*********************************************************************************/ -extern "C" bool ModulePlugin_LibCore_Init() -{ - return m_PluginLib.ModulePlugin_LibCore_Init(); -} -extern "C" bool ModulePlugin_LibCore_Push(XNETHANDLE * pxhModule, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter) -{ - return m_PluginLib.ModulePlugin_LibCore_Push(pxhModule, lpszPluginFile, pSt_PluginParameter); -} -extern "C" bool ModulePlugin_LibCore_Exec(XNETHANDLE xhModule, XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBufer, int nMsgLen) -{ - return m_PluginLib.ModulePlugin_LibCore_Exec(xhModule, pppHDRList, nListCount, pInt_HTTPCode, ptszMsgBuffer, pInt_MsgLen); -} -extern "C" bool ModulePlugin_LibCore_Get(XNETHANDLE xhModule, XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc) -{ - return m_PluginLib.ModulePlugin_LibCore_Get(xhModule, ptszPluginName, ptszPluginVersion, ptszPluginAuthor, ptszPluginDesc); -} -extern "C" bool ModulePlugin_LibCore_Destroy() -{ - return m_PluginLib.ModulePlugin_LibCore_Destroy(); -} -/********************************************************************************* -* LUA插件框架导出函数定义 * -*********************************************************************************/ -extern "C" bool ModulePlugin_Loader_Init() -{ - return m_PluginLoader.ModulePlugin_Loader_Init(); -} -extern "C" bool ModulePlugin_LuaCore_Init() -{ - return m_PluginLua.ModulePlugin_LuaCore_Init(); -} -extern "C" bool ModulePlugin_LuaCore_Push(XNETHANDLE * pxhModule, LPCXSTR lpszPluginFile, XENGINE_PLUGINPARAM* pSt_PluginParameter) -{ - return m_PluginLua.ModulePlugin_LuaCore_Push(pxhModule, lpszPluginFile, pSt_PluginParameter); -} -extern "C" bool ModulePlugin_LuaCore_Exec(XNETHANDLE xhModule, XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBufer, int nMsgLen) -{ - return m_PluginLua.ModulePlugin_LuaCore_Exec(xhModule, pppHDRList, nListCount, pInt_HTTPCode, ptszMsgBuffer, pInt_MsgLen, lpszMsgBufer, nMsgLen); -} -extern "C" bool ModulePlugin_LuaCore_Get(XNETHANDLE xhModule, XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc) -{ - return m_PluginLua.ModulePlugin_LuaCore_Get(xhModule, ptszPluginName, ptszPluginVersion, ptszPluginAuthor, ptszPluginDesc); -} -extern "C" bool ModulePlugin_LuaCore_Destroy() -{ - return m_PluginLua.ModulePlugin_LuaCore_Destroy(); -} -/********************************************************************************* -* 加载器导出函数定义 * -*********************************************************************************/ -extern "C" bool ModulePlugin_Loader_Insert(LPCXSTR lpszModuleName, int nType, XENGINE_PLUGINPARAM* pSt_PluginParameter) -{ - return m_PluginLoader.ModulePlugin_Loader_Insert(lpszModuleName, nType, pSt_PluginParameter); -} -extern "C" bool ModulePlugin_Loader_Find(LPCXSTR lpszMethodName, int* pInt_Type) -{ - return m_PluginLoader.ModulePlugin_Loader_Find(lpszMethodName, pInt_Type); -} -extern "C" bool ModulePlugin_Loader_Get(LPCXSTR lpszMethodName, XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc) -{ - return m_PluginLoader.ModulePlugin_Loader_Get(lpszMethodName, ptszPluginName, ptszPluginVersion, ptszPluginAuthor, ptszPluginDesc); -} -extern "C" bool ModulePlugin_Loader_GetForModule(LPCXSTR lpszModuleName, XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc) -{ - return m_PluginLoader.ModulePlugin_Loader_GetForModule(lpszModuleName, ptszPluginName, ptszPluginVersion, ptszPluginAuthor, ptszPluginDesc); -} -extern "C" bool ModulePlugin_Loader_Exec(LPCXSTR lpszMethodName, XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen) -{ - return m_PluginLoader.ModulePlugin_Loader_Exec(lpszMethodName, pppHDRList, nListCount, pInt_HTTPCode, ptszMsgBuffer, pInt_MsgLen); -} -extern "C" bool ModulePlugin_Loader_Destory() -{ - return m_PluginLoader.ModulePlugin_Loader_Destory(); -} \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModulePlugin/pch.h b/XEngine_Source/XEngine_ModulePlugin/pch.h deleted file mode 100644 index bbc0e4a..0000000 --- a/XEngine_Source/XEngine_ModulePlugin/pch.h +++ /dev/null @@ -1,61 +0,0 @@ -// pch.h: 这是预编译标头文件。 -// 下方列出的文件仅编译一次,提高了将来生成的生成性能。 -// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 -// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 -// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 - -#ifndef PCH_H -#define PCH_H - -#ifdef _MSC_BUILD -// 添加要在此处预编译的标头 -#include "framework.h" -#include -#else -#include -#endif -#endif //PCH_H -#include "../XEngine_BuildSwitch.h" -#if (1 == _XENGINE_BUILD_SWITCH_LUA) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; -#include -#include -#include -#include -#include -#include "../XEngine_UserProtocol.h" -#include "ModulePlugin_Define.h" -#include "ModulePlugin_Error.h" -/******************************************************************** -// Created: 2022/04/20 16:17:24 -// File Name: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin\pch.h -// File Path: D:\XEngine_APIService\XEngine_Source\XEngine_ModulePlugin -// File Base: pch -// File Ext: h -// Project: XEngine(网络通信引擎) -// Author: qyt -// Purpose: 插件核心公有头文件 -// History: -*********************************************************************/ -extern bool ModulePlugin_IsErrorOccur; -extern XLONG ModulePlugin_dwErrorCode; - - -#ifdef _MSC_BUILD -#pragma comment(lib,"XEngine_BaseLib/XEngine_BaseLib") - -#define XFreeModule FreeLibrary -#else -#define XFreeModule dlclose -#endif \ No newline at end of file diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/pch.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/pch.h index bb8b5ac..d579c23 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/pch.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/pch.h @@ -25,7 +25,7 @@ #include #include #include -#include "../../XEngine_UserProtocol.h" +#include "../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_PluginExtension/PluginExtension_Define.h" #include "BMIndex_Define.h" #include "BMIndex_Error.h" using namespace std; diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/pch.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/pch.h index 023b843..7475524 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/pch.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/pch.h @@ -24,7 +24,7 @@ #include #include #include -#include "../../XEngine_UserProtocol.h" +#include "../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_PluginExtension/PluginExtension_Define.h" #include "PluginMeter_Define.h" #include "PluginMeter_Error.h" /******************************************************************** diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/pch.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/pch.h index 4eb6ab8..cd96865 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/pch.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/pch.h @@ -20,7 +20,7 @@ #include #include #include -#include "../../XEngine_UserProtocol.h" +#include "../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_PluginExtension/PluginExtension_Define.h" #include "PluginPass_Define.h" #include "PluginPass_Error.h" using namespace std; diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/pch.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/pch.h index e8af487..23a0d44 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/pch.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/pch.h @@ -24,7 +24,7 @@ #include #include #include -#include "../../XEngine_UserProtocol.h" +#include "../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_PluginExtension/PluginExtension_Define.h" #include "Timezone_Define.h" #include "Timezone_Error.h" using namespace std; diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/pch.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/pch.h index 618a478..ff2d75a 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/pch.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/pch.h @@ -22,7 +22,7 @@ #include #include #include -#include "../../XEngine_UserProtocol.h" +#include "../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_PluginExtension/PluginExtension_Define.h" #include "PluginZodiac_Define.h" #include "PluginZodiac_Error.h" using namespace std; diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp index e8cebc3..e67ac62 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp @@ -274,7 +274,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST } //首先处理插件 int nPluginType = 0; - if (ModulePlugin_Loader_Find(tszValue, &nPluginType)) + if (PluginExtension_Loader_Find(tszValue, &nPluginType)) { XEngine_PluginTask_Handle(tszValue, lpszClientAddr, lpszMSGBuffer, nMSGLen, &pptszList, nListCount, nPluginType); return true; diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_Hdr.h b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_Hdr.h index 9bf2f01..0a6d5e2 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_Hdr.h +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_Hdr.h @@ -71,6 +71,8 @@ using namespace std; #include "../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_InfoReport/InfoReport_Error.h" #include "../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_Verification/Verification_Define.h" #include "../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_Verification/Verification_Error.h" +#include "../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_PluginExtension/PluginExtension_Define.h" +#include "../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_PluginExtension/PluginExtension_Error.h" #include "../../XEngine_DependLibrary/XEngine_IPMacData/XEngine_Source/XIPMac_CommHdr.h" #include "../../XEngine_DependLibrary/XEngine_IPMacData/XEngine_Source/XEngine_APIModuleIPMac/APIIPMac_Define.h" #include "../../XEngine_DependLibrary/XEngine_IPMacData/XEngine_Source/XEngine_APIModuleIPMac/APIIPMac_Error.h" @@ -90,8 +92,6 @@ using namespace std; #include "../../XEngine_ModuleSystem/ModuleSystem_Error.h" #include "../../XEngine_ModuleHelp/ModuleHelp_Define.h" #include "../../XEngine_ModuleHelp/ModuleHelp_Error.h" -#include "../../XEngine_ModulePlugin/ModulePlugin_Define.h" -#include "../../XEngine_ModulePlugin/ModulePlugin_Error.h" //加载自己的头文件 #include "XEngine_Configure.h" #include "XEngine_Network.h" @@ -184,6 +184,7 @@ extern XENGINE_DEAMONAPPLIST st_DeamonAppConfig; #ifdef _M_X64 #pragma comment(lib,"../../x64/Debug/XEngine_InfoReport.lib") #pragma comment(lib,"../../x64/Debug/XEngine_Verification.lib") +#pragma comment(lib,"../../x64/Debug/XEngine_PluginExtension.lib") #pragma comment(lib,"../../x64/Debug/XEngine_APIModuleIPMac.lib") #pragma comment(lib,"../../x64/Debug/XEngine_APIModulePhone.lib") #pragma comment(lib,"../../x64/Debug/XEngine_ModuleConfigure.lib") @@ -191,10 +192,10 @@ extern XENGINE_DEAMONAPPLIST st_DeamonAppConfig; #pragma comment(lib,"../../x64/Debug/XEngine_ModuleProtocol.lib") #pragma comment(lib,"../../x64/Debug/XEngine_ModuleSystem.lib") #pragma comment(lib,"../../x64/Debug/XEngine_ModuleHelp.lib") -#pragma comment(lib,"../../x64/Debug/XEngine_ModulePlugin.lib") #elif _M_ARM64 #pragma comment(lib,"../../ARM64/Debug/XEngine_InfoReport.lib") #pragma comment(lib,"../../ARM64/Debug/XEngine_Verification.lib") +#pragma comment(lib,"../../ARM64/Debug/XEngine_PluginExtension.lib") #pragma comment(lib,"../../ARM64/Debug/XEngine_APIModuleIPMac.lib") #pragma comment(lib,"../../ARM64/Debug/XEngine_APIModulePhone.lib") #pragma comment(lib,"../../ARM64/Debug/XEngine_ModuleConfigure.lib") @@ -202,10 +203,10 @@ extern XENGINE_DEAMONAPPLIST st_DeamonAppConfig; #pragma comment(lib,"../../ARM64/Debug/XEngine_ModuleProtocol.lib") #pragma comment(lib,"../../ARM64/Debug/XEngine_ModuleSystem.lib") #pragma comment(lib,"../../ARM64/Debug/XEngine_ModuleHelp.lib") -#pragma comment(lib,"../../ARM64/Debug/XEngine_ModulePlugin.lib") #elif _M_IX86 #pragma comment(lib,"../../Debug/XEngine_InfoReport.lib") #pragma comment(lib,"../../Debug/XEngine_Verification.lib") +#pragma comment(lib,"../../Debug/XEngine_PluginExtension.lib") #pragma comment(lib,"../../Debug/XEngine_APIModuleIPMac.lib") #pragma comment(lib,"../../Debug/XEngine_APIModulePhone.lib") #pragma comment(lib,"../../Debug/XEngine_ModuleConfigure.lib") @@ -213,12 +214,12 @@ extern XENGINE_DEAMONAPPLIST st_DeamonAppConfig; #pragma comment(lib,"../../Debug/XEngine_ModuleProtocol.lib") #pragma comment(lib,"../../Debug/XEngine_ModuleSystem.lib") #pragma comment(lib,"../../Debug/XEngine_ModuleHelp.lib") -#pragma comment(lib,"../../Debug/XEngine_ModulePlugin.lib") #endif #else #ifdef _M_X64 #pragma comment(lib,"../../x64/Release/XEngine_InfoReport.lib") #pragma comment(lib,"../../x64/Release/XEngine_Verification.lib") +#pragma comment(lib,"../../x64/Release/XEngine_PluginExtension.lib") #pragma comment(lib,"../../x64/Release/XEngine_APIModuleIPMac.lib") #pragma comment(lib,"../../x64/Release/XEngine_APIModulePhone.lib") #pragma comment(lib,"../../x64/Release/XEngine_ModuleConfigure.lib") @@ -226,10 +227,10 @@ extern XENGINE_DEAMONAPPLIST st_DeamonAppConfig; #pragma comment(lib,"../../x64/Release/XEngine_ModuleProtocol.lib") #pragma comment(lib,"../../x64/Release/XEngine_ModuleSystem.lib") #pragma comment(lib,"../../x64/Release/XEngine_ModuleHelp.lib") -#pragma comment(lib,"../../x64/Release/XEngine_ModulePlugin.lib") #elif _M_ARM64 #pragma comment(lib,"../../ARM64/Release/XEngine_InfoReport.lib") #pragma comment(lib,"../../ARM64/Release/XEngine_Verification.lib") +#pragma comment(lib,"../../ARM64/Release/XEngine_PluginExtension.lib") #pragma comment(lib,"../../ARM64/Release/XEngine_APIModuleIPMac.lib") #pragma comment(lib,"../../ARM64/Release/XEngine_APIModulePhone.lib") #pragma comment(lib,"../../ARM64/Release/XEngine_ModuleConfigure.lib") @@ -237,10 +238,10 @@ extern XENGINE_DEAMONAPPLIST st_DeamonAppConfig; #pragma comment(lib,"../../ARM64/Release/XEngine_ModuleProtocol.lib") #pragma comment(lib,"../../ARM64/Release/XEngine_ModuleSystem.lib") #pragma comment(lib,"../../ARM64/Release/XEngine_ModuleHelp.lib") -#pragma comment(lib,"../../ARM64/Release/XEngine_ModulePlugin.lib") #elif _M_IX86 #pragma comment(lib,"../../Release/XEngine_InfoReport.lib") #pragma comment(lib,"../../Release/XEngine_Verification.lib") +#pragma comment(lib,"../../Release/XEngine_PluginExtension.lib") #pragma comment(lib,"../../Release/XEngine_APIModuleIPMac.lib") #pragma comment(lib,"../../Release/XEngine_APIModulePhone.lib") #pragma comment(lib,"../../Release/XEngine_ModuleConfigure.lib") @@ -248,7 +249,6 @@ extern XENGINE_DEAMONAPPLIST st_DeamonAppConfig; #pragma comment(lib,"../../Release/XEngine_ModuleProtocol.lib") #pragma comment(lib,"../../Release/XEngine_ModuleSystem.lib") #pragma comment(lib,"../../Release/XEngine_ModuleHelp.lib") -#pragma comment(lib,"../../Release/XEngine_ModulePlugin.lib") #endif #endif #endif \ No newline at end of file diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.cpp index 9aad8f3..0bdaedf 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.cpp @@ -57,7 +57,7 @@ void ServiceApp_Stop(int signo) APIModule_IPAddr_UnInit(); APIModule_MACInfo_UnInit(); APIModule_PhoneNumber_UnInit(); - ModulePlugin_Loader_Destory(); + PluginExtension_Loader_Destory(); ModuleHelp_P2PClient_Destory(); ModuleHelp_ImageGet_TextDestory(); ModuleHelp_DNSAddr_Destroy(); @@ -459,9 +459,9 @@ int main(int argc, char** argv) { XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,初始化插件配置文件成功")); //启动插件 - if (!ModulePlugin_Loader_Init()) + if (!PluginExtension_Loader_Init()) { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,初始化插件系统失败,错误:%lX"), ModulePlugin_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,初始化插件系统失败,错误:%lX"), PluginExtension_GetLastError()); goto XENGINE_SERVICEAPP_EXIT; } XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,初始化插件系统成功,开始加载插件")); @@ -478,17 +478,17 @@ int main(int argc, char** argv) { nLibCount++; //加载插件 - if (ModulePlugin_Loader_Insert(pptszListFile[i], 0, &st_PluginParam)) + if (PluginExtension_Loader_Insert(pptszListFile[i], 0, &st_PluginParam)) { XCHAR tszModuleName[128] = {}; XCHAR tszModuleAuthor[64] = {}; XCHAR tszModuleVer[64] = {}; - ModulePlugin_Loader_GetForModule(pptszListFile[i], tszModuleName, tszModuleVer, tszModuleAuthor); + PluginExtension_Loader_GetForModule(pptszListFile[i], tszModuleName, tszModuleVer, tszModuleAuthor); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,加载Lib模块插件中,当前第:%d 个加载成功,路径:%s,方法名:%s,作者:%s,版本:V%s"), nLibCount, pptszListFile[i], tszModuleName, tszModuleAuthor, tszModuleVer); } else { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,加载Lib模块插件中,当前第:%d 个加载失败,路径:%s,错误:%lX"), nLibCount, pptszListFile[i], ModulePlugin_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,加载Lib模块插件中,当前第:%d 个加载失败,路径:%s,错误:%lX"), nLibCount, pptszListFile[i], PluginExtension_GetLastError()); } } } @@ -505,17 +505,17 @@ int main(int argc, char** argv) if (0 == _tcsxnicmp(tszFileExt, _X("lua"), 3)) { nLuaCount++; - if (ModulePlugin_Loader_Insert(pptszListFile[i], 1, &st_PluginParam)) + if (PluginExtension_Loader_Insert(pptszListFile[i], 1, &st_PluginParam)) { XCHAR tszModuleName[128] = {}; XCHAR tszModuleAuthor[64] = {}; XCHAR tszModuleVer[64] = {}; - ModulePlugin_Loader_GetForModule(pptszListFile[i], tszModuleName, tszModuleVer, tszModuleAuthor); + PluginExtension_Loader_GetForModule(pptszListFile[i], tszModuleName, tszModuleVer, tszModuleAuthor); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,加载Lua模块插件中,当前第:%d 个加载成功,路径:%s,方法名:%s,作者:%s,版本:V%s"), nLuaCount, pptszListFile[i], tszModuleName, tszModuleAuthor, tszModuleVer); } else { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,加载Lua模块插件中,当前第:%d 个加载失败,路径:%s,错误:%lX"), nLuaCount, pptszListFile[i], ModulePlugin_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,加载Lua模块插件中,当前第:%d 个加载失败,路径:%s,错误:%lX"), nLuaCount, pptszListFile[i], PluginExtension_GetLastError()); } } } @@ -630,7 +630,7 @@ int main(int argc, char** argv) APIModule_IPAddr_UnInit(); APIModule_MACInfo_UnInit(); APIModule_PhoneNumber_UnInit(); - ModulePlugin_Loader_Destory(); + PluginExtension_Loader_Destory(); ModuleHelp_P2PClient_Destory(); ModuleHelp_ImageGet_TextDestory(); ModuleHelp_DNSAddr_Destroy(); diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_PluginTask.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_PluginTask.cpp index d1eac69..abdf938 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_PluginTask.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_PluginTask.cpp @@ -26,7 +26,7 @@ bool XEngine_PluginTask_Handle(LPCXSTR lpszMethodName, LPCXSTR lpszClientAddr, L st_HDRParament.nHttpCode = 200; _tcsxcpy(st_HDRParament.tszMimeType, "json"); - if (ModulePlugin_Loader_Exec(lpszMethodName, ppptszList, nListCount, &st_HDRParament.nHttpCode, tszPktBuffer, &nPktLen)) + if (PluginExtension_Loader_Exec(lpszMethodName, ppptszList, nListCount, &st_HDRParament.nHttpCode, tszPktBuffer, &nPktLen)) { HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszMsgBuffer, &nMsgLen, &st_HDRParament, tszPktBuffer, nPktLen); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,请求的方法:%s,由%s插件模块处理成功"), lpszClientAddr, lpszMethodName, 0 == nPluginType ? "Lib" : "Lua"); @@ -35,7 +35,7 @@ bool XEngine_PluginTask_Handle(LPCXSTR lpszMethodName, LPCXSTR lpszClientAddr, L { st_HDRParament.nHttpCode = 400; HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszMsgBuffer, &nMsgLen, &st_HDRParament); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,请求的方法:%s,由%s插件模块处理失败,错误:%lX"), lpszClientAddr, lpszMethodName, 0 == nPluginType ? "Lib" : "Lua", ModulePlugin_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,请求的方法:%s,由%s插件模块处理失败,错误:%lX"), lpszClientAddr, lpszMethodName, 0 == nPluginType ? "Lib" : "Lua", PluginExtension_GetLastError()); } XEngine_Network_Send(lpszClientAddr, tszMsgBuffer, nMsgLen); return true; diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskGet/TaskGet_Reload.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskGet/TaskGet_Reload.cpp index d178d9e..ea84265 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskGet/TaskGet_Reload.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskGet/TaskGet_Reload.cpp @@ -28,15 +28,15 @@ bool HTTPTask_TaskGet_Reload(LPCXSTR lpszClientAddr, LPCXSTR lpszOPCode) _tcsxcpy(st_PluginParam.tszAPIVersion, st_ServiceConfig.st_XVer.pStl_ListVer->front().c_str()); _tcsxcpy(st_PluginParam.tszXEngineVer, BaseLib_Version_XNumberStr()); - ModulePlugin_Loader_Destory(); - ModulePlugin_Loader_Init(); + PluginExtension_Loader_Destory(); + PluginExtension_Loader_Init(); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,请求操作配置重载成功,加载插件配置成功"), lpszClientAddr); { SystemApi_File_EnumFileA(st_ServiceConfig.st_XPlugin.tszLibPlugin, &pptszListFile, &nLibCount, false, 1); for (int i = 0; i < nLibCount; i++) { //加载插件 - ModulePlugin_Loader_Insert(pptszListFile[i], 0, &st_PluginParam); + PluginExtension_Loader_Insert(pptszListFile[i], 0, &st_PluginParam); } BaseLib_Memory_Free((XPPPMEM)&pptszListFile, nLibCount); } @@ -44,7 +44,7 @@ bool HTTPTask_TaskGet_Reload(LPCXSTR lpszClientAddr, LPCXSTR lpszOPCode) SystemApi_File_EnumFileA(st_ServiceConfig.st_XPlugin.tszLuaPlugin, &pptszListFile, &nLuaCount, false, 1); for (int i = 0; i < nLuaCount; i++) { - ModulePlugin_Loader_Insert(pptszListFile[i], 1, &st_PluginParam); + PluginExtension_Loader_Insert(pptszListFile[i], 1, &st_PluginParam); } } HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszMsgBuffer, &nMsgLen, &st_HDRParam); diff --git a/XEngine_Source/XEngine_UserProtocol.h b/XEngine_Source/XEngine_UserProtocol.h index dddaa05..137ae5f 100644 --- a/XEngine_Source/XEngine_UserProtocol.h +++ b/XEngine_Source/XEngine_UserProtocol.h @@ -283,10 +283,4 @@ typedef struct XCHAR tszUPTime[64]; //更新时间 XCHAR tszNextTime[64]; //更新时间 }XENGINE_OILINFO; -//插件参数 -typedef struct -{ - XCHAR tszAPIVersion[64]; //API服务版本 - XCHAR tszXEngineVer[64]; //XEngine版本 -}XENGINE_PLUGINPARAM; #pragma pack(pop) \ No newline at end of file From 8b4648d93fa3f559493168cabe66feb899b8b136 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 28 Jan 2026 15:55:16 +0800 Subject: [PATCH 09/20] update:depend library and ci --- .github/workflows/msbuild.yml | 2 +- XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index b9663c5..aa2dd75 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -118,7 +118,7 @@ jobs: #编译 - name: Build Solution - run: msbuild XEngine_Source/XEngine.sln /p:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }} + run: msbuild XEngine_Source/XEngine.sln /p:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }} /p:ExtraDefines="_XENGINE_BUILD_SWITCH_LUA" #测试 - name: Conditional Step for x86 Release diff --git a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource index 9b1c9e3..6321e02 160000 --- a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource +++ b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource @@ -1 +1 @@ -Subproject commit 9b1c9e3117fdf04aeff6e26b62e5bfeeaf5a9374 +Subproject commit 6321e02719fb485054134403687a94f4c8e4b9f6 From de67a32d311bd92c00eadeb7df0dcb95a0a2273e Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 28 Jan 2026 16:08:27 +0800 Subject: [PATCH 10/20] fixed:build error --- .github/workflows/codeql.yml | 4 ++-- .../XEngine_ServiceApp/XEngine_HttpApp/Makefile | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 8458037..fd93452 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -56,7 +56,7 @@ jobs: sudo ./XEngine_LINEnv.sh -i 3 - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} @@ -66,6 +66,6 @@ jobs: make - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 with: category: "/language:${{ matrix.language }}" diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile index cc23fd7..725f1cb 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile @@ -3,12 +3,12 @@ PLATVER = FILEEXT = LIBFLAG = LOADHDR = -I ./ -LOADSO = -L ../../XEngine_ModuleConfigure -L ../../XEngine_ModuleDatabase -L ../../XEngine_ModuleProtocol -L ../../XEngine_ModuleSystem -L ../../XEngine_ModuleHelp -L ../../XEngine_ModulePlugin \ - -L ../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/jsoncpp -L ../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_InfoReport -L ../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_Verification \ +LOADSO = -L ../../XEngine_ModuleConfigure -L ../../XEngine_ModuleDatabase -L ../../XEngine_ModuleProtocol -L ../../XEngine_ModuleSystem -L ../../XEngine_ModuleHelp \ + -L ../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/jsoncpp -L ../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_InfoReport -L ../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_Verification -L ../../XEngine_DependLibrary/XEngine_OPenSource/XEngine_Module/XEngine_PluginExtension \ -L ../../XEngine_DependLibrary/XEngine_IPMacData/XEngine_Source/XEngine_APIModuleIPMac -L ../../XEngine_DependLibrary/XEngine_PhoneData/XEngine_Source/XEngine_APIModulePhone LIB = -lXEngine_BaseSafe -lXEngine_BaseLib -lXEngine_Algorithm -lXEngine_Core -lXEngine_ManagePool -lXEngine_Cryption -lXClient_APIHelp -lXClient_Socket -lNetHelp_APIAddr -lNetHelp_XSocket -lHelpComponents_XLog -lRfcComponents_HttpProtocol -lRfcComponents_NatProtocol -lRfcComponents_NTPProtocol -lRfcComponents_DNSProtocol -lXEngine_SystemApi -lXEngine_AVHelp -lXEngine_VideoCodec -lXEngine_AudioCodec -lXEngine_AVFilter -lXEngine_AVCollect -lXEngine_AVFormat \ - -lXEngine_ModuleConfigure -lXEngine_ModuleDatabase -lXEngine_ModuleProtocol -lXEngine_ModuleSystem -lXEngine_ModuleHelp -lXEngine_ModulePlugin \ - -ljsoncpp -lXEngine_InfoReport -lXEngine_Verification \ + -lXEngine_ModuleConfigure -lXEngine_ModuleDatabase -lXEngine_ModuleProtocol -lXEngine_ModuleSystem -lXEngine_ModuleHelp \ + -ljsoncpp -lXEngine_InfoReport -lXEngine_Verification -lXEngine_PluginExtension \ -lXEngine_APIModuleIPMac -lXEngine_APIModulePhone LIBEX = OBJECTS = XEngine_Configure.o XEngine_Network.o XEngine_HTTPTask.o XEngine_PluginTask.o XEngine_HttpApp.o \ From 82bd3306ac03b78e2be72435055bd2b8f07fa206 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 28 Jan 2026 17:21:49 +0800 Subject: [PATCH 11/20] update:depend library --- XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource index 6321e02..05f0983 160000 --- a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource +++ b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource @@ -1 +1 @@ -Subproject commit 6321e02719fb485054134403687a94f4c8e4b9f6 +Subproject commit 05f0983d0a72ae2b11b689bc499a2f12dcc38a14 From 6ed533b2c2cce280a0533a8e4260c35f77b3dfea Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 28 Jan 2026 17:22:05 +0800 Subject: [PATCH 12/20] update:ci build --- .github/workflows/msbuild.yml | 6 +++--- README.en.md | 2 +- README.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index aa2dd75..06982af 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -51,7 +51,7 @@ jobs: run: | cd vcpkg ./bootstrap-vcpkg.bat - ./vcpkg.exe install lua:x86-windows opencv[contrib]:x86-windows libqrencode:x86-windows + ./vcpkg.exe install lua:x86-windows opencv[contrib,freetype]:x86-windows libqrencode:x86-windows leptonica:x86-windows ./vcpkg.exe integrate install shell: pwsh - name: vcpkg install (x64) @@ -59,7 +59,7 @@ jobs: run: | cd vcpkg ./bootstrap-vcpkg.bat - ./vcpkg.exe install lua:x64-windows opencv[contrib]:x64-windows libqrencode:x64-windows + ./vcpkg.exe install lua:x64-windows opencv[contrib,freetype]:x64-windows libqrencode:x64-windows leptonica:x64-windows ./vcpkg.exe integrate install shell: pwsh - name: vcpkg install (ARM64) @@ -69,7 +69,7 @@ jobs: ./bootstrap-vcpkg.bat ./vcpkg.exe install lua:Arm64-windows ./vcpkg.exe integrate install - # ./vcpkg.exe install lua:Arm64-windows opencv[contrib]:Arm64-windows libqrencode:Arm64-windows Windows的opencv 有问题 + # ./vcpkg.exe install lua:Arm64-windows opencv[contrib,freetype]:Arm64-windows libqrencode:Arm64-windows Windows的opencv 有问题 cd .. $filePath = "XEngine_Source/XEngine_BuildSwitch.h" diff --git a/README.en.md b/README.en.md index a3a2f49..638139c 100644 --- a/README.en.md +++ b/README.en.md @@ -84,7 +84,7 @@ Modify the database configuration in XSQL in the configuration file to your The default configuration does not enable database support. If the database interface is required, you need to enable the database yourself #### Windows -need to vcpkg configure third-part env.refer vcpkg install guide.after installed and execution:vcpkg.exe install lua:x86-windows opencv[contrib,freetype]:x86-windows libqrencode:x86-windows lua:x64-windows opencv[contrib,freetype]:x64-windows libqrencode:x64-windows +need to vcpkg configure third-part env.refer vcpkg install guide.after installed and execution:vcpkg.exe install lua:x86-windows opencv[contrib,freetype]:x86-windows libqrencode:x86-windows leptonica:x86-windows lua:x64-windows opencv[contrib,freetype]:x64-windows libqrencode:x64-windows leptonica:x64-windows use vs open and compile,suport windows 7sp1 and above Just Run it diff --git a/README.md b/README.md index fecaa80..ac134fd 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ git clone https://gitee.com/xengine/XEngine_IPMacData.git XEngine_Source/XEngine git clone https://gitee.com/xengine/XEngine_PhoneData.git XEngine_Source/XEngine_DependLibrary/XEngine_PhoneData #### Windows -需要vcpkg配置第三方环境,具体参考vcpkg安装方式,安装好后执行:vcpkg.exe install lua:x86-windows opencv[contrib,freetype]:x86-windows libqrencode:x86-windows lua:x64-windows opencv[contrib,freetype]:x64-windows libqrencode:x64-windows +需要vcpkg配置第三方环境,具体参考vcpkg安装方式,安装好后执行:vcpkg.exe install lua:x86-windows opencv[contrib,freetype]:x86-windows libqrencode:x86-windows leptonica:x86-windows lua:x64-windows opencv[contrib,freetype]:x64-windows libqrencode:x64-windows leptonica:x64-windows 使用VS打开并且编译,支持WINDOWS 7SP1以上系统 直接运行即可 From 3387c9dcb4bd555abbd2b27363220667c4ab8f21 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 28 Jan 2026 17:22:55 +0800 Subject: [PATCH 13/20] modify:adjust plugin parameter order fixed:plugin not load http message buffer --- .../ModulePlugin_BMIndex/BMIndex_Define.h | 2 +- .../ModulePlugin_BMIndex/Plugin_BMIndex/Plugin_BMIndex.cpp | 4 ++-- .../ModulePlugin_BMIndex/Plugin_BMIndex/Plugin_BMIndex.h | 2 +- .../XEngine_PluginModule/ModulePlugin_BMIndex/pch.cpp | 4 ++-- .../ModulePlugin_Meter/PluginMeter_Define.h | 2 +- .../ModulePlugin_Meter/Plugin_Meter/Plugin_Meter.cpp | 4 ++-- .../ModulePlugin_Meter/Plugin_Meter/Plugin_Meter.h | 2 +- .../XEngine_PluginModule/ModulePlugin_Meter/pch.cpp | 4 ++-- .../ModulePlugin_Password/PluginPass_Define.h | 2 +- .../ModulePlugin_Password/Plugin_Password/Plugin_Password.cpp | 4 ++-- .../ModulePlugin_Password/Plugin_Password/Plugin_Password.h | 2 +- .../XEngine_PluginModule/ModulePlugin_Password/pch.cpp | 4 ++-- .../ModulePlugin_Timezone/Plugin_Timezone/Plugin_Timezone.cpp | 4 ++-- .../ModulePlugin_Timezone/Plugin_Timezone/Plugin_Timezone.h | 2 +- .../ModulePlugin_Timezone/Timezone_Define.h | 2 +- .../XEngine_PluginModule/ModulePlugin_Timezone/pch.cpp | 4 ++-- .../ModulePlugin_Zodiac/PluginZodiac_Define.h | 2 +- .../ModulePlugin_Zodiac/Plugin_Zodiac/Plugin_Zodiac.cpp | 4 ++-- .../ModulePlugin_Zodiac/Plugin_Zodiac/Plugin_Zodiac.h | 2 +- .../XEngine_PluginModule/ModulePlugin_Zodiac/pch.cpp | 4 ++-- .../XEngine_ServiceApp/XEngine_HttpApp/XEngine_PluginTask.cpp | 2 +- 21 files changed, 31 insertions(+), 31 deletions(-) diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/BMIndex_Define.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/BMIndex_Define.h index 303bfaf..1a5cdd6 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/BMIndex_Define.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/BMIndex_Define.h @@ -77,4 +77,4 @@ extern "C" void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersi 意思:是否成功 备注: *********************************************************************/ -extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer = NULL, int nMsgLen = 0); \ No newline at end of file +extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer = NULL, int nMsgLen = 0, int* pInt_HTTPCode = NULL); \ No newline at end of file diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/Plugin_BMIndex/Plugin_BMIndex.cpp b/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/Plugin_BMIndex/Plugin_BMIndex.cpp index 4d40c69..412feb4 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/Plugin_BMIndex/Plugin_BMIndex.cpp +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/Plugin_BMIndex/Plugin_BMIndex.cpp @@ -95,11 +95,11 @@ void CPlugin_BMIndex::PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPlugi 意思:是否成功 备注: *********************************************************************/ -bool CPlugin_BMIndex::PluginCore_Call(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen) +bool CPlugin_BMIndex::PluginCore_Call(XCHAR*** pppHDRList, int nListCount, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode) { BMIndex_IsErrorOccur = false; - if ((NULL == pInt_HTTPCode) || (NULL == ptszMsgBuffer) || (NULL == pInt_MsgLen)) + if ((NULL == ptszMsgBuffer) || (NULL == pInt_MsgLen)) { BMIndex_IsErrorOccur = true; BMIndex_dwErrorCode = ERROR_XENGINE_APISERVICE_PLUGIN_MODULE_BMINDEX_PARAMENT; diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/Plugin_BMIndex/Plugin_BMIndex.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/Plugin_BMIndex/Plugin_BMIndex.h index cd27d6b..94f1f11 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/Plugin_BMIndex/Plugin_BMIndex.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/Plugin_BMIndex/Plugin_BMIndex.h @@ -20,7 +20,7 @@ class CPlugin_BMIndex bool PluginCore_Init(XENGINE_PLUGINPARAM *pSt_PluginParameter); void PluginCore_UnInit(); void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc); - bool PluginCore_Call(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen); + bool PluginCore_Call(XCHAR*** pppHDRList, int nListCount, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode); protected: bool Plugin_Timezone_BMIndex(LPCXSTR lpszHigh, LPCXSTR lpszWeight, XCHAR* ptszMsgBufer, int* pInt_Len); private: diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/pch.cpp b/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/pch.cpp index 1aeceb5..a94f30f 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/pch.cpp +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_BMIndex/pch.cpp @@ -37,7 +37,7 @@ extern "C" void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersi { return m_PluginBMIndex.PluginCore_GetInfo(ptszPluginName, ptszPluginVersion, ptszPluginAuthor, ptszPluginDesc); } -extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen) +extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode) { - return m_PluginBMIndex.PluginCore_Call(pppHDRList, nListCount, pInt_HTTPCode, ptszMsgBuffer, pInt_MsgLen, lpszMsgBuffer, nMsgLen); + return m_PluginBMIndex.PluginCore_Call(pppHDRList, nListCount, ptszMsgBuffer, pInt_MsgLen, lpszMsgBuffer, nMsgLen, pInt_HTTPCode); } \ No newline at end of file diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/PluginMeter_Define.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/PluginMeter_Define.h index 36b849d..d601d83 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/PluginMeter_Define.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/PluginMeter_Define.h @@ -130,4 +130,4 @@ extern "C" void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersi 意思:是否成功 备注: *********************************************************************/ -extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer = NULL, int nMsgLen = 0); \ No newline at end of file +extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer = NULL, int nMsgLen = 0, int* pInt_HTTPCode = NULL); \ No newline at end of file diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/Plugin_Meter/Plugin_Meter.cpp b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/Plugin_Meter/Plugin_Meter.cpp index f5e8aaf..7fb0b1b 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/Plugin_Meter/Plugin_Meter.cpp +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/Plugin_Meter/Plugin_Meter.cpp @@ -96,11 +96,11 @@ void CPlugin_Meter::PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginV 意思:是否成功 备注: *********************************************************************/ -bool CPlugin_Meter::PluginCore_Call(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen) +bool CPlugin_Meter::PluginCore_Call(XCHAR*** pppHDRList, int nListCount, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode) { Meter_IsErrorOccur = false; - if ((NULL == pInt_HTTPCode) || (NULL == ptszMsgBuffer) || (NULL == pInt_MsgLen)) + if ((NULL == ptszMsgBuffer) || (NULL == pInt_MsgLen)) { Meter_IsErrorOccur = true; Meter_dwErrorCode = ERROR_XENGINE_APISERVICE_PLUGIN_MODULE_METER_PARAMENT; diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/Plugin_Meter/Plugin_Meter.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/Plugin_Meter/Plugin_Meter.h index cc60c97..b129296 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/Plugin_Meter/Plugin_Meter.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/Plugin_Meter/Plugin_Meter.h @@ -20,7 +20,7 @@ class CPlugin_Meter bool PluginCore_Init(XENGINE_PLUGINPARAM *pSt_PluginParameter); void PluginCore_UnInit(); void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc); - bool PluginCore_Call(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen); + bool PluginCore_Call(XCHAR*** pppHDRList, int nListCount, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode); protected: bool Plugin_Meter_LengthConvert(int nSource, __int64x nValue, Json::Value *pSt_JsonObject); bool Plugin_Meter_TemperatureConvert(int nSource, __int64x nValue, Json::Value* pSt_JsonObject); diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/pch.cpp b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/pch.cpp index 3cd3db6..a96a7db 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/pch.cpp +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Meter/pch.cpp @@ -37,7 +37,7 @@ extern "C" void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersi { return m_PluginMeter.PluginCore_GetInfo(ptszPluginName, ptszPluginVersion, ptszPluginAuthor, ptszPluginDesc); } -extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen) +extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode) { - return m_PluginMeter.PluginCore_Call(pppHDRList, nListCount, pInt_HTTPCode, ptszMsgBuffer, pInt_MsgLen, lpszMsgBuffer, nMsgLen); + return m_PluginMeter.PluginCore_Call(pppHDRList, nListCount, ptszMsgBuffer, pInt_MsgLen, lpszMsgBuffer, nMsgLen, pInt_HTTPCode); } \ No newline at end of file diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/PluginPass_Define.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/PluginPass_Define.h index 2ab9815..040f8c8 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/PluginPass_Define.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/PluginPass_Define.h @@ -77,4 +77,4 @@ extern "C" void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersi 意思:是否成功 备注: *********************************************************************/ -extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer = NULL, int nMsgLen = 0); \ No newline at end of file +extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer = NULL, int nMsgLen = 0, int* pInt_HTTPCode = NULL); \ No newline at end of file diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/Plugin_Password/Plugin_Password.cpp b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/Plugin_Password/Plugin_Password.cpp index 028989a..215e49b 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/Plugin_Password/Plugin_Password.cpp +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/Plugin_Password/Plugin_Password.cpp @@ -96,11 +96,11 @@ void CPlugin_Password::PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPlug 意思:是否成功 备注: *********************************************************************/ -bool CPlugin_Password::PluginCore_Call(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen) +bool CPlugin_Password::PluginCore_Call(XCHAR*** pppHDRList, int nListCount, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode) { Pass_IsErrorOccur = false; - if ((NULL == pInt_HTTPCode) || (NULL == ptszMsgBuffer) || (NULL == pInt_MsgLen)) + if ((NULL == ptszMsgBuffer) || (NULL == pInt_MsgLen)) { Pass_IsErrorOccur = true; Pass_dwErrorCode = ERROR_XENGINE_APISERVICE_PLUGIN_MODULE_PASS_PARAMENT; diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/Plugin_Password/Plugin_Password.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/Plugin_Password/Plugin_Password.h index b717fc5..732bc56 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/Plugin_Password/Plugin_Password.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/Plugin_Password/Plugin_Password.h @@ -20,7 +20,7 @@ class CPlugin_Password bool PluginCore_Init(XENGINE_PLUGINPARAM *pSt_PluginParameter); void PluginCore_UnInit(); void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc); - bool PluginCore_Call(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen); + bool PluginCore_Call(XCHAR*** pppHDRList, int nListCount, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode); protected: bool Plugin_Password_Creator(LPCXSTR lpszPassType, LPCXSTR lpszLength, XCHAR* ptszPassStr); private: diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/pch.cpp b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/pch.cpp index b62a0e5..a3d28bd 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/pch.cpp +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Password/pch.cpp @@ -37,7 +37,7 @@ extern "C" void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersi { return m_PluginPass.PluginCore_GetInfo(ptszPluginName, ptszPluginVersion, ptszPluginAuthor, ptszPluginDesc); } -extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen) +extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode) { - return m_PluginPass.PluginCore_Call(pppHDRList, nListCount, pInt_HTTPCode, ptszMsgBuffer, pInt_MsgLen, lpszMsgBuffer, nMsgLen); + return m_PluginPass.PluginCore_Call(pppHDRList, nListCount, ptszMsgBuffer, pInt_MsgLen, lpszMsgBuffer, nMsgLen, pInt_HTTPCode); } \ No newline at end of file diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Plugin_Timezone/Plugin_Timezone.cpp b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Plugin_Timezone/Plugin_Timezone.cpp index cc3548d..0ccf647 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Plugin_Timezone/Plugin_Timezone.cpp +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Plugin_Timezone/Plugin_Timezone.cpp @@ -558,11 +558,11 @@ void CPlugin_Timezone::PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPlug 意思:是否成功 备注: *********************************************************************/ -bool CPlugin_Timezone::PluginCore_Call(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen) +bool CPlugin_Timezone::PluginCore_Call(XCHAR*** pppHDRList, int nListCount, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode) { Timezone_IsErrorOccur = false; - if ((NULL == pInt_HTTPCode) || (NULL == ptszMsgBuffer) || (NULL == pInt_MsgLen)) + if ((NULL == ptszMsgBuffer) || (NULL == pInt_MsgLen)) { Timezone_IsErrorOccur = true; Timezone_dwErrorCode = ERROR_XENGINE_APISERVICE_PLUGIN_MODULE_TIMEZONE_PARAMENT; diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Plugin_Timezone/Plugin_Timezone.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Plugin_Timezone/Plugin_Timezone.h index 5ccf34d..f13ea2c 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Plugin_Timezone/Plugin_Timezone.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Plugin_Timezone/Plugin_Timezone.h @@ -26,7 +26,7 @@ class CPlugin_Timezone bool PluginCore_Init(XENGINE_PLUGINPARAM *pSt_PluginParameter); void PluginCore_UnInit(); void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc); - bool PluginCore_Call(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen); + bool PluginCore_Call(XCHAR*** pppHDRList, int nListCount, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode); protected: bool Plugin_Timezone_Count(XCHAR* ptszMsgBufer, int* pInt_Len); bool Plugin_Timezone_List(LPCXSTR lpszConvert, XCHAR* ptszMsgBufer, int* pInt_Len); diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Timezone_Define.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Timezone_Define.h index 2da5000..643f4c5 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Timezone_Define.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/Timezone_Define.h @@ -77,4 +77,4 @@ extern "C" void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersi 意思:是否成功 备注: *********************************************************************/ -extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer = NULL, int nMsgLen = 0); \ No newline at end of file +extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer = NULL, int nMsgLen = 0, int* pInt_HTTPCode = NULL); \ No newline at end of file diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/pch.cpp b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/pch.cpp index 21c5252..ca20ed6 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/pch.cpp +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Timezone/pch.cpp @@ -37,7 +37,7 @@ extern "C" void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersi { return m_PluginTimes.PluginCore_GetInfo(ptszPluginName, ptszPluginVersion, ptszPluginAuthor, ptszPluginDesc); } -extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen) +extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode) { - return m_PluginTimes.PluginCore_Call(pppHDRList, nListCount, pInt_HTTPCode, ptszMsgBuffer, pInt_MsgLen, lpszMsgBuffer, nMsgLen); + return m_PluginTimes.PluginCore_Call(pppHDRList, nListCount, ptszMsgBuffer, pInt_MsgLen, lpszMsgBuffer, nMsgLen, pInt_HTTPCode); } \ No newline at end of file diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/PluginZodiac_Define.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/PluginZodiac_Define.h index 3840183..b9c95f4 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/PluginZodiac_Define.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/PluginZodiac_Define.h @@ -77,4 +77,4 @@ extern "C" void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersi 意思:是否成功 备注: *********************************************************************/ -extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer = NULL, int nMsgLen = 0); \ No newline at end of file +extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer = NULL, int nMsgLen = 0, int* pInt_HTTPCode = NULL); \ No newline at end of file diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/Plugin_Zodiac/Plugin_Zodiac.cpp b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/Plugin_Zodiac/Plugin_Zodiac.cpp index 09e3629..7a94f24 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/Plugin_Zodiac/Plugin_Zodiac.cpp +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/Plugin_Zodiac/Plugin_Zodiac.cpp @@ -108,11 +108,11 @@ void CPlugin_Zodiac::PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPlugin 意思:是否成功 备注: *********************************************************************/ -bool CPlugin_Zodiac::PluginCore_Call(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen) +bool CPlugin_Zodiac::PluginCore_Call(XCHAR*** pppHDRList, int nListCount, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode) { Zodiac_IsErrorOccur = false; - if ((NULL == pInt_HTTPCode) || (NULL == ptszMsgBuffer) || (NULL == pInt_MsgLen)) + if ((NULL == ptszMsgBuffer) || (NULL == pInt_MsgLen)) { Zodiac_IsErrorOccur = true; Zodiac_dwErrorCode = ERROR_XENGINE_APISERVICE_PLUGIN_MODULE_ZODIAC_PARAMENT; diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/Plugin_Zodiac/Plugin_Zodiac.h b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/Plugin_Zodiac/Plugin_Zodiac.h index 0ba49d9..b1214d7 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/Plugin_Zodiac/Plugin_Zodiac.h +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/Plugin_Zodiac/Plugin_Zodiac.h @@ -20,7 +20,7 @@ class CPlugin_Zodiac bool PluginCore_Init(XENGINE_PLUGINPARAM *pSt_PluginParameter); void PluginCore_UnInit(); void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersion, XCHAR* ptszPluginAuthor, XCHAR* ptszPluginDesc); - bool PluginCore_Call(XCHAR*** pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen); + bool PluginCore_Call(XCHAR*** pppHDRList, int nListCount, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode); protected: bool Plugin_Zodiac_Chinese(LPCXSTR lpszDate, XCHAR* ptszCZodiac); bool Plugin_Zodiac_English(LPCXSTR lpszDate, XCHAR* ptszEZodiac); diff --git a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/pch.cpp b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/pch.cpp index 387fde3..0af64bb 100644 --- a/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/pch.cpp +++ b/XEngine_Source/XEngine_PluginModule/ModulePlugin_Zodiac/pch.cpp @@ -37,7 +37,7 @@ extern "C" void PluginCore_GetInfo(XCHAR* ptszPluginName, XCHAR* ptszPluginVersi { return m_PluginZodiac.PluginCore_GetInfo(ptszPluginName, ptszPluginVersion, ptszPluginAuthor, ptszPluginDesc); } -extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, int* pInt_HTTPCode, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen) +extern "C" bool PluginCore_Call(XCHAR * **pppHDRList, int nListCount, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCXSTR lpszMsgBuffer, int nMsgLen, int* pInt_HTTPCode) { - return m_PluginZodiac.PluginCore_Call(pppHDRList, nListCount, pInt_HTTPCode, ptszMsgBuffer, pInt_MsgLen, lpszMsgBuffer, nMsgLen); + return m_PluginZodiac.PluginCore_Call(pppHDRList, nListCount, ptszMsgBuffer, pInt_MsgLen, lpszMsgBuffer, nMsgLen, pInt_HTTPCode); } \ No newline at end of file diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_PluginTask.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_PluginTask.cpp index abdf938..2ccdaa4 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_PluginTask.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_PluginTask.cpp @@ -26,7 +26,7 @@ bool XEngine_PluginTask_Handle(LPCXSTR lpszMethodName, LPCXSTR lpszClientAddr, L st_HDRParament.nHttpCode = 200; _tcsxcpy(st_HDRParament.tszMimeType, "json"); - if (PluginExtension_Loader_Exec(lpszMethodName, ppptszList, nListCount, &st_HDRParament.nHttpCode, tszPktBuffer, &nPktLen)) + if (PluginExtension_Loader_Exec(lpszMethodName, ppptszList, nListCount, tszPktBuffer, &nPktLen, lpszRVBuffer, nRVLen, &st_HDRParament.nHttpCode)) { HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszMsgBuffer, &nMsgLen, &st_HDRParament, tszPktBuffer, nPktLen); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,请求的方法:%s,由%s插件模块处理成功"), lpszClientAddr, lpszMethodName, 0 == nPluginType ? "Lib" : "Lua"); From 6113e8656ec54ed5d538bac28e1a203917ccc6f7 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 3 Feb 2026 16:46:39 +0800 Subject: [PATCH 14/20] update:depend library --- XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource index 05f0983..adf48e2 160000 --- a/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource +++ b/XEngine_Source/XEngine_DependLibrary/XEngine_OPenSource @@ -1 +1 @@ -Subproject commit 05f0983d0a72ae2b11b689bc499a2f12dcc38a14 +Subproject commit adf48e22d68f741ec52f299945f8f8f8fb3df9d2 From c6c17e24e8ba21bd783113eb0eecc6e7ca3c2683 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 3 Feb 2026 17:11:37 +0800 Subject: [PATCH 15/20] modify:Separated screen recording from the background service --- .../ModuleProtocol_Define.h | 26 ++- .../ModuleProtocol_Parse.cpp | 65 ++++++ .../ModuleProtocol_Parse.h | 1 + .../XEngine_ModuleProtocol.def | 3 +- XEngine_Source/XEngine_ModuleProtocol/pch.cpp | 4 + .../XEngine_HttpApp/Makefile | 4 +- .../XEngine_HttpApp/XEngine_Hdr.h | 1 + .../XEngine_HttpApp/XEngine_HttpApp.vcxproj | 2 + .../XEngine_HttpApp.vcxproj.filters | 6 + .../XEngine_TaskPost/TaskPost_AVRecord.cpp | 208 ++++++++++++++++++ .../XEngine_TaskPost/TaskPost_AVRecord.h | 6 + .../XEngine_TaskPost/TaskPost_BackService.cpp | 184 ---------------- .../XEngine_TaskPost/TaskPost_BackService.h | 3 - XEngine_Source/XEngine_UserProtocol.h | 9 +- 14 files changed, 330 insertions(+), 192 deletions(-) create mode 100644 XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp create mode 100644 XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.h diff --git a/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Define.h b/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Define.h index 273e517..2a64688 100644 --- a/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Define.h +++ b/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Define.h @@ -1293,4 +1293,28 @@ extern "C" bool ModuleProtocol_Parse_Machine(LPCXSTR lpszMsgBuffer, int nMsgLen, 意思:是否成功 备注: *********************************************************************/ -extern "C" bool ModuleProtocol_Parse_Oil(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_OILINFO* pSt_OilInfo); \ No newline at end of file +extern "C" bool ModuleProtocol_Parse_Oil(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_OILINFO* pSt_OilInfo); +/******************************************************************** +函数名称:ModuleProtocol_Parse_AVRecord +函数功能:解析屏幕录制协议 + 参数.一:lpszMsgBuffer + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入要解析的缓冲区 + 参数.二:nMsgLen + In/Out:In + 类型:整数型 + 可空:N + 意思:输入缓冲区大小 + 参数.三:pSt_AVRecord + In/Out:Out + 类型:数据结构指针 + 可空:N + 意思:输出解析后的信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool ModuleProtocol_Parse_AVRecord(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AVRECORD* pSt_AVRecord); \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Parse/ModuleProtocol_Parse.cpp b/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Parse/ModuleProtocol_Parse.cpp index 084e2d0..7add32f 100644 --- a/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Parse/ModuleProtocol_Parse.cpp +++ b/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Parse/ModuleProtocol_Parse.cpp @@ -1277,4 +1277,69 @@ bool CModuleProtocol_Parse::ModuleProtocol_Parse_Oil(LPCXSTR lpszMsgBuffer, int _tcsxcpy(pSt_OilInfo->tszNextTime, st_JsonObject["next_update_time"].asCString()); } return true; +} +/******************************************************************** +函数名称:ModuleProtocol_Parse_AVRecord +函数功能:解析屏幕录制协议 + 参数.一:lpszMsgBuffer + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入要解析的缓冲区 + 参数.二:nMsgLen + In/Out:In + 类型:整数型 + 可空:N + 意思:输入缓冲区大小 + 参数.三:pSt_AVRecord + In/Out:Out + 类型:数据结构指针 + 可空:N + 意思:输出解析后的信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CModuleProtocol_Parse::ModuleProtocol_Parse_AVRecord(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AVRECORD* pSt_AVRecord) +{ + ModuleProtocol_IsErrorOccur = false; + + if ((NULL == lpszMsgBuffer) || (0 == nMsgLen)) + { + ModuleProtocol_IsErrorOccur = true; + ModuleProtocol_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PROTOCOL_PARSE_PARAMENT; + return false; + } + Json::Value st_JsonRoot; + JSONCPP_STRING st_JsonError; + Json::CharReaderBuilder st_JsonBuilder; + + std::unique_ptr const pSt_JsonReader(st_JsonBuilder.newCharReader()); + if (!pSt_JsonReader->parse(lpszMsgBuffer, lpszMsgBuffer + nMsgLen, &st_JsonRoot, &st_JsonError)) + { + ModuleProtocol_IsErrorOccur = true; + ModuleProtocol_dwErrorCode = ERROR_XENGINE_APISERVICE_MODULE_PROTOCOL_PARSE_PARAMENT; + return false; + } + + Json::Value st_JsonObject = st_JsonRoot["data"]; + + if (!st_JsonObject["tszVideoDevice"].isNull()) + { + _tcsxcpy(pSt_AVRecord->tszVideoDevice, st_JsonObject["tszVideoDevice"].asCString()); + } + if (!st_JsonObject["tszAudioDevice"].isNull()) + { + _tcsxcpy(pSt_AVRecord->tszAudioDevice, st_JsonObject["tszAudioDevice"].asCString()); + } + if (!st_JsonObject["tszFilePath"].isNull()) + { + _tcsxcpy(pSt_AVRecord->tszFilePath, st_JsonObject["tszFilePath"].asCString()); + } + if (!st_JsonObject["tszRsolution"].isNull()) + { + _tcsxcpy(pSt_AVRecord->tszRsolution, st_JsonObject["tszRsolution"].asCString()); + } + return true; } \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Parse/ModuleProtocol_Parse.h b/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Parse/ModuleProtocol_Parse.h index 7ebf228..bc2ae23 100644 --- a/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Parse/ModuleProtocol_Parse.h +++ b/XEngine_Source/XEngine_ModuleProtocol/ModuleProtocol_Parse/ModuleProtocol_Parse.h @@ -34,5 +34,6 @@ class CModuleProtocol_Parse bool ModuleProtocol_Parse_Weather(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_WEATHERINFO* pSt_WeatherInfo); bool ModuleProtocol_Parse_Machine(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_MACHINEINFO* pSt_MachineInfo); bool ModuleProtocol_Parse_Oil(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_OILINFO* pSt_OilInfo); + bool ModuleProtocol_Parse_AVRecord(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AVRECORD* pSt_AVRecord); private: }; \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModuleProtocol/XEngine_ModuleProtocol.def b/XEngine_Source/XEngine_ModuleProtocol/XEngine_ModuleProtocol.def index 86952f3..eec4012 100644 --- a/XEngine_Source/XEngine_ModuleProtocol/XEngine_ModuleProtocol.def +++ b/XEngine_Source/XEngine_ModuleProtocol/XEngine_ModuleProtocol.def @@ -48,4 +48,5 @@ EXPORTS ModuleProtocol_Parse_Deamon ModuleProtocol_Parse_Weather ModuleProtocol_Parse_Machine - ModuleProtocol_Parse_Oil \ No newline at end of file + ModuleProtocol_Parse_Oil + ModuleProtocol_Parse_AVRecord \ No newline at end of file diff --git a/XEngine_Source/XEngine_ModuleProtocol/pch.cpp b/XEngine_Source/XEngine_ModuleProtocol/pch.cpp index 925217b..e72da38 100644 --- a/XEngine_Source/XEngine_ModuleProtocol/pch.cpp +++ b/XEngine_Source/XEngine_ModuleProtocol/pch.cpp @@ -213,4 +213,8 @@ extern "C" bool ModuleProtocol_Parse_Machine(LPCXSTR lpszMsgBuffer, int nMsgLen, extern "C" bool ModuleProtocol_Parse_Oil(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_OILINFO* pSt_OilInfo) { return m_ProtocolParse.ModuleProtocol_Parse_Oil(lpszMsgBuffer, nMsgLen, pSt_OilInfo); +} +extern "C" bool ModuleProtocol_Parse_AVRecord(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_AVRECORD* pSt_AVRecord) +{ + return m_ProtocolParse.ModuleProtocol_Parse_AVRecord(lpszMsgBuffer, nMsgLen, pSt_AVRecord); } \ No newline at end of file diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile index 725f1cb..e4b74cb 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/Makefile @@ -14,7 +14,7 @@ LIBEX = OBJECTS = XEngine_Configure.o XEngine_Network.o XEngine_HTTPTask.o XEngine_PluginTask.o XEngine_HttpApp.o \ RFCTask_Ntp.o RFCTask_Stun.o RFCTask_Dns.o \ TaskGet_Bank.o TaskGet_IDCard.o TaskGet_Locker.o TaskGet_Translation.o TaskGet_Reload.o TaskGet_Weather.o TaskGet_IDRegion.o TaskGet_Oil.o TaskGet_APIModule.o \ - TaskPost_DTest.o TaskPost_Log.o TaskPost_P2PClient.o TaskPost_PostCode.o TaskPost_QRCode.o TaskPost_ShortLink.o TaskPost_SocketTest.o TaskPost_WordFilter.o TaskPost_Image.o TaskPost_BackService.o TaskPost_Deamon.o TaskPost_Machine.o + TaskPost_DTest.o TaskPost_Log.o TaskPost_P2PClient.o TaskPost_PostCode.o TaskPost_QRCode.o TaskPost_ShortLink.o TaskPost_SocketTest.o TaskPost_WordFilter.o TaskPost_Image.o TaskPost_BackService.o TaskPost_Deamon.o TaskPost_Machine.o TaskPost_AVRecord.o ifeq ($(RELEASE),1) FLAGS = -c -D _RELEASE @@ -117,6 +117,8 @@ TaskPost_Deamon.o:./XEngine_TaskPost/TaskPost_Deamon.cpp $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./XEngine_TaskPost/TaskPost_Deamon.cpp TaskPost_Machine.o:./XEngine_TaskPost/TaskPost_Machine.cpp $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./XEngine_TaskPost/TaskPost_Machine.cpp +TaskPost_AVRecord.o:./XEngine_TaskPost/TaskPost_AVRecord.cpp + $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./XEngine_TaskPost/TaskPost_AVRecord.cpp XEngine_HttpApp.o:./XEngine_HttpApp.cpp $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./XEngine_HttpApp.cpp diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_Hdr.h b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_Hdr.h index 0a6d5e2..51837ee 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_Hdr.h +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_Hdr.h @@ -110,6 +110,7 @@ using namespace std; #include "XEngine_TaskPost/TaskPost_Image.h" #include "XEngine_TaskPost/TaskPost_Deamon.h" #include "XEngine_TaskPost/TaskPost_Machine.h" +#include "XEngine_TaskPost/TaskPost_AVRecord.h" //get #include "XEngine_TaskGet/TaskGet_IDCard.h" #include "XEngine_TaskGet/TaskGet_Bank.h" diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.vcxproj b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.vcxproj index 55e051f..982e5bb 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.vcxproj +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.vcxproj @@ -238,6 +238,7 @@ + @@ -270,6 +271,7 @@ + diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.vcxproj.filters b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.vcxproj.filters index aab67b7..f101055 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.vcxproj.filters +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HttpApp.vcxproj.filters @@ -120,6 +120,9 @@ 源文件\XEngine_TaskRfc + + 源文件\XEngine_TaskPost + @@ -212,5 +215,8 @@ 头文件\XEngine_TaskRfc + + 头文件\XEngine_TaskPost + \ No newline at end of file diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp new file mode 100644 index 0000000..89ddf06 --- /dev/null +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp @@ -0,0 +1,208 @@ +#include "../XEngine_Hdr.h" + +static bool bRecord = false; +static XHANDLE xhVideo = NULL; +static XHANDLE xhAudio = NULL; +static XHANDLE xhSound = NULL; +static XHANDLE xhScreen = NULL; +static XHANDLE xhPacket = NULL; +static XHANDLE xhFilter = 0; + +void XCALLBACK HTTPTask_TaskPost_CBVideo(XHANDLE*** pppSt_AVBuffer, XPVOID lParam) +{ + int nListCount = 0; + XHANDLE** ppSt_AVPacket; + VideoCodec_Stream_EnCodec(xhVideo, pppSt_AVBuffer, &ppSt_AVPacket, &nListCount); + for (int i = 0; i < nListCount; i++) + { + AVFormat_Packet_StreamWrite(xhPacket, 0, ppSt_AVPacket[i]); + } + AVHelp_Memory_FreeAVList(&ppSt_AVPacket, nListCount); +} +void XCALLBACK HTTPTask_TaskPost_CBAudio(XHANDLE*** pppSt_AVBuffer, XPVOID lParam) +{ + int nListCount = 0; + XHANDLE** ppSt_MSGBuffer; + AVFilter_Audio_Cvt(xhFilter, pppSt_AVBuffer, &ppSt_MSGBuffer, &nListCount); + for (int i = 0; i < nListCount; i++) + { + int nAudioCount = 0; + XHANDLE** ppSt_AVPacket; + AudioCodec_Stream_EnCodec(xhAudio, ppSt_MSGBuffer[i], &ppSt_AVPacket, &nAudioCount); + for (int j = 0; j < nAudioCount; j++) + { + AVFormat_Packet_StreamWrite(xhPacket, 1, ppSt_AVPacket[j]); + } + AVHelp_Memory_FreeAVList(&ppSt_AVPacket, nAudioCount); + } + AVHelp_Memory_FreeAVList(&ppSt_MSGBuffer, nListCount, false); +} + +bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, int nType) +{ + int nSDLen = 0; + int nRVLen = 0; + CXEngine_MemoryPoolEx m_MemorySend(XENGINE_MEMORY_SIZE_MAX); + CXEngine_MemoryPoolEx m_MemoryRecv(XENGINE_MEMORY_SIZE_MAX); + + RFCCOMPONENTS_HTTP_HDRPARAM st_HDRParam = {}; //发送给客户端的参数 + + st_HDRParam.nHttpCode = 200; //HTTP CODE码 + st_HDRParam.bIsClose = true; //收到回复后就关闭 + if (bRecord) + { + st_HDRParam.nHttpCode = 400; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,因为已经在录制中了"), lpszClientAddr); + return false; + } + + XENGINE_AVRECORD st_AVRecord = {}; + if (!ModuleProtocol_Parse_AVRecord(lpszMsgBuffer, nMsgLen, &st_AVRecord)) + { + return false; + } + //屏幕采集 + AVCOLLECT_SCREENINFO st_AVScreen = {}; + + st_AVScreen.nFrameRate = 24; + st_AVScreen.nPosX = 0; + st_AVScreen.nPosY = 0; + _xstprintf(st_AVScreen.tszVideoSize, _X("%s"), st_AVRecord.tszRsolution); +#ifdef _MSC_BUILD + xhScreen = AVCollect_Video_Init("gdigrab", st_AVRecord.tszVideoDevice, &st_AVScreen, HTTPTask_TaskPost_CBVideo); +#elif __linux__ + xhScreen = AVCollect_Video_Init("x11grab", st_AVRecord.tszVideoDevice, &st_AVScreen, HTTPTask_TaskPost_CBVideo); +#else + xhScreen = AVCollect_Video_Init("avfoundation", st_AVRecord.tszVideoDevice, &st_AVScreen, HTTPTask_TaskPost_CBVideo); +#endif + if (NULL == xhScreen) + { + st_HDRParam.nHttpCode = 400; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,屏幕采集器请求失败,错误码:%lX"), lpszClientAddr, AVCollect_GetLastError()); + return false; + } + xhPacket = AVFormat_Packet_Init(); + if (!AVFormat_Packet_Output(xhPacket, st_AVRecord.tszFilePath, _X("flv"))) + { + st_HDRParam.nHttpCode = 400; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,推流服务端:%s 连接失败,错误码:%lX"), lpszClientAddr, st_AVRecord.tszFilePath, AVFormat_GetLastError()); + return false; + } + XHANDLE xhVideoCodec = NULL; + //初始化屏幕编码器 + XENGINE_PROTOCOL_AVINFO st_AVInfo = {}; + AVCollect_Video_GetInfo(xhScreen, &st_AVInfo); + st_AVInfo.st_VideoInfo.enAVCodec = ENUM_XENGINE_AVCODEC_VIDEO_TYPE_H264; + xhVideo = VideoCodec_Stream_EnInit(&st_AVInfo.st_VideoInfo); + if (NULL == xhVideo) + { + st_HDRParam.nHttpCode = 500; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,打开编码器视频编码器失败,错误码:%lX"), lpszClientAddr, VideoCodec_GetLastError()); + return false; + } + VideoCodec_Stream_GetAVCodec(xhVideo, &xhVideoCodec); + AVFormat_Packet_StreamCreate(xhPacket, xhVideoCodec); + BaseLib_Memory_FreeCStyle((XPPMEM)&xhVideoCodec); + //启用音频 + if (_tcsxlen(st_AVRecord.tszAudioDevice) > 0) + { +#ifdef _MSC_BUILD + xhSound = AVCollect_Audio_Init("dshow", st_AVRecord.tszAudioDevice, HTTPTask_TaskPost_CBAudio); +#elif __linux__ + xhSound = AVCollect_Audio_Init("alsa", st_AVRecord.tszAudioDevice, HTTPTask_TaskPost_CBAudio); +#else + xhSound = AVCollect_Audio_Init("avfoundation", st_AVRecord.tszAudioDevice, HTTPTask_TaskPost_CBAudio); +#endif + if (NULL == xhSound) + { + st_HDRParam.nHttpCode = 400; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,初始化音频采集器请求失败,错误码:%lX"), lpszClientAddr, AVCollect_GetLastError()); + return false; + } + AVCollect_Audio_GetInfo(xhSound, &st_AVInfo); + AVFILTER_AUDIO_INFO st_AudioFilter = {}; + st_AudioFilter.nIndex = 0; + st_AudioFilter.st_AudioInfo = st_AVInfo.st_AudioInfo; + AVCollect_Audio_GetTimeBase(xhSound, &st_AudioFilter.st_AudioTime); + xhFilter = AVFilter_Audio_Init(_X("aresample=44100,aformat=sample_fmts=fltp:channel_layouts=stereo"), &st_AudioFilter); + if (NULL == xhFilter) + { + st_HDRParam.nHttpCode = 400; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,初始化音频滤镜失败,错误码:%lX"), lpszClientAddr, AVFilter_GetLastError()); + return false; + } + st_AVInfo.st_AudioInfo.nSampleRate = 44100; + st_AVInfo.st_AudioInfo.nSampleFmt = ENUM_AVCODEC_AUDIO_SAMPLEFMT_FLTP; + st_AVInfo.st_AudioInfo.enAVCodec = ENUM_XENGINE_AVCODEC_AUDIO_TYPE_AAC; + xhAudio = AudioCodec_Stream_EnInit(&st_AVInfo.st_AudioInfo); + if (NULL == xhAudio) + { + st_HDRParam.nHttpCode = 400; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,初始化音频采集器请求失败,错误码:%lX"), lpszClientAddr, AudioCodec_GetLastError()); + return false; + } + XHANDLE xhAudioCodec = NULL; + AudioCodec_Stream_GetAVCodec(xhAudio, &xhAudioCodec); + AVFormat_Packet_StreamCreate(xhPacket, xhAudioCodec); + //使用了滤镜,需要单独设置 + AVCODEC_TIMEBASE st_TimeBase = {}; + st_TimeBase.nDen = 44100; + st_TimeBase.nNum = 1; + AVFormat_Packet_TimeBase(xhPacket, 1, &st_TimeBase); + BaseLib_Memory_FreeCStyle((XPPMEM)&xhAudioCodec); + } + bRecord = true; + AVFormat_Packet_Start(xhPacket); + AVCollect_Audio_Start(xhSound); + AVCollect_Video_Start(xhScreen); + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,开始屏幕录制,音频:%s,视频:%s 推流:%s 请求成功"), lpszClientAddr, st_AVRecord.tszAudioDevice, st_AVRecord.tszVideoDevice, st_AVRecord.tszFilePath); + return true; +} +bool HTTPTask_TaskPost_AVRecordStop(LPCXSTR lpszClientAddr) +{ + bRecord = false; + + AVCollect_Video_Destory(xhScreen); + AVCollect_Audio_Destory(xhSound); + + VideoCodec_Stream_Destroy(xhVideo); + AudioCodec_Stream_Destroy(xhAudio); + + AVFilter_Audio_Destroy(xhFilter); + + AVFormat_Packet_Stop(xhPacket); + xhScreen = NULL; + xhSound = NULL; + xhVideo = NULL; + xhAudio = NULL; + xhPacket = NULL; + + int nMSGLen = 0; + XCHAR tszMSGBuffer[XPATH_MAX] = {}; + RFCCOMPONENTS_HTTP_HDRPARAM st_HDRParam = {}; //发送给客户端的参数 + + st_HDRParam.nHttpCode = 200; //HTTP CODE码 + st_HDRParam.bIsClose = true; //收到回复后就关闭 + + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszMSGBuffer, &nMSGLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, tszMSGBuffer, nMSGLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,停止屏幕录制推流请求成功"), lpszClientAddr); + + return true; +} \ No newline at end of file diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.h b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.h new file mode 100644 index 0000000..35bd8e4 --- /dev/null +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.h @@ -0,0 +1,6 @@ +#pragma once +void XCALLBACK HTTPTask_TaskPost_CBVideo(XHANDLE*** pppSt_AVBuffer, XPVOID lParam); +void XCALLBACK HTTPTask_TaskPost_CBAudio(XHANDLE*** pppSt_AVBuffer, XPVOID lParam); + +bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, int nType); +bool HTTPTask_TaskPost_AVRecordStop(LPCXSTR lpszClientAddr); \ No newline at end of file diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.cpp index 2cd076e..dc50f1a 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.cpp @@ -1,43 +1,5 @@ #include "../XEngine_Hdr.h" -static bool bRecord = false; -static XHANDLE xhVideo = NULL; -static XHANDLE xhAudio = NULL; -static XHANDLE xhSound = NULL; -static XHANDLE xhScreen = NULL; -static XHANDLE xhPacket = NULL; -static XHANDLE xhFilter = 0; - -void XCALLBACK HTTPTask_TaskPost_CBVideo(XHANDLE*** pppSt_AVBuffer, XPVOID lParam) -{ - int nListCount = 0; - XHANDLE** ppSt_AVPacket; - VideoCodec_Stream_EnCodec(xhVideo, pppSt_AVBuffer, &ppSt_AVPacket, &nListCount); - for (int i = 0; i < nListCount; i++) - { - AVFormat_Packet_StreamWrite(xhPacket, 0, ppSt_AVPacket[i]); - } - AVHelp_Memory_FreeAVList(&ppSt_AVPacket, nListCount); -} -void XCALLBACK HTTPTask_TaskPost_CBAudio(XHANDLE*** pppSt_AVBuffer, XPVOID lParam) -{ - int nListCount = 0; - XHANDLE** ppSt_MSGBuffer; - AVFilter_Audio_Cvt(xhFilter, pppSt_AVBuffer, &ppSt_MSGBuffer, &nListCount); - for (int i = 0; i < nListCount; i++) - { - int nAudioCount = 0; - XHANDLE** ppSt_AVPacket; - AudioCodec_Stream_EnCodec(xhAudio, ppSt_MSGBuffer[i], &ppSt_AVPacket, &nAudioCount); - for (int j = 0; j < nAudioCount; j++) - { - AVFormat_Packet_StreamWrite(xhPacket, 1, ppSt_AVPacket[j]); - } - AVHelp_Memory_FreeAVList(&ppSt_AVPacket, nAudioCount); - } - AVHelp_Memory_FreeAVList(&ppSt_MSGBuffer, nListCount, false); -} - bool HTTPTask_TaskPost_BackService(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, int nType) { int nSDLen = 0; @@ -294,152 +256,6 @@ bool HTTPTask_TaskPost_BackService(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s:请求上报信息成功,上报类型:%d"), lpszClientAddr, nBSType); } break; - case XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_BS_RECORDSTART: - { - if (bRecord) - { - st_HDRParam.nHttpCode = 400; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,因为已经在录制中了"), lpszClientAddr); - return false; - } - //屏幕采集 - AVCOLLECT_SCREENINFO st_AVScreen; - memset(&st_AVScreen, '\0', sizeof(AVCOLLECT_SCREENINFO)); - - st_AVScreen.nFrameRate = 24; - st_AVScreen.nPosX = 0; - st_AVScreen.nPosY = 0; - _xstprintf(st_AVScreen.tszVideoSize, _X("%s"), _X("1920x1080")); -#ifdef _MSC_BUILD - xhScreen = AVCollect_Video_Init("gdigrab", tszDstBuffer, &st_AVScreen, HTTPTask_TaskPost_CBVideo); -#elif __linux__ - xhScreen = AVCollect_Video_Init("x11grab", tszDstBuffer, &st_AVScreen, HTTPTask_TaskPost_CBVideo); -#else - xhScreen = AVCollect_Video_Init("avfoundation", tszDstBuffer, &st_AVScreen, HTTPTask_TaskPost_CBVideo); -#endif - if (NULL == xhScreen) - { - st_HDRParam.nHttpCode = 400; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,屏幕采集器请求失败,错误码:%lX"), lpszClientAddr, AVCollect_GetLastError()); - return false; - } - xhPacket = AVFormat_Packet_Init(); - if (!AVFormat_Packet_Output(xhPacket, tszAPIBuffer, _X("flv"))) - { - st_HDRParam.nHttpCode = 400; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,推流服务端:%s 连接失败,错误码:%lX"), lpszClientAddr, tszAPIBuffer, AVFormat_GetLastError()); - return false; - } - XHANDLE xhVideoCodec = NULL; - //初始化屏幕编码器 - XENGINE_PROTOCOL_AVINFO st_AVInfo = {}; - AVCollect_Video_GetInfo(xhScreen, &st_AVInfo); - st_AVInfo.st_VideoInfo.enAVCodec = ENUM_XENGINE_AVCODEC_VIDEO_TYPE_H264; - xhVideo = VideoCodec_Stream_EnInit(&st_AVInfo.st_VideoInfo); - if (NULL == xhVideo) - { - st_HDRParam.nHttpCode = 500; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,打开编码器视频编码器失败,错误码:%lX"), lpszClientAddr, VideoCodec_GetLastError()); - return false; - } - VideoCodec_Stream_GetAVCodec(xhVideo, &xhVideoCodec); - AVFormat_Packet_StreamCreate(xhPacket, xhVideoCodec); - BaseLib_Memory_FreeCStyle((XPPMEM)&xhVideoCodec); - //启用音频 - if (1 == nBSType) - { -#ifdef _MSC_BUILD - xhSound = AVCollect_Audio_Init("dshow", tszSrcBuffer, HTTPTask_TaskPost_CBAudio); -#elif __linux__ - xhSound = AVCollect_Audio_Init("alsa", tszSrcBuffer, HTTPTask_TaskPost_CBAudio); -#else - xhSound = AVCollect_Audio_Init("avfoundation", tszSrcBuffer, HTTPTask_TaskPost_CBAudio); -#endif - if (NULL == xhSound) - { - st_HDRParam.nHttpCode = 400; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,初始化音频采集器请求失败,错误码:%lX"), lpszClientAddr, AVCollect_GetLastError()); - return false; - } - AVCollect_Audio_GetInfo(xhSound, &st_AVInfo); - AVFILTER_AUDIO_INFO st_AudioFilter = {}; - st_AudioFilter.nIndex = 0; - st_AudioFilter.st_AudioInfo = st_AVInfo.st_AudioInfo; - AVCollect_Audio_GetTimeBase(xhSound, &st_AudioFilter.st_AudioTime); - xhFilter = AVFilter_Audio_Init(_X("aresample=44100,aformat=sample_fmts=fltp:channel_layouts=stereo"), &st_AudioFilter); - if (NULL == xhFilter) - { - st_HDRParam.nHttpCode = 400; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,初始化音频滤镜失败,错误码:%lX"), lpszClientAddr, AVFilter_GetLastError()); - return false; - } - st_AVInfo.st_AudioInfo.nSampleRate = 44100; - st_AVInfo.st_AudioInfo.nSampleFmt = ENUM_AVCODEC_AUDIO_SAMPLEFMT_FLTP; - st_AVInfo.st_AudioInfo.enAVCodec = ENUM_XENGINE_AVCODEC_AUDIO_TYPE_AAC; - xhAudio = AudioCodec_Stream_EnInit(&st_AVInfo.st_AudioInfo); - if (NULL == xhAudio) - { - st_HDRParam.nHttpCode = 400; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,初始化音频采集器请求失败,错误码:%lX"), lpszClientAddr, AudioCodec_GetLastError()); - return false; - } - XHANDLE xhAudioCodec = NULL; - AudioCodec_Stream_GetAVCodec(xhAudio, &xhAudioCodec); - AVFormat_Packet_StreamCreate(xhPacket, xhAudioCodec); - //使用了滤镜,需要单独设置 - AVCODEC_TIMEBASE st_TimeBase = {}; - st_TimeBase.nDen = 44100; - st_TimeBase.nNum = 1; - AVFormat_Packet_TimeBase(xhPacket, 1, &st_TimeBase); - BaseLib_Memory_FreeCStyle((XPPMEM)&xhAudioCodec); - } - bRecord = true; - AVFormat_Packet_Start(xhPacket); - AVCollect_Audio_Start(xhSound); - AVCollect_Video_Start(xhScreen); - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,开始屏幕录制,音频:%s,视频:%s 推流:%s 请求成功"), lpszClientAddr, tszSrcBuffer, tszDstBuffer, tszAPIBuffer); - } - break; - case XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_BS_RECORDSTOP: - { - bRecord = false; - - AVCollect_Video_Destory(xhScreen); - AVCollect_Audio_Destory(xhSound); - - VideoCodec_Stream_Destroy(xhVideo); - AudioCodec_Stream_Destroy(xhAudio); - - AVFilter_Audio_Destroy(xhFilter); - - AVFormat_Packet_Stop(xhPacket); - xhScreen = NULL; - xhSound = NULL; - xhVideo = NULL; - xhAudio = NULL; - xhPacket = NULL; - - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,停止屏幕录制推流请求成功"), lpszClientAddr); - } - break; case XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_BS_NOTHINGTODO: break; default: diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.h b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.h index 438f901..cf6c14f 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.h +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_BackService.h @@ -1,5 +1,2 @@ #pragma once -void XCALLBACK HTTPTask_TaskPost_CBVideo(XHANDLE*** pppSt_AVBuffer, XPVOID lParam); -void XCALLBACK HTTPTask_TaskPost_CBAudio(XHANDLE*** pppSt_AVBuffer, XPVOID lParam); - bool HTTPTask_TaskPost_BackService(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, int nType); \ No newline at end of file diff --git a/XEngine_Source/XEngine_UserProtocol.h b/XEngine_Source/XEngine_UserProtocol.h index 137ae5f..9ae21b0 100644 --- a/XEngine_Source/XEngine_UserProtocol.h +++ b/XEngine_Source/XEngine_UserProtocol.h @@ -84,8 +84,6 @@ typedef enum #define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_BS_SHUTDOWN 0x5008 //远程关闭计算机 #define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_BS_ECMD 0x5009 //执行命令 #define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_BS_REPORT 0x5010 //报告信息 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_BS_RECORDSTART 0x5011 //开始视频录制 -#define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_BS_RECORDSTOP 0x5012 //停止视频录制 //P2XP协议 #define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_P2XP_REQLOGIN 0x6001 //登录 #define XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_P2XP_REPLOGIN 0x6002 @@ -283,4 +281,11 @@ typedef struct XCHAR tszUPTime[64]; //更新时间 XCHAR tszNextTime[64]; //更新时间 }XENGINE_OILINFO; +typedef struct +{ + XCHAR tszFilePath[XPATH_MID]; //文件路径 + XCHAR tszVideoDevice[XPATH_MIN]; //视频设备 + XCHAR tszAudioDevice[XPATH_MIN]; //音频设备 + XCHAR tszRsolution[64]; //分辨率 +}XENGINE_AVRECORD; #pragma pack(pop) \ No newline at end of file From 072df08ec682a10530720165659f91afd80c1954 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 3 Feb 2026 17:16:54 +0800 Subject: [PATCH 16/20] modify:does not are case-insensitive for http function name --- .../XEngine_HttpApp/XEngine_HTTPTask.cpp | 67 ++++++++++++------- .../XEngine_TaskPost/TaskPost_AVRecord.cpp | 2 +- .../XEngine_TaskPost/TaskPost_AVRecord.h | 2 +- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp index e67ac62..5fef5b1 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_HTTPTask.cpp @@ -248,11 +248,12 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST LPCXSTR lpszParamImage = _X("image"); LPCXSTR lpszParamDeamon = _X("deamon"); LPCXSTR lpszParamMachine = _X("machine"); + LPCXSTR lpszParamAVRecord = _X("avrecord"); memset(tszKey, '\0', XPATH_MAX); memset(tszValue, '\0', XPATH_MAX); - if (0 != _tcsxnicmp(lpszFuncName, tszUrlName, _tcsxlen(lpszFuncName))) + if (0 != _tcsxncmp(lpszFuncName, tszUrlName, _tcsxlen(lpszFuncName))) { st_HDRParam.nHttpCode = 404; HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam); @@ -263,7 +264,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST } //获得函数名 BaseLib_String_GetKeyValue(pptszList[0], "=", tszKey, tszValue); - if (0 != _tcsxnicmp(lpszParamFuncKey, tszKey, _tcsxlen(lpszParamFuncKey))) + if (0 != _tcsxncmp(lpszParamFuncKey, tszKey, _tcsxlen(lpszParamFuncKey))) { st_HDRParam.nHttpCode = 404; HttpProtocol_Server_SendMsgEx(xhHTTPPacket, tszSDBuffer, &nSDLen, &st_HDRParam); @@ -279,9 +280,9 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST XEngine_PluginTask_Handle(tszValue, lpszClientAddr, lpszMSGBuffer, nMSGLen, &pptszList, nListCount, nPluginType); return true; } - if (0 == _tcsxnicmp(lpszMethodPost, pSt_HTTPParam->tszHttpMethod, _tcsxlen(lpszMethodPost))) + if (0 == _tcsxncmp(lpszMethodPost, pSt_HTTPParam->tszHttpMethod, _tcsxlen(lpszMethodPost))) { - if (0 == _tcsxnicmp(lpszParamP2PClient, tszValue, _tcsxlen(lpszParamP2PClient))) + if (0 == _tcsxncmp(lpszParamP2PClient, tszValue, _tcsxlen(lpszParamP2PClient))) { //是不是P2P memset(tszKey, '\0', sizeof(tszKey)); @@ -289,7 +290,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszValue); HTTPTask_TastPost_P2PClient(lpszClientAddr, lpszMSGBuffer, nMSGLen, _ttxoi(tszValue)); } - else if (0 == _tcsxnicmp(lpszParamZIPCode, tszValue, _tcsxlen(lpszParamZIPCode))) + else if (0 == _tcsxncmp(lpszParamZIPCode, tszValue, _tcsxlen(lpszParamZIPCode))) { //邮政信息:http://app.xyry.org:5501/api?function=zipcode¶ms1=0 memset(tszKey, '\0', sizeof(tszKey)); @@ -297,7 +298,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszValue); HTTPTask_TastPost_PostCode(lpszClientAddr, lpszMSGBuffer, nMSGLen, _ttxoi(tszValue)); } - else if (0 == _tcsxnicmp(lpszParamXLog, tszValue, _tcsxlen(lpszParamXLog))) + else if (0 == _tcsxncmp(lpszParamXLog, tszValue, _tcsxlen(lpszParamXLog))) { //日志信息:http://app.xyry.org:5501/api?function=log¶ms1=0 memset(tszKey, '\0', sizeof(tszKey)); @@ -305,7 +306,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszValue); HTTPTask_TastPost_LogInfo(lpszClientAddr, lpszMSGBuffer, nMSGLen, _ttxoi(tszValue)); } - else if (0 == _tcsxnicmp(lpszParamQRCode, tszValue, _tcsxlen(lpszParamQRCode))) + else if (0 == _tcsxncmp(lpszParamQRCode, tszValue, _tcsxlen(lpszParamQRCode))) { //二维码生成:http://app.xyry.org:5501/api?function=qrcode¶ms1=0 或者 1 memset(tszKey, '\0', sizeof(tszKey)); @@ -313,7 +314,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszValue); HTTPTask_TaskPost_QRCode(lpszClientAddr, lpszMSGBuffer, nMSGLen, _ttxoi(tszValue)); } - else if (0 == _tcsxnicmp(lpszParamSocket, tszValue, _tcsxlen(lpszParamSocket))) + else if (0 == _tcsxncmp(lpszParamSocket, tszValue, _tcsxlen(lpszParamSocket))) { //网络测试:http://app.xyry.org:5501/api?function=socket¶ms1=0 或者 1 memset(tszKey, '\0', sizeof(tszKey)); @@ -321,7 +322,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszValue); HTTPTask_TastPost_SocketTest(lpszClientAddr, lpszMSGBuffer, nMSGLen, _ttxoi(tszValue)); } - else if (0 == _tcsxnicmp(lpszParamDTest, tszValue, _tcsxlen(lpszParamDTest))) + else if (0 == _tcsxncmp(lpszParamDTest, tszValue, _tcsxlen(lpszParamDTest))) { //数据测试:http://app.xyry.org:5501/api?function=dtest¶ms1=0 或者 1 memset(tszKey, '\0', sizeof(tszKey)); @@ -329,7 +330,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszValue); HTTPTask_TastPost_DTest(lpszClientAddr, lpszMSGBuffer, nMSGLen, _ttxoi(tszValue)); } - else if (0 == _tcsxnicmp(lpszParamShortLink, tszValue, _tcsxlen(lpszParamShortLink))) + else if (0 == _tcsxncmp(lpszParamShortLink, tszValue, _tcsxlen(lpszParamShortLink))) { //短连接:http://app.xyry.org:5501/api?function=slink¶ms1=0 XCHAR tszType[64]; @@ -338,7 +339,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszType); HTTPTask_TaskPost_ShortLink(lpszClientAddr, lpszMSGBuffer, nMSGLen, _ttxoi(tszType)); } - else if (0 == _tcsxnicmp(lpszParamWordFilter, tszValue, _tcsxlen(lpszParamWordFilter))) + else if (0 == _tcsxncmp(lpszParamWordFilter, tszValue, _tcsxlen(lpszParamWordFilter))) { //敏感词:http://app.xyry.org:5501/api?function=wordfilter¶ms1=0 XCHAR tszType[64]; @@ -347,7 +348,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszType); HTTPTask_TastPost_WordFilter(lpszClientAddr, lpszMSGBuffer, nMSGLen, _ttxoi(tszType)); } - else if (0 == _tcsxnicmp(lpszParamBack, tszValue, _tcsxlen(lpszParamBack))) + else if (0 == _tcsxncmp(lpszParamBack, tszValue, _tcsxlen(lpszParamBack))) { //后台管理接口:http://app.xyry.org:5501/api?function=back¶ms1=0 XCHAR tszType[64]; @@ -363,12 +364,12 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszType); HTTPTask_TaskPost_BackService(lpszClientAddr, lpszMSGBuffer, nMSGLen, _ttxoi(tszType)); } - else if (0 == _tcsxnicmp(lpszParamImage, tszValue, _tcsxlen(lpszParamImage))) + else if (0 == _tcsxncmp(lpszParamImage, tszValue, _tcsxlen(lpszParamImage))) { //图像处理接口:http://app.xyry.org:5501/api?function=image¶ms1=0 HTTPTask_TaskPost_Image(lpszClientAddr, lpszMSGBuffer, nMSGLen, &pptszList, nListCount); } - else if (0 == _tcsxnicmp(lpszParamDeamon, tszValue, _tcsxlen(lpszParamDeamon))) + else if (0 == _tcsxncmp(lpszParamDeamon, tszValue, _tcsxlen(lpszParamDeamon))) { //守护进程接口:http://app.xyry.org:5501/api?function=deamon¶ms1=0 if (st_ServiceConfig.st_XVerifcation.st_VerSwitch.bDeamon && !bVerification) @@ -380,7 +381,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST } HTTPTask_TaskPost_Deamon(lpszClientAddr, lpszMSGBuffer, nMSGLen); } - else if (0 == _tcsxnicmp(lpszParamMachine, tszValue, _tcsxlen(lpszParamMachine))) + else if (0 == _tcsxncmp(lpszParamMachine, tszValue, _tcsxlen(lpszParamMachine))) { //信息收集接口:http://app.xyry.org:5501/api?function=machine¶ms1=0 XCHAR tszType[64]; @@ -389,6 +390,22 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszType); HTTPTask_TastPost_Machine(lpszClientAddr, lpszMSGBuffer, nMSGLen, _ttxoi(tszType)); } + else if (0 == _tcsxncmp(lpszParamAVRecord, tszValue, _tcsxlen(lpszParamAVRecord))) + { + //信息收集接口:http://app.xyry.org:5501/api?function=avrecord¶ms1=start 或者 stop + XCHAR tszType[64]; + memset(tszType, '\0', sizeof(tszType)); + + BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszType); + if (0 == _tcsxncmp(_X("start"), tszType, 5)) + { + HTTPTask_TaskPost_AVRecordStart(lpszClientAddr, lpszMSGBuffer, nMSGLen); + } + else + { + HTTPTask_TaskPost_AVRecordStop(lpszClientAddr); + } + } else { st_HDRParam.nHttpCode = 404; @@ -397,16 +414,16 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,发送的请求不支持:%s,内容:\r\n%s"), lpszClientAddr, tszGBKBuffer, lpszMSGBuffer); } } - else if (0 == _tcsxnicmp(lpszMethodGet, pSt_HTTPParam->tszHttpMethod, _tcsxlen(lpszMethodGet))) + else if (0 == _tcsxncmp(lpszMethodGet, pSt_HTTPParam->tszHttpMethod, _tcsxlen(lpszMethodGet))) { - if (0 == _tcsxnicmp(lpszParamReload, tszValue, _tcsxlen(lpszParamReload))) + if (0 == _tcsxncmp(lpszParamReload, tszValue, _tcsxlen(lpszParamReload))) { //是不是配置重载 memset(tszKey, '\0', sizeof(tszKey)); BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszValue); HTTPTask_TaskGet_Reload(lpszClientAddr, tszValue); } - else if (0 == _tcsxnicmp(lpszParamIDCard, tszValue, _tcsxlen(lpszParamIDCard))) + else if (0 == _tcsxncmp(lpszParamIDCard, tszValue, _tcsxlen(lpszParamIDCard))) { //是不是身份证查询 memset(tszKey, '\0', sizeof(tszKey)); @@ -414,7 +431,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszValue); HTTPTask_TaskGet_IDCard(lpszClientAddr, tszValue); } - else if (0 == _tcsxnicmp(lpszParamBank, tszValue, _tcsxlen(lpszParamBank))) + else if (0 == _tcsxncmp(lpszParamBank, tszValue, _tcsxlen(lpszParamBank))) { //是不是银行卡信息 memset(tszKey, '\0', sizeof(tszKey)); @@ -422,7 +439,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszValue); HTTPTask_TaskGet_BankInfo(lpszClientAddr, tszValue); } - else if (0 == _tcsxnicmp(lpszParamTranslation, tszValue, _tcsxlen(lpszParamTranslation))) + else if (0 == _tcsxncmp(lpszParamTranslation, tszValue, _tcsxlen(lpszParamTranslation))) { //是不是翻译 XCHAR tszMSGBuffer[2048] = {}; @@ -434,7 +451,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[3], "=", tszKey, tszDstBuffer); HTTPTask_TaskGet_Translation(lpszClientAddr, tszMSGBuffer, tszSrcBuffer, tszDstBuffer); } - else if (0 == _tcsxnicmp(lpszParamLocker, tszValue, _tcsxlen(lpszParamLocker))) + else if (0 == _tcsxncmp(lpszParamLocker, tszValue, _tcsxlen(lpszParamLocker))) { //是不是分布式锁 XCHAR tszLockToken[128]; @@ -448,7 +465,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[2], "=", tszKey, tszLockType); HTTPTask_TaskGet_Locker(lpszClientAddr, _ttxoll(tszLockToken), (ENUM_XENGINE_APISERVICE_LOCKER_TYPE)_ttxoi(tszLockType)); } - else if (0 == _tcsxnicmp(lpszParamWeather, tszValue, _tcsxlen(lpszParamWeather))) + else if (0 == _tcsxncmp(lpszParamWeather, tszValue, _tcsxlen(lpszParamWeather))) { //天气:http://127.0.0.1:5501/api?function=weather¶ms1=110101 XCHAR tszIDAddr[128] = {}; @@ -456,7 +473,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszIDAddr); HTTPTask_TaskGet_WeatherInfo(lpszClientAddr, tszIDAddr); } - else if (0 == _tcsxnicmp(lpszParamRegion, tszValue, _tcsxlen(lpszParamRegion))) + else if (0 == _tcsxncmp(lpszParamRegion, tszValue, _tcsxlen(lpszParamRegion))) { //地区ID:http://127.0.0.1:5501/api?function=region&type=1¶ms=省份¶ms=市区¶ms=县级 int nType = 0; @@ -500,7 +517,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST } } } - else if (0 == _tcsxnicmp(lpszParamOil, tszValue, _tcsxlen(lpszParamOil))) + else if (0 == _tcsxncmp(lpszParamOil, tszValue, _tcsxlen(lpszParamOil))) { //油价:http://127.0.0.1:5501/api?function=oil¶m=地区 memset(tszValue, '\0', sizeof(tszValue)); @@ -508,7 +525,7 @@ bool HTTPTask_TastPost_Handle(RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, LPCXST BaseLib_String_GetKeyValue(pptszList[1], "=", tszKey, tszValue); HTTPTask_TaskGet_Oil(lpszClientAddr, tszValue); } - else if ((0 == _tcsxnicmp(lpszParamPhone, tszValue, _tcsxlen(lpszParamPhone))) || (0 == _tcsxnicmp(lpszParamIPAddr, tszValue, _tcsxlen(lpszParamIPAddr))) || (0 == _tcsxnicmp(lpszParamMacInfo, tszValue, _tcsxlen(lpszParamMacInfo)))) + else if ((0 == _tcsxncmp(lpszParamPhone, tszValue, _tcsxlen(lpszParamPhone))) || (0 == _tcsxncmp(lpszParamIPAddr, tszValue, _tcsxlen(lpszParamIPAddr))) || (0 == _tcsxncmp(lpszParamMacInfo, tszValue, _tcsxlen(lpszParamMacInfo)))) { //phone:http://127.0.0.1:5501/api?function=phone¶m=1369943 //ip:http://127.0.0.1:5501/api?function=ip¶m=117.172.221.14&language=en diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp index 89ddf06..930b020 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp @@ -38,7 +38,7 @@ void XCALLBACK HTTPTask_TaskPost_CBAudio(XHANDLE*** pppSt_AVBuffer, XPVOID lPara AVHelp_Memory_FreeAVList(&ppSt_MSGBuffer, nListCount, false); } -bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, int nType) +bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen) { int nSDLen = 0; int nRVLen = 0; diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.h b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.h index 35bd8e4..fa6511f 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.h +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.h @@ -2,5 +2,5 @@ void XCALLBACK HTTPTask_TaskPost_CBVideo(XHANDLE*** pppSt_AVBuffer, XPVOID lParam); void XCALLBACK HTTPTask_TaskPost_CBAudio(XHANDLE*** pppSt_AVBuffer, XPVOID lParam); -bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, int nType); +bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen); bool HTTPTask_TaskPost_AVRecordStop(LPCXSTR lpszClientAddr); \ No newline at end of file From 7cbf89eb9e8494e99390264ed48fdb74d3171604 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 4 Feb 2026 10:44:20 +0800 Subject: [PATCH 17/20] modify:screen capture format support scale ci:update --- .github/workflows/msbuild.yml | 4 +-- README.en.md | 2 +- README.md | 2 +- XEngine_Docment/Docment_zh.docx | Bin 170081 -> 173218 bytes .../XEngine_TaskPost/TaskPost_AVRecord.cpp | 31 ++++++++++++++---- 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index 06982af..d107048 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -51,7 +51,7 @@ jobs: run: | cd vcpkg ./bootstrap-vcpkg.bat - ./vcpkg.exe install lua:x86-windows opencv[contrib,freetype]:x86-windows libqrencode:x86-windows leptonica:x86-windows + ./vcpkg.exe install lua:x86-windows opencv[contrib,freetype]:x86-windows libqrencode:x86-windows leptonica:x86-windows tesseract:x86-windows ./vcpkg.exe integrate install shell: pwsh - name: vcpkg install (x64) @@ -59,7 +59,7 @@ jobs: run: | cd vcpkg ./bootstrap-vcpkg.bat - ./vcpkg.exe install lua:x64-windows opencv[contrib,freetype]:x64-windows libqrencode:x64-windows leptonica:x64-windows + ./vcpkg.exe install lua:x64-windows opencv[contrib,freetype]:x64-windows libqrencode:x64-windows leptonica:x64-windows tesseract:x64-windows ./vcpkg.exe integrate install shell: pwsh - name: vcpkg install (ARM64) diff --git a/README.en.md b/README.en.md index 638139c..066f475 100644 --- a/README.en.md +++ b/README.en.md @@ -84,7 +84,7 @@ Modify the database configuration in XSQL in the configuration file to your The default configuration does not enable database support. If the database interface is required, you need to enable the database yourself #### Windows -need to vcpkg configure third-part env.refer vcpkg install guide.after installed and execution:vcpkg.exe install lua:x86-windows opencv[contrib,freetype]:x86-windows libqrencode:x86-windows leptonica:x86-windows lua:x64-windows opencv[contrib,freetype]:x64-windows libqrencode:x64-windows leptonica:x64-windows +need to vcpkg configure third-part env.refer vcpkg install guide.after installed and execution:vcpkg.exe install lua:x86-windows opencv[contrib,freetype]:x86-windows libqrencode:x86-windows leptonica:x86-windows tesseract:x86-windows lua:x64-windows opencv[contrib,freetype]:x64-windows libqrencode:x64-windows leptonica:x64-windows tesseract:x64-windows use vs open and compile,suport windows 7sp1 and above Just Run it diff --git a/README.md b/README.md index ac134fd..2b2b995 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ git clone https://gitee.com/xengine/XEngine_IPMacData.git XEngine_Source/XEngine git clone https://gitee.com/xengine/XEngine_PhoneData.git XEngine_Source/XEngine_DependLibrary/XEngine_PhoneData #### Windows -需要vcpkg配置第三方环境,具体参考vcpkg安装方式,安装好后执行:vcpkg.exe install lua:x86-windows opencv[contrib,freetype]:x86-windows libqrencode:x86-windows leptonica:x86-windows lua:x64-windows opencv[contrib,freetype]:x64-windows libqrencode:x64-windows leptonica:x64-windows +需要vcpkg配置第三方环境,具体参考vcpkg安装方式,安装好后执行:vcpkg.exe install lua:x86-windows opencv[contrib,freetype]:x86-windows libqrencode:x86-windows leptonica:x86-windows tesseract:x86-windows lua:x64-windows opencv[contrib,freetype]:x64-windows libqrencode:x64-windows leptonica:x64-windows tesseract:x64-windows 使用VS打开并且编译,支持WINDOWS 7SP1以上系统 直接运行即可 diff --git a/XEngine_Docment/Docment_zh.docx b/XEngine_Docment/Docment_zh.docx index c50abeac2bcb252aeb4580e094428f1bb3552d83..62535cc7a1683a31bdc1108af329007d5351e84c 100644 GIT binary patch delta 155271 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 delta 152104 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%0Ao_AaWK3tG2Jif*%> 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�rlev2ykgl;y>;`}R9G2k()#r5f+1k@~5J!oa@5vOWC^A&#F4c6xstg)JtQ z>N-hoK=k;By#XD-n3?I65ZWF_!{1t5C%G~kuhOGfjbF7Bo;KY2sY?~~DD%@<%IpfC zzufZNPi}8g&bc=X@tS?x5y31UI|mnrJT6@G+nEO(GIq345N-}3GZ%#(mCoO@xOU&TYR$=?y?(jf`O*wP-#~A)`@R#7F-RiG4GJ*D zN#epbi-sz!ipk2ikgL@TNuusB)KXmz$+N6^&?9R@afhlV7`B_0wCHfNnDIo0dH#K^nXzDCH_1b!4%J~?)m8*bMZ#dF zr)g(rtI^K6sGHGdg*;mPhL>FRLB*x7U;0gAmWW})>LW06-C{JmpG0yo zB?C*ZJPn$FMeI_qu zEAQ3s8-Ego)Qk#C6c#e@--A}2%x8v$U8$eqp6V%RCXX?#*fARj7>;~?j?ETQ16otA z4YnRN9_gmFCyv;nR6xm6*5I89Hw8g`hg%zwXOhjCK(CapqY;qy(T?NQdkdyQB9Mlg z%vf7QgU~)EW4=eDc$sa<&AhK_d)Z9aYnph|SCaQExN~te^@bBaj2^(HfFPX=w47%P zR?pwBPB7g#C(QnN;c?nNH-gjyI9JF(41~LOUg|#l(Ra>KczP!5={SeYhkxixxIwr- z(3Dj>S9I;Pu81x&?o{|wVy7HrEK;GG=0 z8f#g{zHW4mWP1Tc$bsQ>GUK!m9XPajVEa6VP7>{V8o?+($>~J|MUM^eG=K4won^8fTS%?^C)<6`?IR-$Om%<>Sa3bo3dp+-`~7Gkh#c|V{r>w(}+$aB++vYvfdsj5DWIc5lP739?Z;Mi@u1MH?;0;`Uxahs~ zWpcHU&+Wwy)ISI6e?`XGJlyaWE+{mN2pb{7-?ql3Rl^iHLAK02dA{1oS=oto7N9Erx?{X&P&C^W zj}Gq-sqgDLUmR`eeau3|WI;@IVI?_lxcfZBMUkzr>zfnD8CFPtNZOid%4c~&kIvw+ zp%~GQKwy1(O%)b@R$K%XR>@o?H4EF%Tg~F%D)mFA^LkR*PXB(4iHr4`7PzZ%;z6VT zOVn<|9L&1sgUa-@lQTw_ok4_P)8|cj=KnEN;e59D8S)%gJO4Z(x5vPwJ(UENL-ZDE zu9s}aWX$ZXn4&BFO;^K7VWia@0Cy`L+0@QpNgM zA93Iry{##^eBt9`HnM2R{yLA~us|BH2(PS|Lm|$3`NskX)}y@Isn>h#x!iy8nbApF z2V$?2i=g1us&qM%Cl;&6CDuw|eB3z&B8zbpdtq&M|D@0H{NVv%YLa;X$>EAm{fCpQ zkv&W;Fvku8JkZl@$GUJX>&R&5U<0I|@H_a-vm;yL*;A&G89tMxQg`0H` zgEv%g5O8hVSiKjKV=L`Bt=sUUl`Sqj-3-J(a;-X+G8rn)Cl+|j z1Rin$G%gS&*-YmC3mA@d#2GLd#Zg|Dwdvl-4|-#ZFC463}?PUSKSiK&F5~ zrlLb+VD*{X0k3P=WD5Eft6a3d#uJS>6X%-WV%sjwnj_zkbh9GVMU?M+W!rS87^CkS zVrYjDJnqvsZ^U#FU?2`H0svjEofWjVOJ5l&xB7h^tP=uD`k;XCEy} z5>t;SZUNKd_d?(U8btD4A?E|mm5>dn`xK|8(Vp0auglfUbc@$yaa(PSvXe7iaTx_^ zUH1u>4ubt8Rj(qm0{_efGK5QYV=^V9=x!n3+xdm>e*oS%4^VT^j1V0I8m9dA)aJR+# zK;A*an8Wbx6@A#@(d(6;E!?yph{zf410faT*FqvJL`Zb}zjD z35=Wfuv-X71@G-4$fATTCJ*>tXbIM&uyEAA1P<1rsDhso|WA5_f{j6j-Ph3bg&asRY zon!H-m+mu+(2kwb!kS_sZDW0XAP@6%V`up&{B6a!FX)Jw_kXCB8gh{qDzC&Qb=TwS z>|Q_2iU?^7wO?W$p(;e=rh&B;LcCz~c!+NsYNbYKG?AB#7;TJM(h(zVk$nj1tPYG3 zmWHfg=)g7PS>v0@u?x}=M{n$peyeKA?o28qO7$4&9W`0wruO6S+)@v} zZEfC+`hy{d{Gcvi+?f_eXanJDJRzmAMY_8dj6sh3xwEyr`l)O!U+xQ|9z#r=C-IKw zF+~!Q(YcfKcr#!2p5E6cdJf{}g(oh~RO&*#i;!r>fqzJd_GsN^ib4Q-3%Y2NqaB?o zngr77%p^wyt&5N{e;~89AIMiK`iVm7MD2?9ROVSrLRvyUex}o^`kS7Rxw+ym1!Nj{ms0sVAe{AC#*M{5!v8fRdQ`; z-)4z^nSYElUEKH<%B&arhs^Tji7Lby6TA7Hmgn5}Yu1oRlIJi*Shy;4ilZAUO9MF= zbr;7fhVknuj?QY~X*CtzRW{Q@PiWfG$-;LkSCF%CLYy@v)2z!dV0%?c(h`+kZ+MGf=bLxHTB@i=N$-=Q6NI#}s#F zMedY4%H0@eOuj@-){J?B=mpFkojmc`LRN_#HfNvC{i|lbDPs(O>Wr}VYkKvKx|%5` zv7mNkdMNSnm%6S~%m@U+efOuYzIn$-#RFz5gm}U%&m6J_sF)VgdCtSsCP=7q6Vh01 zKYvG5-t)IvE10>P5z4|0;T%124^|=lU>))tqaTa_P7&eE)^doS;%uTRM{#2ea*pU- zi=UY_Rn#8OY0fharnX|^yMB5;IJIbMv5oD))D46l{+y@$I6u0UKFr_>(GJ0N6G!KH z)pOOj?HOqoWB4;Vd9sHRYGGtxbG0A+RDb6R)ek>`Ja6RAbA9sG`P**!`1kCTd48}E zJ@gOc$E?4(^ABau6ao7%vpRQ3+WFf?41Pgm{iuALTiz4j3;X-glX>nNjj{-dzBqh> zMRIwA#G#sV}2_oj3WuLgqf82?KUxwK0o>KyrSPt8}$@Iet%@g zbmV%*oYBA79&0$}Y31@=f1(iwK0&l?Wv}yi=RU#n$RkB|IM1pdW(4MmQSfNv&vUL3 zm{*=RcHx`X3imA%(mv)TcNtd-3h~GL;EGAGe=WYfQ86vV3TE!+OSNE5LWn(7Obd~} zgKPcrk2xGO2Ag14_4&LG)Qin0CVzt(!1=zsQQf4|lkN{BoF{re5xU*D-&X3aqi?xV z_&fAVmw0f(TV_RV6iy^t={D~BCBz%*qO~@e=PIt4YK2+?A$4LtYl&5}yT*207zX7kRztiwTLw`+tPUMPmN5 zbb2}}{e*Z$_1UWOhq1?ioQ-}_3%VjHf?35Cm7I8=u6o)*uDR+h8QI7BXUMomt+tH5 zax{nFoW!zGxTn&xnG0q(mW2R2LYCT!S{nmzGj32Bv zqv9Bm{bS0)YOgNrB(UUJR)1tutJk_vf3UiUJ^xaXHtvG7y5}D|J|Y!(Gs*51R>7}+ z8c(NKQT&2jW<{9-a*U;Cepm^xe1y^fk=Y7HoR{wq%ZRieebCp4;g0wg#%>9HiZx#SFn`{=BIu3%0@f^z zvv6zHAKBP7qZ<`In<%BBm$s%@4o(IVqWg!R;N{C}AcSX;EM0-D3lQQNV<=0`I?r#6 z!GWwpS!-nO$RgxNb^BWL$E2gRzO=FSW$j!V-&tE;8b(fqRGx0R#OEGn|JR=V@f|GJ zX(FRs`?bL~alh^u1%F*%ZWE(YBFL68nzz2_OMrjplaGYn?fSkpF?YCPZXfTelXOV% z@0{Wjxy(B42mcY$4)W7=<`2by5Fc!n&wt}qL{5IFom@BTDBv305|v)hj;rlh?^U(toR!J1_|GjWz5mw8yBc zSt6ks>*to3(Z)_G>&5tZ+*R*2&fxBpqaz9<(R>*Zs}~hFJM|wC^qo8ntiBOaI^ND( zpO`L2ppT}tIXb3&qdA0l!#_|27Q^@H!HXj}7I zmrzFYQ_uQgc5Ig`_KthBYRjYL+qG&9$oB4P`SBjD(de2#BR36iKq39$jlSy?cjnK` zQqhtJ!j?jaO=R!8hI$5fV)RDkzZ1R6(Cge*^TI6LHh+;bjQj6sH;7zjTj<3Yks-&p z|F#{|;0b9tFYFz-We~ZtVK=jh^A30OYFI(BLz9esJ%sd%Ok%egqfHR`oO1}l zwxj+Ob)7q=(PMNakcB;Nb`OUb&s-liQERw^vtd?5Nay|q!3HBL&%h*xAkWB&CTH*vQzA%B%K^w+F~D^J$69}^RVL}d;mF}W3y z7=OyY6KR9|Y?7gTZ_j6qnZuWSAirKxt`9pWt*=VAy6M9hzmRUI zF@M(9hR3|lwX@j952SKefVE{Q&?6&6lnYl!;;`^P-O)V|-?r%1<+FWcdwE|U5k;&B z5fXjXe<2t%TF3ImjKX!oT%rv*qjFx&Iwx_gO-SVlpX=PHz(M5wm@u$z&5OV7>H@-! z;_HfC^Y7fRaAbAe9V6cfc_s0@wn&e^7=MXeG9WyQem$uEQ#-hCu_hr?K_gL{A~9}uHjBOIp)U;sSkJ6PBn}#BCT$WL~g0w5A#%ow2rH@ z(^t-qXNynKKNV6NdN8)G*^63chdsjkXQwN*iQgtsFp)uS$<~hf6f$CYp+(xcm4A&< z9%)|$|_t{rL_Gw^o(eq@&J z8csW60Yb843`|Iy{I;!>ixFHQ&VRK@+gjo|o;xNkVg>BBuW@GSw$L*8wrxAtvV+^A2HeqjANBTbCx7Un-I2+Ro|4^lm!Jn-NOM$rLVThM-Myso3xBB%6~E|P z8K_ux%)7-pqa8Co*^>9LNcgrxBlB74C-Eff?NuTaEuYu+vEA|DD^Q2du9-Dj` zJ^Fj$in@**_K4d4r61?iqX#(tPBfdq>ghdn1ES|tNZouIhgJuf>XxqOn(sZnAN_mx zSU+Z6?4f;yl^S~-JIrck1b=xLsWB!CkqF%3|CwF%37(Mv7FHfHGW9j)pa8TFvz-&<;mnUFR%d(egW!5WUO#pXGL zdxuEJ&zzdLihdtUi%-dk)>8P?XL!M^%6(SM+GE5v-z8_)!}s=yF7dcJl8ptksP@gN zp}%V1VmzHogXt`g?Puv-H|<-=#kNPRgRyYG#k&2 zJ?X0(Js3jTL=AY-)hYRbNH)?AInn6|b>oRKk?7f$KF*H1{(s~cC`)_iWHX)|c=9mE zn8eA`J6gVzmvKKx?ZX&o$B19d+B^BCi7{~@?V?xel$g4L|Frx!;YK8;O3_X{OkMqY0|r>w|`HQjYa))V%1Q!1!5SR5>mJ` zkB~NzL7w(H_ZmMvN0l@q{xEa#gepOPefp{eJEWif(&VT1=+B2M>OHe>Fm7P3Q9Dxa zgYN|w8$_*nT%333(j24ZXRKUN)1GMSgz@b&ZZ^!~Jwwb6S?8IlOzawTX4NUdcRH=G z;uqo@^8(JCKO)j+el~dx=GPYT-ZM}6PzRs+;(8|Ji!m6C6dTxE>qzl)J-QGvNJdVZ z%!IzzGTWV%%SLaW5D^~S2dkuom8oYnTbSi`)_<^sy*C4?m{)Vw%n$PqgotnO6P(VK zb!W@^qc{BgyPR={>}C^vw`a$EGyXO&h0o8v)mdZgR~lx{AIXo!%v%>7N2G;#`tfZ# zix~eor;9=28k`xKPl$Zk+46v*GbiL?_b4I8UXLTiKXJCoxuY$<(XUJ&=DVExdEq^JpN<^9Ig!DNxdcM& z!>F$iKiIYIyyBb}a9+)qPw=a?V20#*R(JxdUY!09p86*i!f)Yy&Xe}ei`-w_Z*Rps zQ$%k2*j~Tu>;V)PEE{9|k*`*eTWTYU4}bD!>_;};O)ZZ~|MVu89i<&2eOwa83U2xm ztKFOKj|}6RbF`{Qq{Ng_Mtq^J|1Z2pKi|#0a1MGjuxH=KKZ2g%n@1m5t9bKD8F`fu z`}LXKE^?QfBX;-$u@CciZq~hxF$o!$YIx7x(!FEM^-2Ib#`J{5TxddSygB?#xPOGu z2YF+%B-)T$mp+3#K8j+H_g;%ZbGX)~y9_JUg;eggB*Y$e;OcPJO3v@Jt>|rq zNDMIH-`UPyg4?8OvFC`8==MNJZ-1pAKM>*_J@q#x7GM_0?XMp6FkO$@KC}nAfj_+K zuh+zR8$xnLf0dB7vF_t~bj!rEEitz+)+WS%ecQB!e!lBp;rVknMuA{Pp%6)DM#MwV zA95uMxIdo|=>>eY7y^hf$~*KSWSw`2d82po&h(?>;hoZE7~v2VvyC~YcYnrsF?@n~ zTEe)@{mPGtenRZyoA#?UV`S)lmOiY`z2DH?&EGcMF%SQKU+2EMLPRR~Gb<0a+n6@94B7gKThQ3ZAk@bm4v4=gp zB++ZbIDfH&(dwQ*wjeevjS%1Q@j~D(WoICcKu3FTM z+HIA+lR_HDWnLTwti}^k3RZ3jv4*)GuZyf>CiCkND#l&ayVMkarvHejy_hYGD(A)Q zT4bs(rpaN>>5J)6c%Q!L;)SzSUOytF{A^Of=nr|J+tAPV{MSshC*4@k6a4(k+`m_d zb$;9ab5b?JiMBTevhY70yHD&R^Tti<2cmP2x>0mTHW5EFbuVE*lsB7Ij7hxdvdj3?(|zHz zjW<`~D(yF4u6&s`{ud}Se4FvjwtbPIDM zM3qy;9Ot)N%2@ICwzm&+e%}5PPqTY_SMEIa_9+}m5n>0m+1s~l%yE9lva#(wRwi?Q zA)7hUv40pjkBAHfM&aJ+b)skC9k<37_UydSfBo)A8GUI&qziC$ZcKf|w;@PK9`xlpi8QmloB&2!Ht!&K(OR!Xk)laWVd#T{CfIAtyO$ zvq0LUwT{^owbR}aQn}w?G`vcf#T$r-D!!i>3`7=Ih;DT9L3+&4#5oUvh^z8bUrQ8y z5%N-{iugbxBbAU+^Cdr@hbQ2Y7gR_Tci>Je?uq|T8F~CbW_SS+IVlkn5_0n<9v?`< z`G4CU4HGJm-XV2Vj0657 zoo-Db(~KCgkY`Q|-;;fID2vJ?EiO~X)+I!uQs28nKIRNq^1YiiSR=NSB8*?~$KR$R{3;|3^Z`C_7z< zX%%qYq9ZfkB|dB6x9uxE%1{Y}qauNnM^RrPH)Ah@K%%iBBC>qsb(b}gg(FX}kRrK_ zZ#ybe$tNVlb0&XcAdY>0gp7`TTZPPwJ>!I|)+yUj$o7wPN!VR!aolg?S*8r|K!1Ev zY|7KjWfG4U68*UFEKKW{YH)?<*8K4q9W1skbL2<*N66=ua!x(kYhH@!1rqbp5ZU=7 zO&f^zBJQeryipyC5UFa4<#>t#Dtu#n#V^0p?<BdT|#zy6d4k7-AIYM2yw&eC?O)Gl!GCpi9g{#Jzc5| z_uKLEJB057BfO<4YD*~CQU1(C+uPw zNW*SeLT2f>ZbEEPpI{-kWQsF+IO8)iyDSK&)d(pWyHEsDv0t>1Dpkv$G3j7j(U^Zq zT?Ji-M-++9PauzG;|b{vJAX<<2jzyDvO+$d^DX2=hhs#RAHd#$o?9uKsxpOqj`g%cmSO&zkbh`Wh^M68JdmN} zaI&Gj&N9{?sbCwK{YF%goG zk@WI#4Te-Y|I?v;&42c7l#10VfmlK2okz9F7IxH7+=%FCA%DxE+EAnCv1EJr*`yaJ z)+XfHMo&qeDaJV<5<|9e-DdP6#5I_^eaN`-ynRp(x{#M1^$zqbEyEs+{N+^9e;}kb z>I(3WU>6r5wP9t05a};eZPEB_AREkIw~h)qf3q&+y*YA0DSzu#$W0i_@w^&OssBeF zb=?Z2P0G6!((Up2S);QTC$Fiuz`yhPrn(#LEVsQhe4uLxJ?=n+^+oTw{fWttx>WJ#FtXLiTzbbleIZuBFSbd#eM6B3&QkykNK zHS&}UXUPe%jMK@5#9c!6pafM#6s7!H-CB&SKsJ4EwbYUeYd4;?Hzn`J;hv3 zL~?eF{|K=k7Pi;&D9cTV^@i%ObO}1jZVIIJAD>w^kqruobUH+ih#h~M?jOpc3Z#9M zM=a#(3P!urZ@Z}YOLQ8dt{Q<@`SqE;X~vruxAb8qOoO(%!i_&OIPXcwl+?l% z^?$fa&{DV*C1zSg&s4*lk}`?}GCtdgE)@6{M%B&DpZPzKKM?FF9!Q;hPRAB|!WA7S zZN7uYs|h`{ffQt_CB|b=$B&qgm~n<>AT=@DnAMoW3W?fkM8=QoGaBIGq^8#13a=5L>96-@#WVt?7FdM%L7{5o248hWX9s>H1DpME1%j4u=s zOPuo^NO!hX-vdKaW`gM(JPtiWrW=BsQ3dJY_Ct&#ffj>cod*A(iZyg%b5}%xCUpIgI+cv-1ke! zXAk|o<^0G_52WWGzq9*6-)*_!g2Z=vWk#txxDd%KRs}agK)5=0W{xgP`=m{CeZ9P_ z7ldr^wPu*_QeH0`eVygM1PQI!^M5p0&%G(l&%g7v${OS8{qQ~aq!us>Br1lmnl%uf z$MTQh%v2$|0g*x0WaYy*SJT%X-X%huwPw{W$ml;1(hJ6rYfj0i@7F&vkdM~fD(6$g z^o2oH7m*EB4&L=OKUW)6|8o?L5O9F9Ju0kqjDt}4oR-CFU zjY3LA+goF3IQ7yIB8`qw(nur59_>O#loKH` zog;U$ZM`8ssP)!GH7Q;#_kotLS`>rxXLK5=OO;2TVnZz>r24~Wi+T_~a~89s@cr0M z2O}KSPR1TlURy~Ydh=?tdVkT9*VeqFc8+9*%Wt8rj=kxkUyfI*&izMNg=*(;9}FR{ zY*fg#M?+$KbG`SHO5wydjSdm+E9IHoHBHqt`k6qP{Et2==@Z@`Xl4 zWa|y_6I_WF{6Ch%pJ@xf8>zHj)Pw$I&d^B>#xMn@Oaep3uJ-1!zLgDqMTrh*R z-Y)TuPkr4wW=Pg6gStKQ;1jY4kOKfdkuj#*UoJ)U>y zrn89sh=oYy;C~ue@{F@C!h`?A$7NX`LJyN^?{>T~EX(#{YXHv@@w=Y(jJa({JUAQR&yCIvR}UJ&A(ondCW z0C87Yix4*=qZjn=n61Q-NRwzx7$ps)U`>~qtR+S(tfl&)*F#9lSeT*ylUJ;AzXBd;HkXw1W(DQ5gT(ZLF1Ip(EI^bMLv(GIS) z4{NBignu|^=$m%i!0591^@)BL8#Sy~2(}lEpv0BB(NEf>T*qC{sDlp08f=b** z@Hc$hBj^*Z^*EwDxCZ0;Kz?l_v?jiv@hV3ZwFg>7-?~jJ1HB$5Vu@3~gy<|_hL^?s z5?-AdJ=*at%ujosKeKA)TSj^=@qH?!qh_*sT7RcG0)ccx|C`O%aW1JxaYsg0BP7yM z5vj&`0TFb*SfOmva}8_D?TeC4JXv2P)$>z-$uK9&zH1Magv@o_e12AG3nT18qIMUN zDEr1ISYhJu&8?wbg{N`N#IapltN!32YxRs3*MV%le^$)Q=HEHd5fYJW6{{|6XAv%Z z+ke~A;hng}9r$hU))sohZ4WUKT+zLBW#RwX#}oR5?3Bb=h;~}Rp3MK_;tV?$SmY7& zvx!*Zj8P$_U5v`xjR_sNLvFQ;zCj^T4S zyZ_@|5P9jMuf|^PiJ8NzsbSWUkhU?q$$wr<4&=|Qx-n*C@20}mn{+UVmytKhl4uU3-MZbhlpHakI$G4p=$>Bbt^w& z1wy>z{nPZixe~gyNYi2D`9gn4>wnQ?6n`gX4WgI2^(y*=Z%$NwBl8wbmFdHG+9hVt zlhyjH7jrOLUwL9QR){ZNYatusS?l(}hZFpzqid?aEfyvGH-b1W=WhIE`KCT+H8euINI!Ovwf2UboAlN9EsiXXQD?GTJkAQj&)$|%LONm2Ow5Rx9QfHEE`cs-S(#C$d3p_wxA7t=zFArI3;n@2XW3PLvI#4ZgFMMRPht zdTGqK*3cHgGq=8eu~uH!QhzC!*V)#~hWR^fCwpwgcDQ@dR_$O(_|&_VgT&Z&@Ys6yL*y)xs9vDBE!+>Y!7_S%!#lNiT0cRuX{d<*BRKX%A@sbC(8 zkX$j^*KXGF#udFKI$Sc+xkjK}-L;reC`m2Kh5O*fTpm29ch$jf?th;8<6d}HIil8{ z&Ng$Gw>r-M5waW3)DUtbXah)3Q3XY7AnlVc=HdvcI2AMyf2bRK8mS`V>gf}&;?Eoz zC4K@4ZsdtQI)$M|7e%szs}nOyIKN6r@5n=<6IDYED8f~_s;tL!XY7#Cb1z&)-}6iZ zdnySLMc}7iKm5I2jDMV?a52aLJ7WvcMT^}#V#LA3JmMZ51~5k^&J|9p38XH}?CFuB zkAA*hjxFr;p!Lky13VDl*oC6kVhbx^g>;--E~G}eFCr$J$iJgghqdLsdL8If?UCAw z7Pi+f(!&us*)VdaOF)Pb;1wKvgt^pE!DDPyijmn^8LO9JVbBh%ZL zK0a9@Ru6qOLVRQ2V{vHhUjCh!r;7Wa#Y9Scr@9yl#v8j#Y(*B(WnK>Y#e}rYYtUQ& zutQVVBRur#3V+E9V;@2cXVL@`d5wq+!}&5oqJtLh-u|ld%@qBBc@5laMsI8P*?!nj z|J+egc3&N5c6*3Z?js|lP0VWPqr}J_L~3*FQl({U1vz;iQNqoi88Igwk!jA>a!frq z|4!uZ;5(hwxW-dR>zHE}2zvngj23-pd*|1=lV_i&7=NGbc_Pu85qI=t^?AKAOZ#-A zWA=0ZbV|^F9mqz8FQhJv#`aHo4(o&aw>vBG{yjhZ=7c=VHt8!ncZu&y*BM*b)qYg3 zMPYZQNmPN@<#k&+bG%2_(+)wayi4P%n7(5QApRc_@{V39A(^Xl`|kasH?MCunK(v# zp*D*EWq-!JjX*9&t%R6i&4Umf6Wj+|S_ZvR+Bm6VMqxiz8%@6si(DT@IAmJH@bNA= zCyW&$&lWST^E&rV7YRw+O)kb%c8omq8%&=nOTeGG z?wHBkpXd(8^n^rL7DQ?@zO$Z5I^*7nsVnH&j(=ftIKRXFG}W@B^95AmUqyk}9+zF>C$9 zK8;bPV5p2l(WKvTkJj50dg|Sh_%-fPD}T{C;s?Uf3O5}_^mV#L=L&pkAs>3?#3<~? znX|9r%&llWkhxY-NaxD?NMdSyPVH6hz#YN&hkj*m-8x2>BN&>H-Fh3caJZuF^Jlns zqQa6bh3Nf5w&C4$8t|!mvxoCOBsObBeh`wfU=41FGw$mi^H;gIut>S_^pJm=hJSoC z$k;+95j21qii~^= z{3;)>9?W;~S<>NqZbp{qkI%Hl_kY4HJ!1u*&ldere<0k~-RHkE0Ff;*g{N`u=&+B- zt(#Y8zS6OukhWW17>V>xS{Jhe!%$tmOGHBs^S4iX7dw9V*E9D^^KVAi1VmOYsM>_| z$vgggX(5jnk`u<>g&22<7t*3q^ zd#e*G5(D8*t0U4wu*x)$i*{7VkJ&0CjYw)lWM-b%HquUx99BrwNh1 zq{Mz$A?4w|9!0Ce`>lNC@ESzq8~r<@#2i9=bLEzaT@J>7voQRfnksYUQFGepyB#rk z4f9<_ow?zCI_g&^`Yna%a>6}Yqk5X3;KjgdLM(Sfi!@C41>PmYnmNWbM>LMbxO2>k zet4S=JEdWr(Xbmzlz)&`q8$h#EnVz2K3b1NYeYPAZS0UfKLWCkIPC$NqP1kyBbAtJsD zSEsL-GL6W|2RYy9FFV#M3ejDUZ#$e^*t2wm=|v?WL%+)y(d>>t6Qxu57PJTlxtI`rh@W~V zo}4~rOWborNG+&B$JAj!KkS$;?tpK5hA$ZJxv6uH%zMo5#}te)*AK-qq7yE^xlil~ zJqzP==jnXon|~>xS9g5JHZvh17we|Rim65TZA-6*ch!pS#<&lbwZ#8tH5n^h(bf9J zeDblRwwc{7FFY?)h&}WXk2Q_w#*XzR?mj&tR*lo&MoiMdjKZ;A9q7Ln;;f9u7E#2! zbs_zrcV+A%YKgzIqrE@A(_Lc<1R~8h=KPHPrNlOVZ-2{tGwoB^Z#ncM+^K6seVVLoIE4M8YFqW##y^7gvQ@q#=3pQ)o3m!RvWaZ{@BWdYGNh_m*ALM;?hF@5=TrZ3 z9;^x^-G6!7#&}k_hH$*rF2B<^e#|Kz?=zk~Fy7K#g75TQaZB8Z`Vp?qohcXI*E7a0 zqo;nRFAc1Pi~hleG1n=J$lceb6!O9Dk~62$G2?UQQXb}h&0Gsdv4wQzZ!=q|Xh&!C zEl01^%v}_gcJItX(v@u0%qvP95jnl!S(wt!hJUfpDTU1Q>jOE+U1rJYVmFdmYIzu8 zpCx9u(+Q55tqYmMtjQ|oZA_h!j{JJok|x$`&e{sk6Q8wr$IQi9XE~TLJ?p2X#+_Kt zkIIu7{Up#EJ}ojA@!72ZsB4=ROEvc%M$YWuezYNbS6CO^?lcw9T|J zW`8uLC=b?W3HdQGP9(Y(KBv8=g)CrpDSOnxGy2eCf6MS|Z{CTX%EJ7r8B=zU+0Ezx zhf#zXc?SG!5kdX&Z6h7bLY)7f!aeF=?x^^ui@>4JK}bwq`GIWgPcfw%ANDYwL+i#i zWTbwvgUKAZF07TG(aIWY2U)JW1$)O(F1%&hbHEH_qNHL{JzA~yoJ=o zJMm@boYVPAspuCIVmx(42G$n(@MUufR~OFbnR6%SlO4sbkMn&oY6y{?6MuTy0&za| z@5Y>}Kf2Czx2_|*!mncZca*NV&N1Q!YD^roI{}0|0435kVQK(Lwc82u?!7iCT6Xf? zf6`gJ_tvRl*Is)>WXA)eGYlD+H`Sa@J@#j6E@rM^-<&nGCK)2GD~?PfXl4gSzjJez zwnV3-Sza~9;ahw3jlL`s)*=;>l{k$A})! zrc2u)-xeaOhwo!;PLUZkYk!Jbr<4HEU6Nv^9t6~cgyaLQ5khK4TR;mnI*b5s;RxKX zt%Wl;Z2{Dz&3m#HR8!?(V{dNIe*+nyI6}>U6RM9 zyB>XDLL|j-AH?Ar>f|js+lz=Ku^F6$BsC3nmu49cXf0}Kiqi7$%$(6K*3#0K@u;`> z0?v-5E@NDP5U~%GE;&T5o!)ZF8MO@|mFvv4JpDp@uaLstOX&?#Re5a7a~6Foz8wl9QGBIkrl_Q^MDQTtUh^(L$Q&I3utE-KrOO;H-8?ad|0rW{U z%a%v$ezTp8vB%QU+yyCCb+Y)zsN+KY5V6Ko`DU`fG_(>3$pLK}?eLy!L^ZP#U?!)K zTu~owhwes<25REJ(n2Q~eBP6se2&oS3JMHL^<9}+}F~UHbLpx^myblhk zb{I7wBo(wh3DFAS-Z`Jb4G}pn)DCRtr7m+qE@WY~bCiLW?RL)K&_mdCP`P(*YnH%< z-_}Oqyj>x6U{!$DX1t)KwV4i##B9xS`*6p13jxHv(|zJP+pX7Jkh!+r%f@J}Ho}G8 zxot=!qMf3NYkyYOHpZDepAxCi3+th@(d*=Io52iyjD(IAS%jDlhe(Q>*K~>lvSv4} z{x!bOJTKJfXmd!7$8THJb>zm97LTW(P*8Pkp#<~Lbq5glt^8?glipjorH=R6hcbm6P$esJa0MFijjUji`1eXBBb!WAf#sGb3LD~ zV6=&l!d20FZe?OTg~eI01+ZI(M9lW;c}wr*Ie*wz>YI?_^F%%;q_D26edyWd-AlA| zJVbKf&P`UEsA8;PFGm;{x!6m0Cwd;bm43l|z+Q&U4Nd<#n@W0k}R*N;K;s z#xYpFbxASaquor9cuFMtI^TfZ3Ra`M?xhs8t#?5IIbiR@1+=d8K3zr4yIU<@J`2Oe zljqv1^rDTp4@;=R5eVU)0DTl|?}A8`kx~` z&YVTBO%)w$HT$d^qi4hnT|~Q!kl3&yOW)F;(9hKOjG0gU-WT$jhWO9I4%0eUW`COF+pt(hiQ#g5>K& zd!mq3P{QicObsKVgyfAm(!=y&tSB+Wf7oj!q%@3`8o7DS_8NKmhIX-0M1L{R4>(GZ zuFRjQg&E7R{?h148DbI#GFKs`qjhDJ6*lJ24a@CgNnTy<=q(pgP99se7<5MRrMb2Y zZj3D&wWWrZEGa_nM2oYKGSQkhj!>D)j3bFP@n=frOz3e)jph@4bm{*1KF4w%Em=Y$ zcY7MgF5G9;RK9^emT`tS_PEZRuz)_)(#APLMx9(p zE_^SXD{}tnICq>Fp)#6vxMAe*71`mCx;1#eHS52Pv(tLm8^_jG2xto!ZKr`&_t9O5 z$dHAkj8`wMm#A(eY~jIKq%Y8S(@3(@avNJ4+3klOeL6sg_F0e?qdZex7NkTS-d ztc4Vh9*!|$s(drq709Pi7f?YKIwY*Q+U$_%W6j$T&U_r!TN3?^LmyfgMK#8>VquI# zhgIGTseGRf>u7;1H)frfp{#RI6YC+<74AK4NJfu<1`sC3)d)$B&(Cb3qIG3VZ4tDt zjJX}#q;>D@$Iz!Yf=Xfc~&$OXOsGw6jdZheN39o9aZA(q7N6Ow0UBqRm2BTcJc z()o9!*Wsz3;eYfABj;xrIifZ=#kW1m_!*Y#Sm9YWmfvU_oZ|bONi(A~RpfI*64%3@ zQLGX5UW;}aXd@O9H%2b%x!dT0(v6uW&uFrwKRk1(`l@(_# z@x&O~X=6rT=&UVVm>u&)B13*c&{8t%2nBn4%_<3t5$*G-q#o{&!-WHN*m;D|Fe6b& zoM;K2M}LkEV}j>lb(C=qjx%$mhk0}#&|4uSRY(mK&nFC;hK zy=Sr>QHYevS@iR)F;QyL_Xdb(KAvM^`Nl~+Mxj4gmu2WVjwh>+N^ z(|?4J%w0XEhET9R-?VP3%p~Rx935x~cXFE&1{-~Cb6N3rloX=um>%ChOSe5{_|LU0>=lt+I6_}jEpCSUK+5&NyeUH_-#^>C#rm6= z_+~yQzU}yZcC>Dli0E~Yi5rqIg4LQ9oqw2lGI#YSMySkvS|1rk;)RvlS_RZcmu|U) z5ne*9CO;yfa2@pJV(93tSXK=ftt*Cb1krM$Kj>AIt{yV_gO_V5qJKf0EpoJpkP^`T zCb=h4%fB;hz7biep)GBR@pDfAo%nKK?AP)ZwTGjY3Z2jwVXdbl#;&Xov`KMx#3KgA!!EN%Ak$kx z$~soI5)u zS@Eg)86syWcx$dWq^a_#hrjrl)PGS&T5(y`970ma#|5N>jdj_CRJJ+jl$H~1H7j-P zc^q3dZ!F5HoI>R}$i+33{wvqiF_wDeQ_>3ML6-F8QD@sdIM;byhzeW9m5uhqRifKy z!(YYf;p3YY>&SwmE{FCaN^)yViuRCIdSX3MNLk3sU;4yP+)u3~aZz_f{F{4+AbreFR6poQu)|dyYm95(1i4{XvohkA?r&AYreXKD8 z%bi2_Ir`^>SjRL(LUE|~3aNu7#Ze09+(}3D0iz7o(Jy#K)-gO+1763B2_v)D=|s12 z4o(*mdN_oXhLL{j48b7}7JpI-+TYeGdCi)`nM*~V>pF{Ldx#Jp&?m9ZBTuxYty2V* z@9h@+U7dS0)9)X^*QZcXLrO)YluNp}6WjXo#aBWXB+R~D06-uHJ$ zzDJ#bjK;;aRm|DHoc+8j4`k&UCuU43U3OS zfA-i}LUg%T=>WqZW(zaeti;NOvETS|Z#_;=zLZ>UDeuv!5Gh4L4y22TI|!;+vNns; zAuxvKmt>=runt9NY00}66+7UG<;)hHz)-5bYKYJh7p1H6s=)93U$$P8u9vt_n;>2P zQy?Y7WKA;oZFeg-E5)|rhgM4YeQH&4usQv^PSEG~nC7mG%rYmF&u7ajyW*9omDx8= zMh&evwaTU(3{0FYKf>1zy1^>nvb0hLgY`MMFw?Bu2}suF99fcGLRhAsVS9Xil!^9n z)5al+oOX#v#4DonfKP-qeEjB6uJ_;P=E0Q?&x$BNI&6~aM^M-t+z>k+4L^K5t9|c2 z;(d$^!yvRppV2Uq?~oKKJfL?o;Yxp_W`B3Xo}m22{++M@`@{ne7*a(CN+)(dKIn1< z>K3b>eUIx};bXIE@=okc|4~)@goL4Y@|}s5@HjCBGW5NZgV9V;nmM7x?p1(eV>bAn zuy^vHYIe&`;*BGdHFFNS6rAs)Br8O!G_o=*s_Tn{r4GB|kX5kcx2K=dY)*%SQCUCD zK4_KtRXNoYF?QMoeQn7J3nxtE5!#=ECT9$oCqzFK2iJxwjh#U~uGmE-wH2ux!S!IP zzK7v@3y>dU-C~dhw}UpapXm0zGK>L(12Es>&DmsW+EDf2^P6*XhlV7~ z!FsC)dcP{_%bD*PnHs9~E(EW-(w!Q>(sl()9xJ>yHRY2DF6D;V_FE-pGw}xbkxe>x zxJuTK?jFN<4W3sRw(98{+iBeN;yhuHGA*BbNqZq72N#*pL|UjaDw|wis&EJWjZ8cV z5;nqM@B5>gStbD%Z)t8*UfV`&-5z4l-D`gg)k?E`vu2%&wvQ=RblWFv8!4*^y!zeA zL>hbtt|mOp7fQTLkK)r2r2SxIj*y7qf&}^?rGd;_U09jEgpOLGM@3@R8TLsd@RedA z5=9ekEae&^9#EabK7Q0)S;~D)TzSu%r3zOUwdzgRY4m2i=R$k=(xO)6ope;r#7Syf zd-*kL6mOZ)!Kbm-bIE)j5ggD*t16OBp6!r*6CavF&EZh;q zA7g#Ouu%wi7~HfGiawgifGL*?bmDl?d$MbSxX z0o?aY;l_qLhIj#*L_ovcX((7!HP|Sa-o~*;^H)r=Vf@+YJL-30@q#kAP<+yJ74$iM zZ#J;rCpeqX6*t?HuQ1~%gE7LS2?GBS^0Bv-{gsp}pDGD9ps8aWyNS>c!0VtG97S8V zC1TS6wN0Si$5V0-*tS^QbFOQhN?eDNtiGG|wL_K+WVcdYAnUAaG>J5HcT-B(KyX9U z8r7TAYKQ+Oo^?4*PaL{oGWGQ+ z_z>ZF5=|?9r^9-)S}2_^CXC|(xjxAkcBRhYPKUz9?Wr7%Yx}Hm+WRQew5%I?buVMEm9I|B<;L)m z$57V|5-xS^que&C)>9HIwZX1A_MiNY+jCU+JoXz9{{~WHe9ff|vCr=4ayFO)0c#_fKX;ga@AT(P6tw78bZPhv z`3aoqSviwe&VAIpn$_$V^&tbbn2MN}&Y~pieNIsK9cCiW3hupAH~DGdc7EXE^T2%h z_^z)yeR?k7kIGa6Y_Q46;(|8T-fMTsC4>y~Fr(R(cl=dQ&{z4~nfq$+o%$;yaWNbI z8G4cv7oomp`JvVsF5DLUq=M!-4b!+ihf(q$K5xxIo=?g3d(fc$0I7B_Io@sDqh?Sm zx`~tV&+J-~ z{1bm&YZ9&keO)G@bnjQ|8PFA0IjLjD~` zoAIyn09D1gc8@c^h#3(f^KSqm--4gb0}d-@8a?Y+5fK_v5Qy||ghV@DGaoPoj&LG5%N)fB^JU@V-UBDRGlj5eoSawC=sZ diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp index 930b020..ead1c46 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp @@ -6,18 +6,24 @@ static XHANDLE xhAudio = NULL; static XHANDLE xhSound = NULL; static XHANDLE xhScreen = NULL; static XHANDLE xhPacket = NULL; -static XHANDLE xhFilter = 0; +static XHANDLE xhFilter = NULL; +static XHANDLE xhScale = NULL; void XCALLBACK HTTPTask_TaskPost_CBVideo(XHANDLE*** pppSt_AVBuffer, XPVOID lParam) { - int nListCount = 0; - XHANDLE** ppSt_AVPacket; - VideoCodec_Stream_EnCodec(xhVideo, pppSt_AVBuffer, &ppSt_AVPacket, &nListCount); - for (int i = 0; i < nListCount; i++) + XHANDLE** ppSt_AVFrame; + if (VideoCodec_Help_ScaleConvert(xhScale, (*pppSt_AVBuffer)[0], &ppSt_AVFrame)) { - AVFormat_Packet_StreamWrite(xhPacket, 0, ppSt_AVPacket[i]); + int nListCount = 0; + XHANDLE** ppSt_AVPacket; + VideoCodec_Stream_EnCodec(xhVideo, ppSt_AVFrame[0], &ppSt_AVPacket, &nListCount); + for (int j = 0; j < nListCount; j++) + { + AVFormat_Packet_StreamWrite(xhPacket, 0, ppSt_AVPacket[j]); + } + AVHelp_Memory_FreeAVList(&ppSt_AVPacket, nListCount); } - AVHelp_Memory_FreeAVList(&ppSt_AVPacket, nListCount); + AVHelp_Memory_FreeAVList(&ppSt_AVFrame, 1, false); } void XCALLBACK HTTPTask_TaskPost_CBAudio(XHANDLE*** pppSt_AVBuffer, XPVOID lParam) { @@ -61,6 +67,10 @@ bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuff XENGINE_AVRECORD st_AVRecord = {}; if (!ModuleProtocol_Parse_AVRecord(lpszMsgBuffer, nMsgLen, &st_AVRecord)) { + st_HDRParam.nHttpCode = 400; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,解析协议失败,错误码:%lX"), lpszClientAddr, ModuleProtocol_GetLastError()); return false; } //屏幕采集 @@ -98,6 +108,10 @@ bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuff //初始化屏幕编码器 XENGINE_PROTOCOL_AVINFO st_AVInfo = {}; AVCollect_Video_GetInfo(xhScreen, &st_AVInfo); + + xhScale = VideoCodec_Help_ScaleInit(st_AVInfo.st_VideoInfo.nWidth, st_AVInfo.st_VideoInfo.nHeight, st_AVInfo.st_VideoInfo.nFormat, st_AVInfo.st_VideoInfo.nWidth, st_AVInfo.st_VideoInfo.nHeight, ENUM_AVCODEC_VIDEO_SAMPLEFMT_YUV420P); + + st_AVInfo.st_VideoInfo.nFormat = 0; st_AVInfo.st_VideoInfo.enAVCodec = ENUM_XENGINE_AVCODEC_VIDEO_TYPE_H264; xhVideo = VideoCodec_Stream_EnInit(&st_AVInfo.st_VideoInfo); if (NULL == xhVideo) @@ -111,6 +125,8 @@ bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuff VideoCodec_Stream_GetAVCodec(xhVideo, &xhVideoCodec); AVFormat_Packet_StreamCreate(xhPacket, xhVideoCodec); BaseLib_Memory_FreeCStyle((XPPMEM)&xhVideoCodec); + //转换 + //启用音频 if (_tcsxlen(st_AVRecord.tszAudioDevice) > 0) { @@ -187,6 +203,7 @@ bool HTTPTask_TaskPost_AVRecordStop(LPCXSTR lpszClientAddr) AVFilter_Audio_Destroy(xhFilter); AVFormat_Packet_Stop(xhPacket); + VideoCodec_Help_ScaleUninit(xhScale); xhScreen = NULL; xhSound = NULL; xhVideo = NULL; From e5c11ed3d44ff01aa81f8c13f722d2a40783da4b Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 4 Feb 2026 10:48:08 +0800 Subject: [PATCH 18/20] modify:support only audio or video for av record --- .../XEngine_TaskPost/TaskPost_AVRecord.cpp | 87 ++++++++++--------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp index ead1c46..f101556 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp @@ -63,8 +63,9 @@ bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuff XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,因为已经在录制中了"), lpszClientAddr); return false; } - XENGINE_AVRECORD st_AVRecord = {}; + XENGINE_PROTOCOL_AVINFO st_AVInfo = {}; + if (!ModuleProtocol_Parse_AVRecord(lpszMsgBuffer, nMsgLen, &st_AVRecord)) { st_HDRParam.nHttpCode = 400; @@ -73,28 +74,6 @@ bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuff XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,解析协议失败,错误码:%lX"), lpszClientAddr, ModuleProtocol_GetLastError()); return false; } - //屏幕采集 - AVCOLLECT_SCREENINFO st_AVScreen = {}; - - st_AVScreen.nFrameRate = 24; - st_AVScreen.nPosX = 0; - st_AVScreen.nPosY = 0; - _xstprintf(st_AVScreen.tszVideoSize, _X("%s"), st_AVRecord.tszRsolution); -#ifdef _MSC_BUILD - xhScreen = AVCollect_Video_Init("gdigrab", st_AVRecord.tszVideoDevice, &st_AVScreen, HTTPTask_TaskPost_CBVideo); -#elif __linux__ - xhScreen = AVCollect_Video_Init("x11grab", st_AVRecord.tszVideoDevice, &st_AVScreen, HTTPTask_TaskPost_CBVideo); -#else - xhScreen = AVCollect_Video_Init("avfoundation", st_AVRecord.tszVideoDevice, &st_AVScreen, HTTPTask_TaskPost_CBVideo); -#endif - if (NULL == xhScreen) - { - st_HDRParam.nHttpCode = 400; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,屏幕采集器请求失败,错误码:%lX"), lpszClientAddr, AVCollect_GetLastError()); - return false; - } xhPacket = AVFormat_Packet_Init(); if (!AVFormat_Packet_Output(xhPacket, st_AVRecord.tszFilePath, _X("flv"))) { @@ -104,29 +83,51 @@ bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuff XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,推流服务端:%s 连接失败,错误码:%lX"), lpszClientAddr, st_AVRecord.tszFilePath, AVFormat_GetLastError()); return false; } - XHANDLE xhVideoCodec = NULL; - //初始化屏幕编码器 - XENGINE_PROTOCOL_AVINFO st_AVInfo = {}; - AVCollect_Video_GetInfo(xhScreen, &st_AVInfo); + //屏幕采集 + if (_tcsxlen(st_AVRecord.tszVideoDevice) > 0) + { + AVCOLLECT_SCREENINFO st_AVScreen = {}; + + st_AVScreen.nFrameRate = 24; + st_AVScreen.nPosX = 0; + st_AVScreen.nPosY = 0; + _xstprintf(st_AVScreen.tszVideoSize, _X("%s"), st_AVRecord.tszRsolution); +#ifdef _MSC_BUILD + xhScreen = AVCollect_Video_Init("gdigrab", st_AVRecord.tszVideoDevice, &st_AVScreen, HTTPTask_TaskPost_CBVideo); +#elif __linux__ + xhScreen = AVCollect_Video_Init("x11grab", st_AVRecord.tszVideoDevice, &st_AVScreen, HTTPTask_TaskPost_CBVideo); +#else + xhScreen = AVCollect_Video_Init("avfoundation", st_AVRecord.tszVideoDevice, &st_AVScreen, HTTPTask_TaskPost_CBVideo); +#endif + if (NULL == xhScreen) + { + st_HDRParam.nHttpCode = 400; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,屏幕采集器请求失败,错误码:%lX"), lpszClientAddr, AVCollect_GetLastError()); + return false; + } + XHANDLE xhVideoCodec = NULL; + //初始化屏幕编码器 + AVCollect_Video_GetInfo(xhScreen, &st_AVInfo); - xhScale = VideoCodec_Help_ScaleInit(st_AVInfo.st_VideoInfo.nWidth, st_AVInfo.st_VideoInfo.nHeight, st_AVInfo.st_VideoInfo.nFormat, st_AVInfo.st_VideoInfo.nWidth, st_AVInfo.st_VideoInfo.nHeight, ENUM_AVCODEC_VIDEO_SAMPLEFMT_YUV420P); + xhScale = VideoCodec_Help_ScaleInit(st_AVInfo.st_VideoInfo.nWidth, st_AVInfo.st_VideoInfo.nHeight, st_AVInfo.st_VideoInfo.nFormat, st_AVInfo.st_VideoInfo.nWidth, st_AVInfo.st_VideoInfo.nHeight, ENUM_AVCODEC_VIDEO_SAMPLEFMT_YUV420P); - st_AVInfo.st_VideoInfo.nFormat = 0; - st_AVInfo.st_VideoInfo.enAVCodec = ENUM_XENGINE_AVCODEC_VIDEO_TYPE_H264; - xhVideo = VideoCodec_Stream_EnInit(&st_AVInfo.st_VideoInfo); - if (NULL == xhVideo) - { - st_HDRParam.nHttpCode = 500; - HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); - XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,打开编码器视频编码器失败,错误码:%lX"), lpszClientAddr, VideoCodec_GetLastError()); - return false; + st_AVInfo.st_VideoInfo.nFormat = 0; + st_AVInfo.st_VideoInfo.enAVCodec = ENUM_XENGINE_AVCODEC_VIDEO_TYPE_H264; + xhVideo = VideoCodec_Stream_EnInit(&st_AVInfo.st_VideoInfo); + if (NULL == xhVideo) + { + st_HDRParam.nHttpCode = 500; + HttpProtocol_Server_SendMsgEx(xhHTTPPacket, m_MemorySend.get(), &nSDLen, &st_HDRParam); + XEngine_Network_Send(lpszClientAddr, m_MemorySend.get(), nSDLen); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,请求屏幕录制失败,打开编码器视频编码器失败,错误码:%lX"), lpszClientAddr, VideoCodec_GetLastError()); + return false; + } + VideoCodec_Stream_GetAVCodec(xhVideo, &xhVideoCodec); + AVFormat_Packet_StreamCreate(xhPacket, xhVideoCodec); + BaseLib_Memory_FreeCStyle((XPPMEM)&xhVideoCodec); } - VideoCodec_Stream_GetAVCodec(xhVideo, &xhVideoCodec); - AVFormat_Packet_StreamCreate(xhPacket, xhVideoCodec); - BaseLib_Memory_FreeCStyle((XPPMEM)&xhVideoCodec); - //转换 - //启用音频 if (_tcsxlen(st_AVRecord.tszAudioDevice) > 0) { From 3e3721a20965c22d40ef49ebf54c11999ba35eb3 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 4 Feb 2026 10:57:34 +0800 Subject: [PATCH 19/20] fixed:av record index --- .../XEngine_TaskPost/TaskPost_AVRecord.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp index f101556..f30e6f2 100644 --- a/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp +++ b/XEngine_Source/XEngine_ServiceApp/XEngine_HttpApp/XEngine_TaskPost/TaskPost_AVRecord.cpp @@ -8,6 +8,8 @@ static XHANDLE xhScreen = NULL; static XHANDLE xhPacket = NULL; static XHANDLE xhFilter = NULL; static XHANDLE xhScale = NULL; +static int nVideoIndex = -1; +static int nAudioIndex = -1; void XCALLBACK HTTPTask_TaskPost_CBVideo(XHANDLE*** pppSt_AVBuffer, XPVOID lParam) { @@ -19,7 +21,7 @@ void XCALLBACK HTTPTask_TaskPost_CBVideo(XHANDLE*** pppSt_AVBuffer, XPVOID lPara VideoCodec_Stream_EnCodec(xhVideo, ppSt_AVFrame[0], &ppSt_AVPacket, &nListCount); for (int j = 0; j < nListCount; j++) { - AVFormat_Packet_StreamWrite(xhPacket, 0, ppSt_AVPacket[j]); + AVFormat_Packet_StreamWrite(xhPacket, nVideoIndex, ppSt_AVPacket[j]); } AVHelp_Memory_FreeAVList(&ppSt_AVPacket, nListCount); } @@ -37,7 +39,7 @@ void XCALLBACK HTTPTask_TaskPost_CBAudio(XHANDLE*** pppSt_AVBuffer, XPVOID lPara AudioCodec_Stream_EnCodec(xhAudio, ppSt_MSGBuffer[i], &ppSt_AVPacket, &nAudioCount); for (int j = 0; j < nAudioCount; j++) { - AVFormat_Packet_StreamWrite(xhPacket, 1, ppSt_AVPacket[j]); + AVFormat_Packet_StreamWrite(xhPacket, nAudioIndex, ppSt_AVPacket[j]); } AVHelp_Memory_FreeAVList(&ppSt_AVPacket, nAudioCount); } @@ -127,6 +129,7 @@ bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuff VideoCodec_Stream_GetAVCodec(xhVideo, &xhVideoCodec); AVFormat_Packet_StreamCreate(xhPacket, xhVideoCodec); BaseLib_Memory_FreeCStyle((XPPMEM)&xhVideoCodec); + nVideoIndex = 0; } //启用音频 if (_tcsxlen(st_AVRecord.tszAudioDevice) > 0) @@ -181,6 +184,15 @@ bool HTTPTask_TaskPost_AVRecordStart(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuff st_TimeBase.nNum = 1; AVFormat_Packet_TimeBase(xhPacket, 1, &st_TimeBase); BaseLib_Memory_FreeCStyle((XPPMEM)&xhAudioCodec); + + if (-1 == nVideoIndex) + { + nAudioIndex = 0; + } + else + { + nAudioIndex = 1; + } } bRecord = true; AVFormat_Packet_Start(xhPacket); From ee0ede362f64e0aac39d34fffbc22ffed18432f7 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 4 Feb 2026 13:52:56 +0800 Subject: [PATCH 20/20] update:CHANGELOG and depend library --- CHANGELOG | 26 +++++++++++++++++++ .../XEngine_DependLibrary/XEngine_IPMacData | 2 +- .../XEngine_DependLibrary/XEngine_PhoneData | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7c3f857..2b5842c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,29 @@ +XEngine_APIService V3.14.0.1001 + +更新:依赖库 +修改:屏幕录像从后台服务中独立 +修改:不在区分http请求url函数的大小写 +修改:屏幕录像支持scale +修改:屏幕录像支持仅音频或者视频 +修改:调整插件参数顺序 +修正:插件没有加载http消息的问题 +修正:构建问题并且移除audio队列 +修正:验证响应状态不正确 +修正:http验证开关不支持 +删除:plugin模块使用submodule的依赖库替代 + +update:depend library +modify:Separated screen recording from the background service +modify:does not are case-insensitive for http function name +modify:screen capture format support scale +modify:support only audio or video for av record +modify:adjust plugin parameter order +fixed:plugin not load http message buffer +fixed:build error and remove audio fifo +fixed:verification reply status is incorrect +fixed:HTTP authentication switch does not support individual verification +delete:plugin module and use depend library plugin module instead +====================================================================================== XEngine_APIService V3.13.0.1001 ci:增加centos和rockylinux以及debian13支持 diff --git a/XEngine_Source/XEngine_DependLibrary/XEngine_IPMacData b/XEngine_Source/XEngine_DependLibrary/XEngine_IPMacData index 4e6e5aa..41d83d3 160000 --- a/XEngine_Source/XEngine_DependLibrary/XEngine_IPMacData +++ b/XEngine_Source/XEngine_DependLibrary/XEngine_IPMacData @@ -1 +1 @@ -Subproject commit 4e6e5aabee8b8c42a6f148d8e50feb44fb6f7b5f +Subproject commit 41d83d3c9b5e53c9d7f6a0a97dc70672d654b477 diff --git a/XEngine_Source/XEngine_DependLibrary/XEngine_PhoneData b/XEngine_Source/XEngine_DependLibrary/XEngine_PhoneData index ce3fd8d..42aca9c 160000 --- a/XEngine_Source/XEngine_DependLibrary/XEngine_PhoneData +++ b/XEngine_Source/XEngine_DependLibrary/XEngine_PhoneData @@ -1 +1 @@ -Subproject commit ce3fd8d987f79c89dbbb707771765de95bfd90ea +Subproject commit 42aca9c4dfeeb4f3e579bd49deb9cb390f0b7677