Impl GetContacts
This commit is contained in:
parent
dca6278d05
commit
51985777f7
17
App/App.cpp
17
App/App.cpp
@ -10,6 +10,16 @@
|
|||||||
等效为在属性,链接,输入中添加该依赖
|
等效为在属性,链接,输入中添加该依赖
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void printContacts(ContactMap_t contacts)
|
||||||
|
{
|
||||||
|
wcout << L"contacts number: " << contacts.size() << endl;
|
||||||
|
for (auto it = contacts.begin(); it != contacts.end(); ++it) {
|
||||||
|
wcout << it->second.wxId << L"\t" << it->second.wxCode << L"\t" << it->second.wxName << L"\t"
|
||||||
|
<< it->second.wxGender << L"\t" << it->second.wxCountry << L"\t" << it->second.wxProvince << L"\t"
|
||||||
|
<< it->second.wxCity << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int onTextMsg(WxMessage_t msg)
|
int onTextMsg(WxMessage_t msg)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -32,7 +42,7 @@ int main()
|
|||||||
wstring content = L"这里填写消息内容";
|
wstring content = L"这里填写消息内容";
|
||||||
wstring img_path = L"test.jpg";
|
wstring img_path = L"test.jpg";
|
||||||
|
|
||||||
//_setmode(_fileno(stdout), _O_WTEXT); // 没有这个wcout遇到一些字符会导致console卡死,用了会导致脱离控制台
|
_setmode(_fileno(stdout), _O_WTEXT); // 没有这个wcout遇到一些字符会导致console卡死,用了会导致脱离控制台
|
||||||
_wsetlocale(LC_ALL, L"chs"); // 这是个大坑,不设置中文直接不见了。。。
|
_wsetlocale(LC_ALL, L"chs"); // 这是个大坑,不设置中文直接不见了。。。
|
||||||
|
|
||||||
// 获取消息类型
|
// 获取消息类型
|
||||||
@ -55,6 +65,11 @@ int main()
|
|||||||
// 发送照片
|
// 发送照片
|
||||||
WxSendImageMsg(wxid, img_path);
|
WxSendImageMsg(wxid, img_path);
|
||||||
|
|
||||||
|
Sleep(10000); // 等待10秒
|
||||||
|
// 测试联系人获取
|
||||||
|
auto mContact = WxGetContacts();
|
||||||
|
printContacts(mContact);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
Sleep(10000); // 休眠,释放CPU
|
Sleep(10000); // 休眠,释放CPU
|
||||||
}
|
}
|
||||||
|
18
App/App.py
18
App/App.py
@ -9,6 +9,7 @@ def main():
|
|||||||
print(dir(sdk)) # 查看SDK支持的方法和属性
|
print(dir(sdk)) # 查看SDK支持的方法和属性
|
||||||
help(sdk.WxSetTextMsgCb) # 查看某方法的情况
|
help(sdk.WxSetTextMsgCb) # 查看某方法的情况
|
||||||
help(sdk.WxMessage) # 查看消息结构
|
help(sdk.WxMessage) # 查看消息结构
|
||||||
|
help(sdk.WxContact) # 查看通讯录结构
|
||||||
WxMsgTypes = sdk.WxGetMsgTypes() # 获取消息类型
|
WxMsgTypes = sdk.WxGetMsgTypes() # 获取消息类型
|
||||||
print(WxMsgTypes) # 查看消息类型
|
print(WxMsgTypes) # 查看消息类型
|
||||||
|
|
||||||
@ -20,6 +21,12 @@ def main():
|
|||||||
|
|
||||||
print("初始化成功")
|
print("初始化成功")
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
print("打印通讯录......")
|
||||||
|
contacts = sdk.WxGetContacts()
|
||||||
|
for k, v in contacts.items():
|
||||||
|
print(k, v.wxCode, v.wxName, v.wxCountry, v.wxProvince, v.wxCity, v.wxGender)
|
||||||
|
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
print("发送文本消息......")
|
print("发送文本消息......")
|
||||||
sdk.WxSendTextMsg("filehelper", "", "message from WeChatFerry...")
|
sdk.WxSendTextMsg("filehelper", "", "message from WeChatFerry...")
|
||||||
@ -30,15 +37,20 @@ def main():
|
|||||||
|
|
||||||
# 接收消息。先定义消息处理回调
|
# 接收消息。先定义消息处理回调
|
||||||
def OnTextMsg(msg: sdk.WxMessage):
|
def OnTextMsg(msg: sdk.WxMessage):
|
||||||
|
s = "收到"
|
||||||
if msg.self == 1: # 忽略自己发的消息
|
if msg.self == 1: # 忽略自己发的消息
|
||||||
|
s += f"来自自己的消息"
|
||||||
|
print(f"\n{s}")
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
s = ""
|
|
||||||
msgType = WxMsgTypes.get(msg.type, '未知消息类型')
|
msgType = WxMsgTypes.get(msg.type, '未知消息类型')
|
||||||
|
nickName = contacts.get(msg.wxId, {'wxName': 'NoBody'}).wxName
|
||||||
if msg.source == 0:
|
if msg.source == 0:
|
||||||
s += f"收到来自好友[{msg.wxId}]的{msgType}消息:"
|
s += f"来自好友[{nickName}]的{msgType}消息:"
|
||||||
else:
|
else:
|
||||||
s += f"收到来自群[{msg.roomId}]的[{msg.wxId}]的{msgType}消息:"
|
groupName = contacts.get(msg.roomId, {'wxName': 'Unknown'}).wxName
|
||||||
|
s += f"来自群[{groupName}]的[{nickName}]的{msgType}消息:"
|
||||||
|
|
||||||
s += f"\r\n{msg.content}"
|
s += f"\r\n{msg.content}"
|
||||||
if msg.type != 0x01:
|
if msg.type != 0x01:
|
||||||
|
69
SDK/sdk.cpp
69
SDK/sdk.cpp
@ -297,4 +297,73 @@ static int getAddrHandle(DWORD *addr, HANDLE *handle)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ContactMap_t WxGetContacts()
|
||||||
|
{
|
||||||
|
ContactMap_t mContact;
|
||||||
|
DWORD moduleBaseAddress;
|
||||||
|
HANDLE hProcess;
|
||||||
|
|
||||||
|
if (getAddrHandle(&moduleBaseAddress, &hProcess) != 0) {
|
||||||
|
return mContact;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD Address1 = moduleBaseAddress + 0x1DB9728;
|
||||||
|
DWORD Address2 = GetMemoryIntByAddress(hProcess, Address1);
|
||||||
|
DWORD Address3 = GetMemoryIntByAddress(hProcess, Address2 + 0x28 + 0xBC);
|
||||||
|
|
||||||
|
vector<DWORD> nodeAddressList;
|
||||||
|
nodeAddressList.push_back(Address3);
|
||||||
|
|
||||||
|
DWORD nodeAddress1 = GetMemoryIntByAddress(hProcess, Address3 + 0x0);
|
||||||
|
DWORD nodeAddress2 = GetMemoryIntByAddress(hProcess, Address3 + 0x4);
|
||||||
|
DWORD nodeAddress3 = GetMemoryIntByAddress(hProcess, Address3 + 0x8);
|
||||||
|
if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress1) == nodeAddressList.end())
|
||||||
|
nodeAddressList.push_back(nodeAddress1);
|
||||||
|
if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress2) == nodeAddressList.end())
|
||||||
|
nodeAddressList.push_back(nodeAddress2);
|
||||||
|
if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress3) == nodeAddressList.end())
|
||||||
|
nodeAddressList.push_back(nodeAddress3);
|
||||||
|
|
||||||
|
unsigned int index = 1;
|
||||||
|
while (index < nodeAddressList.size()) {
|
||||||
|
WxContact_t contactItem;
|
||||||
|
DWORD nodeAddress = nodeAddressList[index++];
|
||||||
|
DWORD checkNullResult = GetMemoryIntByAddress(hProcess, nodeAddress + 0xD);
|
||||||
|
if (checkNullResult == 0) {
|
||||||
|
index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
contactItem.wxId = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x38);
|
||||||
|
contactItem.wxCode = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x4C);
|
||||||
|
contactItem.wxName = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x94);
|
||||||
|
contactItem.wxCountry = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x1D8);
|
||||||
|
contactItem.wxProvince = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x1EC);
|
||||||
|
contactItem.wxCity = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x200);
|
||||||
|
DWORD gender = GetMemoryIntByAddress(hProcess, nodeAddress + 0x18C);
|
||||||
|
|
||||||
|
if (gender == 1)
|
||||||
|
contactItem.wxGender = L"男";
|
||||||
|
else if (gender == 2)
|
||||||
|
contactItem.wxGender = L"女";
|
||||||
|
else
|
||||||
|
contactItem.wxGender = L"未知";
|
||||||
|
|
||||||
|
mContact.insert(make_pair(contactItem.wxId, contactItem));
|
||||||
|
|
||||||
|
DWORD nodeAddress1 = GetMemoryIntByAddress(hProcess, nodeAddress + 0x0);
|
||||||
|
DWORD nodeAddress2 = GetMemoryIntByAddress(hProcess, nodeAddress + 0x4);
|
||||||
|
DWORD nodeAddress3 = GetMemoryIntByAddress(hProcess, nodeAddress + 0x8);
|
||||||
|
if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress1) == nodeAddressList.end())
|
||||||
|
nodeAddressList.push_back(nodeAddress1);
|
||||||
|
if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress2) == nodeAddressList.end())
|
||||||
|
nodeAddressList.push_back(nodeAddress2);
|
||||||
|
if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress3) == nodeAddressList.end())
|
||||||
|
nodeAddressList.push_back(nodeAddress3);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
|
||||||
|
return mContact;
|
||||||
|
}
|
||||||
|
|
||||||
MsgTypesMap_t WxGetMsgTypes() { return WxMsgTypes; }
|
MsgTypesMap_t WxGetMsgTypes() { return WxMsgTypes; }
|
||||||
|
@ -4,3 +4,4 @@ EXPORTS
|
|||||||
WxSendTextMsg
|
WxSendTextMsg
|
||||||
WxGetMsgTypes
|
WxGetMsgTypes
|
||||||
WxSendImageMsg
|
WxSendImageMsg
|
||||||
|
WxGetContacts
|
||||||
|
12
SDK/sdk.h
12
SDK/sdk.h
@ -17,10 +17,22 @@ typedef struct WxMessage {
|
|||||||
wstring content; // 消息内容,MAC版最大:16384,即16KB
|
wstring content; // 消息内容,MAC版最大:16384,即16KB
|
||||||
} WxMessage_t;
|
} WxMessage_t;
|
||||||
|
|
||||||
|
typedef struct WxContact {
|
||||||
|
wstring wxId;
|
||||||
|
wstring wxCode;
|
||||||
|
wstring wxName;
|
||||||
|
wstring wxCountry;
|
||||||
|
wstring wxProvince;
|
||||||
|
wstring wxCity;
|
||||||
|
wstring wxGender;
|
||||||
|
} WxContact_t;
|
||||||
|
|
||||||
typedef map<int, wstring> MsgTypesMap_t;
|
typedef map<int, wstring> MsgTypesMap_t;
|
||||||
|
typedef map<wstring, WxContact_t> ContactMap_t;
|
||||||
|
|
||||||
int WxInitSDK();
|
int WxInitSDK();
|
||||||
int WxSetTextMsgCb(const std::function<int(WxMessage_t)> &onMsg);
|
int WxSetTextMsgCb(const std::function<int(WxMessage_t)> &onMsg);
|
||||||
int WxSendTextMsg(wstring wxid, wstring at_wxid, wstring msg);
|
int WxSendTextMsg(wstring wxid, wstring at_wxid, wstring msg);
|
||||||
int WxSendImageMsg(wstring wxid, wstring path);
|
int WxSendImageMsg(wstring wxid, wstring path);
|
||||||
|
ContactMap_t WxGetContacts();
|
||||||
MsgTypesMap_t WxGetMsgTypes();
|
MsgTypesMap_t WxGetMsgTypes();
|
||||||
|
@ -22,10 +22,20 @@ PYBIND11_MODULE(wcferry, m)
|
|||||||
.def_readonly("roomId", &WxMessage::roomId)
|
.def_readonly("roomId", &WxMessage::roomId)
|
||||||
.def_readonly("content", &WxMessage::content);
|
.def_readonly("content", &WxMessage::content);
|
||||||
|
|
||||||
|
py::class_<WxContact>(m, "WxContact")
|
||||||
|
.def_readonly("wxId", &WxContact::wxId)
|
||||||
|
.def_readonly("wxCode", &WxContact::wxCode)
|
||||||
|
.def_readonly("wxName", &WxContact::wxName)
|
||||||
|
.def_readonly("wxCountry", &WxContact::wxCountry)
|
||||||
|
.def_readonly("wxProvince", &WxContact::wxProvince)
|
||||||
|
.def_readonly("wxCity", &WxContact::wxCity)
|
||||||
|
.def_readonly("wxGender", &WxContact::wxGender);
|
||||||
|
|
||||||
m.def("WxInitSDK", &WxInitSDK);
|
m.def("WxInitSDK", &WxInitSDK);
|
||||||
m.def("WxSetTextMsgCb", &WxSetTextMsgCbPy);
|
m.def("WxSetTextMsgCb", &WxSetTextMsgCbPy);
|
||||||
m.def("WxSendTextMsg", &WxSendTextMsg);
|
m.def("WxSendTextMsg", &WxSendTextMsg);
|
||||||
m.def("WxSendImageMsg", &WxSendImageMsg);
|
m.def("WxSendImageMsg", &WxSendImageMsg);
|
||||||
|
m.def("WxGetContacts", &WxGetContacts, py::return_value_policy::reference);
|
||||||
m.def("WxGetMsgTypes", &WxGetMsgTypes, py::return_value_policy::reference);
|
m.def("WxGetMsgTypes", &WxGetMsgTypes, py::return_value_policy::reference);
|
||||||
|
|
||||||
#ifdef VERSION_INFO
|
#ifdef VERSION_INFO
|
||||||
|
Loading…
Reference in New Issue
Block a user