diff options
Diffstat (limited to 'protocols/Icq10/src')
-rw-r--r-- | protocols/Icq10/src/http.cpp | 7 | ||||
-rw-r--r-- | protocols/Icq10/src/options.cpp | 127 | ||||
-rw-r--r-- | protocols/Icq10/src/proto.cpp | 20 | ||||
-rw-r--r-- | protocols/Icq10/src/proto.h | 5 | ||||
-rw-r--r-- | protocols/Icq10/src/resource.h | 9 | ||||
-rw-r--r-- | protocols/Icq10/src/server.cpp | 1 |
6 files changed, 157 insertions, 12 deletions
diff --git a/protocols/Icq10/src/http.cpp b/protocols/Icq10/src/http.cpp index 5590ddc596..92154cd13e 100644 --- a/protocols/Icq10/src/http.cpp +++ b/protocols/Icq10/src/http.cpp @@ -27,14 +27,7 @@ void __cdecl CIcqProto::ServerThread(void*) memset(&m_ConnPool, 0, sizeof(m_ConnPool)); m_bTerminated = false; - if (m_dwUin == 0 || mir_wstrlen(m_szPassword) == 0) { - debugLogA("Thread ended, UIN/password are not configured"); - ConnectionFailed(LOGINERR_BADUSERID); - return; - } - debugLogA("CIcqProto::WorkerThread: %s", "entering"); - CheckPassword(); while (true) { WaitForSingleObject(m_evRequestsQueue, 1000); diff --git a/protocols/Icq10/src/options.cpp b/protocols/Icq10/src/options.cpp index 2d0445f1a8..357e8617bf 100644 --- a/protocols/Icq10/src/options.cpp +++ b/protocols/Icq10/src/options.cpp @@ -20,19 +20,135 @@ #include "stdafx.h" +struct CIcqRegistrationDlg : public CProtoDlgBase<CIcqProto> +{ + CMStringA szTrans; + int iErrorCode; + + CCtrlEdit edtPhone, edtCode; + CCtrlButton btnSendSms; + + CIcqRegistrationDlg(CIcqProto *ppro) : + CProtoDlgBase<CIcqProto>(ppro, IDD_REGISTER), + edtPhone(this, IDC_PHONE), + edtCode(this, IDC_CODE), + btnSendSms(this, IDC_SENDSMS) + { + btnSendSms.OnClick = Callback(this, &CIcqRegistrationDlg::onClick_SendSms); + edtPhone.OnChange = Callback(this, &CIcqRegistrationDlg::onChange_Phone); + } + + bool OnApply() override + { + auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "https://www.icq.com/smsreg/loginWithPhoneNumber.php", &CIcqProto::OnLoginViaPhone); + pReq << CHAR_PARAM("locale", "en") << WCHAR_PARAM("msisdn", ptrW(edtPhone.GetText())) << CHAR_PARAM("trans_id", szTrans) << CHAR_PARAM("k", ICQ_APP_ID) + << CHAR_PARAM("r", pReq->m_reqId) << CHAR_PARAM("f", "json") << WCHAR_PARAM("sms_code", ptrW(edtCode.GetText())) << INT_PARAM("create_account", 1); + pReq->pUserInfo = this; + + SetCursor(LoadCursor(0, IDC_WAIT)); + m_proto->ExecuteRequest(pReq); + SetCursor(LoadCursor(0, IDC_ARROW)); + + if (iErrorCode != 200) + return false; + + EndDialog(m_hwnd, 1); + return true; + } + + void onChange_Phone(CCtrlEdit*) + { + auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "https://clientapi.icq.net/fcgi-bin/smsphoneinfo", &CIcqProto::OnCheckPhone); + pReq << CHAR_PARAM("service", "icq_registration") << CHAR_PARAM("info", "typing_check,score,iso_country_code") + << WCHAR_PARAM("phone", ptrW(edtPhone.GetText())) << CHAR_PARAM("id", pReq->m_reqId); + pReq->pUserInfo = this; + m_proto->Push(pReq); + } + + void onClick_SendSms(CCtrlButton*) + { + auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "https://www.icq.com/smsreg/requestPhoneValidation.php", &CIcqProto::OnValidateSms); + pReq << CHAR_PARAM("locale", "en") << WCHAR_PARAM("msisdn", ptrW(edtPhone.GetText())) << CHAR_PARAM("r", pReq->m_reqId) + << CHAR_PARAM("smsFormatType", "human") << CHAR_PARAM("k", ICQ_APP_ID); + pReq->pUserInfo = this; + m_proto->Push(pReq); + } +}; + +void CIcqProto::OnCheckPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq) +{ + if (pReply == nullptr || pReply->resultCode != 200) + return; + + CIcqRegistrationDlg *pDlg = (CIcqRegistrationDlg*)pReq->pUserInfo; + pDlg->btnSendSms.Disable(); + pDlg->edtCode.Disable(); + + JSONROOT root(pReply->pData); + CMStringW wszStatus((*root)["status"].as_mstring()); + if (wszStatus != L"OK") { + pDlg->edtCode.SetText((*root)["printable"].as_mstring()); + return; + } + + pDlg->btnSendSms.Enable(); +} + +void CIcqProto::OnValidateSms(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq) +{ + JsonReply root(pReply); + if (root.error() != 200) + return; + + CIcqRegistrationDlg *pDlg = (CIcqRegistrationDlg*)pReq->pUserInfo; + const JSONNode &data = root.data(); + pDlg->szTrans = data["trans_id"].as_mstring(); + + pDlg->edtCode.Enable(); + pDlg->edtCode.SetText(L""); +} + +void CIcqProto::OnLoginViaPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq) +{ + CIcqRegistrationDlg *pDlg = (CIcqRegistrationDlg*)pReq->pUserInfo; + + JsonReply root(pReply); + pDlg->iErrorCode = root.error(); + if (root.error() != 200) + return; + + const JSONNode &data = root.data(); + m_szAToken = data["token"]["a"].as_mstring(); + m_szAToken = ptrA(mir_urlDecode(m_szAToken)); + setString(DB_KEY_ATOKEN, m_szAToken); + + m_szSessionKey = data["sessionKey"].as_mstring(); + m_szSessionKey = ptrA(mir_urlDecode(m_szSessionKey)); + setString(DB_KEY_SESSIONKEY, m_szSessionKey); + + m_dwUin = _wtoi(data["loginId"].as_mstring()); + setByte("PhoneReg", 1); +} + +///////////////////////////////////////////////////////////////////////////////////////// + class CIcqOptionsDlg : public CProtoDlgBase<CIcqProto> { CCtrlEdit edtUin, edtPassword; CCtrlCheck chkSlowSend; + CCtrlButton btnCreate; CMStringW wszOldPass; public: CIcqOptionsDlg(CIcqProto *ppro, int iDlgID, bool bFullDlg) : CProtoDlgBase<CIcqProto>(ppro, iDlgID), edtUin(this, IDC_UIN), + btnCreate(this, IDC_REGISTER), edtPassword(this, IDC_PASSWORD), chkSlowSend(this, IDC_SLOWSEND) { + btnCreate.OnClick = Callback(this, &CIcqOptionsDlg::onClick_Register); + CreateLink(edtUin, ppro->m_dwUin); CreateLink(edtPassword, ppro->m_szPassword); @@ -47,9 +163,20 @@ public: if (wszOldPass != ptrW(edtPassword.GetText())) { m_proto->delSetting(DB_KEY_ATOKEN); m_proto->delSetting(DB_KEY_SESSIONKEY); + m_proto->delSetting("PhoneReg"); } return true; } + + void onClick_Register(CCtrlButton*) + { + CIcqRegistrationDlg dlg(m_proto); + dlg.SetParent(m_hwnd); + if (dlg.DoModal()) { + m_proto->m_dwUin = m_proto->getDword(DB_KEY_UIN); + m_proto->m_szPassword = L""; + } + } }; INT_PTR CIcqProto::CreateAccMgrUI(WPARAM, LPARAM hwndParent) diff --git a/protocols/Icq10/src/proto.cpp b/protocols/Icq10/src/proto.cpp index 3f3e5484dd..e4877204c7 100644 --- a/protocols/Icq10/src/proto.cpp +++ b/protocols/Icq10/src/proto.cpp @@ -62,6 +62,8 @@ CIcqProto::CIcqProto(const char* aProtoName, const wchar_t* aUserName) : nlu.szDescriptiveName.w = descr.GetBuffer(); m_hNetlibUser = Netlib_RegisterUser(&nlu); + m_hWorkerThread = ForkThreadEx(&CIcqProto::ServerThread, nullptr, nullptr); + InitContactCache(); } @@ -79,6 +81,7 @@ void CIcqProto::OnModulesLoaded() void CIcqProto::OnShutdown() { + m_bTerminated = true; } void CIcqProto::OnContactDeleted(MCONTACT hContact) @@ -337,10 +340,23 @@ int CIcqProto::SetStatus(int iNewStatus) ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)iOldStatus, m_iStatus); } // not logged in? come on - else if (m_hWorkerThread == nullptr && !IsStatusConnecting(m_iStatus)) { + else if (!IsStatusConnecting(m_iStatus)) { m_iStatus = ID_STATUS_CONNECTING; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)iOldStatus, m_iStatus); - m_hWorkerThread = ForkThreadEx(&CIcqProto::ServerThread, nullptr, nullptr); + + if (m_dwUin == 0) { + debugLogA("Thread ended, UIN/password are not configured"); + ConnectionFailed(LOGINERR_BADUSERID); + return 0; + } + + if (!getByte("PhoneReg") && mir_wstrlen(m_szPassword) == 0) { + debugLogA("Thread ended, password is not configured"); + ConnectionFailed(LOGINERR_BADUSERID); + return 0; + } + + CheckPassword(); } else if (m_bOnline) { debugLogA("setting server online status to %d", iNewStatus); diff --git a/protocols/Icq10/src/proto.h b/protocols/Icq10/src/proto.h index 8b2861b5a5..ec693efaea 100644 --- a/protocols/Icq10/src/proto.h +++ b/protocols/Icq10/src/proto.h @@ -64,6 +64,8 @@ struct IcqOwnMessage class CIcqProto : public PROTO<CIcqProto> { + friend struct CIcqRegistrationDlg; + bool m_bOnline = false, m_bTerminated = false; void CheckAvatarChange(MCONTACT hContact, const JSONNode&); void CheckNickChange(MCONTACT hContact, const JSONNode&); @@ -80,12 +82,15 @@ class CIcqProto : public PROTO<CIcqProto> void OnAddBuddy(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnAddClient(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnCheckPassword(NETLIBHTTPREQUEST*, AsyncHttpRequest*); + void OnCheckPhone(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnFetchEvents(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnGetUserInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*); + void OnLoginViaPhone(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnReceiveAvatar(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnSearchResults(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnSendMessage(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnStartSession(NETLIBHTTPREQUEST*, AsyncHttpRequest*); + void OnValidateSms(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void ProcessBuddyList(const JSONNode&); void ProcessEvent(const JSONNode&); diff --git a/protocols/Icq10/src/resource.h b/protocols/Icq10/src/resource.h index cdd4695b7e..77e27cc815 100644 --- a/protocols/Icq10/src/resource.h +++ b/protocols/Icq10/src/resource.h @@ -4,17 +4,22 @@ // #define IDD_OPTIONS_FULL 101 #define IDD_OPTIONS_ACCMGR 102 +#define IDD_REGISTER 105 #define IDC_PASSWORD 1001 #define IDC_UIN 1002 #define IDC_SLOWSEND 1003 +#define IDC_REGISTER 1005 +#define IDC_PHONE 1006 +#define IDC_SENDSMS 1008 +#define IDC_CODE 1009 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 104 +#define _APS_NEXT_RESOURCE_VALUE 107 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1004 +#define _APS_NEXT_CONTROL_VALUE 1010 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/protocols/Icq10/src/server.cpp b/protocols/Icq10/src/server.cpp index 006b2d6959..5aee47ddf9 100644 --- a/protocols/Icq10/src/server.cpp +++ b/protocols/Icq10/src/server.cpp @@ -85,7 +85,6 @@ void CIcqProto::OnLoggedOut() { debugLogA("CIcqProto::OnLoggedOut"); m_bOnline = false; - m_bTerminated = true; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE); m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; |