增加注释

This commit is contained in:
LuChao 2024-06-02 01:42:48 +08:00
parent 57200b507f
commit 7be002f7a2
4 changed files with 501 additions and 286 deletions

View File

@ -1,141 +1,207 @@
#include "http_server.h" #include "http_server.h" // 引入 http_server.h 文件,包含了 HttpServer 类的定义
#include "http_router.h" #include "http_router.h" // 引入 http_router.h 文件,包含了 HttpRouter 类的定义
#include "nlohmann/json.hpp" #include "nlohmann/json.hpp" // 引入 nlohmann/json.hpp 文件,用于 JSON 处理
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h" // 引入 spdlog/spdlog.h 文件,用于日志记录
#include "utils.h" #include "utils.h" // 引入 utils.h 文件,包含了一些辅助函数
#include "wxutils.h" // 引入 wxutils.h 文件,包含了一些与 wxWidgets 相关的辅助函数
namespace http { namespace http // 定义命名空间 http用于组织代码
{
HttpServer::~HttpServer() { HttpServer::~HttpServer() // HttpServer 类的析构函数
if (thread_ != nullptr) { {
CloseHandle(thread_); if (thread_ != nullptr) // 如果线程指针 thread_ 不为空
{
// wxhelper::wxutils::print_utf8_to_console("Destroying thread"); // 打印到控制台,告知正在销毁线程
CloseHandle(thread_); // 关闭线程句柄
} }
mg_mgr_free(&mgr_); mg_mgr_free(&mgr_); // 释放 CivetWeb 管理器
} }
void HttpServer::init(std::string &&host, int port) { void HttpServer::init(std::string &&host, int port) // HttpServer 类的初始化函数
if (port < 1 || port > 65535) { {
throw std::invalid_argument("Port number is out of range."); if (port < 1 || port > 65535) // 如果端口号不在有效范围内
{
throw std::invalid_argument("Port number is out of range."); // 抛出异常
} }
mg_mgr_init(&mgr_); mg_mgr_init(&mgr_); // 初始化 CivetWeb 管理器
host_ = std::move(host); host_ = std::move(host); // 使用移动构造函数将 host 参数赋值给成员变量 host_
port_ = port; port_ = port; // 将端口号赋值给成员变量 port_
SPDLOG_INFO("http init :host={},port={}",host_,port_); // wxhelper::wxutils::print_utf8_to_console("http init :");
// wxhelper::wxutils::print_utf8_to_console(host_); // 打印初始化信息到控制台
// wxhelper::wxutils::print_utf8_to_console(std::to_string(port_));
SPDLOG_INFO("http init :host={},port={}", host_, port_); // 记录日志
} }
bool HttpServer::Start() { bool HttpServer::Start() // HttpServer 类的启动函数
if (running_) { {
SPDLOG_INFO("http server is already running"); if (running_) // 如果服务器已经在运行
return true; {
wxhelper::wxutils::print_utf8_to_console("http server is already running");
SPDLOG_INFO("http server is already running"); // 记录日志
return true; // 返回 true
} }
#ifdef _DEBUG #ifdef _DEBUG // 如果定义了 _DEBUG 宏
base::utils::CreateConsole(); base::utils::CreateConsole(); // 创建控制台窗口
#endif #endif
running_.store(true); running_.store(true); // 将 running_ 原子变量设置为 true
thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)LaunchServer, this, thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)LaunchServer, this,
NULL, 0); NULL, 0); // 创建线程运行 LaunchServer 函数
wxhelper::wxutils::print_utf8_to_console("CreateThread for http server ,the result is...");
SPDLOG_INFO("CreateThread for http server ,the result is {}", thread_ != NULL); SPDLOG_INFO("CreateThread for http server ,the result is {}", thread_ != NULL);
return thread_ != NULL; return thread_ != NULL; // 返回线程创建是否成功
} }
bool HttpServer::Stop() { bool HttpServer::Stop() // HttpServer 类的停止函数
if (!running_) { {
return true; if (!running_) // 如果服务器不在运行状态
{
wxhelper::wxutils::print_utf8_to_console("http server is not running");
return true; // 直接返回 true
} }
#ifdef _DEBUG #ifdef _DEBUG
base::utils::CloseConsole(); base::utils::CloseConsole(); // 关闭控制台窗口
#endif #endif
running_ = false; running_ = false; // 将 running_ 设置为 false
if (thread_) { if (thread_) // 如果线程句柄不为空
WaitForSingleObject(thread_, -1); {
CloseHandle(thread_); WaitForSingleObject(thread_, -1); // 等待线程结束
thread_ = NULL; CloseHandle(thread_); // 关闭线程句柄
thread_ = NULL; // 将线程句柄设置为 NULL
} }
return true; return true; // 返回 true
} }
void HttpServer::LaunchServer(HttpServer *server) { void HttpServer::LaunchServer(HttpServer *server) // HttpServer 类的服务器启动函数
int port = server->GetPort(); {
std::string host = server->GetHost(); int port = server->GetPort(); // 获取端口号
const mg_mgr * mgr = server->GetMgr(); std::string host = server->GetHost(); // 获取主机名
std::string listen_addr = host +":"+ std::to_string(port); const mg_mgr *mgr = server->GetMgr(); // 获取 CivetWeb 管理器
std::string listen_addr = host + ":" + std::to_string(port); // 构建监听地址
if (mg_http_listen(const_cast<mg_mgr *>(mgr), listen_addr.c_str(), if (mg_http_listen(const_cast<mg_mgr *>(mgr), listen_addr.c_str(),
EventHandler, NULL) == NULL) { EventHandler, NULL) == NULL) // 如果监听失败
SPDLOG_ERROR("http server listen fail.port:{}", port); {
return; // wxhelper::wxutils::print_utf8_to_console("http server listen fail.port:{}");
// wxhelper::wxutils::print_utf8_to_console(std::to_string(port)); // 打印错误信息到控制台
SPDLOG_ERROR("http server listen fail.port:{}", port); // 记录错误日志
return; // 返回
} }
for (;;) { // wxhelper::wxutils::print_utf8_to_console("Listening on port: {}");
mg_mgr_poll(const_cast<mg_mgr *>(mgr), 100); // wxhelper::wxutils::print_utf8_to_console(std::to_string(port)); // 打印监听信息到控制台
for (;;)
{
mg_mgr_poll(const_cast<mg_mgr *>(mgr), 100); // 轮询 CivetWeb 管理器
} }
} }
void HttpServer::EventHandler(struct mg_connection *c, int ev, void *ev_data, void HttpServer::EventHandler(struct mg_connection *c, int ev, void *ev_data,
void *fn_data) { void *fn_data) // HttpServer 类的事件处理函数
if (ev == MG_EV_OPEN) { {
} else if (ev == MG_EV_HTTP_MSG) { if (ev == MG_EV_OPEN) // 如果事件类型是连接打开
struct mg_http_message *hm = (struct mg_http_message *)ev_data; {
if (mg_http_match_uri(hm, "/websocket/*")) { // wxhelper::wxutils::print_utf8_to_console("Connection opened"); // 打印信息到控制台
mg_ws_upgrade(c, hm, NULL); }
} else if (mg_http_match_uri(hm, "/api/*")) { else if (ev == MG_EV_HTTP_MSG) // 如果事件类型是 HTTP 消息
HandleHttpRequest(c, hm, fn_data); {
} else { struct mg_http_message *hm = (struct mg_http_message *)ev_data; // 转换事件数据为 mg_http_message 类型
if (mg_http_match_uri(hm, "/websocket/*")) // 如果匹配到 WebSocket 路由
{
mg_ws_upgrade(c, hm, NULL); // 升级为 WebSocket 连接
}
else if (mg_http_match_uri(hm, "/api/*")) // 如果匹配到 API 路由
{
HandleHttpRequest(c, hm, fn_data); // 处理 HTTP 请求
}
else // 如果不匹配任何路由
{
nlohmann::json res = {{"code", 400}, nlohmann::json res = {{"code", 400},
{"msg", "invalid url, please check url"}, {"msg", "invalid url, please check url"},
{"data", NULL}}; {"data", NULL}};
std::string ret = res.dump(); std::string ret = res.dump(); // 将 JSON 对象转换为字符串
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s\n", mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s\n",
ret.c_str()); ret.c_str()); // 发送 HTTP 响应
} }
} else if (ev == MG_EV_WS_MSG) { }
HandleWebsocketRequest(c, ev_data, fn_data); else if (ev == MG_EV_WS_MSG) // 如果事件类型是 WebSocket 消息
{
HandleWebsocketRequest(c, ev_data, fn_data); // 处理 WebSocket 请求
} }
} }
void HttpServer::HandleHttpRequest(struct mg_connection *c, void *ev_data, void HttpServer::HandleHttpRequest(struct mg_connection *c, void *ev_data,
void *fn_data) { void *fn_data) // HttpServer 类的 HTTP 请求处理函数
struct mg_http_message *hm = (struct mg_http_message *)ev_data; {
std::string ret = R"({"code":200,"msg":"success"})"; struct mg_http_message *hm = (struct mg_http_message *)ev_data; // 转换事件数据为 mg_http_message 类型
try { wxhelper::wxutils::print_utf8_to_console("Handling HTTP request..."); // 打印信息到控制台
if (mg_vcasecmp(&hm->method, "GET") == 0) { std::string ret = R"({"code":200,"msg":"success"})"; // 初始化 HTTP 响应
try
{
if (mg_vcasecmp(&hm->method, "GET") == 0) // 如果请求方法是 GET
{
nlohmann::json ret_data = { nlohmann::json ret_data = {
{"code", 200}, {"code", 200},
{"data", {}}, {"data", {}},
{"msg", "the get method is not supported.please use post method."}}; {"msg", "the get method is not supported.please use post method."}};
ret = ret_data.dump(); ret = ret_data.dump(); // 将 JSON 对象转换为字符串
} else if (mg_vcasecmp(&hm->method, "POST") == 0) {
std::string url(hm->uri.ptr, hm->uri.len);
std::string p = "{}";
if (hm->body.len > 0){
nlohmann::json params =
nlohmann::json::parse(hm->body.ptr, hm->body.ptr + hm->body.len);
p = params.dump();
} }
ret = HttpRouter::GetInstance().HandleHttpRequest(url, p); else if (mg_vcasecmp(&hm->method, "POST") == 0) // 如果请求方法是 POST
{
std::string url(hm->uri.ptr, hm->uri.len); // 获取请求的 URL
wxhelper::wxutils::print_utf8_to_console("Parsed HTTP url: " + url);
std::string p = "{}"; // 初始化 POST 参数字符串
if (hm->body.len > 0) // 如果请求体长度大于 0
{
nlohmann::json params = nlohmann::json::parse(hm->body.ptr, hm->body.ptr + hm->body.len); // 解析 POST 参数
p = params.dump(); // 将 JSON 对象转换为字符串
} }
} catch (nlohmann::json::exception &e) { wxhelper::wxutils::print_utf8_to_console("Parsed HTTP parameters: " + p);
ret = HttpRouter::GetInstance().HandleHttpRequest(url, p); // 调用 HttpRouter 处理请求
}
}
catch (nlohmann::json::exception &e) // 如果解析 JSON 时发生异常
{
nlohmann::json res = {{"code", "500"}, {"msg", e.what()}, {"data", NULL}}; nlohmann::json res = {{"code", "500"}, {"msg", e.what()}, {"data", NULL}};
ret = res.dump(); ret = res.dump(); // 设置错误响应
} }
try
{
wxhelper::wxutils::print_utf8_to_console("Sending HTTP response... ");
// wxhelper::wxutils::print_utf8_to_console("Sending HTTP response: ");
// wxhelper::wxutils::print_utf8_to_console(std::string(ret));
}
catch (const std::exception &e)
{
wxhelper::wxutils::print_utf8_to_console("Sending HTTP response error: " + std::string(e.what()));
}
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s\n", mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s\n",
ret.c_str()); ret.c_str()); // 发送 HTTP 响应
} }
void HttpServer::HandleWebsocketRequest(struct mg_connection *c, void *ev_data, void HttpServer::HandleWebsocketRequest(struct mg_connection *c, void *ev_data,
void *fn_data) { void *fn_data) // HttpServer 类的 WebSocket 请求处理函数
struct mg_ws_message *wm = (struct mg_ws_message *)ev_data; {
std::string ret = R"({"code":200,"msg":"success"})"; struct mg_ws_message *wm = (struct mg_ws_message *)ev_data; // 转换事件数据为 mg_ws_message 类型
try { wxhelper::wxutils::print_utf8_to_console("Handling WebSocket request"); // 打印信息到控制台
nlohmann::json params = std::string ret = R"({"code":200,"msg":"success"})"; // 初始化 WebSocket 响应
nlohmann::json::parse(wm->data.ptr, wm->data.ptr + wm->data.len); try
std::string cmd = params["cmd"]; {
std::string p = params.dump(); nlohmann::json params = nlohmann::json::parse(wm->data.ptr, wm->data.ptr + wm->data.len); // 解析 WebSocket 参数
ret = HttpRouter::GetInstance().HandleHttpRequest(cmd, p); std::string cmd = params["cmd"]; // 获取命令
} catch (nlohmann::json::exception &e) { std::string p = params.dump(); // 将 JSON 对象转换为字符串
nlohmann::json res = {{"code", "500"}, {"msg", e.what()}, {"data", NULL}}; wxhelper::wxutils::print_utf8_to_console("Parsed WebSocket parameters: " + p);
ret = res.dump(); ret = HttpRouter::GetInstance().HandleHttpRequest(cmd, p); // 调用 HttpRouter 处理请求
} }
mg_ws_send(c, ret.c_str(), ret.size(), WEBSOCKET_OP_TEXT); catch (nlohmann::json::exception &e) // 如果解析 JSON 时发生异常
{
nlohmann::json res = {{"code", "500"}, {"msg", e.what()}, {"data", NULL}};
ret = res.dump(); // 设置错误响应
}
wxhelper::wxutils::print_utf8_to_console("Sending WebSocket response: {}" + ret);
mg_ws_send(c, ret.c_str(), ret.size(), WEBSOCKET_OP_TEXT); // 发送 WebSocket 响应
} }
} // namespace http } // namespace http

View File

@ -5,16 +5,24 @@
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
#include "wechat_interface.h" #include "wechat_interface.h"
#include "wechat_service.h" #include "wechat_service.h"
#include "wxutils.h"
namespace jsonutils = wxhelper::jsonutils; namespace jsonutils = wxhelper::jsonutils;
namespace wxhelper { namespace wxhelper
std::string MiscController::CheckLogin(std::string params) { {
std::string MiscController::CheckLogin(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("CheckLogin called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
int64_t success = wechat::WeChatService::GetInstance().CheckLogin(); int64_t success = wechat::WeChatService::GetInstance().CheckLogin();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::GetUserInfo(std::string params) { std::string MiscController::GetUserInfo(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("GetUserInfo called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
wechat::SelfInfoInner out; wechat::SelfInfoInner out;
int64_t success = wechat::WeChatService::GetInstance().GetSelfInfo(out); int64_t success = wechat::WeChatService::GetInstance().GetSelfInfo(out);
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
@ -37,70 +45,109 @@ std::string MiscController::GetUserInfo(std::string params) {
ret["data"] = j_info; ret["data"] = j_info;
return ret.dump(); return ret.dump();
} }
std::string MiscController::GetSNSFirstPage(std::string params) { std::string MiscController::GetSNSFirstPage(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("GetSNSFirstPage called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json ret = { nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::GetSNSNextPage(std::string params) { std::string MiscController::GetSNSNextPage(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("GetSNSNextPage called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json ret = { nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::AddFavFromMsg(std::string params) { std::string MiscController::AddFavFromMsg(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("AddFavFromMsg called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json ret = { nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::AddFavFromImage(std::string params) { std::string MiscController::AddFavFromImage(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("AddFavFromImage called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json ret = { nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::DecodeImage(std::string params) { std::string MiscController::DecodeImage(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("DecodeImage called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json ret = { nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::GetVoiceByMsgId(std::string params) { std::string MiscController::GetVoiceByMsgId(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("GetVoiceByMsgId called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json ret = { nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::DoOcrTask(std::string params) { std::string MiscController::DoOcrTask(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("DoOcrTask called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json ret = { nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::LockWeChat(std::string params) { std::string MiscController::LockWeChat(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("LockWeChat called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
int64_t success = wechat::WeChatService::GetInstance().LockWeChat(); int64_t success = wechat::WeChatService::GetInstance().LockWeChat();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::UnlockWeChat(std::string params) { std::string MiscController::UnlockWeChat(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("UnlockWeChat called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
int64_t success = wechat::WeChatService::GetInstance().UnlockWeChat(); int64_t success = wechat::WeChatService::GetInstance().UnlockWeChat();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::ClickEnterWeChat(std::string params) { std::string MiscController::ClickEnterWeChat(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("ClickEnterWeChat called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
int64_t success = wechat::WeChatService::GetInstance().EnterWeChat(); int64_t success = wechat::WeChatService::GetInstance().EnterWeChat();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::GetLoginUrl(std::string params) { std::string MiscController::GetLoginUrl(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("GetLoginUrl called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
std::string login_url = wechat::WeChatService::GetInstance().GetLoginUrl(); std::string login_url = wechat::WeChatService::GetInstance().GetLoginUrl();
nlohmann::json ret = { nlohmann::json ret = {
{"code", 1}, {"data", {"loginUrl", login_url}}, {"msg", "success"}}; {"code", 1}, {"data", {"loginUrl", login_url}}, {"msg", "success"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::TranslateVoice(std::string params) { std::string MiscController::TranslateVoice(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("TranslateVoice called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json jp = nlohmann::json::parse(params); nlohmann::json jp = nlohmann::json::parse(params);
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId"); int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
int64_t success = wechat::WeChatService::GetInstance().TranslateVoice(msg_id); int64_t success = wechat::WeChatService::GetInstance().TranslateVoice(msg_id);
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::GetTranslateVoiceText(std::string params) { std::string MiscController::GetTranslateVoiceText(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("GetTranslateVoiceText called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json jp = nlohmann::json::parse(params); nlohmann::json jp = nlohmann::json::parse(params);
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId"); int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
std::string content = std::string content =
@ -109,7 +156,10 @@ std::string MiscController::GetTranslateVoiceText(std::string params) {
{"code", 1}, {"msg", "success"}, {"data", {{"transtext", content}}}}; {"code", 1}, {"msg", "success"}, {"data", {{"transtext", content}}}};
return ret_data.dump(); return ret_data.dump();
} }
std::string MiscController::OpenUrlByWeChat(std::string params) { std::string MiscController::OpenUrlByWeChat(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("OpenUrlByWeChat called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json jp = nlohmann::json::parse(params); nlohmann::json jp = nlohmann::json::parse(params);
std::wstring url = jsonutils::GetWStringParam(jp, "url"); std::wstring url = jsonutils::GetWStringParam(jp, "url");
int flag = jsonutils::GetIntParam(jp, "flag"); int flag = jsonutils::GetIntParam(jp, "flag");
@ -119,12 +169,18 @@ std::string MiscController::OpenUrlByWeChat(std::string params) {
{"code", success}, {"data", {}}, {"msg", "Not Implemented"}}; {"code", success}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::ConfirmReceipt(std::string params) { std::string MiscController::ConfirmReceipt(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("ConfirmReceipt called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json ret = { nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump(); return ret.dump();
} }
std::string MiscController::DownloadAttach(std::string params) { std::string MiscController::DownloadAttach(std::string params)
{
// wxhelper::wxutils::print_utf8_to_console("DownloadAttach called with params: ");
// wxhelper::wxutils::print_utf8_to_console(params);
nlohmann::json ret = { nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump(); return ret.dump();

View File

@ -1,73 +1,98 @@
#include "sync_msg_hook.h" #include "sync_msg_hook.h" // 引入同步消息钩子头文件
#include "base64.h" #include "base64.h" // 引入Base64编码库
#include "config.h" #include "config.h" // 引入配置文件处理库
#include "nlohmann/json.hpp" #include "nlohmann/json.hpp" // 引入nlohmann JSON库
#include "offset.h" #include "offset.h" // 引入偏移量定义文件
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h" // 引入日志库
#include "thread_pool.h" #include "thread_pool.h" // 引入线程池库
#include "utils.h" #include "utils.h" // 引入工具函数库
#include "wxutils.h" #include "wxutils.h" // 引入微信工具函数库
namespace wxhelper namespace wxhelper
{ {
// wxhelper命名空间下的SyncMsgHook类的初始化函数
void SyncMsgHook::Init() void SyncMsgHook::Init()
{ {
// 获取微信窗口的基础地址加上偏移量kDoAddMsg
int64_t addr = wxutils::GetWeChatWinBase() + wechat::offset::kDoAddMsg; int64_t addr = wxutils::GetWeChatWinBase() + wechat::offset::kDoAddMsg;
// 将获取到的地址转换为__DoAddMsg类型的函数指针
kDoAddMsg = (wechat::function::__DoAddMsg)addr; kDoAddMsg = (wechat::function::__DoAddMsg)addr;
// 保存原始的函数指针
origin_ = &kDoAddMsg; origin_ = &kDoAddMsg;
// 设置新的函数指针,用于拦截
detour_ = &HandleSyncMsg; detour_ = &HandleSyncMsg;
// 初始化钩子标志为未激活
hook_flag_ = false; hook_flag_ = false;
} }
// 处理同步消息的函数,用于拦截微信消息并进行处理
void SyncMsgHook::HandleSyncMsg(int64_t param1, int64_t param2, int64_t param3) void SyncMsgHook::HandleSyncMsg(int64_t param1, int64_t param2, int64_t param3)
{ {
// 输出调试信息到控制台
wxhelper::wxutils::print_utf8_to_console("HandleSyncMsg called");
// 输出参数param2的值到控制台
wxhelper::wxutils::print_utf8_to_console("param2:" + std::to_string(param2));
// 创建JSON对象用于存储消息内容
nlohmann::json msg; nlohmann::json msg;
msg["pid"] = GetCurrentProcessId(); // 填充消息内容到JSON对象
msg["fromUser"] = wxutils::ReadSKBuiltinString(*(int64_t *)(param2 + 0x18)); msg["pid"] = GetCurrentProcessId(); // 当前进程ID
msg["toUser"] = wxutils::ReadSKBuiltinString(*(int64_t *)(param2 + 0x28)); msg["fromUser"] = wxutils::ReadSKBuiltinString(*(int64_t *)(param2 + 0x18)); // 发送者
msg["content"] = wxutils::ReadSKBuiltinString(*(int64_t *)(param2 + 0x30)); msg["toUser"] = wxutils::ReadSKBuiltinString(*(int64_t *)(param2 + 0x28)); // 接收者
msg["signature"] = wxutils::ReadWeChatStr(*(int64_t *)(param2 + 0x48)); msg["content"] = wxutils::ReadSKBuiltinString(*(int64_t *)(param2 + 0x30)); // 消息内容
msg["msgId"] = *(int64_t *)(param2 + 0x60); msg["signature"] = wxutils::ReadWeChatStr(*(int64_t *)(param2 + 0x48)); // 消息签名
msg["msgSequence"] = *(DWORD *)(param2 + 0x5C); msg["msgId"] = *(int64_t *)(param2 + 0x60); // 消息ID
msg["createTime"] = *(DWORD *)(param2 + 0x58); msg["msgSequence"] = *(DWORD *)(param2 + 0x5C); // 消息序列号
msg["displayFullContent"] = wxutils::ReadWeChatStr(*(int64_t *)(param2 + 0x50)); msg["createTime"] = *(DWORD *)(param2 + 0x58); // 创建时间
DWORD type = *(DWORD *)(param2 + 0x24); msg["displayFullContent"] = wxutils::ReadWeChatStr(*(int64_t *)(param2 + 0x50)); // 是否展示完整内容
msg["type"] = type; DWORD type = *(DWORD *)(param2 + 0x24); // 消息类型
msg["type"] = type; // 将消息类型添加到JSON对象
// 根据消息类型处理图片消息
if (type == 3) if (type == 3)
{ {
std::string img = wxutils::ReadSKBuiltinBuffer(*(int64_t *)(param2 + 0x40)); std::string img = wxutils::ReadSKBuiltinBuffer(*(int64_t *)(param2 + 0x40)); // 读取图片数据
SPDLOG_INFO("encode size:{}", img.size()); SPDLOG_INFO("encode size:{}", img.size()); // 输出图片编码大小的日志
msg["base64Img"] = base64_encode(img); msg["base64Img"] = base64_encode(img); // 将图片数据编码为Base64字符串
} }
// 将JSON对象转换为字符串并添加换行符
std::string jstr = msg.dump() + '\n'; std::string jstr = msg.dump() + '\n';
// 创建InnerMessageStruct结构体用于存储消息
hook::InnerMessageStruct *inner_msg = new hook::InnerMessageStruct; hook::InnerMessageStruct *inner_msg = new hook::InnerMessageStruct;
// 分配内存并复制JSON字符串到buffer中
inner_msg->buffer = new char[jstr.size() + 1]; inner_msg->buffer = new char[jstr.size() + 1];
memcpy(inner_msg->buffer, jstr.c_str(), jstr.size() + 1); memcpy(inner_msg->buffer, jstr.c_str(), jstr.size() + 1);
// 设置消息长度
inner_msg->length = jstr.size(); inner_msg->length = jstr.size();
std::string mode = Config::GetInstance().GetRecvMessageMode();
// 根据配置的接收消息模式,选择不同的回调函数加入线程池
std::string mode = Config::GetInstance().GetRecvMessageMode(); // 获取接收消息模式
if (mode == "http") if (mode == "http")
{ {
bool add = base::ThreadPool::GetInstance().AddWork( bool add = base::ThreadPool::GetInstance().AddWork(
hook::SendHttpMsgCallback, inner_msg); hook::SendHttpMsgCallback, inner_msg); // 添加HTTP消息发送任务
SPDLOG_INFO("add http msg work:{}", add); SPDLOG_INFO("add http msg work:{}", add); // 输出HTTP消息任务添加结果的日志
} }
else if (mode == "tcp") else if (mode == "tcp")
{ {
bool add = base::ThreadPool::GetInstance().AddWork(hook::SendTcpMsgCallback, bool add = base::ThreadPool::GetInstance().AddWork(hook::SendTcpMsgCallback,
inner_msg); inner_msg); // 添加TCP消息发送任务
wxhelper::wxutils::print_utf8_to_console("add tcp msg work:" + std::to_string(add)); wxhelper::wxutils::print_utf8_to_console("add tcp msg work:" + std::to_string(add)); // 输出TCP消息任务添加结果到控制台
SPDLOG_INFO("add tcp msg work:{}", add); // 输出TCP消息任务添加结果的日志
SPDLOG_INFO("add tcp msg work:{}", add);
} }
// 确保原始的DoAddMsg函数指针不为空
if (kDoAddMsg == nullptr) if (kDoAddMsg == nullptr)
{ {
int64_t addr = wxutils::GetWeChatWinBase() + wechat::offset::kDoAddMsg; int64_t addr = wxutils::GetWeChatWinBase() + wechat::offset::kDoAddMsg;
kDoAddMsg = (wechat::function::__DoAddMsg)addr; kDoAddMsg = (wechat::function::__DoAddMsg)addr; // 重新获取原始函数指针
} }
// 调用原始的DoAddMsg函数完成消息的添加
kDoAddMsg(param1, param2, param3); kDoAddMsg(param1, param2, param3);
} }
} // namespace wxhelper } // namespace wxhelper

View File

@ -1,150 +1,218 @@
#include "wxutils.h" // 引入wxutils.h文件该文件可能包含与wxWidgets相关的工具函数
#include "wxutils.h"
// 引入utils.h文件该文件可能包含一些通用的工具函数
#include "utils.h" #include "utils.h"
// 定义缓冲区大小为1024字节
#define BUFSIZE 1024 #define BUFSIZE 1024
// 定义JPEG文件的魔术数字
#define JPEG0 0xFF #define JPEG0 0xFF
#define JPEG1 0xD8 #define JPEG1 0xD8
#define JPEG2 0xFF #define JPEG2 0xFF
// 定义PNG文件的魔术数字
#define PNG0 0x89 #define PNG0 0x89
#define PNG1 0x50 #define PNG1 0x50
#define PNG2 0x4E #define PNG2 0x4E
// 定义BMP文件的魔术数字
#define BMP0 0x42 #define BMP0 0x42
#define BMP1 0x4D #define BMP1 0x4D
// 定义GIF文件的魔术数字
#define GIF0 0x47 #define GIF0 0x47
#define GIF1 0x49 #define GIF1 0x49
#define GIF2 0x46 #define GIF2 0x46
// 引入标准输入输出库
#include <iostream> #include <iostream>
// 引入本地化设置库
#include <locale> #include <locale>
// 引入codecvt库用于字符编码转换
#include <codecvt> #include <codecvt>
// 引入字符串库
#include <string> #include <string>
#include <string> // 引入时间库,用于时间函数
#include <chrono> #include <chrono>
// 引入iomanip库用于控制输入输出格式
#include <iomanip> #include <iomanip>
// 引入字符串流库
#include <sstream> #include <sstream>
// 引入__msvc_chrono.hpp库用于MSVC特有的时间函数
#include <__msvc_chrono.hpp> #include <__msvc_chrono.hpp>
// 定义wxhelper命名空间用于封装wxWidgets相关的辅助功能
namespace wxhelper namespace wxhelper
{ {
// 定义wxutils命名空间用于封装微信相关的工具函数
namespace wxutils namespace wxutils
{ {
// 根据操作系统平台定义GetWeChatWinBase函数的返回类型
#ifdef _WIN64 #ifdef _WIN64
// 在64位Windows平台上返回类型为int64_t
int64_t GetWeChatWinBase() int64_t GetWeChatWinBase()
{ {
// 使用GetModuleHandleA函数获取WeChatWin.dll的模块句柄
return (int64_t)GetModuleHandleA("WeChatWin.dll"); return (int64_t)GetModuleHandleA("WeChatWin.dll");
} }
#else #else
// 在32位Windows平台上返回类型为int32_t
int32_t GetWeChatWinBase() int32_t GetWeChatWinBase()
{ {
// 使用GetModuleHandleA函数获取WeChatWin.dll的模块句柄
return (int32_t)GetModuleHandleA("WeChatWin.dll"); return (int32_t)GetModuleHandleA("WeChatWin.dll");
} }
#endif #endif
// 定义ReadSKBuiltinString函数用于读取内置字符串
std::string ReadSKBuiltinString(INT64 addr) std::string ReadSKBuiltinString(INT64 addr)
{ {
// 读取地址偏移0x8处的内部字符串地址
INT64 inner_string = *(INT64 *)(addr + 0x8); INT64 inner_string = *(INT64 *)(addr + 0x8);
// 如果内部字符串地址为0则返回空字符串
if (inner_string == 0) if (inner_string == 0)
{ {
return std::string(); return std::string();
} }
// 否则调用ReadWeChatStr函数读取字符串
return ReadWeChatStr(inner_string); return ReadWeChatStr(inner_string);
} }
// 定义ReadSKBuiltinBuffer函数用于读取内置缓冲区
std::string ReadSKBuiltinBuffer(INT64 addr) std::string ReadSKBuiltinBuffer(INT64 addr)
{ {
// 读取地址偏移0x10处的长度
INT64 len = *(INT64 *)(addr + 0x10); INT64 len = *(INT64 *)(addr + 0x10);
// 如果长度为0则返回空字符串
if (len == 0) if (len == 0)
{ {
return std::string(); return std::string();
} }
// 读取地址偏移0x8处的内部字符串地址
INT64 inner_string = *(INT64 *)(addr + 0x8); INT64 inner_string = *(INT64 *)(addr + 0x8);
// 如果内部字符串地址为0则返回空字符串
if (inner_string == 0) if (inner_string == 0)
{ {
return std::string(); return std::string();
} }
// 否则调用ReadWeChatStr函数读取字符串
return ReadWeChatStr(inner_string); return ReadWeChatStr(inner_string);
} }
// 定义ReadWeChatStr函数用于读取微信字符串
std::string ReadWeChatStr(INT64 addr) std::string ReadWeChatStr(INT64 addr)
{ {
// 读取地址偏移0x10处的长度
INT64 len = *(INT64 *)(addr + 0x10); INT64 len = *(INT64 *)(addr + 0x10);
// 如果长度为0则返回空字符串
if (len == 0) if (len == 0)
{ {
return std::string(); return std::string();
} }
// 读取地址偏移0x18处的最大长度
INT64 max_len = *(INT64 *)(addr + 0x18); INT64 max_len = *(INT64 *)(addr + 0x18);
// 如果最大长度的低4位为0xF则直接从地址处读取字符串
if ((max_len | 0xF) == 0xF) if ((max_len | 0xF) == 0xF)
{ {
return std::string((char *)addr, len); return std::string((char *)addr, len);
} }
// 否则,读取地址处指向的字符指针,并从该指针处读取字符串
char *char_from_user = *(char **)(addr); char *char_from_user = *(char **)(addr);
return std::string(char_from_user, len); return std::string(char_from_user, len);
} }
// 定义ImageXor函数用于对图像数据进行异或解密
std::string ImageXor(std::string buf) std::string ImageXor(std::string buf)
{ {
// 获取原始数据的C风格字符串表示
const char *origin = buf.c_str(); const char *origin = buf.c_str();
short key = 0; short key = 0;
// 尝试使用JPEG的魔术数字进行解密
if ((*origin ^ JPEG0) == (*(origin + 1) ^ JPEG1)) if ((*origin ^ JPEG0) == (*(origin + 1) ^ JPEG1))
{ {
key = *origin ^ JPEG0; key = *origin ^ JPEG0;
} }
// 尝试使用PNG的魔术数字进行解密
else if ((*origin ^ PNG1) == (*(origin + 1) ^ PNG2)) else if ((*origin ^ PNG1) == (*(origin + 1) ^ PNG2))
{ {
key = *origin ^ PNG1; key = *origin ^ PNG1;
} }
// 尝试使用GIF的魔术数字进行解密
else if ((*origin ^ GIF0) == (*(origin + 1) ^ GIF1)) else if ((*origin ^ GIF0) == (*(origin + 1) ^ GIF1))
{ {
key = *origin ^ GIF0; key = *origin ^ GIF0;
} }
// 尝试使用BMP的魔术数字进行解密
else if ((*origin ^ BMP0) == (*(origin + 1) ^ BMP1)) else if ((*origin ^ BMP0) == (*(origin + 1) ^ BMP1))
{ {
key = *origin ^ BMP0; key = *origin ^ BMP0;
} }
// 如果无法解密,则返回空字符串
else else
{ {
key = -1; key = -1;
} }
// 如果找到了解密密钥,则进行解密
if (key > 0) if (key > 0)
{ {
// 分配内存用于存放解密后的图像数据
char *img_buf = new char[buf.size()]; char *img_buf = new char[buf.size()];
// 对图像数据进行异或操作进行解密
for (unsigned int i = 0; i < buf.size(); i++) for (unsigned int i = 0; i < buf.size(); i++)
{ {
img_buf[i] = *(origin + i) ^ key; img_buf[i] = *(origin + i) ^ key;
} }
// 创建解密后的字符串并返回
std::string str(img_buf); std::string str(img_buf);
// 释放分配的内存
delete[] img_buf; delete[] img_buf;
img_buf = NULL; img_buf = NULL;
return str; return str;
} }
// 如果没有找到解密密钥,则返回空字符串
return std::string(); return std::string();
} }
// 定义ReadWstring函数用于读取宽字符字符串
std::wstring ReadWstring(INT64 addr) std::wstring ReadWstring(INT64 addr)
{ {
// 读取地址偏移0x8处的长度
DWORD len = *(DWORD *)(addr + 0x8); DWORD len = *(DWORD *)(addr + 0x8);
// 如果长度为0则返回空宽字符串
if (len == 0) if (len == 0)
{ {
return std::wstring(); return std::wstring();
} }
// 读取地址处指向的宽字符指针
wchar_t *str = *(wchar_t **)(addr); wchar_t *str = *(wchar_t **)(addr);
// 如果宽字符指针为空,则返回空宽字符串
if (str == NULL) if (str == NULL)
{ {
return std::wstring(); return std::wstring();
} }
// 否则,从宽字符指针处读取宽字符串
return std::wstring(str, len); return std::wstring(str, len);
} }
// 定义ReadWstringThenConvert函数用于读取宽字符串并转换为UTF-8字符串
std::string ReadWstringThenConvert(INT64 addr) std::string ReadWstringThenConvert(INT64 addr)
{ {
// 调用ReadWstring函数读取宽字符串
std::wstring wstr = ReadWstring(addr); std::wstring wstr = ReadWstring(addr);
// 调用WstringToUtf8函数将宽字符串转换为UTF-8字符串
return base::utils::WstringToUtf8(wstr); return base::utils::WstringToUtf8(wstr);
} }
// 定义DecodeImage函数用于解码图像数据
int DecodeImage(const wchar_t *file_path, const wchar_t *save_dir) int DecodeImage(const wchar_t *file_path, const wchar_t *save_dir)
{ {
// 该函数目前尚未实现,返回-1表示失败
return -1; return -1;
} }
// 定义print_utf8_to_console函数用于将UTF-8字符串打印到控制台
void print_utf8_to_console(const std::string &utf8_str) void print_utf8_to_console(const std::string &utf8_str)
{ {
// 获取当前时间 // 获取当前时间