From 951bd950ea3a9270008bc606dd83698663b2be27 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 20 Jan 2025 19:18:21 +0300 Subject: Steam: mentions in group chats --- protocols/Steam/src/steam_chats.cpp | 29 ++++++++++++------- protocols/Steam/src/steam_utils.cpp | 55 +++++++++++++++++++++++++++++++++++++ protocols/Steam/src/steam_utils.h | 3 ++ 3 files changed, 77 insertions(+), 10 deletions(-) (limited to 'protocols/Steam/src') diff --git a/protocols/Steam/src/steam_chats.cpp b/protocols/Steam/src/steam_chats.cpp index a425fc8aca..8daa77cd53 100644 --- a/protocols/Steam/src/steam_chats.cpp +++ b/protocols/Steam/src/steam_chats.cpp @@ -138,12 +138,15 @@ void CSteamProto::OnGetChatHistory(const CChatRoomGetMessageHistoryResponse &rep mir_snprintf(szMsgId, "%d_%d", iChatId, pMsg->server_timestamp); _i64toa(AccountIdToSteamId(pMsg->sender), szUserId, 10); + CMStringA szText(pMsg->message); + DecodeBbcodes(si, szText); + DB::EventInfo dbei(db_event_getById(m_szModuleName, szMsgId)); dbei.flags |= DBEF_UTF; dbei.eventType = EVENTTYPE_MESSAGE; dbei.szModule = m_szModuleName; - replaceStr(dbei.pBlob, mir_strdup(pMsg->message)); - dbei.cbBlob = (int)mir_strlen(dbei.pBlob); + dbei.cbBlob = szText.GetLength(); + replaceStr(dbei.pBlob, szText.Detach()); dbei.iTimestamp = pMsg->server_timestamp; dbei.szId = szMsgId; dbei.szUserId = szUserId; @@ -171,12 +174,15 @@ void CSteamProto::OnGetChatMessage(const CChatRoomIncomingChatMessageNotificatio mir_snprintf(szMsgId, "%lld_%d", reply.chat_id, reply.timestamp); _i64toa(reply.steamid_sender, szUserId, 10); + CMStringA szText(reply.message); + DecodeBbcodes(si, szText); + DB::EventInfo dbei(db_event_getById(m_szModuleName, szMsgId)); dbei.flags |= DBEF_UTF; dbei.eventType = EVENTTYPE_MESSAGE; dbei.szModule = m_szModuleName; - replaceStr(dbei.pBlob, mir_strdup(reply.message)); - dbei.cbBlob = (int)mir_strlen(dbei.pBlob); + dbei.cbBlob = szText.GetLength(); + replaceStr(dbei.pBlob, szText.Detach()); dbei.iTimestamp = reply.timestamp; dbei.szId = szMsgId; dbei.szUserId = szUserId; @@ -229,20 +235,23 @@ int CSteamProto::GcEventHook(WPARAM, LPARAM lParam) if (gch == nullptr) return 0; - if (mir_strcmpi(gch->si->pszModule, m_szModuleName)) + auto *si = gch->si; + if (mir_strcmpi(si->pszModule, m_szModuleName)) return 0; switch (gch->iType) { case GC_USER_MESSAGE: if (gch->ptszText && mir_wstrlen(gch->ptszText) > 0) { - rtrimw(gch->ptszText); - T2Utf szMessage(gch->ptszText); + CMStringW wszText(gch->ptszText); + wszText.TrimRight(); + EncodeBbcodes(si, wszText); + T2Utf szText(wszText); CChatRoomSendChatMessageRequest request; - request.chat_group_id = _wtoi64(gch->si->ptszID); request.has_chat_group_id = true; - request.chat_id = getDword(gch->si->hContact, "ChatId"); request.has_chat_id = true; + request.chat_group_id = _wtoi64(si->ptszID); request.has_chat_group_id = true; + request.chat_id = getDword(si->hContact, "ChatId"); request.has_chat_id = true; request.echo_to_sender = request.has_echo_to_sender = true; - request.message = szMessage; + request.message = szText; WSSendService(SendChatMessage, request); } break; diff --git a/protocols/Steam/src/steam_utils.cpp b/protocols/Steam/src/steam_utils.cpp index 2b8c3263db..235da7a173 100644 --- a/protocols/Steam/src/steam_utils.cpp +++ b/protocols/Steam/src/steam_utils.cpp @@ -20,6 +20,61 @@ bool IsNull(const ProtobufCBinaryData &buf) ///////////////////////////////////////////////////////////////////////////////////////// +void EncodeBbcodes(SESSION_INFO *si, CMStringW &wszText) +{ + int idx = wszText.Find(':'); + if (idx != -1) { + CMStringW wszNick(wszText.Left(idx)); + for (auto &it : si->getUserList()) { + if (wszNick == it->pszNick) { + wszText.Delete(0, idx+1); + + CMStringW wszReplace(FORMAT, L"[mention=%lld]@%s[/mention]", SteamIdToAccountId(_wtoi64(it->pszUID)), it->pszNick); + wszText = wszReplace + wszText; + break; + } + } + } +} + +void DecodeBbcodes(SESSION_INFO *si, CMStringA &szText) +{ + for (int idx = 0; idx != -1; idx = szText.Find('[', idx+1)) { + bool isClosing = false; + idx++; + if (szText[idx] == '/') { + isClosing = true; + idx++; + } + + int iEnd = szText.Find(']', idx + 1); + if (iEnd == -1) + return; + + if (!isClosing) { + auto *p = szText.c_str() + idx; + if (!strncmp(p, "mention=", 8)) { + CMStringW wszId(FORMAT, L"%lld", AccountIdToSteamId(_atoi64(p + 8))); + if (auto *pUser = g_chatApi.UM_FindUser(si, wszId)) { + int iEnd2 = szText.Find("[/mention]", iEnd); + if (iEnd2 == -1) + return; + + szText.Delete(idx - 1, iEnd2 - idx + 11); + szText.Insert(0, ":"); + szText.Insert(0, T2Utf(pUser->pszNick)); + continue; + } + } + } + + szText.Delete(idx - 1, iEnd - idx + 1); + idx = iEnd; + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + MBinBuffer createMachineID(const char *accName) { uint8_t hashOut[MIR_SHA1_HASH_SIZE]; diff --git a/protocols/Steam/src/steam_utils.h b/protocols/Steam/src/steam_utils.h index b183837a78..91b0baf311 100644 --- a/protocols/Steam/src/steam_utils.h +++ b/protocols/Steam/src/steam_utils.h @@ -10,6 +10,9 @@ void ShowNotification(const wchar_t *caption, const wchar_t *message, int flags MBinBuffer RsaEncrypt(const char *pszModulus, const char *exponent, const char *data); MBinBuffer createMachineID(const char *accName); +void EncodeBbcodes(SESSION_INFO *si, CMStringW &szText); +void DecodeBbcodes(SESSION_INFO *si, CMStringA &szText); + #define now() time(0) bool IsNull(const ProtobufCBinaryData &buf); -- cgit v1.2.3