diff --git a/WeChatFerry/rpc/proto/wcf.proto b/WeChatFerry/rpc/proto/wcf.proto index f7293e0..a92f637 100644 --- a/WeChatFerry/rpc/proto/wcf.proto +++ b/WeChatFerry/rpc/proto/wcf.proto @@ -12,6 +12,7 @@ enum Functions { FUNC_GET_DB_NAMES = 0x13; FUNC_GET_DB_TABLES = 0x14; FUNC_GET_USER_INFO = 0x15; + FUNC_GET_AUDIO_MSG = 0x16; FUNC_SEND_TXT = 0x20; FUNC_SEND_IMG = 0x21; FUNC_SEND_FILE = 0x22; @@ -49,6 +50,7 @@ message Request uint64 ui64 = 12; // 64 位整数,通用 bool flag = 13; AttachMsg att = 14; + AudioMsg am = 15; } } @@ -187,3 +189,9 @@ message AttachMsg string thumb = 2; // 消息中的 thumb string extra = 3; // 消息中的 extra } + +message AudioMsg +{ + uint64 id = 1; // 语音消息 id + string dir = 2; // 存放目录 +} diff --git a/WeChatFerry/smc/Codec.lib b/WeChatFerry/smc/Codec.lib new file mode 100644 index 0000000..5d2fdd6 Binary files /dev/null and b/WeChatFerry/smc/Codec.lib differ diff --git a/WeChatFerry/smc/codec.h b/WeChatFerry/smc/codec.h new file mode 100644 index 0000000..8b73771 --- /dev/null +++ b/WeChatFerry/smc/codec.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include +#include + +typedef struct { + double filetime; + int32_t totPackets; +} DecTime_t; + +int Mp3Encode(std::vector &pcm, std::string &mp3path, int32_t sr); +int Mp3Encode(std::vector &pcm, std::vector &mp3, int32_t sr); +DecTime_t SilkDecode(std::vector &silk, std::vector &pcm, int32_t sr); + +int Silk2Mp3(std::string inpath, std::string outpath, int sr); +int Silk2Mp3(std::vector &silk, std::string mp3path, int sr); +int Silk2Mp3(std::vector &silk, std::vector &mp3, int sr); diff --git a/WeChatFerry/spy/Spy.vcxproj b/WeChatFerry/spy/Spy.vcxproj index 973b9d2..5b68551 100644 --- a/WeChatFerry/spy/Spy.vcxproj +++ b/WeChatFerry/spy/Spy.vcxproj @@ -105,7 +105,7 @@ NotUsing - $(SolutionDir)rpc;$(SolutionDir)rpc\nanopb;$(SolutionDir)rpc\proto;$(SolutionDir)spy;C:\Tools\vcpkg\installed\x86-windows-static\include + $(SolutionDir)rpc;$(SolutionDir)rpc\nanopb;$(SolutionDir)rpc\proto;$(SolutionDir)smc;$(SolutionDir)spy;C:\Tools\vcpkg\installed\x86-windows-static\include 4251;4731;4819 MultiThreaded @@ -118,8 +118,10 @@ true true false - iphlpapi.lib;wsock32.lib;ws2_32.lib;crypt32.lib;%(AdditionalDependencies) + iphlpapi.lib;wsock32.lib;ws2_32.lib;crypt32.lib;Codec.lib;%(AdditionalDependencies) spy.def + $(SolutionDir)smc;%(AdditionalLibraryDirectories) + /ignore:4099 %(AdditionalOptions) if not exist $(SolutionDir)Out md $(SolutionDir)Out @@ -151,7 +153,7 @@ $(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto NotUsing - $(SolutionDir)rpc;$(SolutionDir)rpc\nanopb;$(SolutionDir)rpc\proto;$(SolutionDir)spy;C:\Tools\vcpkg\installed\x86-windows-static\include + $(SolutionDir)rpc;$(SolutionDir)rpc\nanopb;$(SolutionDir)rpc\proto;$(SolutionDir)smc;$(SolutionDir)spy;C:\Tools\vcpkg\installed\x86-windows-static\include 4251;4731;4819 MultiThreaded @@ -163,8 +165,10 @@ $(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto true true false - iphlpapi.lib;wsock32.lib;ws2_32.lib;crypt32.lib;%(AdditionalDependencies) + iphlpapi.lib;wsock32.lib;ws2_32.lib;crypt32.lib;Codec.lib;%(AdditionalDependencies) spy.def + $(SolutionDir)smc;%(AdditionalLibraryDirectories) + /ignore:4099 %(AdditionalOptions) if not exist $(SolutionDir)Out md $(SolutionDir)Out @@ -196,6 +200,7 @@ $(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto true false spy.def + /ignore:4099 %(AdditionalOptions) @@ -226,6 +231,7 @@ $(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto + diff --git a/WeChatFerry/spy/Spy.vcxproj.filters b/WeChatFerry/spy/Spy.vcxproj.filters index f8b47c4..1574f30 100644 --- a/WeChatFerry/spy/Spy.vcxproj.filters +++ b/WeChatFerry/spy/Spy.vcxproj.filters @@ -90,6 +90,9 @@ 头文件 + + 头文件 + diff --git a/WeChatFerry/spy/exec_sql.cpp b/WeChatFerry/spy/exec_sql.cpp index 309f37a..14d3275 100644 --- a/WeChatFerry/spy/exec_sql.cpp +++ b/WeChatFerry/spy/exec_sql.cpp @@ -195,3 +195,33 @@ int GetLocalIdandDbidx(uint64_t id, uint64_t *localId, uint32_t *dbIdx) return -1; } + +vector GetAudioData(uint64_t id) +{ + DWORD msgMgrAddr = GET_DWORD(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR); + DWORD dbIndex = GET_DWORD(msgMgrAddr + 0x38); + + string sql = "SELECT Buf from Media WHERE Reserved0=" + to_string(id) + ";"; + for (int i = dbIndex - 1; i >= 0; i--) { + string dbname = "MediaMSG" + to_string(i) + ".db"; + DbRows_t rows = ExecDbQuery(dbname, sql); + if (rows.empty()) { + continue; + } + DbRow_t row = rows.front(); + if (row.empty()) { + continue; + } + DbField_t field = row.front(); + if (field.column.compare("Buf") != 0) { + continue; + } + + // 首字节为 0x02,估计是混淆用的?去掉。 + vector rv(field.content.begin() + 1, field.content.end()); + + return rv; + } + + return vector(); +} diff --git a/WeChatFerry/spy/exec_sql.h b/WeChatFerry/spy/exec_sql.h index 86ce30e..ea7fc8f 100644 --- a/WeChatFerry/spy/exec_sql.h +++ b/WeChatFerry/spy/exec_sql.h @@ -1,8 +1,11 @@ #pragma once +#include + #include "pb_types.h" DbNames_t GetDbNames(); DbTables_t GetDbTables(const string db); DbRows_t ExecDbQuery(const string db, const string sql); int GetLocalIdandDbidx(uint64_t id, uint64_t *localId, uint32_t *dbIdx); +vector GetAudioData(uint64_t msgid); diff --git a/WeChatFerry/spy/funcs.cpp b/WeChatFerry/spy/funcs.cpp index b0245cd..ca6ccd3 100644 --- a/WeChatFerry/spy/funcs.cpp +++ b/WeChatFerry/spy/funcs.cpp @@ -4,6 +4,7 @@ #include #include +#include "codec.h" #include "exec_sql.h" #include "funcs.h" #include "log.h" @@ -93,6 +94,8 @@ string DecryptImage(string src, string dir) } replace(dst.begin(), dst.end(), '\\', '/'); + } catch (const std::exception &e) { + LOG_ERROR(GB2312ToUtf8(e.what())); } catch (...) { LOG_ERROR("Unknow exception."); return ""; @@ -313,3 +316,23 @@ int RevokeMsg(uint64_t id) return status; } + +string GetAudio(uint64_t id, string dir) +{ + string mp3path = (dir.back() == '\\' || dir.back() == '/') ? dir : (dir + "/"); + mp3path += to_string(id) + ".mp3"; + replace(mp3path.begin(), mp3path.end(), '\\', '/'); + if (fs::exists(mp3path)) { // 不重复下载 + return mp3path; + } + + vector silk = GetAudioData(id); + if (silk.size() == 0) { + LOG_ERROR("Empty audio data."); + return ""; + } + + Silk2Mp3(silk, mp3path, 24000); + + return mp3path; +} diff --git a/WeChatFerry/spy/funcs.h b/WeChatFerry/spy/funcs.h index 4cc2806..ef679e5 100644 --- a/WeChatFerry/spy/funcs.h +++ b/WeChatFerry/spy/funcs.h @@ -3,7 +3,8 @@ #include "stdint.h" #include -string DecryptImage(std::string src, std::string dst); +std::string GetAudio(uint64_t id, std::string dir); +std::string DecryptImage(std::string src, std::string dst); int RefreshPyq(uint64_t id); int DownloadAttach(uint64_t id, std::string thumb, std::string extra); int RevokeMsg(uint64_t id); diff --git a/WeChatFerry/spy/rpc_server.cpp b/WeChatFerry/spy/rpc_server.cpp index b20064f..142b346 100644 --- a/WeChatFerry/spy/rpc_server.cpp +++ b/WeChatFerry/spy/rpc_server.cpp @@ -187,6 +187,30 @@ bool func_get_user_info(uint8_t *out, size_t *len) return true; } +bool func_get_audio_msg(uint64_t id, char *dir, uint8_t *out, size_t *len) +{ + Response rsp = Response_init_default; + rsp.func = Functions_FUNC_GET_AUDIO_MSG; + rsp.which_msg = Response_str_tag; + + string path = string(dir ? dir : ""); + if (path.empty()) { + LOG_ERROR("Empty dir."); + rsp.msg.str = (char *)""; + } else { + rsp.msg.str = (char *)GetAudio(id, dir).c_str(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(out, *len); + if (!pb_encode(&stream, Response_fields, &rsp)) { + LOG_ERROR("Encoding failed: {}", PB_GET_ERROR(&stream)); + return false; + } + *len = stream.bytes_written; + + return true; +} + bool func_send_txt(TextMsg txt, uint8_t *out, size_t *len) { Response rsp = Response_init_default; @@ -692,6 +716,11 @@ static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len ret = func_get_user_info(out, out_len); break; } + case Functions_FUNC_GET_AUDIO_MSG: { + LOG_DEBUG("[Functions_FUNC_GET_AUDIO_MSG]"); + ret = func_get_audio_msg(req.msg.am.id, req.msg.am.dir, out, out_len); + break; + } case Functions_FUNC_SEND_TXT: { LOG_DEBUG("[Functions_FUNC_SEND_TXT]"); ret = func_send_txt(req.msg.txt, out, out_len); diff --git a/clients/python/wcferry/client.py b/clients/python/wcferry/client.py index 65308e6..226b4e4 100644 --- a/clients/python/wcferry/client.py +++ b/clients/python/wcferry/client.py @@ -234,6 +234,23 @@ class Wcf(): return ui + def get_audio_msg(self, id: int, dir: str) -> str: + """获取语音消息并转成 MP3 + Args: + id (int): 语音消息 id + dir (str): MP3 保存目录(目录不存在会出错) + + Returns: + str: 成功返回存储路径;空字符串为失败,原因见日志。 + """ + req = wcf_pb2.Request() + req.func = wcf_pb2.FUNC_GET_AUDIO_MSG # FUNC_GET_AUDIO_MSG + req.am.id = id + req.am.dir = dir + rsp = self._send_request(req) + + return rsp.str + def send_text(self, msg: str, receiver: str, aters: Optional[str] = "") -> int: """发送文本消息 diff --git a/clients/python/wcferry/wcf_pb2.py b/clients/python/wcferry/wcf_pb2.py index 9631651..0a53657 100644 --- a/clients/python/wcferry/wcf_pb2.py +++ b/clients/python/wcferry/wcf_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\twcf.proto\x12\x03wcf\"\x87\x03\n\x07Request\x12\x1c\n\x04\x66unc\x18\x01 \x01(\x0e\x32\x0e.wcf.Functions\x12\x1b\n\x05\x65mpty\x18\x02 \x01(\x0b\x32\n.wcf.EmptyH\x00\x12\r\n\x03str\x18\x03 \x01(\tH\x00\x12\x1b\n\x03txt\x18\x04 \x01(\x0b\x32\x0c.wcf.TextMsgH\x00\x12\x1c\n\x04\x66ile\x18\x05 \x01(\x0b\x32\x0c.wcf.PathMsgH\x00\x12\x1d\n\x05query\x18\x06 \x01(\x0b\x32\x0c.wcf.DbQueryH\x00\x12\x1e\n\x01v\x18\x07 \x01(\x0b\x32\x11.wcf.VerificationH\x00\x12\x1c\n\x01m\x18\x08 \x01(\x0b\x32\x0f.wcf.AddMembersH\x00\x12\x1a\n\x03xml\x18\t \x01(\x0b\x32\x0b.wcf.XmlMsgH\x00\x12\x1b\n\x03\x64\x65\x63\x18\n \x01(\x0b\x32\x0c.wcf.DecPathH\x00\x12\x1b\n\x02tf\x18\x0b \x01(\x0b\x32\r.wcf.TransferH\x00\x12\x0e\n\x04ui64\x18\x0c \x01(\x04H\x00\x12\x0e\n\x04\x66lag\x18\r \x01(\x08H\x00\x12\x1d\n\x03\x61tt\x18\x0e \x01(\x0b\x32\x0e.wcf.AttachMsgH\x00\x42\x05\n\x03msg\"\xab\x02\n\x08Response\x12\x1c\n\x04\x66unc\x18\x01 \x01(\x0e\x32\x0e.wcf.Functions\x12\x10\n\x06status\x18\x02 \x01(\x05H\x00\x12\r\n\x03str\x18\x03 \x01(\tH\x00\x12\x1b\n\x05wxmsg\x18\x04 \x01(\x0b\x32\n.wcf.WxMsgH\x00\x12\x1e\n\x05types\x18\x05 \x01(\x0b\x32\r.wcf.MsgTypesH\x00\x12$\n\x08\x63ontacts\x18\x06 \x01(\x0b\x32\x10.wcf.RpcContactsH\x00\x12\x1b\n\x03\x64\x62s\x18\x07 \x01(\x0b\x32\x0c.wcf.DbNamesH\x00\x12\x1f\n\x06tables\x18\x08 \x01(\x0b\x32\r.wcf.DbTablesH\x00\x12\x1b\n\x04rows\x18\t \x01(\x0b\x32\x0b.wcf.DbRowsH\x00\x12\x1b\n\x02ui\x18\n \x01(\x0b\x32\r.wcf.UserInfoH\x00\x42\x05\n\x03msg\"\x07\n\x05\x45mpty\"\xba\x01\n\x05WxMsg\x12\x0f\n\x07is_self\x18\x01 \x01(\x08\x12\x10\n\x08is_group\x18\x02 \x01(\x08\x12\n\n\x02id\x18\x03 \x01(\x04\x12\x0c\n\x04type\x18\x04 \x01(\r\x12\n\n\x02ts\x18\x05 \x01(\r\x12\x0e\n\x06roomid\x18\x06 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x07 \x01(\t\x12\x0e\n\x06sender\x18\x08 \x01(\t\x12\x0c\n\x04sign\x18\t \x01(\t\x12\r\n\x05thumb\x18\n \x01(\t\x12\r\n\x05\x65xtra\x18\x0b \x01(\t\x12\x0b\n\x03xml\x18\x0c \x01(\t\"7\n\x07TextMsg\x12\x0b\n\x03msg\x18\x01 \x01(\t\x12\x10\n\x08receiver\x18\x02 \x01(\t\x12\r\n\x05\x61ters\x18\x03 \x01(\t\")\n\x07PathMsg\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x10\n\x08receiver\x18\x02 \x01(\t\"G\n\x06XmlMsg\x12\x10\n\x08receiver\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\t\x12\x0c\n\x04path\x18\x03 \x01(\t\x12\x0c\n\x04type\x18\x04 \x01(\x05\"a\n\x08MsgTypes\x12\'\n\x05types\x18\x01 \x03(\x0b\x32\x18.wcf.MsgTypes.TypesEntry\x1a,\n\nTypesEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x87\x01\n\nRpcContact\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x0c\n\x04\x63ode\x18\x02 \x01(\t\x12\x0e\n\x06remark\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0f\n\x07\x63ountry\x18\x05 \x01(\t\x12\x10\n\x08province\x18\x06 \x01(\t\x12\x0c\n\x04\x63ity\x18\x07 \x01(\t\x12\x0e\n\x06gender\x18\x08 \x01(\x05\"0\n\x0bRpcContacts\x12!\n\x08\x63ontacts\x18\x01 \x03(\x0b\x32\x0f.wcf.RpcContact\"\x18\n\x07\x44\x62Names\x12\r\n\x05names\x18\x01 \x03(\t\"$\n\x07\x44\x62Table\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03sql\x18\x02 \x01(\t\"(\n\x08\x44\x62Tables\x12\x1c\n\x06tables\x18\x01 \x03(\x0b\x32\x0c.wcf.DbTable\"\"\n\x07\x44\x62Query\x12\n\n\x02\x64\x62\x18\x01 \x01(\t\x12\x0b\n\x03sql\x18\x02 \x01(\t\"8\n\x07\x44\x62\x46ield\x12\x0c\n\x04type\x18\x01 \x01(\x05\x12\x0e\n\x06\x63olumn\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x03 \x01(\x0c\"%\n\x05\x44\x62Row\x12\x1c\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x0c.wcf.DbField\"\"\n\x06\x44\x62Rows\x12\x18\n\x04rows\x18\x01 \x03(\x0b\x32\n.wcf.DbRow\"5\n\x0cVerification\x12\n\n\x02v3\x18\x01 \x01(\t\x12\n\n\x02v4\x18\x02 \x01(\t\x12\r\n\x05scene\x18\x03 \x01(\x05\"+\n\nAddMembers\x12\x0e\n\x06roomid\x18\x01 \x01(\t\x12\r\n\x05wxids\x18\x02 \x01(\t\"D\n\x08UserInfo\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06mobile\x18\x03 \x01(\t\x12\x0c\n\x04home\x18\x04 \x01(\t\"#\n\x07\x44\x65\x63Path\x12\x0b\n\x03src\x18\x01 \x01(\t\x12\x0b\n\x03\x64st\x18\x02 \x01(\t\"4\n\x08Transfer\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x0c\n\x04tfid\x18\x02 \x01(\t\x12\x0c\n\x04taid\x18\x03 \x01(\t\"5\n\tAttachMsg\x12\n\n\x02id\x18\x01 \x01(\x04\x12\r\n\x05thumb\x18\x02 \x01(\t\x12\r\n\x05\x65xtra\x18\x03 \x01(\t*\xce\x04\n\tFunctions\x12\x11\n\rFUNC_RESERVED\x10\x00\x12\x11\n\rFUNC_IS_LOGIN\x10\x01\x12\x16\n\x12\x46UNC_GET_SELF_WXID\x10\x10\x12\x16\n\x12\x46UNC_GET_MSG_TYPES\x10\x11\x12\x15\n\x11\x46UNC_GET_CONTACTS\x10\x12\x12\x15\n\x11\x46UNC_GET_DB_NAMES\x10\x13\x12\x16\n\x12\x46UNC_GET_DB_TABLES\x10\x14\x12\x16\n\x12\x46UNC_GET_USER_INFO\x10\x15\x12\x11\n\rFUNC_SEND_TXT\x10 \x12\x11\n\rFUNC_SEND_IMG\x10!\x12\x12\n\x0e\x46UNC_SEND_FILE\x10\"\x12\x11\n\rFUNC_SEND_XML\x10#\x12\x15\n\x11\x46UNC_SEND_EMOTION\x10$\x12\x18\n\x14\x46UNC_ENABLE_RECV_TXT\x10\x30\x12\x19\n\x15\x46UNC_DISABLE_RECV_TXT\x10@\x12\x16\n\x12\x46UNC_EXEC_DB_QUERY\x10P\x12\x16\n\x12\x46UNC_ACCEPT_FRIEND\x10Q\x12\x16\n\x12\x46UNC_RECV_TRANSFER\x10R\x12\x14\n\x10\x46UNC_REFRESH_PYQ\x10S\x12\x18\n\x14\x46UNC_DOWNLOAD_ATTACH\x10T\x12\x19\n\x15\x46UNC_GET_CONTACT_INFO\x10U\x12\x13\n\x0f\x46UNC_REVOKE_MSG\x10V\x12\x16\n\x12\x46UNC_DECRYPT_IMAGE\x10`\x12\x19\n\x15\x46UNC_ADD_ROOM_MEMBERS\x10p\x12\x19\n\x15\x46UNC_DEL_ROOM_MEMBERS\x10qB\r\n\x0b\x63om.iamteerb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\twcf.proto\x12\x03wcf\"\xa4\x03\n\x07Request\x12\x1c\n\x04\x66unc\x18\x01 \x01(\x0e\x32\x0e.wcf.Functions\x12\x1b\n\x05\x65mpty\x18\x02 \x01(\x0b\x32\n.wcf.EmptyH\x00\x12\r\n\x03str\x18\x03 \x01(\tH\x00\x12\x1b\n\x03txt\x18\x04 \x01(\x0b\x32\x0c.wcf.TextMsgH\x00\x12\x1c\n\x04\x66ile\x18\x05 \x01(\x0b\x32\x0c.wcf.PathMsgH\x00\x12\x1d\n\x05query\x18\x06 \x01(\x0b\x32\x0c.wcf.DbQueryH\x00\x12\x1e\n\x01v\x18\x07 \x01(\x0b\x32\x11.wcf.VerificationH\x00\x12\x1c\n\x01m\x18\x08 \x01(\x0b\x32\x0f.wcf.AddMembersH\x00\x12\x1a\n\x03xml\x18\t \x01(\x0b\x32\x0b.wcf.XmlMsgH\x00\x12\x1b\n\x03\x64\x65\x63\x18\n \x01(\x0b\x32\x0c.wcf.DecPathH\x00\x12\x1b\n\x02tf\x18\x0b \x01(\x0b\x32\r.wcf.TransferH\x00\x12\x0e\n\x04ui64\x18\x0c \x01(\x04H\x00\x12\x0e\n\x04\x66lag\x18\r \x01(\x08H\x00\x12\x1d\n\x03\x61tt\x18\x0e \x01(\x0b\x32\x0e.wcf.AttachMsgH\x00\x12\x1b\n\x02\x61m\x18\x0f \x01(\x0b\x32\r.wcf.AudioMsgH\x00\x42\x05\n\x03msg\"\xab\x02\n\x08Response\x12\x1c\n\x04\x66unc\x18\x01 \x01(\x0e\x32\x0e.wcf.Functions\x12\x10\n\x06status\x18\x02 \x01(\x05H\x00\x12\r\n\x03str\x18\x03 \x01(\tH\x00\x12\x1b\n\x05wxmsg\x18\x04 \x01(\x0b\x32\n.wcf.WxMsgH\x00\x12\x1e\n\x05types\x18\x05 \x01(\x0b\x32\r.wcf.MsgTypesH\x00\x12$\n\x08\x63ontacts\x18\x06 \x01(\x0b\x32\x10.wcf.RpcContactsH\x00\x12\x1b\n\x03\x64\x62s\x18\x07 \x01(\x0b\x32\x0c.wcf.DbNamesH\x00\x12\x1f\n\x06tables\x18\x08 \x01(\x0b\x32\r.wcf.DbTablesH\x00\x12\x1b\n\x04rows\x18\t \x01(\x0b\x32\x0b.wcf.DbRowsH\x00\x12\x1b\n\x02ui\x18\n \x01(\x0b\x32\r.wcf.UserInfoH\x00\x42\x05\n\x03msg\"\x07\n\x05\x45mpty\"\xba\x01\n\x05WxMsg\x12\x0f\n\x07is_self\x18\x01 \x01(\x08\x12\x10\n\x08is_group\x18\x02 \x01(\x08\x12\n\n\x02id\x18\x03 \x01(\x04\x12\x0c\n\x04type\x18\x04 \x01(\r\x12\n\n\x02ts\x18\x05 \x01(\r\x12\x0e\n\x06roomid\x18\x06 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x07 \x01(\t\x12\x0e\n\x06sender\x18\x08 \x01(\t\x12\x0c\n\x04sign\x18\t \x01(\t\x12\r\n\x05thumb\x18\n \x01(\t\x12\r\n\x05\x65xtra\x18\x0b \x01(\t\x12\x0b\n\x03xml\x18\x0c \x01(\t\"7\n\x07TextMsg\x12\x0b\n\x03msg\x18\x01 \x01(\t\x12\x10\n\x08receiver\x18\x02 \x01(\t\x12\r\n\x05\x61ters\x18\x03 \x01(\t\")\n\x07PathMsg\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x10\n\x08receiver\x18\x02 \x01(\t\"G\n\x06XmlMsg\x12\x10\n\x08receiver\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\t\x12\x0c\n\x04path\x18\x03 \x01(\t\x12\x0c\n\x04type\x18\x04 \x01(\x05\"a\n\x08MsgTypes\x12\'\n\x05types\x18\x01 \x03(\x0b\x32\x18.wcf.MsgTypes.TypesEntry\x1a,\n\nTypesEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x87\x01\n\nRpcContact\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x0c\n\x04\x63ode\x18\x02 \x01(\t\x12\x0e\n\x06remark\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0f\n\x07\x63ountry\x18\x05 \x01(\t\x12\x10\n\x08province\x18\x06 \x01(\t\x12\x0c\n\x04\x63ity\x18\x07 \x01(\t\x12\x0e\n\x06gender\x18\x08 \x01(\x05\"0\n\x0bRpcContacts\x12!\n\x08\x63ontacts\x18\x01 \x03(\x0b\x32\x0f.wcf.RpcContact\"\x18\n\x07\x44\x62Names\x12\r\n\x05names\x18\x01 \x03(\t\"$\n\x07\x44\x62Table\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03sql\x18\x02 \x01(\t\"(\n\x08\x44\x62Tables\x12\x1c\n\x06tables\x18\x01 \x03(\x0b\x32\x0c.wcf.DbTable\"\"\n\x07\x44\x62Query\x12\n\n\x02\x64\x62\x18\x01 \x01(\t\x12\x0b\n\x03sql\x18\x02 \x01(\t\"8\n\x07\x44\x62\x46ield\x12\x0c\n\x04type\x18\x01 \x01(\x05\x12\x0e\n\x06\x63olumn\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x03 \x01(\x0c\"%\n\x05\x44\x62Row\x12\x1c\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x0c.wcf.DbField\"\"\n\x06\x44\x62Rows\x12\x18\n\x04rows\x18\x01 \x03(\x0b\x32\n.wcf.DbRow\"5\n\x0cVerification\x12\n\n\x02v3\x18\x01 \x01(\t\x12\n\n\x02v4\x18\x02 \x01(\t\x12\r\n\x05scene\x18\x03 \x01(\x05\"+\n\nAddMembers\x12\x0e\n\x06roomid\x18\x01 \x01(\t\x12\r\n\x05wxids\x18\x02 \x01(\t\"D\n\x08UserInfo\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06mobile\x18\x03 \x01(\t\x12\x0c\n\x04home\x18\x04 \x01(\t\"#\n\x07\x44\x65\x63Path\x12\x0b\n\x03src\x18\x01 \x01(\t\x12\x0b\n\x03\x64st\x18\x02 \x01(\t\"4\n\x08Transfer\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x0c\n\x04tfid\x18\x02 \x01(\t\x12\x0c\n\x04taid\x18\x03 \x01(\t\"5\n\tAttachMsg\x12\n\n\x02id\x18\x01 \x01(\x04\x12\r\n\x05thumb\x18\x02 \x01(\t\x12\r\n\x05\x65xtra\x18\x03 \x01(\t\"#\n\x08\x41udioMsg\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0b\n\x03\x64ir\x18\x02 \x01(\t*\xe6\x04\n\tFunctions\x12\x11\n\rFUNC_RESERVED\x10\x00\x12\x11\n\rFUNC_IS_LOGIN\x10\x01\x12\x16\n\x12\x46UNC_GET_SELF_WXID\x10\x10\x12\x16\n\x12\x46UNC_GET_MSG_TYPES\x10\x11\x12\x15\n\x11\x46UNC_GET_CONTACTS\x10\x12\x12\x15\n\x11\x46UNC_GET_DB_NAMES\x10\x13\x12\x16\n\x12\x46UNC_GET_DB_TABLES\x10\x14\x12\x16\n\x12\x46UNC_GET_USER_INFO\x10\x15\x12\x16\n\x12\x46UNC_GET_AUDIO_MSG\x10\x16\x12\x11\n\rFUNC_SEND_TXT\x10 \x12\x11\n\rFUNC_SEND_IMG\x10!\x12\x12\n\x0e\x46UNC_SEND_FILE\x10\"\x12\x11\n\rFUNC_SEND_XML\x10#\x12\x15\n\x11\x46UNC_SEND_EMOTION\x10$\x12\x18\n\x14\x46UNC_ENABLE_RECV_TXT\x10\x30\x12\x19\n\x15\x46UNC_DISABLE_RECV_TXT\x10@\x12\x16\n\x12\x46UNC_EXEC_DB_QUERY\x10P\x12\x16\n\x12\x46UNC_ACCEPT_FRIEND\x10Q\x12\x16\n\x12\x46UNC_RECV_TRANSFER\x10R\x12\x14\n\x10\x46UNC_REFRESH_PYQ\x10S\x12\x18\n\x14\x46UNC_DOWNLOAD_ATTACH\x10T\x12\x19\n\x15\x46UNC_GET_CONTACT_INFO\x10U\x12\x13\n\x0f\x46UNC_REVOKE_MSG\x10V\x12\x16\n\x12\x46UNC_DECRYPT_IMAGE\x10`\x12\x19\n\x15\x46UNC_ADD_ROOM_MEMBERS\x10p\x12\x19\n\x15\x46UNC_DEL_ROOM_MEMBERS\x10qB\r\n\x0b\x63om.iamteerb\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'wcf_pb2', globals()) @@ -23,54 +23,56 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._serialized_options = b'\n\013com.iamteer' _MSGTYPES_TYPESENTRY._options = None _MSGTYPES_TYPESENTRY._serialized_options = b'8\001' - _FUNCTIONS._serialized_start=1964 - _FUNCTIONS._serialized_end=2554 + _FUNCTIONS._serialized_start=2030 + _FUNCTIONS._serialized_end=2644 _REQUEST._serialized_start=19 - _REQUEST._serialized_end=410 - _RESPONSE._serialized_start=413 - _RESPONSE._serialized_end=712 - _EMPTY._serialized_start=714 - _EMPTY._serialized_end=721 - _WXMSG._serialized_start=724 - _WXMSG._serialized_end=910 - _TEXTMSG._serialized_start=912 - _TEXTMSG._serialized_end=967 - _PATHMSG._serialized_start=969 - _PATHMSG._serialized_end=1010 - _XMLMSG._serialized_start=1012 - _XMLMSG._serialized_end=1083 - _MSGTYPES._serialized_start=1085 - _MSGTYPES._serialized_end=1182 - _MSGTYPES_TYPESENTRY._serialized_start=1138 - _MSGTYPES_TYPESENTRY._serialized_end=1182 - _RPCCONTACT._serialized_start=1185 - _RPCCONTACT._serialized_end=1320 - _RPCCONTACTS._serialized_start=1322 - _RPCCONTACTS._serialized_end=1370 - _DBNAMES._serialized_start=1372 - _DBNAMES._serialized_end=1396 - _DBTABLE._serialized_start=1398 - _DBTABLE._serialized_end=1434 - _DBTABLES._serialized_start=1436 - _DBTABLES._serialized_end=1476 - _DBQUERY._serialized_start=1478 - _DBQUERY._serialized_end=1512 - _DBFIELD._serialized_start=1514 - _DBFIELD._serialized_end=1570 - _DBROW._serialized_start=1572 - _DBROW._serialized_end=1609 - _DBROWS._serialized_start=1611 - _DBROWS._serialized_end=1645 - _VERIFICATION._serialized_start=1647 - _VERIFICATION._serialized_end=1700 - _ADDMEMBERS._serialized_start=1702 - _ADDMEMBERS._serialized_end=1745 - _USERINFO._serialized_start=1747 - _USERINFO._serialized_end=1815 - _DECPATH._serialized_start=1817 - _DECPATH._serialized_end=1852 - _TRANSFER._serialized_start=1854 - _TRANSFER._serialized_end=1906 - _ATTACHMSG._serialized_start=1908 - _ATTACHMSG._serialized_end=1961 + _REQUEST._serialized_end=439 + _RESPONSE._serialized_start=442 + _RESPONSE._serialized_end=741 + _EMPTY._serialized_start=743 + _EMPTY._serialized_end=750 + _WXMSG._serialized_start=753 + _WXMSG._serialized_end=939 + _TEXTMSG._serialized_start=941 + _TEXTMSG._serialized_end=996 + _PATHMSG._serialized_start=998 + _PATHMSG._serialized_end=1039 + _XMLMSG._serialized_start=1041 + _XMLMSG._serialized_end=1112 + _MSGTYPES._serialized_start=1114 + _MSGTYPES._serialized_end=1211 + _MSGTYPES_TYPESENTRY._serialized_start=1167 + _MSGTYPES_TYPESENTRY._serialized_end=1211 + _RPCCONTACT._serialized_start=1214 + _RPCCONTACT._serialized_end=1349 + _RPCCONTACTS._serialized_start=1351 + _RPCCONTACTS._serialized_end=1399 + _DBNAMES._serialized_start=1401 + _DBNAMES._serialized_end=1425 + _DBTABLE._serialized_start=1427 + _DBTABLE._serialized_end=1463 + _DBTABLES._serialized_start=1465 + _DBTABLES._serialized_end=1505 + _DBQUERY._serialized_start=1507 + _DBQUERY._serialized_end=1541 + _DBFIELD._serialized_start=1543 + _DBFIELD._serialized_end=1599 + _DBROW._serialized_start=1601 + _DBROW._serialized_end=1638 + _DBROWS._serialized_start=1640 + _DBROWS._serialized_end=1674 + _VERIFICATION._serialized_start=1676 + _VERIFICATION._serialized_end=1729 + _ADDMEMBERS._serialized_start=1731 + _ADDMEMBERS._serialized_end=1774 + _USERINFO._serialized_start=1776 + _USERINFO._serialized_end=1844 + _DECPATH._serialized_start=1846 + _DECPATH._serialized_end=1881 + _TRANSFER._serialized_start=1883 + _TRANSFER._serialized_end=1935 + _ATTACHMSG._serialized_start=1937 + _ATTACHMSG._serialized_end=1990 + _AUDIOMSG._serialized_start=1992 + _AUDIOMSG._serialized_end=2027 # @@protoc_insertion_point(module_scope)