diff --git a/src/Components/Modules/AssetInterfaces/IFont_s.cpp b/src/Components/Modules/AssetInterfaces/IFont_s.cpp index 0840b809..59c072a9 100644 --- a/src/Components/Modules/AssetInterfaces/IFont_s.cpp +++ b/src/Components/Modules/AssetInterfaces/IFont_s.cpp @@ -103,14 +103,14 @@ namespace Assets return; } - nlohmann::json fontDef = nlohmann::json::parse(fontDefFile.getBuffer()); + nlohmann::json fontDef; try { fontDef = nlohmann::json::parse(fontDefFile.getBuffer()); } catch (const nlohmann::json::parse_error& ex) { - Components::Logger::Error(Game::ERR_FATAL, "Json Parse Error: {}. Font {} is invalid", ex.what(), name); + Components::Logger::Error(Game::ERR_FATAL, "Json Parse Error: {}. Font {} is invalid\n", ex.what(), name); return; } diff --git a/src/Components/Modules/ClientCommand.cpp b/src/Components/Modules/ClientCommand.cpp index fd6c3cc6..8eaf76e2 100644 --- a/src/Components/Modules/ClientCommand.cpp +++ b/src/Components/Modules/ClientCommand.cpp @@ -37,9 +37,9 @@ namespace Components { const auto ent = &Game::g_entities[clientNum]; - if (ent->client == nullptr) + if (!ent->client) { - Logger::Debug("ClientCommand: client {} is not fully in game yet", clientNum); + Logger::Debug("ClientCommand: client {} is not fully connected", clientNum); return; } @@ -129,7 +129,7 @@ namespace Components Add("setviewpos", [](Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params) { - assert(ent != nullptr); + assert(ent); if (!CheatsOk(ent)) return; @@ -245,7 +245,7 @@ namespace Components Add("kill", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params) { - assert(ent->client != nullptr); + assert(ent->client); assert(ent->client->sess.connected != Game::CON_DISCONNECTED); if (ent->client->sess.sessionState != Game::SESS_STATE_PLAYING || !CheatsOk(ent)) @@ -299,7 +299,7 @@ namespace Components duration = static_cast(std::floorf(input * 1000.0f + 0.5f)); } - assert(ent->client != nullptr); + assert(ent->client); constexpr auto visMode = Game::visionSetMode_t::VISIONSET_NORMAL; const auto* name = params->get(1); @@ -327,7 +327,7 @@ namespace Components duration = static_cast(std::floorf(input * 1000.0f + 0.5f)); } - assert(ent->client != nullptr); + assert(ent->client); constexpr auto visMode = Game::visionSetMode_t::VISIONSET_NIGHT; const auto* name = params->get(1); @@ -342,7 +342,7 @@ namespace Components Add("g_testCmd", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params) { - assert(ent != nullptr); + assert(ent); ent->client->ps.stunTime = 1000 + Game::level->time; // 1000 is the default test stun time Logger::Debug("playerState_s.stunTime is {}", ent->client->ps.stunTime); @@ -464,9 +464,11 @@ namespace Components const auto* line = EntInfoLine(i); const auto lineLen = std::strlen(line); + assert(line); assert(lineLen); - Game::FS_Write(line, lineLen, h); + + Game::FS_Write(line, static_cast(lineLen), h); } Game::FS_FCloseFile(h); diff --git a/src/Components/Modules/GSC/ScriptStorage.cpp b/src/Components/Modules/GSC/ScriptStorage.cpp index 95879747..e89425d7 100644 --- a/src/Components/Modules/GSC/ScriptStorage.cpp +++ b/src/Components/Modules/GSC/ScriptStorage.cpp @@ -86,6 +86,27 @@ namespace Components FileSystem::FileWriter("scriptdata/scriptstorage.json").write(json.dump()); }); + Script::AddFunction("StorageLoad", [] // gsc: StorageLoad(); + { + FileSystem::File storageFile("scriptdata/scriptstorage.json"); + if (!storageFile.exists()) + { + return; + } + + const auto& buffer = storageFile.getBuffer(); + try + { + const nlohmann::json storageDef = nlohmann::json::parse(buffer); + const auto& newData = storageDef.get>(); + Data.insert(newData.begin(), newData.end()); + } + catch (const std::exception& ex) + { + Logger::PrintError(Game::CON_CHANNEL_ERROR, "Json Parse Error: {}. File {} is invalid\n", ex.what(), storageFile.getName()); + } + }); + Script::AddFunction("StorageClear", [] // gsc: StorageClear(); { Data.clear(); diff --git a/src/Components/Modules/Logger.hpp b/src/Components/Modules/Logger.hpp index c794ecbd..359e473e 100644 --- a/src/Components/Modules/Logger.hpp +++ b/src/Components/Modules/Logger.hpp @@ -33,12 +33,14 @@ namespace Components template static void Print(std::string_view fmt, Args&&... args) { + (Utils::String::SanitizeFormatArgs(args), ...); PrintInternal(Game::CON_CHANNEL_DONT_FILTER, fmt, std::make_format_args(args...)); } template static void Print(int channel, std::string_view fmt, Args&&... args) { + (Utils::String::SanitizeFormatArgs(args), ...); PrintInternal(channel, fmt, std::make_format_args(args...)); } @@ -50,6 +52,7 @@ namespace Components template static void Error(Game::errorParm_t error, std::string_view fmt, Args&&... args) { + (Utils::String::SanitizeFormatArgs(args), ...); ErrorInternal(error, fmt, std::make_format_args(args...)); } @@ -61,6 +64,7 @@ namespace Components template static void Warning(int channel, std::string_view fmt, Args&&... args) { + (Utils::String::SanitizeFormatArgs(args), ...); WarningInternal(channel, fmt, std::make_format_args(args...)); } @@ -72,6 +76,7 @@ namespace Components template static void PrintError(int channel, std::string_view fmt, Args&&... args) { + (Utils::String::SanitizeFormatArgs(args), ...); PrintErrorInternal(channel, fmt, std::make_format_args(args...)); } @@ -82,6 +87,7 @@ namespace Components Debug([[maybe_unused]] std::string_view fmt, [[maybe_unused]] const Args&... args, [[maybe_unused]] const std::source_location& loc = std::source_location::current()) { #ifdef _DEBUG + (Utils::String::SanitizeFormatArgs(args), ...); DebugInternal(fmt, std::make_format_args(args...), loc); #endif } diff --git a/src/Components/Modules/MapRotation.cpp b/src/Components/Modules/MapRotation.cpp index 2c3da9cf..a9f01a8a 100644 --- a/src/Components/Modules/MapRotation.cpp +++ b/src/Components/Modules/MapRotation.cpp @@ -339,7 +339,7 @@ namespace Components } catch (const std::exception& ex) { - Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: parsing of 'normal' failed", ex.what()); + Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: parsing of 'normal' failed\n", ex.what()); return false; } diff --git a/src/Utils/String.cpp b/src/Utils/String.cpp index 502fe000..13e18025 100644 --- a/src/Utils/String.cpp +++ b/src/Utils/String.cpp @@ -5,7 +5,7 @@ namespace Utils::String { - const char *VA(const char *fmt, ...) + const char* VA(const char* fmt, ...) { static VAProvider<4, 100> globalProvider; static thread_local VAProvider<8, 256> provider; @@ -21,24 +21,26 @@ namespace Utils::String return result; } - std::string ToLower(std::string text) + std::string ToLower(const std::string& text) { - std::transform(text.begin(), text.end(), text.begin(), [](const unsigned char input) + std::string result; + std::ranges::transform(text, std::back_inserter(result), [](const unsigned char input) { return static_cast(std::tolower(input)); }); - return text; + return result; } - std::string ToUpper(std::string text) + std::string ToUpper(const std::string& text) { - std::transform(text.begin(), text.end(), text.begin(), [](const unsigned char input) + std::string result; + std::ranges::transform(text, std::back_inserter(result), [](const unsigned char input) { return static_cast(std::toupper(input)); }); - return text; + return result; } bool Compare(const std::string& lhs, const std::string& rhs) diff --git a/src/Utils/String.hpp b/src/Utils/String.hpp index 7ff19f5c..84c900fb 100644 --- a/src/Utils/String.hpp +++ b/src/Utils/String.hpp @@ -70,15 +70,31 @@ namespace Utils::String Entry stringPool[Buffers]; }; - const char *VA(const char *fmt, ...); + template // This should display a nice "null" instead of a number + static void SanitizeFormatArgs(Arg& arg) + { + if constexpr (std::is_same_v || std::is_same_v) + { + if (arg == nullptr) + { + arg = const_cast("nullptr"); + } + } + } + + const char* VA(const char* fmt, ...); + + std::string ToLower(const std::string& text); + std::string ToUpper(const std::string& text); - std::string ToLower(std::string text); - std::string ToUpper(std::string text); bool Compare(const std::string& lhs, const std::string& rhs); + std::vector Split(const std::string& str, char delim); void Replace(std::string& str, const std::string& from, const std::string& to); + bool StartsWith(const std::string& haystack, const std::string& needle); bool EndsWith(const std::string& haystack, const std::string& needle); + bool IsNumber(const std::string& str); std::string& LTrim(std::string& str); @@ -95,7 +111,7 @@ namespace Utils::String std::string XOR(std::string str, char value); - std::string EncodeBase64(const char* input, const unsigned long inputSize); + std::string EncodeBase64(const char* input, unsigned long inputSize); std::string EncodeBase64(const std::string& input); std::string EncodeBase128(const std::string& input);