From 6fa68cf0d363869146059d78181c7debbfd4f3b9 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Tue, 17 Jan 2023 13:45:51 +0300 Subject: Telegram: files renamed according to Miranda standard --- protocols/Telegram/src/mt_proto.cpp | 197 --------------------------------- protocols/Telegram/src/mt_proto.h | 211 ------------------------------------ protocols/Telegram/src/proto.cpp | 197 +++++++++++++++++++++++++++++++++ protocols/Telegram/src/proto.h | 211 ++++++++++++++++++++++++++++++++++++ protocols/Telegram/src/stdafx.h | 2 +- 5 files changed, 409 insertions(+), 409 deletions(-) delete mode 100644 protocols/Telegram/src/mt_proto.cpp delete mode 100644 protocols/Telegram/src/mt_proto.h create mode 100644 protocols/Telegram/src/proto.cpp create mode 100644 protocols/Telegram/src/proto.h (limited to 'protocols/Telegram/src') diff --git a/protocols/Telegram/src/mt_proto.cpp b/protocols/Telegram/src/mt_proto.cpp deleted file mode 100644 index 0e1515eb1c..0000000000 --- a/protocols/Telegram/src/mt_proto.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#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) - return 0; - - return (p1->id < p2->id) ? -1 : 1; -} - -CMTProto::CMTProto(const char* protoName, const wchar_t* userName) : - PROTO(protoName, userName), - m_impl(*this), - m_arUsers(10, CompareUsers), - m_arRequests(10, CompareRequests), - m_szOwnPhone(this, "Phone"), - m_wszDeviceName(this, "DeviceName", L"Miranda NG"), - m_wszDefaultGroup(this, "DefaultGroup", L"Telegram"), - m_bUsePopups(this, "UsePopups", true), - m_bHideGroupchats(this, "HideChats", true) -{ - m_iOwnId = _atoi64(getMStringA(DBKEY_ID)); - - CreateProtoService(PS_CREATEACCMGRUI, &CMTProto::SvcCreateAccMgrUI); - CreateProtoService(PS_GETAVATARCAPS, &CMTProto::SvcGetAvatarCaps); - CreateProtoService(PS_GETAVATARINFO, &CMTProto::SvcGetAvatarInfo); - CreateProtoService(PS_GETMYAVATAR, &CMTProto::SvcGetMyAvatar); - CreateProtoService(PS_SETMYAVATAR, &CMTProto::SvcSetMyAvatar); - - HookProtoEvent(ME_OPT_INITIALISE, &CMTProto::OnOptionsInit); - HookProtoEvent(ME_DB_EVENT_MARKED_READ, &CMTProto::OnDbMarkedRead); - - // default contacts group - if (m_wszDefaultGroup == NULL) - m_wszDefaultGroup = mir_wstrdup(L"WhatsApp"); - m_iBaseGroup = Clist_GroupCreate(0, m_wszDefaultGroup); - - // Create standard network connection - NETLIBUSER nlu = {}; - nlu.flags = NUF_UNICODE; - nlu.szSettingsModule = m_szModuleName; - nlu.szDescriptiveName.w = m_tszUserName; - m_hNetlibUser = Netlib_RegisterUser(&nlu); - - // groupchat initialization - GCREGISTER gcr = {}; - gcr.dwFlags = GC_TYPNOTIF | GC_DATABASE; - gcr.ptszDispName = m_tszUserName; - gcr.pszModule = m_szModuleName; - Chat_Register(&gcr); - - // HookProtoEvent(ME_GC_EVENT, &WhatsAppProto::GcEventHook); - // HookProtoEvent(ME_GC_BUILDMENU, &WhatsAppProto::GcMenuHook); -} - -CMTProto::~CMTProto() -{ -} - -void CMTProto::OnModulesLoaded() -{ - CMStringA szId(getMStringA(DBKEY_ID)); - if (!szId.IsEmpty()) - m_arUsers.insert(new TG_USER(_atoi64(szId.c_str()), 0)); - - for (auto &cc : AccContacts()) { - bool isGroupChat = isChatRoom(cc); - szId = getMStringA(cc, isGroupChat ? "ChatRoomID" : DBKEY_ID); - if (!szId.IsEmpty()) { - auto *pUser = new TG_USER(_atoi64(szId.c_str()), cc, isGroupChat); - pUser->szAvatarHash = getMStringA(cc, DBKEY_AVATAR_HASH); - m_arUsers.insert(pUser); - } - } -} - -void CMTProto::OnShutdown() -{ - m_bTerminated = true; -} - -void CMTProto::OnErase() -{ - m_bUnregister = true; - ServerThread(0); - - DeleteDirectoryTreeW(GetProtoFolder(), false); -} - -int CMTProto::OnDbMarkedRead(WPARAM hContact, LPARAM hDbEvent) -{ - if (!hContact) - return 0; - - // filter out only events of my protocol - const char *szProto = Proto_GetBaseAccountName(hContact); - if (mir_strcmp(szProto, m_szModuleName)) - return 0; - - ptrA userId(getStringA(hContact, DBKEY_ID)); - if (userId) { - DBEVENTINFO dbei = {}; - db_event_get(hDbEvent, &dbei); - if (dbei.szId) { - mir_cslock lck(m_csMarkRead); - if (m_markContact) { - if (m_markContact != hContact) - SendMarkRead(); - - m_impl.m_markRead.Stop(); - } - - m_markContact = hContact; - m_markIds.push_back(_atoi64(dbei.szId)); - m_impl.m_markRead.Start(500); - } - } - - return 0; -} - -INT_PTR CMTProto::GetCaps(int type, MCONTACT) -{ - switch (type) { - case PFLAGNUM_1: - return PF1_IM | PF1_FILE | PF1_CHAT | PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_MODEMSGRECV; - case PFLAGNUM_2: - return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY; - case PFLAGNUM_4: - return PF4_NOCUSTOMAUTH | PF4_NOAUTHDENYREASON | PF4_IMSENDOFFLINE | PF4_OFFLINEFILES | PF4_SUPPORTTYPING | PF4_AVATARS | PF4_SERVERMSGID; - case PFLAGNUM_5: - return PF2_SHORTAWAY | PF2_LONGAWAY; - case PFLAG_UNIQUEIDTEXT: - return (INT_PTR)L"Phone"; - default: - 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) - 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 (isRunning()) - SendQuery(new TD::close()); - - m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); - } - else if (!isRunning() && !IsStatusConnecting(m_iStatus)) { - m_iStatus = ID_STATUS_CONNECTING; - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); - - ForkThread(&CMTProto::ServerThread); - } - else if (isRunning()) { - 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 deleted file mode 100644 index 9ab923de87..0000000000 --- a/protocols/Telegram/src/mt_proto.h +++ /dev/null @@ -1,211 +0,0 @@ -#pragma once - -#define STATUS_SWITCH_TIMEOUT 600 - -#define DBKEY_ID "id" - -#define DBKEY_AVATAR_HASH "AvatarHash" -#define DBKEY_AVATAR_PATH "AvatarPath" -#define DBKEY_AVATAR_TYPE "AvatarType" - -class CMTProto; -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_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) : - TG_REQUEST_BASE(_1), - pHandler(_2) - {} - - 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) : - id(_1), - hContact(_2), - isGroupChat(_3) - {} - - uint64_t id; - MCONTACT hContact; - bool isGroupChat; - CMStringA szAvatarHash; - time_t m_timer1 = 0, m_timer2 = 0; -}; - -class CMTProto : public PROTO -{ - class CProtoImpl - { - friend class CMTProto; - CMTProto &m_proto; - - CTimer m_keepAlive, m_markRead; - void OnKeepAlive(CTimer *) - { m_proto.SendKeepAlive(); - } - - void OnMarkRead(CTimer *) - { m_proto.SendMarkRead(); - } - - CProtoImpl(CMTProto &pro) : - m_proto(pro), - m_markRead(Miranda_GetSystemWindow(), UINT_PTR(this)), - m_keepAlive(Miranda_GetSystemWindow(), UINT_PTR(this)+1) - { - m_markRead.OnEvent = Callback(this, &CProtoImpl::OnMarkRead); - m_keepAlive.OnEvent = Callback(this, &CProtoImpl::OnKeepAlive); - } - } m_impl; - - bool __forceinline isRunning() const - { return m_pClientMmanager != nullptr; - } - - std::unique_ptr m_pClientMmanager; - TD::object_ptr pAuthState; - - mir_cs m_csMarkRead; - MCONTACT m_markContact = 0; - TD::array m_markIds; - - bool m_bAuthorized, m_bTerminated, m_bUnregister = false; - int32_t m_iClientId, m_iMsgId; - uint64_t m_iQueryId; - - OBJLIST m_arRequests; - - static INT_PTR CALLBACK EnterPhoneCode(void *param); - static INT_PTR CALLBACK EnterPassword(void *param); - - CMStringW GetProtoFolder() const - { return CMStringW(VARSW(L"%miranda_userdata%")) + L"\\" + _A2T(m_szModuleName); - } - - void OnEndSession(td::ClientManager::Response &response); - void OnSendMessage(td::ClientManager::Response &response, void *pUserInfo); - void OnUpdateAuth(td::ClientManager::Response &response); - - void LogOut(void); - void OnLoggedIn(void); - void ProcessResponse(td::ClientManager::Response); - - void SendKeepAlive(void); - void SendMarkRead(void); - void SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER pHandler = nullptr); - void SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER_FULL pHandler, void *pUserInfo); - int SendTextMessage(uint64_t chatId, const char *pszMessage); - - void ProcessAuth(TD::updateAuthorizationState *pObj); - void ProcessChat(TD::updateNewChat *pObj); - void ProcessChatPosition(TD::updateChatPosition *pObj); - void ProcessFile(TD::updateFile *pObj); - void ProcessGroups(TD::updateChatFilters *pObj); - void ProcessMarkRead(TD::updateChatReadInbox *pObj); - void ProcessMessage(TD::updateNewMessage *pObj); - void ProcessStatus(TD::updateUserStatus *pObj); - void ProcessUser(TD::updateUser *pObj); - - void UpdateString(MCONTACT hContact, const char *pszSetting, const std::string &str); - - // Users - int64_t m_iOwnId; - MGROUP m_iBaseGroup; - OBJLIST m_arUsers; - - TG_USER* FindUser(uint64_t id); - TG_USER* AddUser(uint64_t id, bool bIsChat); - - // Popups - HANDLE m_hPopupClass; - - void InitPopups(void); - void Popup(MCONTACT hContact, const wchar_t *szMsg, const wchar_t *szTitle); - -public: - ////////////////////////////////////////////////////////////////////////////////////// - // Ctors - - CMTProto(const char *protoName, const wchar_t *userName); - ~CMTProto(); - - ////////////////////////////////////////////////////////////////////////////////////// - // Virtual functions - - 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; - void OnShutdown() override; - void OnErase() override; - - // Services ////////////////////////////////////////////////////////////////////////// - - INT_PTR __cdecl SvcCreateAccMgrUI(WPARAM, LPARAM); - INT_PTR __cdecl SvcGetAvatarCaps(WPARAM, LPARAM); - INT_PTR __cdecl SvcGetAvatarInfo(WPARAM, LPARAM); - INT_PTR __cdecl SvcGetMyAvatar(WPARAM, LPARAM); - INT_PTR __cdecl SvcSetMyAvatar(WPARAM, LPARAM); - - // Events //////////////////////////////////////////////////////////////////////////// - - int __cdecl OnOptionsInit(WPARAM, LPARAM); - int __cdecl OnDbMarkedRead(WPARAM, LPARAM); - - // Options /////////////////////////////////////////////////////////////////////////// - - CMOption m_szOwnPhone; // our own phone number - CMOption m_wszDefaultGroup; // clist group to store contacts - CMOption m_wszDeviceName; // how do you see this session in Device List - CMOption m_bHideGroupchats; // do not open chat windows on creation - CMOption m_bUsePopups; - - // Processing Threads //////////////////////////////////////////////////////////////// - - void __cdecl ServerThread(void *); -}; diff --git a/protocols/Telegram/src/proto.cpp b/protocols/Telegram/src/proto.cpp new file mode 100644 index 0000000000..6fbde8731e --- /dev/null +++ b/protocols/Telegram/src/proto.cpp @@ -0,0 +1,197 @@ +#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) + return 0; + + return (p1->id < p2->id) ? -1 : 1; +} + +CMTProto::CMTProto(const char* protoName, const wchar_t* userName) : + PROTO(protoName, userName), + m_impl(*this), + m_arUsers(10, CompareUsers), + m_arRequests(10, CompareRequests), + m_szOwnPhone(this, "Phone"), + m_wszDeviceName(this, "DeviceName", L"Miranda NG"), + m_wszDefaultGroup(this, "DefaultGroup", L"Telegram"), + m_bUsePopups(this, "UsePopups", true), + m_bHideGroupchats(this, "HideChats", true) +{ + m_iOwnId = _atoi64(getMStringA(DBKEY_ID)); + + CreateProtoService(PS_CREATEACCMGRUI, &CMTProto::SvcCreateAccMgrUI); + CreateProtoService(PS_GETAVATARCAPS, &CMTProto::SvcGetAvatarCaps); + CreateProtoService(PS_GETAVATARINFO, &CMTProto::SvcGetAvatarInfo); + CreateProtoService(PS_GETMYAVATAR, &CMTProto::SvcGetMyAvatar); + CreateProtoService(PS_SETMYAVATAR, &CMTProto::SvcSetMyAvatar); + + HookProtoEvent(ME_OPT_INITIALISE, &CMTProto::OnOptionsInit); + HookProtoEvent(ME_DB_EVENT_MARKED_READ, &CMTProto::OnDbMarkedRead); + + // default contacts group + if (m_wszDefaultGroup == NULL) + m_wszDefaultGroup = mir_wstrdup(L"WhatsApp"); + m_iBaseGroup = Clist_GroupCreate(0, m_wszDefaultGroup); + + // Create standard network connection + NETLIBUSER nlu = {}; + nlu.flags = NUF_UNICODE; + nlu.szSettingsModule = m_szModuleName; + nlu.szDescriptiveName.w = m_tszUserName; + m_hNetlibUser = Netlib_RegisterUser(&nlu); + + // groupchat initialization + GCREGISTER gcr = {}; + gcr.dwFlags = GC_TYPNOTIF | GC_DATABASE; + gcr.ptszDispName = m_tszUserName; + gcr.pszModule = m_szModuleName; + Chat_Register(&gcr); + + // HookProtoEvent(ME_GC_EVENT, &WhatsAppProto::GcEventHook); + // HookProtoEvent(ME_GC_BUILDMENU, &WhatsAppProto::GcMenuHook); +} + +CMTProto::~CMTProto() +{ +} + +void CMTProto::OnModulesLoaded() +{ + CMStringA szId(getMStringA(DBKEY_ID)); + if (!szId.IsEmpty()) + m_arUsers.insert(new TG_USER(_atoi64(szId.c_str()), 0)); + + for (auto &cc : AccContacts()) { + bool isGroupChat = isChatRoom(cc); + szId = getMStringA(cc, isGroupChat ? "ChatRoomID" : DBKEY_ID); + if (!szId.IsEmpty()) { + auto *pUser = new TG_USER(_atoi64(szId.c_str()), cc, isGroupChat); + pUser->szAvatarHash = getMStringA(cc, DBKEY_AVATAR_HASH); + m_arUsers.insert(pUser); + } + } +} + +void CMTProto::OnShutdown() +{ + m_bTerminated = true; +} + +void CMTProto::OnErase() +{ + m_bUnregister = true; + ServerThread(0); + + DeleteDirectoryTreeW(GetProtoFolder(), false); +} + +int CMTProto::OnDbMarkedRead(WPARAM hContact, LPARAM hDbEvent) +{ + if (!hContact) + return 0; + + // filter out only events of my protocol + const char *szProto = Proto_GetBaseAccountName(hContact); + if (mir_strcmp(szProto, m_szModuleName)) + return 0; + + ptrA userId(getStringA(hContact, DBKEY_ID)); + if (userId) { + DBEVENTINFO dbei = {}; + db_event_get(hDbEvent, &dbei); + if (dbei.szId) { + mir_cslock lck(m_csMarkRead); + if (m_markContact) { + if (m_markContact != hContact) + SendMarkRead(); + + m_impl.m_markRead.Stop(); + } + + m_markContact = hContact; + m_markIds.push_back(_atoi64(dbei.szId)); + m_impl.m_markRead.Start(500); + } + } + + return 0; +} + +INT_PTR CMTProto::GetCaps(int type, MCONTACT) +{ + switch (type) { + case PFLAGNUM_1: + return PF1_IM | PF1_FILE | PF1_CHAT | PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_MODEMSGRECV; + case PFLAGNUM_2: + return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY; + case PFLAGNUM_4: + return PF4_NOCUSTOMAUTH | PF4_NOAUTHDENYREASON | PF4_IMSENDOFFLINE | PF4_OFFLINEFILES | PF4_SUPPORTTYPING | PF4_AVATARS | PF4_SERVERMSGID; + case PFLAGNUM_5: + return PF2_SHORTAWAY | PF2_LONGAWAY; + case PFLAG_UNIQUEIDTEXT: + return (INT_PTR)L"Phone"; + default: + 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) + 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 (isRunning()) + SendQuery(new TD::close()); + + m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); + } + else if (!isRunning() && !IsStatusConnecting(m_iStatus)) { + m_iStatus = ID_STATUS_CONNECTING; + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); + + ForkThread(&CMTProto::ServerThread); + } + else if (isRunning()) { + 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/proto.h b/protocols/Telegram/src/proto.h new file mode 100644 index 0000000000..3a5a622198 --- /dev/null +++ b/protocols/Telegram/src/proto.h @@ -0,0 +1,211 @@ +#pragma once + +#define STATUS_SWITCH_TIMEOUT 600 + +#define DBKEY_ID "id" + +#define DBKEY_AVATAR_HASH "AvatarHash" +#define DBKEY_AVATAR_PATH "AvatarPath" +#define DBKEY_AVATAR_TYPE "AvatarType" + +class CMTProto; +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_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) : + TG_REQUEST_BASE(_1), + pHandler(_2) + {} + + 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) : + id(_1), + hContact(_2), + isGroupChat(_3) + {} + + uint64_t id; + MCONTACT hContact; + bool isGroupChat; + CMStringA szAvatarHash; + time_t m_timer1 = 0, m_timer2 = 0; +}; + +class CMTProto : public PROTO +{ + class CProtoImpl + { + friend class CMTProto; + CMTProto &m_proto; + + CTimer m_keepAlive, m_markRead; + void OnKeepAlive(CTimer *) + { m_proto.SendKeepAlive(); + } + + void OnMarkRead(CTimer *) + { m_proto.SendMarkRead(); + } + + CProtoImpl(CMTProto &pro) : + m_proto(pro), + m_markRead(Miranda_GetSystemWindow(), UINT_PTR(this)), + m_keepAlive(Miranda_GetSystemWindow(), UINT_PTR(this)+1) + { + m_markRead.OnEvent = Callback(this, &CProtoImpl::OnMarkRead); + m_keepAlive.OnEvent = Callback(this, &CProtoImpl::OnKeepAlive); + } + } m_impl; + + bool __forceinline isRunning() const + { return m_pClientMmanager != nullptr; + } + + std::unique_ptr m_pClientMmanager; + TD::object_ptr pAuthState; + + mir_cs m_csMarkRead; + MCONTACT m_markContact = 0; + TD::array m_markIds; + + bool m_bAuthorized, m_bTerminated, m_bUnregister = false; + int32_t m_iClientId, m_iMsgId; + uint64_t m_iQueryId; + + OBJLIST m_arRequests; + + static INT_PTR CALLBACK EnterPhoneCode(void *param); + static INT_PTR CALLBACK EnterPassword(void *param); + + CMStringW GetProtoFolder() const + { return CMStringW(VARSW(L"%miranda_userdata%")) + L"\\" + _A2T(m_szModuleName); + } + + void OnEndSession(td::ClientManager::Response &response); + void OnSendMessage(td::ClientManager::Response &response, void *pUserInfo); + void OnUpdateAuth(td::ClientManager::Response &response); + + void LogOut(void); + void OnLoggedIn(void); + void ProcessResponse(td::ClientManager::Response); + + void SendKeepAlive(void); + void SendMarkRead(void); + void SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER pHandler = nullptr); + void SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER_FULL pHandler, void *pUserInfo); + int SendTextMessage(uint64_t chatId, const char *pszMessage); + + void ProcessAuth(TD::updateAuthorizationState *pObj); + void ProcessChat(TD::updateNewChat *pObj); + void ProcessChatPosition(TD::updateChatPosition *pObj); + void ProcessFile(TD::updateFile *pObj); + void ProcessGroups(TD::updateChatFilters *pObj); + void ProcessMarkRead(TD::updateChatReadInbox *pObj); + void ProcessMessage(TD::updateNewMessage *pObj); + void ProcessStatus(TD::updateUserStatus *pObj); + void ProcessUser(TD::updateUser *pObj); + + void UpdateString(MCONTACT hContact, const char *pszSetting, const std::string &str); + + // Users + int64_t m_iOwnId; + MGROUP m_iBaseGroup; + OBJLIST m_arUsers; + + TG_USER* FindUser(uint64_t id); + TG_USER* AddUser(uint64_t id, bool bIsChat); + + // Popups + HANDLE m_hPopupClass; + + void InitPopups(void); + void Popup(MCONTACT hContact, const wchar_t *szMsg, const wchar_t *szTitle); + +public: + ////////////////////////////////////////////////////////////////////////////////////// + // Ctors + + CMTProto(const char *protoName, const wchar_t *userName); + ~CMTProto(); + + ////////////////////////////////////////////////////////////////////////////////////// + // Virtual functions + + 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; + void OnShutdown() override; + void OnErase() override; + + // Services ////////////////////////////////////////////////////////////////////////// + + INT_PTR __cdecl SvcCreateAccMgrUI(WPARAM, LPARAM); + INT_PTR __cdecl SvcGetAvatarCaps(WPARAM, LPARAM); + INT_PTR __cdecl SvcGetAvatarInfo(WPARAM, LPARAM); + INT_PTR __cdecl SvcGetMyAvatar(WPARAM, LPARAM); + INT_PTR __cdecl SvcSetMyAvatar(WPARAM, LPARAM); + + // Events //////////////////////////////////////////////////////////////////////////// + + int __cdecl OnOptionsInit(WPARAM, LPARAM); + int __cdecl OnDbMarkedRead(WPARAM, LPARAM); + + // Options /////////////////////////////////////////////////////////////////////////// + + CMOption m_szOwnPhone; // our own phone number + CMOption m_wszDefaultGroup; // clist group to store contacts + CMOption m_wszDeviceName; // how do you see this session in Device List + CMOption m_bHideGroupchats; // do not open chat windows on creation + CMOption m_bUsePopups; + + // Processing Threads //////////////////////////////////////////////////////////////// + + void __cdecl ServerThread(void *); +}; diff --git a/protocols/Telegram/src/stdafx.h b/protocols/Telegram/src/stdafx.h index 8e56956840..ce2aaf4abf 100644 --- a/protocols/Telegram/src/stdafx.h +++ b/protocols/Telegram/src/stdafx.h @@ -33,7 +33,7 @@ namespace TD = td::td_api; #include "version.h" #include "resource.h" -#include "mt_proto.h" +#include "proto.h" #include "utils.h" struct CMPlugin : public ACCPROTOPLUGIN -- cgit v1.2.3