summaryrefslogtreecommitdiff
path: root/protocols/IcqOscarJ
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2018-03-08 13:58:24 +0300
committerGeorge Hazan <ghazan@miranda.im>2018-03-08 13:58:31 +0300
commit6206d9efcead4e4cd92df1b6c9bb0150d13052cc (patch)
tree780e6bee288a40d65886d374af6a116a0dc89ea7 /protocols/IcqOscarJ
parent7b5a7da18a7834e9eb3aaa25cad0f256491c90ee (diff)
fixes #1154 (Invisible" status is broken)
This reverts commit 1ca493fc7af16dd20ad13453fc19774da3c65181.
Diffstat (limited to 'protocols/IcqOscarJ')
-rw-r--r--protocols/IcqOscarJ/src/fam_01service.cpp3
-rw-r--r--protocols/IcqOscarJ/src/fam_15icqserver.cpp17
-rw-r--r--protocols/IcqOscarJ/src/icq_proto.cpp20
-rw-r--r--protocols/IcqOscarJ/src/icq_proto.h1
-rw-r--r--protocols/IcqOscarJ/src/icq_xstatus.cpp24
-rw-r--r--protocols/IcqOscarJ/src/utilities.cpp38
6 files changed, 102 insertions, 1 deletions
diff --git a/protocols/IcqOscarJ/src/fam_01service.cpp b/protocols/IcqOscarJ/src/fam_01service.cpp
index d6d6e821dc..c77b939f51 100644
--- a/protocols/IcqOscarJ/src/fam_01service.cpp
+++ b/protocols/IcqOscarJ/src/fam_01service.cpp
@@ -711,6 +711,9 @@ void CIcqProto::handleServUINSettings(int nPort, serverthread_info *info)
else
szMoodData[0] = '\0';
+ //! Tricky code, this ensures that the status note will be saved to the directory
+ SetStatusNote(szStatusNote, m_bGatewayMode ? 5000 : 2500, TRUE);
+
size_t wStatusNoteLen = mir_strlen(szStatusNote);
size_t wStatusMoodLen = mir_strlen(szMoodData);
size_t wSessionDataLen = (wStatusNoteLen ? wStatusNoteLen + 4 : 0) + 4 + wStatusMoodLen + 4;
diff --git a/protocols/IcqOscarJ/src/fam_15icqserver.cpp b/protocols/IcqOscarJ/src/fam_15icqserver.cpp
index 0bce60710f..3a58297543 100644
--- a/protocols/IcqOscarJ/src/fam_15icqserver.cpp
+++ b/protocols/IcqOscarJ/src/fam_15icqserver.cpp
@@ -857,6 +857,23 @@ void CIcqProto::parseDirectoryUserDetailsData(MCONTACT hContact, oscar_tlv_chain
writeDbInfoSettingTLVStringUtf(hContact, "About", cDetails, 0x186);
+ // if (hContact)
+ // writeDbInfoSettingTLVStringUtf(hContact, DBSETTING_STATUS_NOTE, cDetails, 0x226);
+ // else
+ if (!hContact) { // Owner contact needs special processing, in the database is current status note for the client
+ // We just received the last status note set on directory, if it differs call SetStatusNote() to
+ // ensure the directory will be updated (it should be in process anyway)
+ char *szClientStatusNote = getSettingStringUtf(hContact, DBSETTING_STATUS_NOTE, nullptr);
+ char *szDirectoryStatusNote = cDetails->getString(0x226, 1);
+
+ if (mir_strcmp(szClientStatusNote, szDirectoryStatusNote))
+ SetStatusNote(szClientStatusNote, 1000, TRUE);
+
+ // Release memory
+ SAFE_FREE(&szDirectoryStatusNote);
+ SAFE_FREE(&szClientStatusNote);
+ }
+
writeDbInfoSettingTLVByte(hContact, "PrivacyLevel", cDetails, 0x1F9);
if (!hContact) {
diff --git a/protocols/IcqOscarJ/src/icq_proto.cpp b/protocols/IcqOscarJ/src/icq_proto.cpp
index 16efe23929..25ba07ecd5 100644
--- a/protocols/IcqOscarJ/src/icq_proto.cpp
+++ b/protocols/IcqOscarJ/src/icq_proto.cpp
@@ -1505,6 +1505,12 @@ int __cdecl CIcqProto::SetStatus(int iNewStatus)
// New status is OFFLINE
if (nNewStatus == ID_STATUS_OFFLINE) { // for quick logoff
+ if (icqOnline()) { // set offline status note (otherwise the old will remain)
+ char *szOfflineNote = PrepareStatusNote(nNewStatus);
+ SetStatusNote(szOfflineNote, 0, FALSE);
+ SAFE_FREE(&szOfflineNote);
+ }
+
m_iDesiredStatus = nNewStatus;
if (hServerConn) { // Connected, Send disconnect packet
@@ -1557,6 +1563,11 @@ int __cdecl CIcqProto::SetStatus(int iNewStatus)
char *szStatusNote = PrepareStatusNote(nNewStatus);
+ //! This is a bit tricky, we do trigger status note change thread and then
+ // change the status note right away (this spares one packet) - so SetStatusNote()
+ // will only change User Details Directory
+ SetStatusNote(szStatusNote, 6000, FALSE);
+
if (m_iStatus == ID_STATUS_INVISIBLE) {
if (m_bSsiEnabled)
updateServVisibilityCode(3);
@@ -1730,8 +1741,15 @@ int __cdecl CIcqProto::SetAwayMsg(int status, const wchar_t* msg)
*ppszMsg = szNewUtf;
szNewUtf = nullptr;
- if ((m_iStatus == status) && icqOnline()) // update current status note
+ if ((m_iStatus == status) && icqOnline()) { // update current status note
+ char *szNote = *ppszMsg ? *ppszMsg : "";
+
+ BYTE bXStatus = getContactXStatus(NULL);
+ if (!bXStatus)
+ SetStatusNote(szNote, 1000, FALSE);
+
icq_sendSetAimAwayMsgServ(*ppszMsg);
+ }
}
SAFE_FREE(&szNewUtf);
diff --git a/protocols/IcqOscarJ/src/icq_proto.h b/protocols/IcqOscarJ/src/icq_proto.h
index 294fea1da5..004a7148ed 100644
--- a/protocols/IcqOscarJ/src/icq_proto.h
+++ b/protocols/IcqOscarJ/src/icq_proto.h
@@ -880,6 +880,7 @@ struct CIcqProto : public PROTO<CIcqProto>
char *setStatusNoteText, *setStatusMoodData;
void __cdecl SetStatusNoteThread(void *pArguments);
+ int SetStatusNote(const char *szStatusNote, DWORD dwDelay, int bForced);
int SetStatusMood(const char *szMoodData, DWORD dwDelay);
void writeDbInfoSettingTLVStringUtf(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv);
diff --git a/protocols/IcqOscarJ/src/icq_xstatus.cpp b/protocols/IcqOscarJ/src/icq_xstatus.cpp
index a06b0a1241..0a98def4bf 100644
--- a/protocols/IcqOscarJ/src/icq_xstatus.cpp
+++ b/protocols/IcqOscarJ/src/icq_xstatus.cpp
@@ -519,6 +519,30 @@ void CIcqProto::updateServerCustomStatus(int fullUpdate)
SetStatusMood(szMoodData, 1500);
}
+
+ char *szStatusNote = nullptr;
+
+ // use custom status message as status note
+ if (bXStatus && (m_bXStatusEnabled || m_bMoodsEnabled))
+ szStatusNote = getSettingStringUtf(NULL, DBSETTING_XSTATUS_MSG, "");
+ // retrieve standard status message (e.g. custom status set to none)
+ else {
+ char **pszMsg = MirandaStatusToAwayMsg(m_iStatus);
+ {
+ mir_cslock l(m_modeMsgsMutex);
+ if (pszMsg)
+ szStatusNote = null_strdup(*pszMsg);
+ }
+
+ // no default status message, set empty
+ if (!szStatusNote)
+ szStatusNote = null_strdup("");
+ }
+
+ if (szStatusNote)
+ SetStatusNote(szStatusNote, 1500, FALSE);
+
+ SAFE_FREE(&szStatusNote);
}
static LRESULT CALLBACK MessageEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
diff --git a/protocols/IcqOscarJ/src/utilities.cpp b/protocols/IcqOscarJ/src/utilities.cpp
index db1af286c9..97253e2cc1 100644
--- a/protocols/IcqOscarJ/src/utilities.cpp
+++ b/protocols/IcqOscarJ/src/utilities.cpp
@@ -1095,6 +1095,44 @@ void __cdecl CIcqProto::SetStatusNoteThread(void *pDelay)
}
+int CIcqProto::SetStatusNote(const char *szStatusNote, DWORD dwDelay, int bForce)
+{
+ int bChanged = FALSE;
+
+ // bForce is intended for login sequence - need to call this earlier than icqOnline()
+ // the process is delayed and icqOnline() is ready when needed inside SetStatusNoteThread()
+ if (!bForce && !icqOnline()) return bChanged;
+
+ // reuse generic critical section (used for cookies list and object variables locks)
+ mir_cslock l(cookieMutex);
+
+ if (!setStatusNoteText && (!m_bMoodsEnabled || !setStatusMoodData)) { // check if the status note was changed and if yes, create thread to change it
+ char *szCurrentStatusNote = getSettingStringUtf(NULL, DBSETTING_STATUS_NOTE, nullptr);
+
+ if (mir_strcmp(szCurrentStatusNote, szStatusNote)) { // status note was changed
+ // create thread to change status note on existing server connection
+ setStatusNoteText = null_strdup(szStatusNote);
+
+ if (dwDelay)
+ ForkThread(&CIcqProto::SetStatusNoteThread, (void*)dwDelay);
+ else // we cannot afford any delay, so do not run in separate thread
+ SetStatusNoteThread(nullptr);
+
+ bChanged = TRUE;
+ }
+ SAFE_FREE(&szCurrentStatusNote);
+ }
+ else { // only alter status note object with new status note, keep the thread waiting for execution
+ SAFE_FREE(&setStatusNoteText);
+ setStatusNoteText = null_strdup(szStatusNote);
+
+ bChanged = TRUE;
+ }
+
+ return bChanged;
+}
+
+
int CIcqProto::SetStatusMood(const char *szMoodData, DWORD dwDelay)
{
int bChanged = FALSE;