diff options
-rw-r--r-- | protocols/ICQ-WIM/res/resources.rc | 17 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/options.cpp | 33 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/poll.cpp | 17 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/proto.cpp | 4 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/proto.h | 6 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/resource.h | 14 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/server.cpp | 41 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/utils.cpp | 10 |
8 files changed, 127 insertions, 15 deletions
diff --git a/protocols/ICQ-WIM/res/resources.rc b/protocols/ICQ-WIM/res/resources.rc index a5644efe4d..e0b3a3a157 100644 --- a/protocols/ICQ-WIM/res/resources.rc +++ b/protocols/ICQ-WIM/res/resources.rc @@ -37,12 +37,12 @@ BEGIN PUSHBUTTON "Sign in/sign up using phone",IDC_REGISTER,42,49,142,14 END -IDD_OPTIONS_FULL DIALOGEX 0, 0, 310, 97 +IDD_OPTIONS_FULL DIALOGEX 0, 0, 310, 174 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - GROUPBOX "ICQ",IDC_STATIC,4,0,302,76 + GROUPBOX "ICQ",IDC_STATIC,4,0,302,75 RTEXT "ICQ number:",IDC_STATIC,12,14,51,8 EDITTEXT IDC_UIN,68,12,106,12,ES_AUTOHSCROLL RTEXT "Email:",IDC_STATIC,12,29,51,8 @@ -51,7 +51,16 @@ BEGIN EDITTEXT IDC_PASSWORD,68,42,106,12,ES_PASSWORD | ES_AUTOHSCROLL CONTROL "Do not open chat windows on creation",IDC_HIDECHATS, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,61,285,10 - PUSHBUTTON "Sign in/sign up using phone",IDC_REGISTER,163,79,142,14 + GROUPBOX "Advanced",IDC_STATIC,4,75,302,77 + LTEXT "After this number of seconds set offline contact to the following status (0 - disabled)",IDC_STATIC,12,88,204,23,0,WS_EX_DLGMODALFRAME + EDITTEXT IDC_DIFF1,221,85,54,12,ES_AUTOHSCROLL + CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,275,84,11,14 + COMBOBOX IDC_STATUS1,221,100,81,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "After that. set offline contact to the following status after this number of seconds (0 - disabled)",IDC_STATIC,12,121,204,23,0,WS_EX_DLGMODALFRAME + EDITTEXT IDC_DIFF2,221,118,54,12,ES_AUTOHSCROLL + CONTROL "",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,275,117,11,14 + COMBOBOX IDC_STATUS2,221,133,81,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Sign in/sign up using phone",IDC_REGISTER,165,155,142,14 END IDD_GROUPCHAT_INVITE DIALOGEX 0, 0, 215, 263 @@ -123,7 +132,7 @@ BEGIN IDD_OPTIONS_FULL, DIALOG BEGIN - BOTTOMMARGIN, 81 + BOTTOMMARGIN, 169 END IDD_GROUPCHAT_INVITE, DIALOG diff --git a/protocols/ICQ-WIM/src/options.cpp b/protocols/ICQ-WIM/src/options.cpp index f948f64e21..dbac044638 100644 --- a/protocols/ICQ-WIM/src/options.cpp +++ b/protocols/ICQ-WIM/src/options.cpp @@ -155,6 +155,8 @@ void CIcqProto::OnLoginViaPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pRe class CIcqOptionsDlg : public CProtoDlgBase<CIcqProto> { CCtrlEdit edtUin, edtEmail, edtPassword; + CCtrlSpin spin1, spin2; + CCtrlCombo cmbStatus1, cmbStatus2; CCtrlCheck chkHideChats; CCtrlButton btnCreate; CMStringW wszOldPass; @@ -162,9 +164,13 @@ class CIcqOptionsDlg : public CProtoDlgBase<CIcqProto> public: CIcqOptionsDlg(CIcqProto *ppro, int iDlgID, bool bFullDlg) : CProtoDlgBase<CIcqProto>(ppro, iDlgID), + spin1(this, IDC_SPIN1), + spin2(this, IDC_SPIN2), edtUin(this, IDC_UIN), edtEmail(this, IDC_EMAIL), btnCreate(this, IDC_REGISTER), + cmbStatus1(this, IDC_STATUS1), + cmbStatus2(this, IDC_STATUS2), edtPassword(this, IDC_PASSWORD), chkHideChats(this, IDC_HIDECHATS) { @@ -173,14 +179,34 @@ public: CreateLink(edtUin, ppro->m_dwUin); CreateLink(edtEmail, ppro->m_szEmail); CreateLink(edtPassword, ppro->m_szPassword); - if (bFullDlg) + if (bFullDlg) { + CreateLink(spin1, ppro->m_iTimeDiff1); + CreateLink(spin2, ppro->m_iTimeDiff2); CreateLink(chkHideChats, ppro->m_bHideGroupchats); + } wszOldPass = ppro->m_szPassword; } bool OnInitDialog() override { + if (cmbStatus1.GetHwnd()) { + for (int iStatus = ID_STATUS_OFFLINE; iStatus <= ID_STATUS_OUTTOLUNCH; iStatus++) { + int idx = cmbStatus1.AddString(Clist_GetStatusModeDescription(iStatus, 0)); + cmbStatus1.SetItemData(idx, iStatus); + if (iStatus == m_proto->m_iStatus1) + cmbStatus1.SetCurSel(idx); + + idx = cmbStatus2.AddString(Clist_GetStatusModeDescription(iStatus, 0)); + cmbStatus2.SetItemData(idx, iStatus); + if (iStatus == m_proto->m_iStatus2) + cmbStatus2.SetCurSel(idx); + + spin1.SetRange(3600); + spin2.SetRange(3600); + } + } + if (m_proto->m_dwUin == 0) edtUin.SetText(L""); return true; @@ -188,6 +214,11 @@ public: bool OnApply() override { + if (cmbStatus1.GetHwnd()) { + m_proto->m_iStatus1 = cmbStatus1.GetItemData(cmbStatus1.GetCurSel()); + m_proto->m_iStatus2 = cmbStatus2.GetItemData(cmbStatus2.GetCurSel()); + } + if (wszOldPass != ptrW(edtPassword.GetText())) { m_proto->delSetting(DB_KEY_ATOKEN); m_proto->delSetting(DB_KEY_SESSIONKEY); diff --git a/protocols/ICQ-WIM/src/poll.cpp b/protocols/ICQ-WIM/src/poll.cpp index 3d987b334b..e6553c1f51 100644 --- a/protocols/ICQ-WIM/src/poll.cpp +++ b/protocols/ICQ-WIM/src/poll.cpp @@ -192,7 +192,22 @@ void CIcqProto::ProcessPresence(const JSONNode &ev) IcqCacheItem *pCache = FindContactByUIN(dwUin); if (pCache) { - setDword(pCache->m_hContact, "Status", StatusFromString(ev["state"].as_mstring())); + int iNewStatus = StatusFromString(ev["state"].as_mstring()); + + // major crutch dedicated to the official client behaviour to go offline + // when its window gets closed. we don't really change the status of a contact + // but initialize a timer instead + if (iNewStatus == ID_STATUS_OFFLINE) { + if (m_iTimeDiff1) + pCache->m_timer1 = time(0); + else + setDword(pCache->m_hContact, "Status", iNewStatus); + } + // if a client returns back online, we clear timers not to play with statuses anymore + else { + pCache->m_timer1 = pCache->m_timer2 = 0; + setDword(pCache->m_hContact, "Status", iNewStatus); + } Json2string(pCache->m_hContact, ev, "friendly", "Nick"); CheckAvatarChange(pCache->m_hContact, ev); diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp index 38d65bf345..2e225891c4 100644 --- a/protocols/ICQ-WIM/src/proto.cpp +++ b/protocols/ICQ-WIM/src/proto.cpp @@ -42,6 +42,10 @@ CIcqProto::CIcqProto(const char* aProtoName, const wchar_t* aUserName) : m_evRequestsQueue(CreateEvent(nullptr, FALSE, FALSE, nullptr)), m_dwUin(this, DB_KEY_UIN, 0), m_szEmail(this, "Email"), + m_iStatus1(this, "Status1", ID_STATUS_AWAY), + m_iStatus2(this, "Status2", ID_STATUS_NA), + m_iTimeDiff1(this, "TimeDiff1", 0), + m_iTimeDiff2(this, "TimeDiff2", 0), m_szPassword(this, "Password"), m_bHideGroupchats(this, "HideChats", 1) { diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h index 7fe801df0b..c9fb72f146 100644 --- a/protocols/ICQ-WIM/src/proto.h +++ b/protocols/ICQ-WIM/src/proto.h @@ -55,6 +55,7 @@ struct IcqCacheItem MCONTACT m_hContact; bool m_bInList = false; int m_iApparentMode; + time_t m_timer1, m_timer2; }; struct IcqOwnMessage @@ -311,7 +312,12 @@ public: CMOption<wchar_t*> m_szEmail; // email, if present CMOption<wchar_t*> m_szPassword; // password, if present CMOption<BYTE> m_bHideGroupchats; // don't pop up group chat windows on startup + CMOption<DWORD> m_iTimeDiff1; // set this status to m_iStatus1 after this interval of secs + CMOption<DWORD> m_iStatus1; + CMOption<DWORD> m_iTimeDiff2; // set this status to m_iStatus2 after this interval of secs + CMOption<DWORD> m_iStatus2; + void CheckStatus(void); CMStringA GetUserId(MCONTACT); int __cdecl OnContactMenu(WPARAM, LPARAM); diff --git a/protocols/ICQ-WIM/src/resource.h b/protocols/ICQ-WIM/src/resource.h index b38a314f8f..c62742adb3 100644 --- a/protocols/ICQ-WIM/src/resource.h +++ b/protocols/ICQ-WIM/src/resource.h @@ -7,7 +7,7 @@ #define IDD_GROUPCHAT_INVITE 103 #define IDD_INFO_ICQ 104 #define IDD_REGISTER 105 -#define IDD_EDITIGNORE 106 +#define IDD_EDITIGNORE 106 #define IDC_PASSWORD 1001 #define IDC_UIN 1002 #define IDC_UIN2 1003 @@ -24,15 +24,21 @@ #define IDC_MEMBERSINCE 1013 #define IDC_LASTSEEN 1014 #define IDC_EMAIL 1015 -#define IDC_LIST 1016 +#define IDC_LIST 1016 +#define IDC_DIFF1 1017 +#define IDC_SPIN1 1018 +#define IDC_STATUS1 1019 +#define IDC_DIFF2 1023 +#define IDC_SPIN2 1024 +#define IDC_STATUS2 1025 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_RESOURCE_VALUE 109 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1017 +#define _APS_NEXT_CONTROL_VALUE 1020 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp index 9f7a36ef15..c7f7bb3c05 100644 --- a/protocols/ICQ-WIM/src/server.cpp +++ b/protocols/ICQ-WIM/src/server.cpp @@ -97,6 +97,26 @@ void CIcqProto::CheckPassword() else StartSession(); } +void CIcqProto::CheckStatus() +{ + time_t now = time(0); + int diff1 = m_iTimeDiff1, diff2 = m_iTimeDiff2; + + for (auto &it : m_arCache) { + if (diff2 && it->m_timer2 && now - it->m_timer2 > m_iTimeDiff2) { + it->m_timer2 = 0; + setDword(it->m_hContact, "Status", m_iStatus2); + continue; + } + + if (diff1 && it->m_timer1 && now - it->m_timer1 > diff1) { + setDword(it->m_hContact, "Status", m_iStatus1); + it->m_timer1 = 0; + it->m_timer2 = now; + } + } +} + void CIcqProto::ConnectionFailed(int iReason, int iErrorCode) { debugLogA("ConnectionFailed -> reason %d", iReason); @@ -136,26 +156,47 @@ void CIcqProto::MoveContactToGroup(MCONTACT hContact, const wchar_t *pwszGroup, Push(pReq); } +///////////////////////////////////////////////////////////////////////////////////////// + +static void CALLBACK CheckStatusTimerProc(HWND, UINT, UINT_PTR id, DWORD) +{ + CIcqProto *ppro = (CIcqProto*)(id - 1); + ppro->CheckStatus(); +} + void CIcqProto::OnLoggedIn() { debugLogA("CIcqProto::OnLoggedIn"); m_bOnline = true; + + ::SetTimer(g_hwndHeartbeat, UINT_PTR(this)+1, 1000, CheckStatusTimerProc); + for (auto &it : m_arCache) + it->m_timer1 = it->m_timer2 = 0; + SetServerStatus(m_iDesiredStatus); RetrieveUserInfo(0); GetPermitDeny(); } +///////////////////////////////////////////////////////////////////////////////////////// + void CIcqProto::OnLoggedOut() { debugLogA("CIcqProto::OnLoggedOut"); m_bOnline = false; + ::KillTimer(g_hwndHeartbeat, UINT_PTR(this)+1); + for (auto &it : m_arCache) + it->m_timer1 = it->m_timer2 = 0; + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE); m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; setAllContactStatuses(ID_STATUS_OFFLINE, false); } +///////////////////////////////////////////////////////////////////////////////////////// + MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact) { // user chat? diff --git a/protocols/ICQ-WIM/src/utils.cpp b/protocols/ICQ-WIM/src/utils.cpp index a962cb6a3c..afebaba7f4 100644 --- a/protocols/ICQ-WIM/src/utils.cpp +++ b/protocols/ICQ-WIM/src/utils.cpp @@ -226,15 +226,15 @@ bool IsChat(const CMStringW &aimid) int StatusFromString(const CMStringW &wszStatus) { - if (wszStatus == "online") + if (wszStatus == L"online") return ID_STATUS_ONLINE; - if (wszStatus == "n/a") + if (wszStatus == L"n/a") return ID_STATUS_NA; - if (wszStatus == "away") + if (wszStatus == L"away") return ID_STATUS_AWAY; - if (wszStatus == "occupied") + if (wszStatus == L"occupied") return ID_STATUS_OCCUPIED; - if (wszStatus == "dnd") + if (wszStatus == L"dnd") return ID_STATUS_DND; return ID_STATUS_OFFLINE; |