增加注释

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

View File

@ -5,128 +5,184 @@
#include "spdlog/spdlog.h"
#include "wechat_interface.h"
#include "wechat_service.h"
#include "wxutils.h"
namespace jsonutils = wxhelper::jsonutils;
namespace wxhelper {
std::string MiscController::CheckLogin(std::string params) {
int64_t success = wechat::WeChatService::GetInstance().CheckLogin();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump();
}
std::string MiscController::GetUserInfo(std::string params) {
wechat::SelfInfoInner out;
int64_t success = wechat::WeChatService::GetInstance().GetSelfInfo(out);
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
nlohmann::json j_info = {
{"name", out.name},
{"city", out.city},
{"province", out.province},
{"country", out.country},
{"account", out.account},
{"wxid", out.wxid},
{"mobile", out.mobile},
{"headImage", out.head_img},
{"signature", out.signature},
{"dataSavePath", out.data_save_path},
{"currentDataPath", out.current_data_path},
{"dbKey", out.db_key},
{"publicKey", out.public_key},
{"privateKey", out.private_key},
};
ret["data"] = j_info;
return ret.dump();
}
std::string MiscController::GetSNSFirstPage(std::string params) {
nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
std::string MiscController::GetSNSNextPage(std::string params) {
nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
std::string MiscController::AddFavFromMsg(std::string params) {
nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
std::string MiscController::AddFavFromImage(std::string params) {
nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
std::string MiscController::DecodeImage(std::string params) {
nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
std::string MiscController::GetVoiceByMsgId(std::string params) {
nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
std::string MiscController::DoOcrTask(std::string params) {
nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
std::string MiscController::LockWeChat(std::string params) {
int64_t success = wechat::WeChatService::GetInstance().LockWeChat();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump();
}
std::string MiscController::UnlockWeChat(std::string params) {
int64_t success = wechat::WeChatService::GetInstance().UnlockWeChat();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump();
}
std::string MiscController::ClickEnterWeChat(std::string params) {
int64_t success = wechat::WeChatService::GetInstance().EnterWeChat();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump();
}
std::string MiscController::GetLoginUrl(std::string params) {
std::string login_url = wechat::WeChatService::GetInstance().GetLoginUrl();
nlohmann::json ret = {
{"code", 1}, {"data", {"loginUrl", login_url}}, {"msg", "success"}};
return ret.dump();
}
std::string MiscController::TranslateVoice(std::string params) {
nlohmann::json jp = nlohmann::json::parse(params);
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
int64_t success = wechat::WeChatService::GetInstance().TranslateVoice(msg_id);
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump();
}
std::string MiscController::GetTranslateVoiceText(std::string params) {
nlohmann::json jp = nlohmann::json::parse(params);
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
std::string content =
wechat::WeChatService::GetInstance().GetTranslateVoiceText(msg_id);
nlohmann::json ret_data = {
{"code", 1}, {"msg", "success"}, {"data", {{"transtext", content}}}};
return ret_data.dump();
}
std::string MiscController::OpenUrlByWeChat(std::string params) {
nlohmann::json jp = nlohmann::json::parse(params);
std::wstring url = jsonutils::GetWStringParam(jp, "url");
int flag = jsonutils::GetIntParam(jp, "flag");
int64_t success =
wechat::WeChatService::GetInstance().OpenUrlByWeChatBrowser(url, flag);
nlohmann::json ret = {
{"code", success}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
std::string MiscController::ConfirmReceipt(std::string params) {
nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
std::string MiscController::DownloadAttach(std::string params) {
nlohmann::json ret = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
} // namespace wxhelper
namespace wxhelper
{
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();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump();
}
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;
int64_t success = wechat::WeChatService::GetInstance().GetSelfInfo(out);
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
nlohmann::json j_info = {
{"name", out.name},
{"city", out.city},
{"province", out.province},
{"country", out.country},
{"account", out.account},
{"wxid", out.wxid},
{"mobile", out.mobile},
{"headImage", out.head_img},
{"signature", out.signature},
{"dataSavePath", out.data_save_path},
{"currentDataPath", out.current_data_path},
{"dbKey", out.db_key},
{"publicKey", out.public_key},
{"privateKey", out.private_key},
};
ret["data"] = j_info;
return ret.dump();
}
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 = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
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 = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
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 = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
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 = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
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 = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
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 = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
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 = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
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();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump();
}
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();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump();
}
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();
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump();
}
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();
nlohmann::json ret = {
{"code", 1}, {"data", {"loginUrl", login_url}}, {"msg", "success"}};
return ret.dump();
}
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);
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
int64_t success = wechat::WeChatService::GetInstance().TranslateVoice(msg_id);
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
return ret.dump();
}
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);
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
std::string content =
wechat::WeChatService::GetInstance().GetTranslateVoiceText(msg_id);
nlohmann::json ret_data = {
{"code", 1}, {"msg", "success"}, {"data", {{"transtext", content}}}};
return ret_data.dump();
}
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);
std::wstring url = jsonutils::GetWStringParam(jp, "url");
int flag = jsonutils::GetIntParam(jp, "flag");
int64_t success =
wechat::WeChatService::GetInstance().OpenUrlByWeChatBrowser(url, flag);
nlohmann::json ret = {
{"code", success}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
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 = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
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 = {
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
return ret.dump();
}
} // namespace wxhelper

View File

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

View File

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