summaryrefslogtreecommitdiff
path: root/protocols/ICQ-WIM
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2023-03-13 20:00:04 +0300
committerGeorge Hazan <ghazan@miranda.im>2023-03-13 20:00:04 +0300
commit15da86e11646f0465febbc6cd1eb29864abacfe6 (patch)
tree07cc3712d368b41daa19238baf74f17c352d71ec /protocols/ICQ-WIM
parent5bf9848f7ca25a4844075e44b3e76e8981092169 (diff)
fixes #3426 (ICQ: не обрабатывается событие исключения из чата)
Diffstat (limited to 'protocols/ICQ-WIM')
-rw-r--r--protocols/ICQ-WIM/src/groupchats.cpp12
-rw-r--r--protocols/ICQ-WIM/src/ignore.cpp6
-rw-r--r--protocols/ICQ-WIM/src/poll.cpp44
-rw-r--r--protocols/ICQ-WIM/src/proto.cpp18
-rw-r--r--protocols/ICQ-WIM/src/proto.h10
-rw-r--r--protocols/ICQ-WIM/src/server.cpp61
-rw-r--r--protocols/ICQ-WIM/src/utils.cpp20
7 files changed, 98 insertions, 73 deletions
diff --git a/protocols/ICQ-WIM/src/groupchats.cpp b/protocols/ICQ-WIM/src/groupchats.cpp
index 42c1b21c64..0e4bbb1a53 100644
--- a/protocols/ICQ-WIM/src/groupchats.cpp
+++ b/protocols/ICQ-WIM/src/groupchats.cpp
@@ -246,14 +246,14 @@ void CIcqProto::Chat_ProcessLogMenu(SESSION_INFO *si, int iChoice)
void CIcqProto::Chat_SendPrivateMessage(GCHOOK *gch)
{
MCONTACT hContact;
- auto *pCache = FindContactByUIN(gch->ptszUID);
- if (pCache == nullptr) {
+ auto *pUser = FindUser(gch->ptszUID);
+ if (pUser == nullptr) {
hContact = CreateContact(gch->ptszUID, true);
setWString(hContact, "Nick", gch->ptszNick);
Contact::Hide(hContact);
db_set_dw(hContact, "Ignore", "Mask1", 0);
}
- else hContact = pCache->m_hContact;
+ else hContact = pUser->m_hContact;
CallService(MS_MSG_SENDMESSAGE, hContact, 0);
}
@@ -276,11 +276,11 @@ void CIcqProto::ProcessGroupChat(const JSONNode &ev)
if (member.IsEmpty())
break;
- auto *pCache = FindContactByUIN(member);
- if (pCache == nullptr)
+ auto *pUser = FindUser(member);
+ if (pUser == nullptr)
continue;
- gce.pszNick.w = Clist_GetContactDisplayName(pCache->m_hContact);
+ gce.pszNick.w = Clist_GetContactDisplayName(pUser->m_hContact);
gce.pszUID.w = member;
gce.time = ::time(0);
gce.bIsMe = member == m_szOwnId;
diff --git a/protocols/ICQ-WIM/src/ignore.cpp b/protocols/ICQ-WIM/src/ignore.cpp
index a2ce8c098f..7d64edceba 100644
--- a/protocols/ICQ-WIM/src/ignore.cpp
+++ b/protocols/ICQ-WIM/src/ignore.cpp
@@ -41,7 +41,7 @@ void CIcqProto::ProcessPermissions(const JSONNode &ev)
}
for (auto &it : ev["allows"]) {
- auto *p = FindContactByUIN(it.as_mstring());
+ auto *p = FindUser(it.as_mstring());
if (p)
p->m_iApparentMode = ID_STATUS_ONLINE;
}
@@ -49,10 +49,10 @@ void CIcqProto::ProcessPermissions(const JSONNode &ev)
m_bIgnoreListEmpty = true;
for (auto &it : ev["ignores"]) {
CMStringW wszId(it.as_mstring());
- auto *p = FindContactByUIN(wszId);
+ auto *p = FindUser(wszId);
if (p == nullptr) {
CreateContact(wszId, false);
- p = FindContactByUIN(wszId);
+ p = FindUser(wszId);
}
p->m_iApparentMode = ID_STATUS_OFFLINE;
Contact::Hide(p->m_hContact);
diff --git a/protocols/ICQ-WIM/src/poll.cpp b/protocols/ICQ-WIM/src/poll.cpp
index c6c7d0b2e0..b7cd908ea2 100644
--- a/protocols/ICQ-WIM/src/poll.cpp
+++ b/protocols/ICQ-WIM/src/poll.cpp
@@ -164,7 +164,7 @@ void CIcqProto::ProcessHistData(const JSONNode &ev)
bool bVeryBeginning = m_bFirstBos;
CMStringW wszId(ev["sn"].as_mstring());
- auto *pCache = FindContactByUIN(wszId); // might be NULL for groupchats
+ auto *pUser = FindUser(wszId); // might be NULL for groupchats
if (IsChat(wszId)) {
SESSION_INFO *si = Chat_Find(wszId, m_szModuleName);
@@ -189,9 +189,9 @@ void CIcqProto::ProcessHistData(const JSONNode &ev)
hContact = CreateContact(wszId, true);
// for temporary contacts that just gonna be created
- if (pCache == nullptr) {
+ if (pUser == nullptr) {
bVeryBeginning = true;
- pCache = FindContactByUIN(wszId);
+ pUser = FindUser(wszId);
}
}
@@ -209,9 +209,9 @@ void CIcqProto::ProcessHistData(const JSONNode &ev)
// we load history in the very beginning or if the previous message
if (bVeryBeginning) {
- if (pCache) {
+ if (pUser) {
debugLogA("Setting cache = %lld for %d", srvLastId, hContact);
- pCache->m_iProcessedMsgId = srvLastId;
+ pUser->m_iProcessedMsgId = srvLastId;
}
if (srvLastId > lastMsgId) {
@@ -220,9 +220,9 @@ void CIcqProto::ProcessHistData(const JSONNode &ev)
}
}
else {
- if (!(pCache && pCache->m_iProcessedMsgId >= srvLastId)) {
- if (pCache)
- debugLogA("Proceeding with cache for %d: %lld < %lld", hContact, pCache->m_iProcessedMsgId, srvLastId);
+ if (!(pUser && pUser->m_iProcessedMsgId >= srvLastId)) {
+ if (pUser)
+ debugLogA("Proceeding with cache for %d: %lld < %lld", hContact, pUser->m_iProcessedMsgId, srvLastId);
else
debugLogA("Proceeding with empty cache for %d", hContact);
@@ -230,8 +230,8 @@ void CIcqProto::ProcessHistData(const JSONNode &ev)
ParseMessage(hContact, lastMsgId, it, false, true);
setId(hContact, DB_KEY_LASTMSGID, lastMsgId);
- if (pCache) {
- pCache->m_iProcessedMsgId = lastMsgId;
+ if (pUser) {
+ pUser->m_iProcessedMsgId = lastMsgId;
debugLogA("Setting second cache = %lld for %d", srvLastId, hContact);
}
}
@@ -317,11 +317,11 @@ void CIcqProto::ProcessPresence(const JSONNode &ev)
{
CMStringW aimId = ev["aimId"].as_mstring();
- IcqCacheItem *pCache = FindContactByUIN(aimId);
- if (pCache == nullptr)
+ auto *pUser = FindUser(aimId);
+ if (pUser == nullptr)
return;
- int iNewStatus = StatusFromPresence(ev, pCache->m_hContact);
+ int iNewStatus = StatusFromPresence(ev, pUser->m_hContact);
if (iNewStatus == -1)
iNewStatus = ID_STATUS_OFFLINE;
@@ -331,16 +331,16 @@ void CIcqProto::ProcessPresence(const JSONNode &ev)
if (iNewStatus == ID_STATUS_OFFLINE) {
if (m_iTimeDiff1) {
iNewStatus = m_iStatus1;
- pCache->m_timer1 = time(0);
+ pUser->m_timer1 = time(0);
}
}
// if a client returns back online, we clear timers not to play with statuses anymore
- else pCache->m_timer1 = pCache->m_timer2 = 0;
+ else pUser->m_timer1 = pUser->m_timer2 = 0;
- setWord(pCache->m_hContact, "Status", iNewStatus);
+ setWord(pUser->m_hContact, "Status", iNewStatus);
- Json2string(pCache->m_hContact, ev, "friendly", "Nick", true);
- CheckAvatarChange(pCache->m_hContact, ev);
+ Json2string(pUser->m_hContact, ev, "friendly", "Nick", true);
+ CheckAvatarChange(pUser->m_hContact, ev);
}
void CIcqProto::ProcessSessionEnd(const JSONNode &/*ev*/)
@@ -357,12 +357,12 @@ void CIcqProto::ProcessTyping(const JSONNode &ev)
CMStringW aimId = ev["aimId"].as_mstring();
CMStringW wszStatus = ev["typingStatus"].as_mstring();
- IcqCacheItem *pCache = FindContactByUIN(aimId);
- if (pCache) {
+ auto *pUser = FindUser(aimId);
+ if (pUser) {
if (wszStatus == "typing")
- CallService(MS_PROTO_CONTACTISTYPING, pCache->m_hContact, 60);
+ CallService(MS_PROTO_CONTACTISTYPING, pUser->m_hContact, 60);
else
- CallService(MS_PROTO_CONTACTISTYPING, pCache->m_hContact, PROTOTYPE_CONTACTTYPING_OFF);
+ CallService(MS_PROTO_CONTACTISTYPING, pUser->m_hContact, PROTOTYPE_CONTACTTYPING_OFF);
}
}
diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp
index 41cd2119fb..1e6ffb5ada 100644
--- a/protocols/ICQ-WIM/src/proto.cpp
+++ b/protocols/ICQ-WIM/src/proto.cpp
@@ -33,7 +33,7 @@
#pragma warning(disable:4355)
-static int CompareCache(const IcqCacheItem *p1, const IcqCacheItem *p2)
+static int CompareCache(const IcqUser *p1, const IcqUser *p2)
{
return mir_wstrcmp(p1->m_aimid, p2->m_aimid);
}
@@ -145,9 +145,9 @@ void CIcqProto::OnShutdown()
void CIcqProto::OnContactAdded(MCONTACT hContact)
{
CMStringW wszId(getMStringW(hContact, DB_KEY_ID));
- if (!wszId.IsEmpty() && !FindContactByUIN(wszId)) {
+ if (!wszId.IsEmpty() && !FindUser(wszId)) {
mir_cslock l(m_csCache);
- m_arCache.insert(new IcqCacheItem(wszId, hContact));
+ m_arCache.insert(new IcqUser(wszId, hContact));
}
}
@@ -155,7 +155,7 @@ void CIcqProto::OnContactDeleted(MCONTACT hContact)
{
CMStringW szId(GetUserId(hContact));
if (!isChatRoom(hContact))
- m_arCache.remove(FindContactByUIN(szId));
+ m_arCache.remove(FindUser(szId));
Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, ICQ_API_SERVER "/buddylist/removeBuddy")
<< AIMSID(this) << WCHAR_PARAM("buddy", szId) << INT_PARAM("allGroups", 1));
@@ -239,7 +239,7 @@ void CIcqProto::SendMarkRead()
{
mir_cslock lck(m_csMarkReadQueue);
while (m_arMarkReadQueue.getCount()) {
- IcqCacheItem *pUser = m_arMarkReadQueue[0];
+ auto *pUser = m_arMarkReadQueue[0];
auto *pReq = new AsyncRapiRequest(this, "setDlgStateWim");
pReq->params << WCHAR_PARAM("sn", GetUserId(pUser->m_hContact)) << INT64_PARAM("lastRead", getId(pUser->m_hContact, DB_KEY_LASTMSGID));
@@ -256,11 +256,11 @@ void CIcqProto::OnMarkRead(MCONTACT hContact, MEVENT)
m_impl.m_markRead.Start(200);
- auto *pCache = FindContactByUIN(GetUserId(hContact));
- if (pCache) {
+ auto *pUser = FindUser(GetUserId(hContact));
+ if (pUser) {
mir_cslock lck(m_csMarkReadQueue);
- if (m_arMarkReadQueue.indexOf(pCache) == -1)
- m_arMarkReadQueue.insert(pCache);
+ if (m_arMarkReadQueue.indexOf(pUser) == -1)
+ m_arMarkReadQueue.insert(pUser);
}
}
diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h
index f36f6911ab..75e33ef5c2 100644
--- a/protocols/ICQ-WIM/src/proto.h
+++ b/protocols/ICQ-WIM/src/proto.h
@@ -107,9 +107,9 @@ struct IcqGroup
}
};
-struct IcqCacheItem : public MZeroedObject
+struct IcqUser : public MZeroedObject
{
- IcqCacheItem(const CMStringW &wszId, MCONTACT _contact) :
+ IcqUser(const CMStringW &wszId, MCONTACT _contact) :
m_aimid(wszId),
m_hContact(_contact)
{}
@@ -282,7 +282,7 @@ class CIcqProto : public PROTO<CIcqProto>
void OnLoggedOut(void);
mir_cs m_csMarkReadQueue;
- LIST<IcqCacheItem> m_arMarkReadQueue;
+ LIST<IcqUser> m_arMarkReadQueue;
void SendMarkRead();
__int64 getId(MCONTACT hContact, const char *szSetting);
@@ -383,10 +383,10 @@ class CIcqProto : public PROTO<CIcqProto>
// cache
mir_cs m_csCache;
- OBJLIST<IcqCacheItem> m_arCache;
+ OBJLIST<IcqUser> m_arCache;
void InitContactCache(void);
- IcqCacheItem* FindContactByUIN(const CMStringW &pwszId);
+ IcqUser* FindUser(const CMStringW &pwszId);
MCONTACT CreateContact(const CMStringW &pwszId, bool bTemporary);
void GetAvatarFileName(MCONTACT hContact, wchar_t *pszDest, size_t cbLen);
diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp
index 918ee2d119..818807d3ea 100644
--- a/protocols/ICQ-WIM/src/server.cpp
+++ b/protocols/ICQ-WIM/src/server.cpp
@@ -277,8 +277,8 @@ MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact, boo
CMStringW wszChatId(buddy["aimId"].as_mstring());
CMStringW wszChatName(buddy["friendly"].as_mstring());
- auto *pContact = FindContactByUIN(wszId);
- if (pContact && pContact->m_iApparentMode == ID_STATUS_OFFLINE)
+ auto *pUser = FindUser(wszId);
+ if (pUser && pUser->m_iApparentMode == ID_STATUS_OFFLINE)
return INVALID_CONTACT_ID;
auto *si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, wszChatId, wszChatName);
@@ -298,7 +298,7 @@ MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact, boo
return INVALID_CONTACT_ID;
hContact = CreateContact(wszId, false);
- FindContactByUIN(wszId)->m_bInList = true;
+ FindUser(wszId)->m_bInList = true;
}
else if (bIgnored) {
db_delete_contact(hContact, true);
@@ -424,6 +424,8 @@ void CIcqProto::ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNo
if (msgId > lastMsgId)
lastMsgId = msgId;
+ int iMsgTime = (bLocalTime) ? time(0) : it["time"].as_int();
+
CMStringW wszText;
const JSONNode &sticker = it["sticker"];
if (sticker) {
@@ -439,25 +441,48 @@ void CIcqProto::ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNo
wszText = it["text"].as_mstring();
wszText.TrimRight();
- // user added you
- if (it["class"].as_mstring() == L"event" && it["eventTypeId"].as_mstring() == L"27:33000") {
- if (bLocalTime) {
- CMStringA id = getMStringA(hContact, DB_KEY_ID);
- int pos = id.Find('@');
- CMStringA nick = (pos == -1) ? id : id.Left(pos);
- DB::AUTH_BLOB blob(hContact, nick, nullptr, nullptr, id, nullptr);
-
- PROTORECVEVENT pre = {};
- pre.timestamp = (uint32_t)time(0);
- pre.lParam = blob.size();
- pre.szMessage = blob;
- ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre);
+ if (it["class"].as_mstring() == L"event") {
+ // user added you
+ if (it["eventTypeId"].as_mstring() == L"27:33000") {
+ if (bLocalTime) {
+ CMStringA id = getMStringA(hContact, DB_KEY_ID);
+ int pos = id.Find('@');
+ CMStringA nick = (pos == -1) ? id : id.Left(pos);
+ DB::AUTH_BLOB blob(hContact, nick, nullptr, nullptr, id, nullptr);
+
+ PROTORECVEVENT pre = {};
+ pre.timestamp = (uint32_t)time(0);
+ pre.lParam = blob.size();
+ pre.szMessage = blob;
+ ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre);
+ }
+ return;
+ }
+
+ if (auto &pChat = it["chat"]) {
+ auto *si = Chat_Find(pChat["sender"].as_mstring(), m_szModuleName);
+ if (si == nullptr)
+ return;
+
+ if (pChat["type"].as_string() == "group") {
+ if (pChat["memberEvent"]["type"].as_string() == "kicked") {
+ GCEVENT gce = {};
+ gce.si = si;
+ gce.time = iMsgTime;
+ gce.iType = GC_EVENT_KICK;
+
+ for (auto &jt : pChat["memberEvent"]["members"]) {
+ auto userId = jt.as_mstring();
+ gce.pszUID.w = userId;
+ Chat_Event(&gce);
+ }
+ }
+ }
+ return;
}
- return;
}
}
- int iMsgTime = (bLocalTime) ? time(0) : it["time"].as_int();
bool bIsOutgoing = it["outgoing"].as_bool(), bIsFileTransfer = false;
IcqFileInfo *pFileInfo = nullptr;
diff --git a/protocols/ICQ-WIM/src/utils.cpp b/protocols/ICQ-WIM/src/utils.cpp
index 6bfc868e96..bdaac877bf 100644
--- a/protocols/ICQ-WIM/src/utils.cpp
+++ b/protocols/ICQ-WIM/src/utils.cpp
@@ -43,18 +43,18 @@ void CIcqProto::InitContactCache()
}
CMStringW wszId = GetUserId(it);
- auto *pCache = FindContactByUIN(wszId);
- if (pCache == nullptr) {
- pCache = new IcqCacheItem(wszId, it);
- m_arCache.insert(pCache);
+ auto *pUser = FindUser(wszId);
+ if (pUser == nullptr) {
+ pUser = new IcqUser(wszId, it);
+ m_arCache.insert(pUser);
}
- pCache->m_iProcessedMsgId = getId(it, DB_KEY_LASTMSGID);
+ pUser->m_iProcessedMsgId = getId(it, DB_KEY_LASTMSGID);
}
}
-IcqCacheItem* CIcqProto::FindContactByUIN(const CMStringW &wszId)
+IcqUser* CIcqProto::FindUser(const CMStringW &wszId)
{
- IcqCacheItem tmp(wszId, -1);
+ IcqUser tmp(wszId, -1);
mir_cslock l(m_csCache);
return m_arCache.find(&tmp);
@@ -90,9 +90,9 @@ wchar_t* CIcqProto::GetUIN(MCONTACT hContact)
MCONTACT CIcqProto::CreateContact(const CMStringW &wszId, bool bTemporary)
{
- auto *pCache = FindContactByUIN(wszId);
- if (pCache != nullptr)
- return pCache->m_hContact;
+ auto *pUser = FindUser(wszId);
+ if (pUser != nullptr)
+ return pUser->m_hContact;
MCONTACT hContact = db_add_contact();
setWString(hContact, DB_KEY_ID, wszId);