From 967eeb29893f51a17d49800b2be6b5b1755d1c43 Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 7 Sep 2021 14:33:36 +0200 Subject: [PATCH] Update playername cleaning to clean fonticons and enforce 3 character minimum serverside --- src/Components/Modules/Dvar.cpp | 2 +- src/Components/Modules/TextRenderer.cpp | 124 ++++++++++++++++++++++-- src/Components/Modules/TextRenderer.hpp | 6 +- 3 files changed, 124 insertions(+), 8 deletions(-) diff --git a/src/Components/Modules/Dvar.cpp b/src/Components/Modules/Dvar.cpp index d6971470..e9a0067d 100644 --- a/src/Components/Modules/Dvar.cpp +++ b/src/Components/Modules/Dvar.cpp @@ -162,7 +162,7 @@ namespace Components // Don't perform any checks if name didn't change if (name == lastValidName) return; - std::string saneName = TextRenderer::StripColors(Utils::String::Trim(name)); + std::string saneName = TextRenderer::StripAllTextIcons(TextRenderer::StripColors(Utils::String::Trim(name))); if (saneName.size() < 3 || (saneName[0] == '[' && saneName[1] == '{')) { Logger::Print("Username '%s' is invalid. It must at least be 3 characters long and not appear empty!\n", name.data()); diff --git a/src/Components/Modules/TextRenderer.cpp b/src/Components/Modules/TextRenderer.cpp index 88db6d0e..eda8ee13 100644 --- a/src/Components/Modules/TextRenderer.cpp +++ b/src/Components/Modules/TextRenderer.cpp @@ -650,12 +650,12 @@ namespace Components return result; } - void TextRenderer::StripColors(const char* in, char* out, int max) + void TextRenderer::StripColors(const char* in, char* out, size_t max) { if (!in || !out) return; max--; - int current = 0; + size_t current = 0; while (*in != 0 && current < max) { const char index = *(in + 1); @@ -682,17 +682,129 @@ namespace Components return std::string(buffer); } - void TextRenderer::UserInfoCopy(char* buffer, const char* name, size_t size) + void TextRenderer::StripMaterialTextIcons(const char* in, char* out, size_t max) { - Utils::Memory::Allocator allocator; + if (!in || !out) return; + max--; + size_t current = 0; + while (*in != 0 && current < max) + { + if (*in == '^' && (in[1] == '\x01' || in[1] == '\x02')) + { + in += 2; + + if (*in) // width + in++; + if (*in) // height + in++; + + if(*in) // material name length + material name characters + { + const auto materialNameLength = *in; + in++; + for(auto i = 0; i < materialNameLength; i++) + { + if (*in) + in++; + } + } + } + else + { + *out = *in; + ++out; + ++current; + ++in; + } + + } + *out = '\0'; + } + + std::string TextRenderer::StripMaterialTextIcons(const std::string& in) + { + char buffer[1000] = { 0 }; // Should be more than enough + StripAllTextIcons(in.data(), buffer, sizeof(buffer)); + return std::string(buffer); + } + + void TextRenderer::StripAllTextIcons(const char* in, char* out, size_t max) + { + if (!in || !out) return; + + max--; + size_t current = 0; + while (*in != 0 && current < max) + { + if (*in == '^' && (in[1] == '\x01' || in[1] == '\x02')) + { + in += 2; + + if (*in) // width + in++; + if (*in) // height + in++; + + if(*in) // material name length + material name characters + { + const auto materialNameLength = *in; + in++; + for(auto i = 0; i < materialNameLength; i++) + { + if (*in) + in++; + } + } + + continue; + } + + if(*in == ':') + { + const auto* fontIconEndPos = &in[1]; + FontIconInfo fontIcon{}; + if(IsFontIcon(fontIconEndPos, fontIcon)) + { + in = fontIconEndPos; + continue; + } + } + + *out = *in; + ++out; + ++current; + ++in; + } + *out = '\0'; + } + + std::string TextRenderer::StripAllTextIcons(const std::string& in) + { + char buffer[1000] = { 0 }; // Should be more than enough + StripAllTextIcons(in.data(), buffer, sizeof(buffer)); + return std::string(buffer); + } + + void TextRenderer::UserInfoCopy(char* buffer, const char* name, const size_t size) + { if (!sv_allowColoredNames.get()) { - StripColors(name, buffer, size); + char nameBuffer[64] = {0}; + StripColors(name, nameBuffer, sizeof(nameBuffer)); + StripAllTextIcons(nameBuffer, buffer, size); } else { - strncpy_s(buffer, size, name, _TRUNCATE); + StripAllTextIcons(name, buffer, size); + } + + std::string readablePlayerName(buffer); + readablePlayerName = Utils::String::Trim(readablePlayerName); + + if(readablePlayerName.size() < 3) + { + strncpy(buffer, "Unknown Soldier", size); } } diff --git a/src/Components/Modules/TextRenderer.hpp b/src/Components/Modules/TextRenderer.hpp index 6e4db036..84f4e818 100644 --- a/src/Components/Modules/TextRenderer.hpp +++ b/src/Components/Modules/TextRenderer.hpp @@ -83,8 +83,12 @@ namespace Components static void DrawText2D(const char* text, float x, float y, Game::Font_s* font, float xScale, float yScale, float sinAngle, float cosAngle, Game::GfxColor color, int maxLength, int renderFlags, int cursorPos, char cursorLetter, float padding, Game::GfxColor glowForcedColor, int fxBirthTime, int fxLetterTime, int fxDecayStartTime, int fxDecayDuration, Game::Material* fxMaterial, Game::Material* fxMaterialGlow); static int R_TextWidth_Hk(const char* text, int maxChars, Game::Font_s* font); static unsigned int ColorIndex(char index); - static void StripColors(const char* in, char* out, int max); + static void StripColors(const char* in, char* out, size_t max); static std::string StripColors(const std::string& in); + static void StripMaterialTextIcons(const char* in, char* out, size_t max); + static std::string StripMaterialTextIcons(const std::string& in); + static void StripAllTextIcons(const char* in, char* out, size_t max); + static std::string StripAllTextIcons(const std::string& in); static void UserInfoCopy(char* buffer, const char* name, size_t size); TextRenderer();