diff --git a/WeChatFerry/spy/chatroom_manager.cpp b/WeChatFerry/spy/chatroom_manager.cpp index 00a9bf7..4ce74ce 100644 --- a/WeChatFerry/spy/chatroom_manager.cpp +++ b/WeChatFerry/spy/chatroom_manager.cpp @@ -88,20 +88,26 @@ int invite_chatroom_member(const string &roomid, const string &wxids) reinterpret_cast(wx_roomid.get()), 0)); } -bool rpc_add_chatroom_member(const string &roomid, const string &wxids, uint8_t *out, size_t *len) +bool rpc_add_chatroom_member(const MemberMgmt &m, uint8_t *out, size_t *len) { + const std::string wxids = m.wxids; + const std::string roomid = m.roomid; return fill_response( out, len, [&](Response &rsp) { rsp.msg.status = add_chatroom_member(roomid, wxids); }); } -bool rpc_del_chatroom_member(const string &roomid, const string &wxids, uint8_t *out, size_t *len) +bool rpc_delete_chatroom_member(const MemberMgmt &m, uint8_t *out, size_t *len) { + const std::string wxids = m.wxids; + const std::string roomid = m.roomid; return fill_response( out, len, [&](Response &rsp) { rsp.msg.status = del_chatroom_member(roomid, wxids); }); } -bool rpc_invite_chatroom_member(const string &roomid, const string &wxids, uint8_t *out, size_t *len) +bool rpc_invite_chatroom_member(const MemberMgmt &m, uint8_t *out, size_t *len) { + const std::string wxids = m.wxids; + const std::string roomid = m.roomid; return fill_response( out, len, [&](Response &rsp) { rsp.msg.status = invite_chatroom_member(roomid, wxids); }); } diff --git a/WeChatFerry/spy/chatroom_manager.h b/WeChatFerry/spy/chatroom_manager.h index 9791ed7..3be999d 100644 --- a/WeChatFerry/spy/chatroom_manager.h +++ b/WeChatFerry/spy/chatroom_manager.h @@ -2,6 +2,8 @@ #include +#include "wcf.pb.h" + namespace chatroom { @@ -15,8 +17,8 @@ int del_chatroom_member(const std::string &roomid, const std::string &wxids); int invite_chatroom_member(const std::string &roomid, const std::string &wxids); // RPC 方法 -bool rpc_add_chatroom_member(const std::string &roomid, const std::string &wxids, uint8_t *out, size_t *len); -bool rpc_del_chatroom_member(const std::string &roomid, const std::string &wxids, uint8_t *out, size_t *len); -bool rpc_invite_chatroom_member(const std::string &roomid, const std::string &wxids, uint8_t *out, size_t *len); +bool rpc_add_chatroom_member(const MemberMgmt &m, uint8_t *out, size_t *len); +bool rpc_delete_chatroom_member(const MemberMgmt &m, uint8_t *out, size_t *len); +bool rpc_invite_chatroom_member(const MemberMgmt &m, uint8_t *out, size_t *len); } // namespace chatroom diff --git a/WeChatFerry/spy/contact_manager.cpp b/WeChatFerry/spy/contact_manager.cpp index bb4efe8..0e1ecb3 100644 --- a/WeChatFerry/spy/contact_manager.cpp +++ b/WeChatFerry/spy/contact_manager.cpp @@ -212,8 +212,11 @@ bool rpc_get_contact_info(const string &wxid, uint8_t *out, size_t *len) }); } -bool rpc_accept_friend(const string &v3, const string &v4, int scene, uint8_t *out, size_t *len) +bool rpc_accept_friend(const Verification &v, uint8_t *out, size_t *len) { + const string v3 = v.v3; + const string v4 = v.v4; + int scene = v.scene; return fill_response( out, len, [&](Response &rsp) { rsp.msg.status = accept_new_friend(v3, v4, scene); }); } diff --git a/WeChatFerry/spy/contact_manager.h b/WeChatFerry/spy/contact_manager.h index 5b330c0..440091e 100644 --- a/WeChatFerry/spy/contact_manager.h +++ b/WeChatFerry/spy/contact_manager.h @@ -3,6 +3,8 @@ #include #include +#include "wcf.pb.h" + #include "pb_types.h" namespace contact @@ -23,6 +25,6 @@ int accept_new_friend(const std::string &v3, const std::string &v4, int scene); // RPC 方法 bool rpc_get_contacts(uint8_t *out, size_t *len); bool rpc_get_contact_info(const std::string &wxid, uint8_t *out, size_t *len); -bool rpc_accept_friend(const std::string &v3, const std::string &v4, int scene, uint8_t *out, size_t *len); +bool rpc_accept_friend(const Verification &v, uint8_t *out, size_t *len); } // namespace contact diff --git a/WeChatFerry/spy/database_executor.cpp b/WeChatFerry/spy/database_executor.cpp index 3f850a3..bd5a7f8 100644 --- a/WeChatFerry/spy/database_executor.cpp +++ b/WeChatFerry/spy/database_executor.cpp @@ -278,8 +278,10 @@ bool rpc_get_db_tables(const std::string &db, uint8_t *out, size_t *len) }); } -bool rpc_exec_db_query(const std::string &db, const std::string &sql, uint8_t *out, size_t *len) +bool rpc_exec_db_query(const DbQuery query, uint8_t *out, size_t *len) { + const std::string db(query.db); + const std::string sql(query.sql); return fill_response(out, len, [&](Response &rsp) { DbRows_t rows = exec_db_query(db, sql); rsp.msg.rows.rows.funcs.encode = encode_rows; diff --git a/WeChatFerry/spy/database_executor.h b/WeChatFerry/spy/database_executor.h index 4f2752d..0d50373 100644 --- a/WeChatFerry/spy/database_executor.h +++ b/WeChatFerry/spy/database_executor.h @@ -4,6 +4,8 @@ #include #include +#include "wcf.pb.h" + #include "pb_types.h" namespace db @@ -27,6 +29,6 @@ std::vector get_audio_data(uint64_t msg_id); // RPC 方法 bool rpc_get_db_names(uint8_t *out, size_t *len); bool rpc_get_db_tables(const std::string &db, uint8_t *out, size_t *len); -bool rpc_exec_db_query(const std::string &db, const std::string &sql, uint8_t *out, size_t *len); +bool rpc_exec_db_query(const DbQuery query, uint8_t *out, size_t *len); } // namespace db diff --git a/WeChatFerry/spy/message_handler.cpp b/WeChatFerry/spy/message_handler.cpp index c1070e8..3889c09 100644 --- a/WeChatFerry/spy/message_handler.cpp +++ b/WeChatFerry/spy/message_handler.cpp @@ -7,6 +7,7 @@ #include "framework.h" #include "log.hpp" +#include "pb_util.h" #include "rpc_helper.h" #include "userinfo_manager.h" #include "util.h" @@ -268,7 +269,7 @@ MH_STATUS Handler::UninitializeHook() return status; } -bool Handler::rpc_get_msg_types() +bool Handler::rpc_get_msg_types(uint8_t *out, size_t *len) { return fill_response(out, len, [&](Response &rsp) { MsgTypes_t types = GetMsgTypes(); @@ -276,35 +277,4 @@ bool Handler::rpc_get_msg_types() rsp.msg.types.types.arg = &types; }); } - -bool rpc_enable_recv_msg(void *cb, bool pyq, uint8_t *out, size_t *len) -{ - return fill_response(out, len, [cb, pyq](Response &rsp) { - auto &handler = Handler::getInstance(); - rsp.msg.status = handler.ListenMsg(); - if (rsp.msg.status == 0) { - if (pyq) { - msgHandler.ListenPyq(); - } - msgThread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)cb, nullptr, 0, nullptr); - if (msgThread == nullptr) { - rsp.msg.status = GetLastError(); - LOG_ERROR("func_enable_recv_txt failed: {}", rsp.msg.status); - } - } - }); } -bool Handler::rpc_disable_recv_msg(uint8_t *out, size_t *len) -{ - return fill_response(out, len, [](Response &rsp) { - rsp.msg.status = UnListenMsg(); - if (rsp.msg.status == 0) { - UnListenPyq(); - if (msgThread != nullptr) { - TerminateThread(msgThread, 0); - msgThread = nullptr; - } - } - }); -} -} \ No newline at end of file diff --git a/WeChatFerry/spy/message_handler.h b/WeChatFerry/spy/message_handler.h index c9e0898..c4227ec 100644 --- a/WeChatFerry/spy/message_handler.h +++ b/WeChatFerry/spy/message_handler.h @@ -37,9 +37,7 @@ public: std::condition_variable &getConditionVariable() { return cv_; }; std::mutex &getMutex() { return mutex_; }; - bool rpc_get_msg_types(); - bool rpc_enable_recv_msg(void *cb, bool pyq, uint8_t *out, size_t *len); - bool rpc_disable_recv_msg(uint8_t *out, size_t *len); + bool rpc_get_msg_types(uint8_t *out, size_t *len); private: Handler(); diff --git a/WeChatFerry/spy/message_sender.cpp b/WeChatFerry/spy/message_sender.cpp index 0c79503..c1cb7c8 100644 --- a/WeChatFerry/spy/message_sender.cpp +++ b/WeChatFerry/spy/message_sender.cpp @@ -262,8 +262,10 @@ bool Sender::rpc_send_text(const TextMsg &text, uint8_t *out, size_t *len) }); } -bool Sender::rpc_send_image(const std::string &path, const std::string &receiver, uint8_t *out, size_t *len) +bool Sender::rpc_send_image(const PathMsg &file, uint8_t *out, size_t *len) { + std::string path(file.path); + std::string receiver(file.receiver); return fill_response(out, len, [&](Response &rsp) { if (path.empty() || receiver.empty()) { LOG_ERROR("Empty path or receiver."); @@ -275,8 +277,10 @@ bool Sender::rpc_send_image(const std::string &path, const std::string &receiver }); } -bool Sender::rpc_send_file(const std::string &path, const std::string &receiver, uint8_t *out, size_t *len) +bool Sender::rpc_send_file(const PathMsg &file, uint8_t *out, size_t *len) { + std::string path(file.path); + std::string receiver(file.receiver); return fill_response(out, len, [&](Response &rsp) { if (path.empty() || receiver.empty()) { LOG_ERROR("Empty path or receiver."); @@ -288,8 +292,10 @@ bool Sender::rpc_send_file(const std::string &path, const std::string &receiver, }); } -bool Sender::rpc_send_emotion(const std::string &path, const std::string &receiver, uint8_t *out, size_t *len) +bool Sender::rpc_send_emotion(const PathMsg &file, uint8_t *out, size_t *len) { + std::string path(file.path); + std::string receiver(file.receiver); return fill_response(out, len, [&](Response &rsp) { if (path.empty() || receiver.empty()) { LOG_ERROR("Empty path or receiver."); @@ -326,8 +332,10 @@ bool Sender::rpc_send_rich_text(const RichText &rt, uint8_t *out, size_t *len) }); } -bool Sender::rpc_send_pat(const std::string &roomid, const std::string &wxid, uint8_t *out, size_t *len) +bool Sender::rpc_send_pat(const PatMsg &pat, uint8_t *out, size_t *len) { + std::string wxid(pat.wxid); + std::string roomid(pat.roomid); return fill_response(out, len, [&](Response &rsp) { if (roomid.empty() || wxid.empty()) { LOG_ERROR("Empty roomid or wxid."); @@ -338,8 +346,10 @@ bool Sender::rpc_send_pat(const std::string &roomid, const std::string &wxid, ui }); } -bool Sender::rpc_forward(uint64_t msgid, const std::string &receiver, uint8_t *out, size_t *len) +bool Sender::rpc_forward(const ForwardMsg &fm, uint8_t *out, size_t *len) { + uint64_t msgid = fm.id; + std::string receiver(fm.receiver); return fill_response(out, len, [&](Response &rsp) { if (receiver.empty()) { LOG_ERROR("Empty receiver."); @@ -350,4 +360,4 @@ bool Sender::rpc_forward(uint64_t msgid, const std::string &receiver, uint8_t *o }); } -} \ No newline at end of file +} diff --git a/WeChatFerry/spy/message_sender.h b/WeChatFerry/spy/message_sender.h index e528065..1f0a855 100644 --- a/WeChatFerry/spy/message_sender.h +++ b/WeChatFerry/spy/message_sender.h @@ -4,9 +4,10 @@ #include #include -#include "spy_types.h" #include "wcf.pb.h" +#include "spy_types.h" + namespace message { @@ -26,13 +27,13 @@ public: // RPC 方法 bool rpc_send_text(const TextMsg &text, uint8_t *out, size_t *len); - bool rpc_send_image(const std::string &path, const std::string &receiver, uint8_t *out, size_t *len); - bool rpc_send_file(const std::string &path, const std::string &receiver, uint8_t *out, size_t *len); - bool rpc_send_emotion(const std::string &path, const std::string &receiver, uint8_t *out, size_t *len); + bool rpc_send_image(const PathMsg &file, uint8_t *out, size_t *len); + bool rpc_send_file(const PathMsg &file, uint8_t *out, size_t *len); + bool rpc_send_emotion(const PathMsg &file, uint8_t *out, size_t *len); bool rpc_send_xml(const XmlMsg &rt, uint8_t *out, size_t *len); bool rpc_send_rich_text(const RichText &rt, uint8_t *out, size_t *len); - bool rpc_send_pat(const std::string &roomid, const std::string &wxid, uint8_t *out, size_t *len); - bool rpc_forward(uint64_t msgid, const std::string &receiver, uint8_t *out, size_t *len); + bool rpc_send_pat(const PatMsg &pat, uint8_t *out, size_t *len); + bool rpc_forward(const ForwardMsg &fm, uint8_t *out, size_t *len); private: Sender(); @@ -76,5 +77,4 @@ private: std::unique_ptr new_wx_string(const std::string &str); std::vector parse_wxids(const std::string &wxids); }; - -} \ No newline at end of file +} diff --git a/WeChatFerry/spy/misc_manager.cpp b/WeChatFerry/spy/misc_manager.cpp index 4cf414f..f6f1b3f 100644 --- a/WeChatFerry/spy/misc_manager.cpp +++ b/WeChatFerry/spy/misc_manager.cpp @@ -10,6 +10,7 @@ #include "database_executor.h" #include "log.hpp" #include "message_handler.h" +#include "rpc_helper.h" #include "spy_types.h" #include "util.h" @@ -349,4 +350,66 @@ int receive_transfer(const std::string &wxid, const std::string &transferid, con // 别想了,这个不实现了 return -1; } + +bool rpc_is_logged_in(uint8_t *out, size_t *len) +{ + return fill_response(out, len, [](Response &rsp) { rsp.msg.status = is_logged_in(); }); +} + +bool rpc_get_audio(const AudioMsg &am, uint8_t *out, size_t *len) +{ + return fill_response( + out, len, [&](Response &rsp) { rsp.msg.str = (char *)get_audio(am.id, am.dir).c_str(); }); +} + +bool rpc_get_pcm_audio(uint64_t id, const std::filesystem::path &dir, int32_t sr, uint8_t *out, size_t *len) +{ + return false; +} + +bool rpc_decrypt_image(const DecPath &dec, uint8_t *out, size_t *len) +{ + return fill_response( + out, len, [&](Response &rsp) { rsp.msg.str = (char *)decrypt_image(dec.src, dec.dst).c_str(); }); +} + +bool rpc_get_login_url(uint8_t *out, size_t *len) +{ + return fill_response( + out, len, [&](Response &rsp) { rsp.msg.str = (char *)get_login_url().c_str(); }); +} + +bool rpc_refresh_pyq(uint64_t id, uint8_t *out, size_t *len) +{ + return fill_response(out, len, + [&](Response &rsp) { rsp.msg.status = refresh_pyq(id); }); +} + +bool rpc_download_attachment(const AttachMsg &att, uint8_t *out, size_t *len) +{ + return fill_response( + out, len, [&](Response &rsp) { rsp.msg.status = download_attachment(att.id, att.thumb, att.extra); }); +} + +bool rpc_revoke_message(uint64_t id, uint8_t *out, size_t *len) +{ + return fill_response(out, len, + [&](Response &rsp) { rsp.msg.status = revoke_message(id); }); +} + +bool rpc_get_ocr_result(const std::filesystem::path &path, uint8_t *out, size_t *len) +{ + return fill_response(out, len, [&](Response &rsp) { + OcrResult_t ret = { -1, "" }; + ret = get_ocr_result(path); + rsp.msg.ocr.status = ret.status; + rsp.msg.ocr.result = (char *)ret.result.c_str(); + }); +} + +bool rpc_receive_transfer(const Transfer &tf, uint8_t *out, size_t *len) +{ + return fill_response( + out, len, [&](Response &rsp) { rsp.msg.status = receive_transfer(tf.wxid, tf.tfid, tf.taid); }); +} } // namespace misc diff --git a/WeChatFerry/spy/misc_manager.h b/WeChatFerry/spy/misc_manager.h index 378dc42..2f995ae 100644 --- a/WeChatFerry/spy/misc_manager.h +++ b/WeChatFerry/spy/misc_manager.h @@ -30,14 +30,14 @@ int receive_transfer(const std::string &wxid, const std::string &transferid, con // RPC // clang-format off bool rpc_is_logged_in(uint8_t *out, size_t *len); -bool rpc_get_audio(uint64_t id, const std::filesystem::path &dir, uint8_t *out, size_t *len); +bool rpc_get_audio(const AudioMsg &am, uint8_t *out, size_t *len); bool rpc_get_pcm_audio(uint64_t id, const std::filesystem::path &dir, int32_t sr, uint8_t *out, size_t *len); bool rpc_decrypt_image(const DecPath &dec, uint8_t *out, size_t *len); bool rpc_get_login_url(uint8_t *out, size_t *len); bool rpc_refresh_pyq(uint64_t id, uint8_t *out, size_t *len); -bool rpc_download_attachment(uint64_t id, const std::filesystem::path &thumb, const std::filesystem::path &extra, uint8_t *out, size_t *len); +bool rpc_download_attachment(const AttachMsg &att, uint8_t *out, size_t *len); bool rpc_revoke_message(uint64_t id, uint8_t *out, size_t *len); bool rpc_get_ocr_result(const std::filesystem::path &path, uint8_t *out, size_t *len); -bool rpc_receive_transfer(const std::string &wxid, const std::string &transferid, const std::string &transactionid, uint8_t *out, size_t *len); +bool rpc_receive_transfer(const Transfer &tf, uint8_t *out, size_t *len); // clang-format on } // namespace misc diff --git a/WeChatFerry/spy/rpc_server.cpp b/WeChatFerry/spy/rpc_server.cpp index 999166d..d4be76e 100644 --- a/WeChatFerry/spy/rpc_server.cpp +++ b/WeChatFerry/spy/rpc_server.cpp @@ -29,6 +29,7 @@ #include "misc_manager.h" #include "pb_types.h" #include "pb_util.h" +#include "rpc_helper.h" #include "spy.h" #include "spy_types.h" #include "userinfo_manager.h" @@ -44,52 +45,14 @@ static HANDLE cmdThread = NULL; static HANDLE msgThread = NULL; static nng_socket cmdSock = NNG_SOCKET_INITIALIZER; // TODO: 断开检测 static nng_socket msgSock = NNG_SOCKET_INITIALIZER; // TODO: 断开检测 +auto &handler = message::Handler::getInstance(); +auto &sender = message::Sender::get_instance(); using FunctionHandler = std::function; inline std::string build_url(int port) { return "tcp://0.0.0.0:" + std::to_string(port); } -void receive_message_callback(); -auto &handler = message::Handler::getInstance(); -auto &sender = message::Sender::get_instance(); - -const std::unordered_map rpc_function_map = { - // clang-format off - { Functions_FUNC_IS_LOGIN, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_is_logged_in(out, len); } }, - { Functions_FUNC_GET_SELF_WXID, [](const Request &r, uint8_t *out, size_t *len) { return userinfo::rpc_get_self_wxid(out, len)} }, - { Functions_FUNC_GET_USER_INFO, [](const Request &r, uint8_t *out, size_t *len) { return userinfo::rpc_get_user_info(out, len); } }, - { Functions_FUNC_GET_MSG_TYPES, [](const Request &r, uint8_t *out, size_t *len) { return handler.rpc_get_msg_types(out, len); } }, - { Functions_FUNC_GET_CONTACTS, [](const Request &r, uint8_t *out, size_t *len) { return contact::rpc_get_contacts(out, len); } }, - { Functions_FUNC_GET_DB_NAMES, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_get_db_names(out, len); } }, - { Functions_FUNC_GET_DB_TABLES, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_get_db_tables(r.msg.str, out, len); } }, - { Functions_FUNC_GET_AUDIO_MSG, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_get_audio(r.msg.am.id, r.msg.am.dir, out, len); } }, - { Functions_FUNC_SEND_TXT, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_text(r.msg.txt, out, len); } }, - { Functions_FUNC_SEND_IMG, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_image(r.msg.file.path, r.msg.file.receiver, out, len); } }, - { Functions_FUNC_SEND_FILE, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_file(r.msg.file.path, r.msg.file.receiver, out, len); } }, - { Functions_FUNC_SEND_XML, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_xml(r.msg.xml, out, len); } }, - { Functions_FUNC_SEND_RICH_TXT, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_rich_text(r.msg.rt, out, len); } }, - { Functions_FUNC_SEND_PAT_MSG, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_pat(r.msg.pm.roomid, r.msg.pm.wxid, out, len); } }, - { Functions_FUNC_FORWARD_MSG, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_forward(r.msg.fm.id, r.msg.fm.receiver, out, len); } }, - { Functions_FUNC_SEND_EMOTION, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_emotion(r.msg.file.path, r.msg.file.receiver, out, len); } }, - { Functions_FUNC_ENABLE_RECV_TXT, [](const Request &r, uint8_t *out, size_t *len) { return handler.rpc_enable_recv_msg(receive_message_callback, r.msg.flag, out, len); } }, - { Functions_FUNC_DISABLE_RECV_TXT, [](const Request &r, uint8_t *out, size_t *len) { return handler.rpc_disable_recv_msg(out, len); } }, - { Functions_FUNC_EXEC_DB_QUERY, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_exec_db_query(r.msg.query.db, r.msg.query.sql, out, len); } }, - { Functions_FUNC_REFRESH_PYQ, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_refresh_pyq(r.msg.ui64, out, len); } }, - { Functions_FUNC_DOWNLOAD_ATTACH, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_download_attachment(r.msg.att, out, len); } }, - { Functions_FUNC_GET_CONTACT_INFO, [](const Request &r, uint8_t *out, size_t *len) { return contact::rpc_get_contact_info(r.msg.str, out, len); } }, - { Functions_FUNC_ACCEPT_FRIEND, [](const Request &r, uint8_t *out, size_t *len) { return contact::rpc_accept_friend(r.msg.v, out, len); } }, - { Functions_FUNC_RECV_TRANSFER, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_receive_transfer(r.msg.tf, out, len); } }, - { Functions_FUNC_REVOKE_MSG, [](const Request &r, uint8_t *out, size_t *len) { return misc::revoke_message(r.msg.ui64, out, len); } }, - { Functions_FUNC_REFRESH_QRCODE, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_get_login_url(out, len); } }, - { Functions_FUNC_DECRYPT_IMAGE, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_decrypt_image(r.msg.dec, out, len); } }, - { Functions_FUNC_EXEC_OCR, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_get_ocr_result(r.msg.str, out, len); } }, - { Functions_FUNC_ADD_ROOM_MEMBERS, [](const Request &r, uint8_t *out, size_t *len) { return chatroom::rpc_add_chatroom_member(r.msg.m, out, len); } }, - { Functions_FUNC_DEL_ROOM_MEMBERS, [](const Request &r, uint8_t *out, size_t *len) { return chatroom::rpc_del_chatroom_member(r.msg.m, out, len); } }, - { Functions_FUNC_INV_ROOM_MEMBERS, [](const Request &r, uint8_t *out, size_t *len) { return chatroom::rpc_invite_chatroom_memberr.msg.m, out, len); } }, - // clang-format on -}; - -void receive_message_callback() +static void receive_message_callback() { int rv; Response rsp = Response_init_default; @@ -155,6 +118,73 @@ void receive_message_callback() } } +static bool rpc_enable_recv_msg(bool pyq, uint8_t *out, size_t *len) +{ + return fill_response(out, len, [&](Response &rsp) { + rsp.msg.status = handler.ListenMsg(); + if (rsp.msg.status == 0) { + if (pyq) { + handler.ListenPyq(); + } + msgThread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)receive_message_callback, nullptr, 0, nullptr); + if (msgThread == nullptr) { + rsp.msg.status = GetLastError(); + LOG_ERROR("func_enable_recv_txt failed: {}", rsp.msg.status); + } + } + }); +} + +static bool rpc_disable_recv_msg(uint8_t *out, size_t *len) +{ + return fill_response(out, len, [](Response &rsp) { + rsp.msg.status = handler.UnListenMsg(); + if (rsp.msg.status == 0) { + handler.UnListenPyq(); + if (msgThread != nullptr) { + TerminateThread(msgThread, 0); + msgThread = nullptr; + } + } + }); +} + +const std::unordered_map rpc_function_map = { + // clang-format off + { Functions_FUNC_IS_LOGIN, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_is_logged_in(out, len); } }, + { Functions_FUNC_GET_SELF_WXID, [](const Request &r, uint8_t *out, size_t *len) { return userinfo::rpc_get_self_wxid(out, len); } }, + { Functions_FUNC_GET_USER_INFO, [](const Request &r, uint8_t *out, size_t *len) { return userinfo::rpc_get_user_info(out, len); } }, + { Functions_FUNC_GET_MSG_TYPES, [](const Request &r, uint8_t *out, size_t *len) { return handler.rpc_get_msg_types(out, len); } }, + { Functions_FUNC_GET_CONTACTS, [](const Request &r, uint8_t *out, size_t *len) { return contact::rpc_get_contacts(out, len); } }, + { Functions_FUNC_GET_DB_NAMES, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_get_db_names(out, len); } }, + { Functions_FUNC_GET_DB_TABLES, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_get_db_tables(r.msg.str, out, len); } }, + { Functions_FUNC_GET_AUDIO_MSG, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_get_audio(r.msg.am, out, len); } }, + { Functions_FUNC_SEND_TXT, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_text(r.msg.txt, out, len); } }, + { Functions_FUNC_SEND_IMG, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_image(r.msg.file, out, len); } }, + { Functions_FUNC_SEND_FILE, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_file(r.msg.file, out, len); } }, + { Functions_FUNC_SEND_XML, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_xml(r.msg.xml, out, len); } }, + { Functions_FUNC_SEND_EMOTION, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_emotion(r.msg.file, out, len); } }, + { Functions_FUNC_SEND_RICH_TXT, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_rich_text(r.msg.rt, out, len); } }, + { Functions_FUNC_SEND_PAT_MSG, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_pat(r.msg.pm, out, len); } }, + { Functions_FUNC_FORWARD_MSG, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_forward(r.msg.fm, out, len); } }, + { Functions_FUNC_ENABLE_RECV_TXT, [](const Request &r, uint8_t *out, size_t *len) { return rpc_enable_recv_msg(r.msg.flag, out, len); } }, + { Functions_FUNC_DISABLE_RECV_TXT, [](const Request &r, uint8_t *out, size_t *len) { return rpc_disable_recv_msg(out, len); } }, + { Functions_FUNC_EXEC_DB_QUERY, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_exec_db_query(r.msg.query, out, len); } }, + { Functions_FUNC_ACCEPT_FRIEND, [](const Request &r, uint8_t *out, size_t *len) { return contact::rpc_accept_friend(r.msg.v, out, len); } }, + { Functions_FUNC_RECV_TRANSFER, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_receive_transfer(r.msg.tf, out, len); } }, + { Functions_FUNC_REFRESH_PYQ, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_refresh_pyq(r.msg.ui64, out, len); } }, + { Functions_FUNC_DOWNLOAD_ATTACH, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_download_attachment(r.msg.att, out, len); } }, + { Functions_FUNC_GET_CONTACT_INFO, [](const Request &r, uint8_t *out, size_t *len) { return contact::rpc_get_contact_info(r.msg.str, out, len); } }, + { Functions_FUNC_REVOKE_MSG, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_revoke_message(r.msg.ui64, out, len); } }, + { Functions_FUNC_REFRESH_QRCODE, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_get_login_url(out, len); } }, + { Functions_FUNC_DECRYPT_IMAGE, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_decrypt_image(r.msg.dec, out, len); } }, + { Functions_FUNC_EXEC_OCR, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_get_ocr_result(r.msg.str, out, len); } }, + { Functions_FUNC_ADD_ROOM_MEMBERS, [](const Request &r, uint8_t *out, size_t *len) { return chatroom::rpc_add_chatroom_member(r.msg.m, out, len); } }, + { Functions_FUNC_DEL_ROOM_MEMBERS, [](const Request &r, uint8_t *out, size_t *len) { return chatroom::rpc_delete_chatroom_member(r.msg.m, out, len); } }, + { Functions_FUNC_INV_ROOM_MEMBERS, [](const Request &r, uint8_t *out, size_t *len) { return chatroom::rpc_invite_chatroom_member(r.msg.m, out, len); } }, + // clang-format on +}; + static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len) { bool ret = false;