summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/Telegram/Telegram.vcxproj4
-rw-r--r--protocols/Telegram/Telegram.vcxproj.filters4
-rw-r--r--protocols/Telegram/src/proto.cpp (renamed from protocols/Telegram/src/mt_proto.cpp)394
-rw-r--r--protocols/Telegram/src/proto.h (renamed from protocols/Telegram/src/mt_proto.h)422
-rw-r--r--protocols/Telegram/src/stdafx.h2
5 files changed, 413 insertions, 413 deletions
diff --git a/protocols/Telegram/Telegram.vcxproj b/protocols/Telegram/Telegram.vcxproj
index 16b8bbd8a1..6586c6698e 100644
--- a/protocols/Telegram/Telegram.vcxproj
+++ b/protocols/Telegram/Telegram.vcxproj
@@ -29,7 +29,7 @@
<ClCompile Include="src\auth.cpp" />
<ClCompile Include="src\avatars.cpp" />
<ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\mt_proto.cpp" />
+ <ClCompile Include="src\proto.cpp" />
<ClCompile Include="src\options.cpp" />
<ClCompile Include="src\server.cpp" />
<ClCompile Include="src\stdafx.cxx">
@@ -48,7 +48,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClInclude Include="src\mt_proto.h" />
+ <ClInclude Include="src\proto.h" />
<ClInclude Include="src\resource.h" />
<ClInclude Include="src\stdafx.h" />
<ClInclude Include="src\version.h" />
diff --git a/protocols/Telegram/Telegram.vcxproj.filters b/protocols/Telegram/Telegram.vcxproj.filters
index 528f29127c..b4b601b02e 100644
--- a/protocols/Telegram/Telegram.vcxproj.filters
+++ b/protocols/Telegram/Telegram.vcxproj.filters
@@ -2,7 +2,7 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(ProjectDir)..\..\build\vc.common\common.filters" />
<ItemGroup>
- <ClCompile Include="src\mt_proto.cpp">
+ <ClCompile Include="src\proto.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\stdafx.cxx">
@@ -36,7 +36,7 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="src\mt_proto.h">
+ <ClInclude Include="src\proto.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\stdafx.h">
diff --git a/protocols/Telegram/src/mt_proto.cpp b/protocols/Telegram/src/proto.cpp
index 0e1515eb1c..6fbde8731e 100644
--- a/protocols/Telegram/src/mt_proto.cpp
+++ b/protocols/Telegram/src/proto.cpp
@@ -1,197 +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<CMTProto>(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;
-}
+#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<CMTProto>(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/proto.h
index 9ab923de87..3a5a622198 100644
--- a/protocols/Telegram/src/mt_proto.h
+++ b/protocols/Telegram/src/proto.h
@@ -1,211 +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<CMTProto>
-{
- 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<td::ClientManager> m_pClientMmanager;
- TD::object_ptr<TD::AuthorizationState> pAuthState;
-
- mir_cs m_csMarkRead;
- MCONTACT m_markContact = 0;
- TD::array<TD::int53> m_markIds;
-
- bool m_bAuthorized, m_bTerminated, m_bUnregister = false;
- int32_t m_iClientId, m_iMsgId;
- uint64_t m_iQueryId;
-
- OBJLIST<TG_REQUEST_BASE> 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<TG_USER> 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<wchar_t*> m_szOwnPhone; // our own phone number
- CMOption<wchar_t*> m_wszDefaultGroup; // clist group to store contacts
- CMOption<wchar_t*> m_wszDeviceName; // how do you see this session in Device List
- CMOption<bool> m_bHideGroupchats; // do not open chat windows on creation
- CMOption<bool> m_bUsePopups;
-
- // Processing Threads ////////////////////////////////////////////////////////////////
-
- void __cdecl ServerThread(void *);
-};
+#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<CMTProto>
+{
+ 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<td::ClientManager> m_pClientMmanager;
+ TD::object_ptr<TD::AuthorizationState> pAuthState;
+
+ mir_cs m_csMarkRead;
+ MCONTACT m_markContact = 0;
+ TD::array<TD::int53> m_markIds;
+
+ bool m_bAuthorized, m_bTerminated, m_bUnregister = false;
+ int32_t m_iClientId, m_iMsgId;
+ uint64_t m_iQueryId;
+
+ OBJLIST<TG_REQUEST_BASE> 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<TG_USER> 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<wchar_t*> m_szOwnPhone; // our own phone number
+ CMOption<wchar_t*> m_wszDefaultGroup; // clist group to store contacts
+ CMOption<wchar_t*> m_wszDeviceName; // how do you see this session in Device List
+ CMOption<bool> m_bHideGroupchats; // do not open chat windows on creation
+ CMOption<bool> 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<CMTProto>