summaryrefslogtreecommitdiff
path: root/protocols/Tox/src
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Tox/src')
-rw-r--r--protocols/Tox/src/http_request.h151
-rw-r--r--protocols/Tox/src/resource.h3
-rw-r--r--protocols/Tox/src/stdafx.h3
-rw-r--r--protocols/Tox/src/tox_network.cpp66
-rw-r--r--protocols/Tox/src/tox_options.cpp166
-rw-r--r--protocols/Tox/src/tox_options.h4
-rw-r--r--protocols/Tox/src/tox_proto.h4
-rw-r--r--protocols/Tox/src/version.h2
8 files changed, 271 insertions, 128 deletions
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 <m_folders.h>
#include <m_assocmgr.h>
#include <m_json.h>
+#include <m_http.h>
#include <tox.h>
#include <ToxAV.h>
@@ -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 <stdver.h>