summaryrefslogtreecommitdiff
path: root/protocols/Discord/src/connection.cpp
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2016-12-28 16:57:55 +0300
committerGeorge Hazan <ghazan@miranda.im>2016-12-28 16:58:16 +0300
commite7a87b3c82204e048f23750a18b456e567a6f436 (patch)
treefaf10111046c42cd4fcffb23d2e749effa10e540 /protocols/Discord/src/connection.cpp
parent4efdd531337b74d819a40c87c454a0fa1f6ca838 (diff)
http framework
Diffstat (limited to 'protocols/Discord/src/connection.cpp')
-rw-r--r--protocols/Discord/src/connection.cpp142
1 files changed, 142 insertions, 0 deletions
diff --git a/protocols/Discord/src/connection.cpp b/protocols/Discord/src/connection.cpp
index a7e3babd41..13a12129e2 100644
--- a/protocols/Discord/src/connection.cpp
+++ b/protocols/Discord/src/connection.cpp
@@ -17,7 +17,149 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
+void CDiscordProto::ExecuteRequest(AsyncHttpRequest *pReq)
+{
+ CMStringA str;
+
+ pReq->szUrl = pReq->m_szUrl.GetBuffer();
+ if (!pReq->m_szParam.IsEmpty()) {
+ if (pReq->requestType == REQUEST_GET) {
+ str.Format("%s?%s", pReq->m_szUrl, pReq->m_szParam);
+ pReq->szUrl = str.GetBuffer();
+ }
+ else {
+ pReq->pData = mir_strdup(pReq->m_szParam);
+ pReq->dataLength = pReq->m_szParam.GetLength();
+ }
+ }
+
+ pReq->flags |= NLHRF_PERSISTENT;
+ pReq->nlc = m_hAPIConnection;
+
+ debugLogA("Executing request #%d:\n%s", pReq->m_iReqNum, pReq->szUrl);
+ NETLIBHTTPREQUEST *reply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)pReq);
+ if (reply != NULL) {
+ if (pReq->m_pCallback != NULL)
+ (this->*(pReq->m_pCallback))(reply, pReq);
+
+ m_hAPIConnection = reply->nlc;
+
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)reply);
+ }
+ else {
+ debugLogA("Request %d failed", pReq->m_iReqNum);
+
+ if (IsStatusConnecting(m_iStatus))
+ ConnectionFailed(LOGINERR_NONETWORK);
+ else
+ ShutdownSession();
+ m_hAPIConnection = NULL;
+ }
+ delete pReq;
+}
+
+void CDiscordProto::OnLoggedIn()
+{
+ debugLogA("CDiscordProto::OnLoggedIn");
+ m_bOnline = true;
+ SetServerStatus(m_iDesiredStatus);
+}
+
+void CDiscordProto::OnLoggedOut()
+{
+ debugLogA("CDiscordProto::OnLoggedOut");
+ m_bOnline = false;
+ m_hWorkerThread = NULL;
+
+ if (m_hAPIConnection)
+ Netlib_CloseHandle(m_hAPIConnection);
+
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE);
+ m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
+}
+
+void CDiscordProto::ShutdownSession()
+{
+ debugLogA("CDiscordProto::ShutdownSession");
+ m_bTerminated = true;
+ if (m_hWorkerThread)
+ SetEvent(m_evRequestsQueue);
+ OnLoggedOut();
+}
+
+void CDiscordProto::ConnectionFailed(int iReason)
+{
+ debugLogA("CDiscordProto::ConnectionFailed -> reason %d", iReason);
+ delSetting("AccessToken");
+
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, iReason);
+ ShutdownSession();
+}
+
+bool CDiscordProto::TryToConnect(void)
+{
+ ptrW wszLogin(getWStringA(DB_KEY_EMAIL)), wszPassword(getWStringA(DB_KEY_PASSWORD));
+ if (wszLogin == NULL) {
+ ConnectionFailed(LOGINERR_BADUSERID);
+ return false;
+ }
+ if (wszPassword == NULL) {
+ ConnectionFailed(LOGINERR_WRONGPASSWORD);
+ return false;
+ }
+
+ Push(new AsyncHttpRequest(this, REQUEST_GET, "/user/login", &CDiscordProto::OnReceiveToken)
+ << WCHAR_PARAM("email", wszLogin)
+ << WCHAR_PARAM("password", wszPassword));
+ return true;
+}
+
void CDiscordProto::ServerThread(void*)
{
+ m_szAccessToken = getStringA("AccessToken");
+ m_hAPIConnection = NULL;
+ m_bTerminated = false;
+
+ debugLogA("CDiscordProto::WorkerThread: %s", "entering");
+
+ if (m_szAccessToken != NULL)
+ // try to receive a response from server
+ RetrieveMyInfo();
+ else if (!TryToConnect())
+ return;
+
+ while (true) {
+ WaitForSingleObject(m_evRequestsQueue, 1000);
+ if (m_bTerminated)
+ break;
+
+ AsyncHttpRequest *pReq;
+ bool need_sleep = false;
+ while (true) {
+ {
+ mir_cslock lck(m_csHttpQueue);
+ if (m_arHttpQueue.getCount() == 0)
+ break;
+
+ pReq = m_arHttpQueue[0];
+ m_arHttpQueue.remove(0);
+ need_sleep = (m_arHttpQueue.getCount() > 1);
+ }
+ if (m_bTerminated)
+ break;
+ ExecuteRequest(pReq);
+ if (need_sleep) {
+ Sleep(330);
+ debugLogA("CDiscordProto::WorkerThread: %s", "need to sleep");
+ }
+ }
+ }
+
+ m_hWorkerThread = NULL;
+ if (m_hAPIConnection) {
+ Netlib_CloseHandle(m_hAPIConnection);
+ m_hAPIConnection = NULL;
+ }
+ debugLogA("CDiscordProto::WorkerThread: %s", "leaving");
}