summaryrefslogtreecommitdiff
path: root/protocols/Telegram/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2022-12-05 15:29:28 +0300
committerGeorge Hazan <ghazan@miranda.im>2022-12-05 15:29:28 +0300
commit1c7167406020c45856358a95c1ade1aa217dccd3 (patch)
tree1a583350e6b311e35638a0f37b5593845703b705 /protocols/Telegram/src
parentcf6686206e050f0e010f76e5ff33b1d8c1e20c5b (diff)
Telegram: setting statuses
Diffstat (limited to 'protocols/Telegram/src')
-rw-r--r--protocols/Telegram/src/mt_proto.cpp41
-rw-r--r--protocols/Telegram/src/mt_proto.h31
-rw-r--r--protocols/Telegram/src/server.cpp55
-rw-r--r--protocols/Telegram/src/stdafx.h2
4 files changed, 124 insertions, 5 deletions
diff --git a/protocols/Telegram/src/mt_proto.cpp b/protocols/Telegram/src/mt_proto.cpp
index 8d7b0123e5..83cf3b82cf 100644
--- a/protocols/Telegram/src/mt_proto.cpp
+++ b/protocols/Telegram/src/mt_proto.cpp
@@ -2,8 +2,10 @@
CMTProto::CMTProto(const char* protoName, const wchar_t* userName) :
PROTO<CMTProto>(protoName, userName),
- client_manager_(std::make_unique<td::ClientManager>())
+ m_pClientMmanager(std::make_unique<td::ClientManager>()),
+ m_arRequests(10, NumericKeySortT)
{
+ m_iClientId = m_pClientMmanager->create_client_id();
}
CMTProto::~CMTProto()
@@ -21,5 +23,42 @@ INT_PTR CMTProto::GetCaps(int type, MCONTACT)
int CMTProto::SetStatus(int iNewStatus)
{
+ if (m_iDesiredStatus == iNewStatus)
+ return 0;
+
+ int oldStatus = m_iStatus;
+
+ // Routing statuses not supported by Telegram
+ switch (iNewStatus) {
+ case ID_STATUS_OFFLINE:
+ m_iDesiredStatus = iNewStatus;
+ break;
+
+ case ID_STATUS_ONLINE:
+ case ID_STATUS_FREECHAT:
+ default:
+ m_iDesiredStatus = ID_STATUS_ONLINE;
+ break;
+ }
+
+ if (m_iDesiredStatus == ID_STATUS_OFFLINE) {
+ if (m_bRunning)
+ SendQuery(new td::td_api::close());
+
+ m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
+ }
+ else if (!m_bRunning && !IsStatusConnecting(m_iStatus)) {
+ m_iStatus = ID_STATUS_CONNECTING;
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
+
+ ForkThread(&CMTProto::ServerThread);
+ }
+ else if (m_bRunning) {
+ m_iStatus = m_iDesiredStatus;
+ ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
+ }
+ else ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
+
return 0;
}
diff --git a/protocols/Telegram/src/mt_proto.h b/protocols/Telegram/src/mt_proto.h
index 22f5a5352f..a42c06dcf6 100644
--- a/protocols/Telegram/src/mt_proto.h
+++ b/protocols/Telegram/src/mt_proto.h
@@ -1,8 +1,31 @@
#pragma once
-struct CMTProto : public PROTO<CMTProto>
+class CMTProto;
+typedef void (CMTProto::*TG_QUERY_HANDLER)(td::ClientManager::Response &response);
+
+struct TG_REQUEST
+{
+ TG_REQUEST(int32_t _1, TG_QUERY_HANDLER _2) :
+ queryId(_1),
+ pHandler(_2)
+ {}
+
+ int32_t queryId;
+ TG_QUERY_HANDLER pHandler;
+};
+
+class CMTProto : public PROTO<CMTProto>
{
- std::unique_ptr<td::ClientManager> client_manager_;
+ std::unique_ptr<td::ClientManager> m_pClientMmanager;
+ td::td_api::object_ptr<td::td_api::AuthorizationState> pAuthState;
+
+ bool m_bAuthorized, m_bRunning = false, m_bTerminated;
+ int32_t m_iClientId;
+ uint64_t m_iQueryId;
+
+ OBJLIST<TG_REQUEST> m_arRequests;
+ void ProcessResponse(td::ClientManager::Response);
+ void SendQuery(td::td_api::Function *pFunc, TG_QUERY_HANDLER pHandler = nullptr);
public:
//////////////////////////////////////////////////////////////////////////////////////
@@ -17,4 +40,8 @@ public:
INT_PTR GetCaps(int type, MCONTACT hContact = NULL) override;
int SetStatus(int iNewStatus) override;
+
+ // Processing Threads //////////////////////////////////////////////////////////////////
+
+ void __cdecl ServerThread(void *);
};
diff --git a/protocols/Telegram/src/server.cpp b/protocols/Telegram/src/server.cpp
new file mode 100644
index 0000000000..f8985e5ecb
--- /dev/null
+++ b/protocols/Telegram/src/server.cpp
@@ -0,0 +1,55 @@
+/*
+Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+
+void __cdecl CMTProto::ServerThread(void *)
+{
+ m_bRunning = true;
+ m_bTerminated = m_bAuthorized = false;
+
+ while (!m_bTerminated) {
+ ProcessResponse(m_pClientMmanager->receive(10));
+ }
+
+ m_bRunning = false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void CMTProto::ProcessResponse(td::ClientManager::Response response)
+{
+ if (!response.object)
+ return;
+
+ if (response.client_id) {
+ auto *p = m_arRequests.find((TG_REQUEST *)&response.client_id);
+ if (p) {
+ (this->*p->pHandler)(response);
+ m_arRequests.remove(p);
+ }
+ }
+}
+
+void CMTProto::SendQuery(td::td_api::Function *pFunc, TG_QUERY_HANDLER pHandler)
+{
+ int queryId = ++m_iQueryId;
+ m_pClientMmanager->send(m_iClientId, queryId, td::td_api::object_ptr<td::td_api::Function>(pFunc));
+
+ if (pHandler)
+ m_arRequests.insert(new TG_REQUEST(queryId, pHandler));
+}
diff --git a/protocols/Telegram/src/stdafx.h b/protocols/Telegram/src/stdafx.h
index f8658bacb0..5436b91e03 100644
--- a/protocols/Telegram/src/stdafx.h
+++ b/protocols/Telegram/src/stdafx.h
@@ -17,8 +17,6 @@
#include "td/telegram/td_api.h"
#include "td/telegram/td_api.hpp"
-struct CMTProto;
-
#define MODULE "Telegram"
#include "version.h"