/* Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "stdafx.h" 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; } } } } ///////////////////////////////////////////////////////////////////////////////////////// struct BBCode { CMStringA szTag, szValue, szBody; std::map attrs; }; int parseBbcode(const char *p, BBCode &ret) { auto *pSave = p; while (isalpha(*p)) ret.szTag.AppendChar(*p++); // [tag=value][/tag] if (*p == '=') { while (*p && *p != ']') ret.szValue.AppendChar(*p++); if (*p != ']') return -1; } // [tag attr=value][/tag] else if (*p == ' ') { p++; while (*p != ']') { CMStringA szName, szValue; while (*p && *p != '=') szName.AppendChar(*p++); if (*p++ != '=') return -1; if (*p == '\"') { auto *p1 = strchr(++p, '\"'); if (p1 == nullptr) return -1; p++; szValue.Append(p, p1 - p); p = p1 + 1; } else { while (*p && *p != ' ' && *p != ']') szValue.AppendChar(*p++); if (*p == 0) return -1; } if (*p == ' ') p++; } } // [tag][/tag] else if (*p != ']') return -1; p++; // skip first ] CMStringA szClose = "[/" + ret.szTag + "]"; auto *pEnd = strstr(p, szClose); if (pEnd == nullptr) return -1; if (pEnd != p) ret.szValue.Append(p, pEnd - p); return pEnd + szClose.GetLength() - pSave; } void DecodeBbcodes(SESSION_INFO *si, CMStringA &szText) { for (int idx = szText.Find('['); idx != -1; idx = szText.Find('[', idx + 1)) { BBCode code; int iLength = parseBbcode(szText.c_str() + idx + 1, code) + 1; if (iLength == 0) continue; bool bPlaceFirst = false; CMStringA szReplace; if (code.szTag == "emoticon") szReplace.Format(":%s:", code.szValue.c_str()); else if (code.szTag == "sticker") szReplace.Format(":%s:", code.attrs["type"].c_str()); else if (code.szTag == "mention") { CMStringW wszId(FORMAT, L"%lld", AccountIdToSteamId(_atoi64(code.szValue))); if (auto *pUser = g_chatApi.UM_FindUser(si, wszId)) { szReplace.Format("%s:", T2Utf(pUser->pszNick).get()); bPlaceFirst = true; } } else if (code.szTag == "lobbyinvite") { szReplace = TranslateU("You were invited to play a game"); } else continue; szText.Delete(idx, iLength); if (!szReplace.IsEmpty()) { if (bPlaceFirst) szText = szReplace + szText; else szText.Insert(idx, szReplace); } } }