From 9fa8edc73b6687bbc0f43743b872af83d4d06759 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Thu, 28 Apr 2016 16:42:53 +0000 Subject: Tox: updating tox nodes from https://nodes.tox.chat/json git-svn-id: http://svn.miranda-ng.org/main/trunk@16790 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tox/src/http_request.h | 151 ++++++++++++++++++++++++++++++++++ protocols/Tox/src/resource.h | 3 +- protocols/Tox/src/stdafx.h | 3 +- protocols/Tox/src/tox_network.cpp | 66 ++++++++------- protocols/Tox/src/tox_options.cpp | 166 +++++++++++++++++--------------------- protocols/Tox/src/tox_options.h | 4 + protocols/Tox/src/tox_proto.h | 4 +- protocols/Tox/src/version.h | 2 +- 8 files changed, 271 insertions(+), 128 deletions(-) create mode 100644 protocols/Tox/src/http_request.h (limited to 'protocols/Tox/src') diff --git a/protocols/Tox/src/http_request.h b/protocols/Tox/src/http_request.h new file mode 100644 index 0000000000..e52de2c179 --- /dev/null +++ b/protocols/Tox/src/http_request.h @@ -0,0 +1,151 @@ +#ifndef _HTTP_REQUEST_H_ +#define _HTTP_REQUEST_H_ + +class HttpRequestException +{ + CMStringA message; + +public: + HttpRequestException(const char *message) : + message(message) + { + } + + const char* what() const throw() + { + return message.c_str(); + } +}; + +class HttpRequest : protected NETLIBHTTPREQUEST +{ +private: + CMStringA m_szUrl; + + void Init(int type) + { + cbSize = sizeof(NETLIBHTTPREQUEST); + requestType = type; + flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT; + szUrl = NULL; + headers = NULL; + headersCount = 0; + pData = NULL; + dataLength = 0; + resultCode = 0; + szResultDescr = NULL; + nlc = NULL; + timeout = 0; + } + +protected: + enum HttpRequestUrlFormat { FORMAT }; + + void AddHeader(LPCSTR szName, LPCSTR szValue) + { + headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER) * (headersCount + 1)); + headers[headersCount].szName = mir_strdup(szName); + headers[headersCount].szValue = mir_strdup(szValue); + headersCount++; + } + + void AddBasicAuthHeader(LPCSTR szLogin, LPCSTR szPassword) + { + char cPair[128]; + mir_snprintf( + cPair, + _countof(cPair), + "%s:%s", + szLogin, + szPassword); + + char *ePair = (char *)mir_base64_encode((BYTE*)cPair, (UINT)mir_strlen(cPair)); + + char value[128]; + mir_snprintf( + value, + _countof(value), + "Basic %s", + ePair); + + mir_free(ePair); + + headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1)); + headers[headersCount].szName = mir_strdup("Authorization"); + headers[headersCount].szValue = mir_strdup(value); + headersCount++; + } + + void AddBearerAuthHeader(LPCSTR szValue) + { + char value[128]; + mir_snprintf( + value, + _countof(value), + "Bearer %s", + szValue); + + headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1)); + headers[headersCount].szName = mir_strdup("Authorization"); + headers[headersCount].szValue = mir_strdup(value); + headersCount++; + } + + void AddUrlParameter(const char *urlFormat, ...) + { + va_list urlArgs; + va_start(urlArgs, urlFormat); + m_szUrl += m_szUrl.Find('?') == -1 ? '?' : '&'; + m_szUrl.AppendFormatV(urlFormat, urlArgs); + va_end(urlArgs); + } + + void SetData(const char *data, size_t size) + { + if (pData != NULL) + mir_free(pData); + + dataLength = (int)size; + pData = (char*)mir_alloc(size); + memcpy(pData, data, size); + } + +public: + HttpRequest(int type, LPCSTR url) + { + Init(type); + + m_szUrl = url; + } + + HttpRequest(int type, HttpRequestUrlFormat, LPCSTR urlFormat, ...) + { + Init(type); + + va_list formatArgs; + va_start(formatArgs, urlFormat); + m_szUrl.AppendFormatV(urlFormat, formatArgs); + va_end(formatArgs); + } + + ~HttpRequest() + { + for (int i = 0; i < headersCount; i++) + { + mir_free(headers[i].szName); + mir_free(headers[i].szValue); + } + mir_free(headers); + if (pData) + mir_free(pData); + } + + NETLIBHTTPREQUEST* Send(HANDLE hNetlibConnection) + { + m_szUrl.Replace('\\', '/'); + szUrl = m_szUrl.GetBuffer(); + return (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibConnection, (LPARAM)this); + } +}; + +#endif //_HTTP_REQUEST_H_ \ No newline at end of file diff --git a/protocols/Tox/src/resource.h b/protocols/Tox/src/resource.h index 5f21b0905b..ae4158d754 100644 --- a/protocols/Tox/src/resource.h +++ b/protocols/Tox/src/resource.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by w:\miranda-ng\protocols\Tox\res\resource.rc +// Used by D:\Projects\MirandaNG\protocols\Tox\res\resource.rc // #define IDI_TOX 100 #define IDD_USER_INFO 101 @@ -42,6 +42,7 @@ #define IDC_NODESLIST 1015 #define IDC_ADDNODE 1016 #define IDC_IPV4 1017 +#define IDC_UPDATENODES 1081 #define IDC_IPV6 1018 #define IDC_PORT 1019 #define IDC_PKEY 1020 diff --git a/protocols/Tox/src/stdafx.h b/protocols/Tox/src/stdafx.h index 21a3f7fa2a..12dfcc7845 100644 --- a/protocols/Tox/src/stdafx.h +++ b/protocols/Tox/src/stdafx.h @@ -42,6 +42,7 @@ DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0 #include #include #include +#include #include #include @@ -78,7 +79,7 @@ extern HINSTANCE g_hInstance; #define TOX_MAX_CALLS 1 #define TOX_INI_PATH "%miranda_path%\\Plugins\\tox.ini" -#define TOX_JSON_PATH "%miranda_path%\\Plugins\\tox.json" +#define TOX_JSON_PATH "%miranda_userdata%\\tox.json" #define TOX_SETTINGS_ID "ToxID" #define TOX_SETTINGS_DNS "DnsID" diff --git a/protocols/Tox/src/tox_network.cpp b/protocols/Tox/src/tox_network.cpp index 65934e533a..1090b75e0c 100644 --- a/protocols/Tox/src/tox_network.cpp +++ b/protocols/Tox/src/tox_network.cpp @@ -45,44 +45,14 @@ void CToxProto::BootstrapNodesFromDb(bool isIPv6) } } -void CToxProto::BootstrapNodesFromIni(bool isIPv6) -{ - if (IsFileExists((TCHAR*)VARST(_T(TOX_INI_PATH)))) - { - char fileName[MAX_PATH]; - mir_strcpy(fileName, VARS(TOX_INI_PATH)); - - char *section, sections[MAX_PATH], value[MAX_PATH]; - GetPrivateProfileSectionNamesA(sections, _countof(sections), fileName); - section = sections; - while (*section != NULL) - { - if (strstr(section, TOX_SETTINGS_NODE_PREFIX) == section) - { - GetPrivateProfileStringA(section, "IPv4", NULL, value, _countof(value), fileName); - ptrA address(mir_strdup(value)); - int port = GetPrivateProfileIntA(section, "Port", 33445, fileName); - GetPrivateProfileStringA(section, "PubKey", NULL, value, _countof(value), fileName); - ptrA pubKey(mir_strdup(value)); - BootstrapNode(address, port, pubKey); - if (isIPv6) - { - GetPrivateProfileStringA(section, "IPv6", NULL, value, _countof(value), fileName); - address = mir_strdup(value); - BootstrapNode(address, port, pubKey); - } - } - section += mir_strlen(section) + 1; - } - } -} - void CToxProto::BootstrapNodesFromJson(bool isIPv6) { char *json = NULL; ptrT path(mir_tstrdup((TCHAR*)VARST(_T(TOX_JSON_PATH)))); - // todo: download from https://nodes.tox.chat/json + + if (!IsFileExists(path)) + UpdateNodes(); if (IsFileExists(path)) { @@ -127,10 +97,38 @@ void CToxProto::BootstrapNodes() logger->Log(__FUNCTION__": bootstraping DHT"); bool isIPv6 = getBool("EnableIPv6", 0); BootstrapNodesFromDb(isIPv6); - BootstrapNodesFromIni(isIPv6); BootstrapNodesFromJson(isIPv6); } +void CToxProto::UpdateNodes() +{ + ptrT path(mir_tstrdup((TCHAR*)VARST(_T(TOX_JSON_PATH)))); + + if (!IsFileExists(path)) + { + HANDLE hProfile = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + if (hProfile == NULL) + { + logger->Log(__FUNCTION__": failed to create tox.json"); + return; + } + CloseHandle(hProfile); + } + + HttpRequest request(REQUEST_GET, "https://nodes.tox.chat/json"); + NLHR_PTR response(request.Send(hNetlib)); + + if (response->resultCode == 200 && response->pData) + { + FILE *hFile = _tfopen(path, _T("w")); + if (hFile) + { + fwrite(response->pData, sizeof(char), response->dataLength, hFile); + fclose(hFile); + } + } +} + void CToxProto::TryConnect() { if (toxThread != NULL) diff --git a/protocols/Tox/src/tox_options.cpp b/protocols/Tox/src/tox_options.cpp index db44e8f1af..8eb0b05026 100644 --- a/protocols/Tox/src/tox_options.cpp +++ b/protocols/Tox/src/tox_options.cpp @@ -389,9 +389,11 @@ BOOL CCtrlNodeList::OnNotify(int idCtrl, NMHDR *pnmh) CToxOptionsNodeList::CToxOptionsNodeList(CToxProto *proto) : CSuper(proto, IDD_OPTIONS_NODES, false), - m_nodes(this, IDC_NODESLIST), m_addNode(this, IDC_ADDNODE) + m_nodes(this, IDC_NODESLIST), m_addNode(this, IDC_ADDNODE), + m_updateNodes(this, IDC_UPDATENODES) { m_addNode.OnClick = Callback(this, &CToxOptionsNodeList::OnAddNode); + m_updateNodes.OnClick = Callback(this, &CToxOptionsNodeList::OnUpdateNodes); m_nodes.OnClick = Callback(this, &CToxOptionsNodeList::OnNodeListClick); m_nodes.OnDoubleClick = Callback(this, &CToxOptionsNodeList::OnNodeListDoubleClick); m_nodes.OnKeyDown = Callback(this, &CToxOptionsNodeList::OnNodeListKeyDown); @@ -418,37 +420,88 @@ void CToxOptionsNodeList::OnInitDialog() m_nodes.AddGroup(0, TranslateT("Common nodes")); m_nodes.AddGroup(1, TranslateT("User nodes")); - //////////////////////////////////////// + ReloadNodeList(); +} - int iItem = -1; +void CToxOptionsNodeList::OnAddNode(CCtrlBase*) +{ + CToxNodeEditor nodeEditor(-1, &m_nodes); + if (nodeEditor.DoModal()) + SendMessage(GetParent(m_hwnd), PSM_CHANGED, 0, 0); +} + +void CToxOptionsNodeList::OnUpdateNodes(CCtrlBase*) +{ + m_proto->UpdateNodes(); + + ReloadNodeList(); +} - if (CToxProto::IsFileExists((TCHAR*)VARST(_T(TOX_INI_PATH)))) +void CToxOptionsNodeList::OnNodeListDoubleClick(CCtrlBase*) +{ + int iItem = m_nodes.GetNextItem(-1, LVNI_SELECTED); + + LVITEM lvi = { 0 }; + lvi.iItem = iItem; + lvi.mask = LVIF_GROUPID; + m_nodes.GetItem(&lvi); + if (lvi.iGroupId || (lvi.iGroupId == 0 && lvi.iItem == -1)) { - char fileName[MAX_PATH]; - mir_strcpy(fileName, VARS(TOX_INI_PATH)); + CToxNodeEditor nodeEditor(lvi.iItem, &m_nodes); + if (nodeEditor.DoModal()) + SendMessage(GetParent(m_hwnd), PSM_CHANGED, 0, 0); + } +} - char *section, sections[MAX_PATH], value[MAX_PATH]; - GetPrivateProfileSectionNamesA(sections, _countof(sections), fileName); - section = sections; - while (*section != NULL) +void CToxOptionsNodeList::OnNodeListClick(CCtrlListView::TEventInfo *evt) +{ + LVITEM lvi = { 0 }; + lvi.iItem = evt->nmlvia->iItem; + lvi.mask = LVIF_GROUPID; + m_nodes.GetItem(&lvi); + lvi.iSubItem = evt->nmlvia->iSubItem; + if (lvi.iGroupId && lvi.iSubItem == 4) + { + CToxNodeEditor nodeEditor(lvi.iItem, &m_nodes); + if (nodeEditor.DoModal()) + SendMessage(GetParent(GetParent(m_hwnd)), PSM_CHANGED, 0, 0); + } + else if (lvi.iGroupId && lvi.iSubItem == 5) + { + if (MessageBox(m_hwnd, TranslateT("Are you sure?"), TranslateT("Node deleting"), MB_YESNO | MB_ICONWARNING) == IDYES) { - if (strstr(section, TOX_SETTINGS_NODE_PREFIX) == section) - { - GetPrivateProfileStringA(section, "IPv4", NULL, value, _countof(value), fileName); - iItem = m_nodes.AddItem(mir_a2t(value), -1, NULL, 0); - - GetPrivateProfileStringA(section, "IPv6", NULL, value, _countof(value), fileName); - m_nodes.SetItem(iItem, 1, mir_a2t(value)); + m_nodes.DeleteItem(lvi.iItem); + SendMessage(GetParent(GetParent(m_hwnd)), PSM_CHANGED, 0, 0); + } + } +} - GetPrivateProfileStringA(section, "Port", NULL, value, _countof(value), fileName); - m_nodes.SetItem(iItem, 2, mir_a2t(value)); +void CToxOptionsNodeList::OnNodeListKeyDown(CCtrlListView::TEventInfo *evt) +{ + LVITEM lvi = { 0 }; + lvi.iItem = m_nodes.GetSelectionMark(); + lvi.mask = LVIF_GROUPID; + m_nodes.GetItem(&lvi); - GetPrivateProfileStringA(section, "PubKey", NULL, value, _countof(value), fileName); - m_nodes.SetItem(iItem, 3, mir_a2t(value)); - } - section += mir_strlen(section) + 1; + if (lvi.iGroupId && lvi.iItem != -1 && (evt->nmlvkey)->wVKey == VK_DELETE) + { + if (MessageBox( + GetParent(m_hwnd), + TranslateT("Are you sure?"), + TranslateT("Node deleting"), + MB_YESNO | MB_ICONWARNING) == IDYES) + { + m_nodes.DeleteItem(lvi.iItem); + SendMessage(GetParent(GetParent(m_hwnd)), PSM_CHANGED, 0, 0); } } +} + +void CToxOptionsNodeList::ReloadNodeList() +{ + m_nodes.DeleteAllItems(); + + int iItem = -1; ptrT path(mir_tstrdup((TCHAR*)VARST(_T(TOX_JSON_PATH)))); if (CToxProto::IsFileExists(path)) @@ -524,73 +577,6 @@ void CToxOptionsNodeList::OnInitDialog() } } -void CToxOptionsNodeList::OnAddNode(CCtrlBase*) -{ - CToxNodeEditor nodeEditor(-1, &m_nodes); - if (nodeEditor.DoModal()) - SendMessage(GetParent(m_hwnd), PSM_CHANGED, 0, 0); -} - -void CToxOptionsNodeList::OnNodeListDoubleClick(CCtrlBase*) -{ - int iItem = m_nodes.GetNextItem(-1, LVNI_SELECTED); - - LVITEM lvi = { 0 }; - lvi.iItem = iItem; - lvi.mask = LVIF_GROUPID; - m_nodes.GetItem(&lvi); - if (lvi.iGroupId || (lvi.iGroupId == 0 && lvi.iItem == -1)) - { - CToxNodeEditor nodeEditor(lvi.iItem, &m_nodes); - if (nodeEditor.DoModal()) - SendMessage(GetParent(m_hwnd), PSM_CHANGED, 0, 0); - } -} - -void CToxOptionsNodeList::OnNodeListClick(CCtrlListView::TEventInfo *evt) -{ - LVITEM lvi = { 0 }; - lvi.iItem = evt->nmlvia->iItem; - lvi.mask = LVIF_GROUPID; - m_nodes.GetItem(&lvi); - lvi.iSubItem = evt->nmlvia->iSubItem; - if (lvi.iGroupId && lvi.iSubItem == 4) - { - CToxNodeEditor nodeEditor(lvi.iItem, &m_nodes); - if (nodeEditor.DoModal()) - SendMessage(GetParent(GetParent(m_hwnd)), PSM_CHANGED, 0, 0); - } - else if (lvi.iGroupId && lvi.iSubItem == 5) - { - if (MessageBox(m_hwnd, TranslateT("Are you sure?"), TranslateT("Node deleting"), MB_YESNO | MB_ICONWARNING) == IDYES) - { - m_nodes.DeleteItem(lvi.iItem); - SendMessage(GetParent(GetParent(m_hwnd)), PSM_CHANGED, 0, 0); - } - } -} - -void CToxOptionsNodeList::OnNodeListKeyDown(CCtrlListView::TEventInfo *evt) -{ - LVITEM lvi = { 0 }; - lvi.iItem = m_nodes.GetSelectionMark(); - lvi.mask = LVIF_GROUPID; - m_nodes.GetItem(&lvi); - - if (lvi.iGroupId && lvi.iItem != -1 && (evt->nmlvkey)->wVKey == VK_DELETE) - { - if (MessageBox( - GetParent(m_hwnd), - TranslateT("Are you sure?"), - TranslateT("Node deleting"), - MB_YESNO | MB_ICONWARNING) == IDYES) - { - m_nodes.DeleteItem(lvi.iItem); - SendMessage(GetParent(GetParent(m_hwnd)), PSM_CHANGED, 0, 0); - } - } -} - void CToxOptionsNodeList::OnApply() { char setting[MAX_PATH]; diff --git a/protocols/Tox/src/tox_options.h b/protocols/Tox/src/tox_options.h index a3550bf454..675d9a2294 100644 --- a/protocols/Tox/src/tox_options.h +++ b/protocols/Tox/src/tox_options.h @@ -117,12 +117,16 @@ private: CCtrlNodeList m_nodes; CCtrlButton m_addNode; + CCtrlButton m_updateNodes; protected: void OnInitDialog(); void OnApply(); + void ReloadNodeList(); + void OnAddNode(CCtrlBase*); + void OnUpdateNodes(CCtrlBase*); void OnNodeListDoubleClick(CCtrlBase*); void OnNodeListClick(CCtrlListView::TEventInfo *evt); void OnNodeListKeyDown(CCtrlListView::TEventInfo *evt); diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h index fa138d3c23..996c34a681 100644 --- a/protocols/Tox/src/tox_proto.h +++ b/protocols/Tox/src/tox_proto.h @@ -95,9 +95,11 @@ private: void BootstrapNode(const char *address, int port, const char *pubKey); void BootstrapNodesFromDb(bool isIPv6); - void BootstrapNodesFromIni(bool isIPv6); void BootstrapNodesFromJson(bool isIPv6); void BootstrapNodes(); + + void UpdateNodes(); + void TryConnect(); void CheckConnection(int &retriesCount); diff --git a/protocols/Tox/src/version.h b/protocols/Tox/src/version.h index 4ab90defe2..c78311d2b6 100644 --- a/protocols/Tox/src/version.h +++ b/protocols/Tox/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 11 #define __RELEASE_NUM 1 -#define __BUILD_NUM 20 +#define __BUILD_NUM 21 #include -- cgit v1.2.3