diff options
-rw-r--r-- | protocols/Steam/Steam.vcxproj | 1 | ||||
-rw-r--r-- | protocols/Steam/Steam.vcxproj.filters | 3 | ||||
-rw-r--r-- | protocols/Steam/src/steam_bbcodes.cpp | 139 | ||||
-rw-r--r-- | protocols/Steam/src/steam_utils.cpp | 85 |
4 files changed, 143 insertions, 85 deletions
diff --git a/protocols/Steam/Steam.vcxproj b/protocols/Steam/Steam.vcxproj index 445cb17cd3..160884db1b 100644 --- a/protocols/Steam/Steam.vcxproj +++ b/protocols/Steam/Steam.vcxproj @@ -79,6 +79,7 @@ <PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="src\steam_avatars.cpp" />
+ <ClCompile Include="src\steam_bbcodes.cpp" />
<ClCompile Include="src\steam_chats.cpp" />
<ClCompile Include="src\steam_contacts.cpp" />
<ClCompile Include="src\steam_crypt.cpp" />
diff --git a/protocols/Steam/Steam.vcxproj.filters b/protocols/Steam/Steam.vcxproj.filters index 73efa626bb..576ca61aa2 100644 --- a/protocols/Steam/Steam.vcxproj.filters +++ b/protocols/Steam/Steam.vcxproj.filters @@ -114,6 +114,9 @@ <ClCompile Include="src\steam_chats.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\steam_bbcodes.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\resource.h">
diff --git a/protocols/Steam/src/steam_bbcodes.cpp b/protocols/Steam/src/steam_bbcodes.cpp new file mode 100644 index 0000000000..662ef58b6c --- /dev/null +++ b/protocols/Steam/src/steam_bbcodes.cpp @@ -0,0 +1,139 @@ +/* +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 <http://www.gnu.org/licenses/>. +*/ + +#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<CMStringA, CMStringA> 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); + } + } +} diff --git a/protocols/Steam/src/steam_utils.cpp b/protocols/Steam/src/steam_utils.cpp index 7f1275add3..2b8c3263db 100644 --- a/protocols/Steam/src/steam_utils.cpp +++ b/protocols/Steam/src/steam_utils.cpp @@ -20,91 +20,6 @@ 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;
-
- bool bPlaceFirst = false;
- CMStringA szReplace;
-
- auto *p = szText.c_str() + idx;
- if (!strncmp(p, "emoticon", 8) || !strncmp(p, "sticker", 7))
- szReplace = ":";
-
- if (!isClosing) {
- 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;
-
- iEnd = iEnd2 + 10;
- szReplace.Format("%s:", T2Utf(pUser->pszNick).get());
- bPlaceFirst = true;
- }
- }
- else if (!strncmp(p, "lobbyinvite ", 12)) {
- szReplace = TranslateU("You were invited to play a game");
- }
- else if (!strncmp(p, "sticker ", 8)) {
- std::regex regex("type=\"(.+?)\"");
- std::smatch match;
- std::string content(p + 8);
- if (std::regex_search(content, match, regex)) {
- std::string szType = match[1];
- szReplace += szType.c_str();
- szReplace.Replace(" ", "_");
- }
- iEnd++;
- }
- else iEnd++;
- }
- else iEnd++, idx--;
-
- idx--;
- szText.Delete(idx, iEnd - idx);
-
- if (!szReplace.IsEmpty()) {
- if (bPlaceFirst)
- szText = szReplace + szText;
- else
- szText.Insert(idx, szReplace);
- }
- iEnd -= iEnd - idx;
- idx = iEnd;
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
MBinBuffer createMachineID(const char *accName)
{
uint8_t hashOut[MIR_SHA1_HASH_SIZE];
|