#include "stdafx.h" ToxHexAddress ResolveToxAddressFromToxme(HNETLIBUSER hNetlib, const char *query) { ToxHexAddress address = ToxHexAddress::Empty(); HttpRequest request(REQUEST_POST, "https://toxme.io/api"); JSONNode root(JSON_NODE); root << JSONNode("action", 3) << JSONNode("name", query); json_string data = root.write(); request.SetData(data.c_str(), data.length()); NLHR_PTR response(request.Send(hNetlib)); if (response->resultCode != HTTP_CODE_OK || !response->pData) return ToxHexAddress::Empty(); root = JSONNode::parse(response->pData); if (root.empty()) return ToxHexAddress::Empty(); json_string id = root.at("tox_id").as_string(); return ToxHexAddress(id.c_str()); } void CToxProto::SearchByNameAsync(void *arg) { Thread_SetName(MODULE ": SearchByNameThread"); char *query = (char*)arg; char *name = strtok(query, "@"); ToxHexAddress address = ResolveToxAddressFromToxme(m_hNetlibUser, query); if (!address.IsEmpty()) { PROTOSEARCHRESULT psr = { sizeof(PROTOSEARCHRESULT) }; psr.flags = PSR_UTF8; psr.id.a = mir_strdup(address); psr.nick.a = mir_strdup(name); char email[MAX_PATH]; mir_snprintf(email, "%s@toxme.io", name); psr.email.a = mir_strdup(email); ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)1, (LPARAM)&psr); } ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)1, 0); mir_free(arg); } void CToxProto::SearchFailedAsync(void*) { Thread_SetName(MODULE ": SearchFailedThread"); ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HWND)1, 0); } INT_PTR CToxProto::SearchDlgProc(HWND hwnd, UINT uMsg, WPARAM, LPARAM lParam) { CToxProto *proto = (CToxProto*)GetWindowLongPtr(hwnd, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: TranslateDialogDefault(hwnd); { proto = (CToxProto*)lParam; SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); //ShowWindow(GetDlgItem(GetParent(hwnd), 1408/*IDC_BYCUSTOM*/), SW_HIDE); //ShowWindow(GetDlgItem(GetParent(hwnd), 1402/*IDC_ADVANCEDGROUP*/), SW_HIDE); SetDlgItemText(GetParent(hwnd), 1408/*IDC_BYCUSTOM*/, TranslateT("Query")); } return TRUE; } return FALSE; } HWND CToxProto::OnSearchAdvanced(HWND owner) { if (!IsOnline()) { // we cannot add someone to friend list while tox is offline return nullptr; } std::smatch match; std::regex regex("^\\s*([A-Fa-f0-9]{76})\\s*$"); wchar_t text[MAX_PATH]; GetDlgItemText(owner, IDC_SEARCH, text, _countof(text)); const std::string query = T2Utf(text).str(); if (std::regex_search(query, match, regex)) { std::string address = match[1]; PROTOSEARCHRESULT psr = { sizeof(psr) }; psr.flags = PSR_UTF8; psr.id.a = mir_strdup(query.c_str()); Contact_AddBySearch(m_szModuleName, &psr, owner); ForkThread(&CToxProto::SearchFailedAsync, nullptr); } else { regex = "^\\s*(([^ @/:;()\"']+)(@[A-Za-z]+.[A-Za-z]{2,6})?)\\s*$"; if (std::regex_search(query, match, regex)) ForkThread(&CToxProto::SearchByNameAsync, mir_strdup(query.c_str())); else ForkThread(&CToxProto::SearchFailedAsync, nullptr); } return (HWND)1; } HWND CToxProto::OnCreateExtendedSearchUI(HWND owner) { return CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_SEARCH), owner, SearchDlgProc, (LPARAM)this); }