diff options
author | George Hazan <ghazan@miranda.im> | 2022-12-08 18:48:51 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2022-12-08 18:48:51 +0300 |
commit | 9589c7adf93691f60c613f944ae60ff9bd692b91 (patch) | |
tree | c786705d8cce2f43587166dd9b7a0f390162075b | |
parent | e4a555d8e146994b7fc99c8f0c0f6b4ca8af1495 (diff) |
Telegram: device registration
-rw-r--r-- | protocols/Telegram/Telegram.vcxproj | 2 | ||||
-rw-r--r-- | protocols/Telegram/Telegram.vcxproj.filters | 6 | ||||
-rw-r--r-- | protocols/Telegram/res/resource.rc | 52 | ||||
-rw-r--r-- | protocols/Telegram/src/mt_proto.cpp | 15 | ||||
-rw-r--r-- | protocols/Telegram/src/mt_proto.h | 44 | ||||
-rw-r--r-- | protocols/Telegram/src/options.cpp | 81 | ||||
-rw-r--r-- | protocols/Telegram/src/resource.h | 8 | ||||
-rw-r--r-- | protocols/Telegram/src/server.cpp | 147 | ||||
-rw-r--r-- | protocols/Telegram/src/stdafx.h | 4 | ||||
-rw-r--r-- | protocols/Telegram/src/utils.cpp | 66 |
10 files changed, 384 insertions, 41 deletions
diff --git a/protocols/Telegram/Telegram.vcxproj b/protocols/Telegram/Telegram.vcxproj index b0f02c7588..2928b017a3 100644 --- a/protocols/Telegram/Telegram.vcxproj +++ b/protocols/Telegram/Telegram.vcxproj @@ -28,10 +28,12 @@ <ItemGroup> <ClCompile Include="src\main.cpp" /> <ClCompile Include="src\mt_proto.cpp" /> + <ClCompile Include="src\options.cpp" /> <ClCompile Include="src\server.cpp" /> <ClCompile Include="src\stdafx.cxx"> <PrecompiledHeader>Create</PrecompiledHeader> </ClCompile> + <ClCompile Include="src\utils.cpp" /> </ItemGroup> <ItemDefinitionGroup> <ClCompile> diff --git a/protocols/Telegram/Telegram.vcxproj.filters b/protocols/Telegram/Telegram.vcxproj.filters index 397701677d..4a38c95a4b 100644 --- a/protocols/Telegram/Telegram.vcxproj.filters +++ b/protocols/Telegram/Telegram.vcxproj.filters @@ -11,6 +11,12 @@ <ClCompile Include="src\server.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="src\options.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="src\utils.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClCompile Include="src\stdafx.cxx"> diff --git a/protocols/Telegram/res/resource.rc b/protocols/Telegram/res/resource.rc index a0e2523557..5c3e00eb73 100644 --- a/protocols/Telegram/res/resource.rc +++ b/protocols/Telegram/res/resource.rc @@ -60,46 +60,32 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // Dialog // -IDD_ACCOUNT_MANAGER DIALOGEX 0, 0, 186, 119 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU +IDD_ACCMGRUI DIALOGEX 0, 0, 188, 144 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 400, 0, 0x1 +FONT 8, "MS Shell Dlg", 400, 0, 0x0 BEGIN + LTEXT "Phone number:",IDC_STATIC,0,6,89,10 + EDITTEXT IDC_PHONE,96,4,86,12,ES_AUTOHSCROLL + LTEXT "Default group:",IDC_STATIC,0,23,89,10 + EDITTEXT IDC_DEFGROUP,96,21,86,12,ES_AUTOHSCROLL + CONTROL "Do not open chat windows on creation",IDC_HIDECHATS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,57,182,10 END - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_ACCOUNT_MANAGER, DIALOG - BEGIN - BOTTOMMARGIN, 112 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// AFX_DIALOG_LAYOUT -// - -IDD_PASSWORD_CHANGE2 AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_ACCOUNT_MANAGER AFX_DIALOG_LAYOUT +IDD_OPTIONS DIALOGEX 0, 0, 305, 188 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - 0 + LTEXT "Phone number:",IDC_STATIC,5,6,79,10 + EDITTEXT IDC_PHONE,87,5,211,12,ES_AUTOHSCROLL + LTEXT "Default group:",IDC_STATIC,5,24,79,10 + EDITTEXT IDC_DEFGROUP,87,23,211,12,ES_AUTOHSCROLL + CONTROL "Do not open chat windows on creation",IDC_HIDECHATS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,64,294,10 END - ///////////////////////////////////////////////////////////////////////////// // // Icon diff --git a/protocols/Telegram/src/mt_proto.cpp b/protocols/Telegram/src/mt_proto.cpp index b767d79475..8f8476636b 100644 --- a/protocols/Telegram/src/mt_proto.cpp +++ b/protocols/Telegram/src/mt_proto.cpp @@ -3,15 +3,28 @@ CMTProto::CMTProto(const char* protoName, const wchar_t* userName) : PROTO<CMTProto>(protoName, userName), m_pClientMmanager(std::make_unique<td::ClientManager>()), - m_arRequests(10, NumericKeySortT) + m_arRequests(10, NumericKeySortT), + m_szOwnPhone(this, "Phone"), + m_wszDefaultGroup(this, "DefaultGroup", L"Telegram"), + m_bUsePopups(this, "UsePopups", true), + m_bHideGroupchats(this, "HideChats", true) { m_iClientId = m_pClientMmanager->create_client_id(); + + CreateProtoService(PS_CREATEACCMGRUI, &CMTProto::SvcCreateAccMgrUI); + + HookProtoEvent(ME_OPT_INITIALISE, &CMTProto::OnOptionsInit); } CMTProto::~CMTProto() { } +void CMTProto::OnErase() +{ + DeleteDirectoryTreeW(GetProtoFolder(), false); +} + INT_PTR CMTProto::GetCaps(int type, MCONTACT) { switch (type) { diff --git a/protocols/Telegram/src/mt_proto.h b/protocols/Telegram/src/mt_proto.h index a42c06dcf6..e6e6764000 100644 --- a/protocols/Telegram/src/mt_proto.h +++ b/protocols/Telegram/src/mt_proto.h @@ -5,12 +5,12 @@ typedef void (CMTProto::*TG_QUERY_HANDLER)(td::ClientManager::Response &response struct TG_REQUEST { - TG_REQUEST(int32_t _1, TG_QUERY_HANDLER _2) : - queryId(_1), + TG_REQUEST(td::ClientManager::RequestId _1, TG_QUERY_HANDLER _2) : + requestId(_1), pHandler(_2) {} - int32_t queryId; + td::ClientManager::RequestId requestId; TG_QUERY_HANDLER pHandler; }; @@ -24,9 +24,28 @@ class CMTProto : public PROTO<CMTProto> uint64_t m_iQueryId; OBJLIST<TG_REQUEST> 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 OnUpdateAuth(td::ClientManager::Response &response); + + void LogOut(void); + void OnLoggedIn(void); + void ProcessAuth(td::td_api::updateAuthorizationState *pObj); void ProcessResponse(td::ClientManager::Response); void SendQuery(td::td_api::Function *pFunc, TG_QUERY_HANDLER pHandler = nullptr); + // Popups + HANDLE m_hPopupClass; + + void InitPopups(void); + void Popup(MCONTACT hContact, const wchar_t *szMsg, const wchar_t *szTitle); + public: ////////////////////////////////////////////////////////////////////////////////////// // Ctors @@ -41,7 +60,24 @@ public: int SetStatus(int iNewStatus) override; - // Processing Threads ////////////////////////////////////////////////////////////////// + void OnErase() override; + + // Services ////////////////////////////////////////////////////////////////////////// + + INT_PTR __cdecl SvcCreateAccMgrUI(WPARAM, LPARAM); + + // Events //////////////////////////////////////////////////////////////////////////// + + int __cdecl OnOptionsInit(WPARAM, LPARAM); + + // Options /////////////////////////////////////////////////////////////////////////// + + CMOption<wchar_t*> m_szOwnPhone; // our own phone number + CMOption<wchar_t*> m_wszDefaultGroup; // clist group to store contacts + 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/options.cpp b/protocols/Telegram/src/options.cpp new file mode 100644 index 0000000000..7f13c65239 --- /dev/null +++ b/protocols/Telegram/src/options.cpp @@ -0,0 +1,81 @@ +/* +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" + +///////////////////////////////////////////////////////////////////////////////////////// + +class COptionsDlg : public CProtoDlgBase<CMTProto> +{ + CCtrlCheck chkHideChats, chkUsePopups; + CCtrlEdit edtGroup, edtPhone; + ptrW m_wszOldGroup; + +public: + COptionsDlg(CMTProto *ppro, int iDlgID, bool bFullDlg) : + CProtoDlgBase<CMTProto>(ppro, iDlgID), + chkUsePopups(this, IDC_POPUPS), + chkHideChats(this, IDC_HIDECHATS), + edtPhone(this, IDC_PHONE), + edtGroup(this, IDC_DEFGROUP), + m_wszOldGroup(mir_wstrdup(ppro->m_wszDefaultGroup)) + { + CreateLink(edtPhone, ppro->m_szOwnPhone); + CreateLink(edtGroup, ppro->m_wszDefaultGroup); + + if (bFullDlg) { + CreateLink(chkUsePopups, ppro->m_bUsePopups); + CreateLink(chkHideChats, ppro->m_bHideGroupchats); + } + } + + bool OnApply() override + { + if (!mir_wstrlen(m_proto->m_szOwnPhone)) { + SetFocus(edtPhone.GetHwnd()); + return false; + } + + if (mir_wstrcmp(m_proto->m_wszDefaultGroup, m_wszOldGroup)) + Clist_GroupCreate(0, m_proto->m_wszDefaultGroup); + return true; + } +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +INT_PTR CMTProto::SvcCreateAccMgrUI(WPARAM, LPARAM hwndParent) +{ + auto *pDlg = new COptionsDlg(this, IDD_ACCMGRUI, false); + pDlg->SetParent((HWND)hwndParent); + pDlg->Create(); + return (INT_PTR)pDlg->GetHwnd(); +} + +int CMTProto::OnOptionsInit(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = {}; + odp.szTitle.w = m_tszUserName; + odp.flags = ODPF_UNICODE; + odp.szGroup.w = LPGENW("Network"); + + odp.position = 1; + odp.szTab.w = LPGENW("Account"); + odp.pDialog = new COptionsDlg(this, IDD_OPTIONS, true); + g_plugin.addOptions(wParam, &odp); + return 0; +} diff --git a/protocols/Telegram/src/resource.h b/protocols/Telegram/src/resource.h index 8627d4d5cd..a9cc327636 100644 --- a/protocols/Telegram/src/resource.h +++ b/protocols/Telegram/src/resource.h @@ -3,7 +3,13 @@ // Used by D:\Projects\miranda-ng\miranda-ng\protocols\Telegram\res\resource.rc // #define IDI_TELEGRAM 100 -#define IDD_ACCOUNT_MANAGER 110 +#define IDD_ACCMGRUI 101 +#define IDD_OPTIONS 102 + +#define IDC_PHONE 1001 +#define IDC_DEFGROUP 1002 +#define IDC_HIDECHATS 1003 +#define IDC_POPUPS 1004 // Next default values for new objects // diff --git a/protocols/Telegram/src/server.cpp b/protocols/Telegram/src/server.cpp index f8985e5ecb..1905b4ae70 100644 --- a/protocols/Telegram/src/server.cpp +++ b/protocols/Telegram/src/server.cpp @@ -22,6 +22,8 @@ void __cdecl CMTProto::ServerThread(void *) m_bRunning = true; m_bTerminated = m_bAuthorized = false; + SendQuery(new td::td_api::getOption("version")); + while (!m_bTerminated) { ProcessResponse(m_pClientMmanager->receive(10)); } @@ -29,6 +31,138 @@ void __cdecl CMTProto::ServerThread(void *) m_bRunning = false; } +void CMTProto::LogOut() +{ + if (m_bTerminated) + return; + + debugLogA("CMTProto::OnLoggedOut"); + m_bTerminated = true; + m_bAuthorized = false; + + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE); + m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; + + setAllContactStatuses(ID_STATUS_OFFLINE, false); +} + +void CMTProto::OnLoggedIn() +{ + m_bAuthorized = true; + + debugLogA("CMTProto::OnLoggedIn"); + + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, m_iDesiredStatus); + m_iStatus = m_iDesiredStatus; +} + +/////////////////////////////////////////////////////////////////////////////// + +INT_PTR CALLBACK CMTProto::EnterPhoneCode(void *param) +{ + auto *ppro = (CMTProto *)param; + + ENTER_STRING es = {}; + es.szModuleName = ppro->m_szModuleName; + es.caption = TranslateT("Enter secret code sent to your phone"); + if (EnterString(&es)) { + ppro->SendQuery(new td::td_api::checkAuthenticationCode(_T2A(es.ptszResult).get()), &CMTProto::OnUpdateAuth); + mir_free(es.ptszResult); + } + else ppro->LogOut(); + return 0; +} + +INT_PTR CALLBACK CMTProto::EnterPassword(void *param) +{ + auto *ppro = (CMTProto *)param; + CMStringW wszTitle(TranslateT("Enter password")); + + auto *pAuth = (td::td_api::authorizationStateWaitPassword *)ppro->pAuthState.get(); + if (!pAuth->password_hint_.empty()) + wszTitle.AppendFormat(TranslateT(" (hint: %s)"), Utf2T(pAuth->password_hint_.c_str()).get()); + + ENTER_STRING es = {}; + es.szModuleName = ppro->m_szModuleName; + es.caption = wszTitle; + es.type = ESF_PASSWORD; + if (EnterString(&es)) { + ppro->SendQuery(new td::td_api::checkAuthenticationPassword(_T2A(es.ptszResult).get()), &CMTProto::OnUpdateAuth); + mir_free(es.ptszResult); + } + else ppro->LogOut(); + return 0; +} + +void CMTProto::ProcessAuth(td::td_api::updateAuthorizationState *pObj) +{ + pAuthState = std::move(pObj->authorization_state_); + switch (pAuthState->get_id()) { + case td::td_api::authorizationStateWaitTdlibParameters::ID: + { + char text[100]; + Miranda_GetVersionText(text, sizeof(text)); + + CMStringW wszPath(GetProtoFolder()); + + auto *request = new td::td_api::setTdlibParameters(); + request->database_directory_ = T2Utf(wszPath).get(); + request->use_message_database_ = false; + request->use_secret_chats_ = true; + request->api_id_ = 94575; + request->api_hash_ = "a3406de8d171bb422bb6ddf3bbd800e2"; + request->system_language_code_ = "en"; + request->device_model_ = "Miranda NG"; + request->application_version_ = text; + request->enable_storage_optimizer_ = true; + SendQuery(request, &CMTProto::OnUpdateAuth); + } + break; + + case td::td_api::authorizationStateWaitPhoneNumber::ID: + SendQuery(new td::td_api::setAuthenticationPhoneNumber(_T2A(m_szOwnPhone).get(), nullptr), &CMTProto::OnUpdateAuth); + break; + + case td::td_api::authorizationStateWaitCode::ID: + CallFunctionSync(EnterPhoneCode, this); + break; + + case td::td_api::authorizationStateWaitPassword::ID: + CallFunctionSync(EnterPassword, this); + break; + + case td::td_api::authorizationStateReady::ID: + OnLoggedIn(); + break; + + case td::td_api::authorizationStateLoggingOut::ID: + debugLogA("Server required us to log out, exiting"); + LogOut(); + break; + + case td::td_api::authorizationStateClosing::ID: + debugLogA("Connection terminated, exiting"); + LogOut(); + break; + } +} + +void CMTProto::OnUpdateAuth(td::ClientManager::Response &response) +{ + if (response.object->get_id() == td::td_api::error::ID) { + auto *pError = (td::td_api::error*)response.object.get(); + debugLogA("error happened: %s", to_string(*pError).c_str()); + + if (pError->message_ == "PHONE_CODE_EXPIRED") + Popup(0, TranslateT("Phone code expired"), TranslateT("Error")); + else if(pError->message_ == "INVALID_PHONE_CODE") + Popup(0, TranslateT("Invalid phone code"), TranslateT("Error")); + + pAuthState = std::move(nullptr); + LogOut(); + } +} + /////////////////////////////////////////////////////////////////////////////// void CMTProto::ProcessResponse(td::ClientManager::Response response) @@ -36,12 +170,21 @@ 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); + 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); if (p) { (this->*p->pHandler)(response); m_arRequests.remove(p); } + return; + } + + switch (response.object->get_id()) { + case td::td_api::updateAuthorizationState::ID: + ProcessAuth((td::td_api::updateAuthorizationState *)response.object.get()); + break; } } diff --git a/protocols/Telegram/src/stdafx.h b/protocols/Telegram/src/stdafx.h index 5436b91e03..dd58e471ee 100644 --- a/protocols/Telegram/src/stdafx.h +++ b/protocols/Telegram/src/stdafx.h @@ -10,8 +10,12 @@ #include <m_protoint.h> #include <m_protosvc.h> +#include <m_clist.h> #include <m_database.h> +#include <m_icolib.h> #include <m_langpack.h> +#include <m_options.h> +#include <m_popup.h> #include "td/telegram/Client.h" #include "td/telegram/td_api.h" diff --git a/protocols/Telegram/src/utils.cpp b/protocols/Telegram/src/utils.cpp new file mode 100644 index 0000000000..0228dc3756 --- /dev/null +++ b/protocols/Telegram/src/utils.cpp @@ -0,0 +1,66 @@ +/* +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" + +///////////////////////////////////////////////////////////////////////////////////////// +// Popups + +void CMTProto::InitPopups(void) +{ + g_plugin.addPopupOption(CMStringW(FORMAT, TranslateT("%s error notifications"), m_tszUserName), m_bUsePopups); + + char name[256]; + mir_snprintf(name, "%s_%s", m_szModuleName, "Error"); + + wchar_t desc[256]; + mir_snwprintf(desc, L"%s/%s", m_tszUserName, TranslateT("Errors")); + + POPUPCLASS ppc = {}; + ppc.flags = PCF_UNICODE; + ppc.pszName = name; + ppc.pszDescription.w = desc; + ppc.hIcon = IcoLib_GetIconByHandle(m_hProtoIcon); + ppc.colorBack = RGB(191, 0, 0); //Red + ppc.colorText = RGB(255, 245, 225); //Yellow + ppc.iSeconds = 60; + m_hPopupClass = Popup_RegisterClass(&ppc); + + IcoLib_ReleaseIcon(ppc.hIcon); +} + +void CMTProto::Popup(MCONTACT hContact, const wchar_t *szMsg, const wchar_t *szTitle) +{ + if (!m_bUsePopups) + return; + + char name[256]; + mir_snprintf(name, "%s_%s", m_szModuleName, "Error"); + + CMStringW wszTitle(szTitle); + if (hContact == 0) { + wszTitle.Insert(0, L": "); + wszTitle.Insert(0, m_tszUserName); + } + + POPUPDATACLASS ppd = {}; + ppd.szTitle.w = wszTitle; + ppd.szText.w = szMsg; + ppd.pszClassName = name; + ppd.hContact = hContact; + Popup_AddClass(&ppd); +} |