diff options
author | George Hazan <ghazan@miranda.im> | 2022-12-25 21:02:38 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2022-12-25 21:02:38 +0300 |
commit | 815d356584371b59545f5a2918a48cebd3a3b396 (patch) | |
tree | da2ab9dfd087c5d39eb4b2224677e7c13dbef689 | |
parent | 0c66b748a7b6b223d34374994e4d7d207e3d2c71 (diff) |
Telegram: text message sending
-rw-r--r-- | protocols/Telegram/src/mt_proto.cpp | 19 | ||||
-rw-r--r-- | protocols/Telegram/src/mt_proto.h | 55 | ||||
-rw-r--r-- | protocols/Telegram/src/server.cpp | 51 |
3 files changed, 115 insertions, 10 deletions
diff --git a/protocols/Telegram/src/mt_proto.cpp b/protocols/Telegram/src/mt_proto.cpp index 9e0cffd97c..e3dd7b6d29 100644 --- a/protocols/Telegram/src/mt_proto.cpp +++ b/protocols/Telegram/src/mt_proto.cpp @@ -1,5 +1,13 @@ #include "stdafx.h" +static int CompareRequests(const TG_REQUEST_BASE *p1, const TG_REQUEST_BASE *p2) +{ + if (p1->requestId == p2->requestId) + return 0; + + return (p1->requestId < p2->requestId) ? -1 : 1; +} + static int CompareUsers(const TG_USER *p1, const TG_USER *p2) { if (p1->id == p2->id) @@ -12,7 +20,7 @@ CMTProto::CMTProto(const char* protoName, const wchar_t* userName) : PROTO<CMTProto>(protoName, userName), m_pClientMmanager(std::make_unique<td::ClientManager>()), m_arUsers(10, CompareUsers), - m_arRequests(10, NumericKeySortT), + m_arRequests(10, CompareRequests), m_szOwnPhone(this, "Phone"), m_wszDefaultGroup(this, "DefaultGroup", L"Telegram"), m_bUsePopups(this, "UsePopups", true), @@ -90,6 +98,15 @@ INT_PTR CMTProto::GetCaps(int type, MCONTACT) return 0; } +int CMTProto::SendMsg(MCONTACT hContact, int, const char *pszMessage) +{ + ptrA szId(getStringA(hContact, DBKEY_ID)); + if (szId == nullptr) + return 0; + + return SendTextMessage(_atoi64(szId), pszMessage); +} + int CMTProto::SetStatus(int iNewStatus) { if (m_iDesiredStatus == iNewStatus) diff --git a/protocols/Telegram/src/mt_proto.h b/protocols/Telegram/src/mt_proto.h index 402dee432f..cc07eddd99 100644 --- a/protocols/Telegram/src/mt_proto.h +++ b/protocols/Telegram/src/mt_proto.h @@ -3,19 +3,57 @@ #define DBKEY_ID "id" class CMTProto; -typedef void (CMTProto::*TG_QUERY_HANDLER)(td::ClientManager::Response &response); +typedef void (CMTProto:: *TG_QUERY_HANDLER)(td::ClientManager::Response &response); +typedef void (CMTProto:: *TG_QUERY_HANDLER_FULL)(td::ClientManager::Response &response, void *pUserInfo); -struct TG_REQUEST +struct TG_REQUEST_BASE +{ + TG_REQUEST_BASE(td::ClientManager::RequestId _1) : + requestId(_1) + {} + + virtual ~TG_REQUEST_BASE() + {} + + td::ClientManager::RequestId requestId; + + virtual void Execute(CMTProto *ppro, td::ClientManager::Response &response) = 0; +}; + +struct TG_REQUEST : public TG_REQUEST_BASE { TG_REQUEST(td::ClientManager::RequestId _1, TG_QUERY_HANDLER _2) : - requestId(_1), + TG_REQUEST_BASE(_1), pHandler(_2) {} - td::ClientManager::RequestId requestId; TG_QUERY_HANDLER pHandler; + + void Execute(CMTProto *ppro, td::ClientManager::Response &response) override + { + (ppro->*pHandler)(response); + } +}; + +struct TG_REQUEST_FULL : public TG_REQUEST_BASE +{ + TG_REQUEST_FULL(td::ClientManager::RequestId _1, TG_QUERY_HANDLER_FULL _2, void *_3) : + TG_REQUEST_BASE(_1), + pHandler(_2), + pUserInfo(_3) + {} + + TG_QUERY_HANDLER_FULL pHandler; + void *pUserInfo; + + void Execute(CMTProto *ppro, td::ClientManager::Response &response) override + { + (ppro->*pHandler)(response, pUserInfo); + } }; +///////////////////////////////////////////////////////////////////////////////////////// + struct TG_USER { TG_USER(uint64_t _1, MCONTACT _2, bool _3 = false) : @@ -35,10 +73,10 @@ class CMTProto : public PROTO<CMTProto> TD::object_ptr<TD::AuthorizationState> pAuthState; bool m_bAuthorized, m_bRunning = false, m_bTerminated; - int32_t m_iClientId; + int32_t m_iClientId, m_iMsgId; uint64_t m_iQueryId; - OBJLIST<TG_REQUEST> m_arRequests; + OBJLIST<TG_REQUEST_BASE> m_arRequests; static INT_PTR CALLBACK EnterPhoneCode(void *param); static INT_PTR CALLBACK EnterPassword(void *param); @@ -53,6 +91,7 @@ class CMTProto : public PROTO<CMTProto> void OnLoggedIn(void); void ProcessResponse(td::ClientManager::Response); void SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER pHandler = nullptr); + void SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER_FULL pHandler, void *pUserInfo); void ProcessAuth(TD::updateAuthorizationState *pObj); void ProcessChat(TD::updateNewChat *pObj); @@ -60,6 +99,9 @@ class CMTProto : public PROTO<CMTProto> void ProcessMessage(TD::updateNewMessage *pObj); void ProcessUser(TD::updateUser *pObj); + void OnSendMessage(td::ClientManager::Response &response, void *pUserInfo); + int SendTextMessage(uint64_t chatId, const char *pszMessage); + void UpdateString(MCONTACT hContact, const char *pszSetting, const std::string &str); // Users @@ -87,6 +129,7 @@ public: INT_PTR GetCaps(int type, MCONTACT hContact = NULL) override; + int SendMsg(MCONTACT hContact, int flags, const char *pszMessage) override; int SetStatus(int iNewStatus) override; void OnModulesLoaded() override; diff --git a/protocols/Telegram/src/server.cpp b/protocols/Telegram/src/server.cpp index 89db787400..a94fe77e8f 100644 --- a/protocols/Telegram/src/server.cpp +++ b/protocols/Telegram/src/server.cpp @@ -68,9 +68,10 @@ void CMTProto::ProcessResponse(td::ClientManager::Response response) debugLogA("ProcessResponse: id=%d (%s)", int(response.request_id), to_string(response.object).c_str()); if (response.request_id) { - auto *p = m_arRequests.find((TG_REQUEST *)&response.request_id); + TG_REQUEST tmp(response.request_id, 0); + auto *p = m_arRequests.find(&tmp); if (p) { - (this->*p->pHandler)(response); + p->Execute(this, response); m_arRequests.remove(p); } return; @@ -99,6 +100,41 @@ void CMTProto::ProcessResponse(td::ClientManager::Response response) } } +void CMTProto::OnSendMessage(td::ClientManager::Response &response, void *pUserInfo) +{ + if (!response.object) + return; + + if (response.object->get_id() != TD::message::ID) { + debugLogA("Gotten class ID %d instead of %d, exiting", response.object->get_id(), TD::message::ID); + return; + } + + auto *pMessage = ((TD::message *)response.object.get()); + auto *pUser = FindUser(pMessage->chat_id_); + if (pUser) { + char szMsgId[100]; + _i64toa(pMessage->id_, szMsgId, 10); + ProtoBroadcastAck(pUser->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, pUserInfo, (LPARAM)szMsgId); + } +} + +int CMTProto::SendTextMessage(uint64_t chatId, const char *pszMessage) +{ + int ret = m_iMsgId++; + + auto pContent = TD::make_object<TD::inputMessageText>(); + pContent->text_ = TD::make_object<TD::formattedText>(); + pContent->text_->text_ = std::move(pszMessage); + + auto *pMessage = new TD::sendMessage(); + pMessage->chat_id_ = chatId; + pMessage->input_message_content_ = std::move(pContent); + SendQuery(pMessage, &CMTProto::OnSendMessage, (void*)ret); + + return ret; +} + void CMTProto::SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER pHandler) { int queryId = ++m_iQueryId; @@ -108,6 +144,15 @@ void CMTProto::SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER pHandler) m_arRequests.insert(new TG_REQUEST(queryId, pHandler)); } +void CMTProto::SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER_FULL pHandler, void *pUserInfo) +{ + int queryId = ++m_iQueryId; + m_pClientMmanager->send(m_iClientId, queryId, TD::object_ptr<TD::Function>(pFunc)); + + if (pHandler) + m_arRequests.insert(new TG_REQUEST_FULL(queryId, pHandler, pUserInfo)); +} + /////////////////////////////////////////////////////////////////////////////// void CMTProto::ProcessChat(TD::updateNewChat *pObj) @@ -169,7 +214,7 @@ void CMTProto::ProcessMessage(TD::updateNewMessage *pObj) } char szId[100]; - _i64toa(pMessage->id_, szId, _countof(szId)); + _i64toa(pMessage->id_, szId, 10); PROTORECVEVENT pre = {}; pre.szMessage = szText.GetBuffer(); |