From 69592a5656a512efa4566c096f1035d07bbc9afc Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 4 Dec 2021 18:34:19 +0000 Subject: [PATCH] Use .cfg over unordered map --- src/Components/Modules/Dvar.cpp | 48 ++++++++++++++++++++------------- src/Components/Modules/Dvar.hpp | 6 ++--- src/Game/Functions.cpp | 2 ++ src/Game/Functions.hpp | 6 +++++ src/Utils/IO.cpp | 5 ++++ src/Utils/IO.hpp | 1 + 6 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/Components/Modules/Dvar.cpp b/src/Components/Modules/Dvar.cpp index c32044d4..496bb488 100644 --- a/src/Components/Modules/Dvar.cpp +++ b/src/Components/Modules/Dvar.cpp @@ -3,7 +3,7 @@ namespace Components { Utils::Signal Dvar::RegistrationSignal; - std::unordered_set Dvar::ChangedDvars; + const char* Dvar::ArchiveDvarPath = "userraw/archivedvars.cfg"; Dvar::Var::Var(const std::string& dvarName) : Var() { @@ -190,22 +190,11 @@ namespace Components Dvar::RegistrationSignal.connect(callback); } - void Dvar::DvarReset(Game::dvar_t* var, Game::DvarSetSource source) - { - assert(var != nullptr); - - Game::Dvar_SetVariant(var, var->reset, source); - } - void Dvar::ResetDvarsValue() { - auto it = Dvar::ChangedDvars.begin(); - while (it != Dvar::ChangedDvars.end()) - { - auto var = Dvar::Var(*it).get(); - Dvar::DvarReset(var, Game::DVAR_SOURCE_INTERNAL); - it = Dvar::ChangedDvars.erase(it); - } + Command::Execute("exec archivedvars.cfg"); + // Cleanup + Utils::IO::RemoveFile(Dvar::ArchiveDvarPath); } Game::dvar_t* Dvar::RegisterName(const char* name, const char* /*default*/, Game::dvar_flag flag, const char* description) @@ -280,10 +269,28 @@ namespace Components return Game::Dvar_SetFromStringByNameFromSource(dvar, value, Game::DvarSetSource::DVAR_SOURCE_EXTERNAL); } - void Dvar::DvarSetFromStringByNameStub(const char* var, const char* value) + void Dvar::SaveArchiveDvar(const Game::dvar_t* var) { - Dvar::ChangedDvars.emplace(var); - Utils::Hook::Call(0x4F52E0)(var, value); + if (!Utils::IO::FileExists(Dvar::ArchiveDvarPath)) + { + Utils::IO::WriteFile(Dvar::ArchiveDvarPath, + "// generated by IW4x, do not modify\n"); + } + + Utils::IO::WriteFile(Dvar::ArchiveDvarPath, + Utils::String::VA("seta %s \"%s\"\n", var->name, Game::Dvar_DisplayableValue(var)), true); + } + + void Dvar::DvarSetFromStringByNameStub(const char* dvarName, const char* value) + { + // Save the dvar original value if it has the archive flag + const auto* dvar = Game::Dvar_FindVar(dvarName); + if (dvar != nullptr && dvar->flags & Game::dvar_flag::DVAR_FLAG_SAVED) + { + Dvar::SaveArchiveDvar(dvar); + } + + Utils::Hook::Call(0x4F52E0)(dvarName, value); } Dvar::Dvar() @@ -356,11 +363,14 @@ namespace Components // Hook Dvar_SetFromStringByName inside CG_SetClientDvarFromServer so we can reset dvars when the player leaves the server Utils::Hook(0x59386A, Dvar::DvarSetFromStringByNameStub, HOOK_CALL).install()->quick(); + + // If the game closed abruptly the file would have not been deleted + Utils::IO::RemoveFile(Dvar::ArchiveDvarPath); } Dvar::~Dvar() { Dvar::RegistrationSignal.clear(); - Dvar::ChangedDvars.clear(); + Utils::IO::RemoveFile(Dvar::ArchiveDvarPath); } } diff --git a/src/Components/Modules/Dvar.hpp b/src/Components/Modules/Dvar.hpp index 239cfdac..b29ef1bd 100644 --- a/src/Components/Modules/Dvar.hpp +++ b/src/Components/Modules/Dvar.hpp @@ -50,18 +50,18 @@ namespace Components template static Var Register(const char* name, T value, Flag flag, const char* description); template static Var Register(const char* name, T value, T min, T max, Flag flag, const char* description); - static void DvarReset(Game::dvar_t* var, Game::DvarSetSource source); static void ResetDvarsValue(); private: static Utils::Signal RegistrationSignal; - static std::unordered_set ChangedDvars; + static const char* ArchiveDvarPath; static Game::dvar_t* RegisterName(const char* name, const char* defaultVal, Game::dvar_flag flag, const char* description); static Game::dvar_t* SetFromStringByNameExternal(const char* dvar, const char* value); static Game::dvar_t* SetFromStringByNameSafeExternal(const char* dvar, const char* value); - static void DvarSetFromStringByNameStub(const char* var, const char* value); + static void SaveArchiveDvar(const Game::dvar_t* var); + static void DvarSetFromStringByNameStub(const char* dvarName, const char* value); }; } diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 8ee5f675..dee730d1 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -116,6 +116,7 @@ namespace Game Dvar_FindVar_t Dvar_FindVar = Dvar_FindVar_t(0x4D5390); Dvar_InfoString_Big_t Dvar_InfoString_Big = Dvar_InfoString_Big_t(0x4D98A0); Dvar_SetCommand_t Dvar_SetCommand = Dvar_SetCommand_t(0x4EE430); + Dvar_DisplayableValue_t Dvar_DisplayableValue = Dvar_DisplayableValue_t(0x4B5530); Encode_Init_t Encode_Init = Encode_Init_t(0x462AB0); @@ -145,6 +146,7 @@ namespace Game FS_Restart_t FS_Restart = FS_Restart_t(0x461A50); FS_BuildPathToFile_t FS_BuildPathToFile = FS_BuildPathToFile_t(0x4702C0); FS_IsShippedIWD_t FS_IsShippedIWD = FS_IsShippedIWD_t(0x642440); + FS_Delete_t FS_Delete = FS_Delete_t(0x48A5B0); G_GetWeaponIndexForName_t G_GetWeaponIndexForName = G_GetWeaponIndexForName_t(0x49E540); G_SpawnEntitiesFromString_t G_SpawnEntitiesFromString = G_SpawnEntitiesFromString_t(0x4D8840); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index d7d3959f..516039f0 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -289,6 +289,9 @@ namespace Game typedef dvar_t* (__cdecl * Dvar_SetCommand_t)(const char* name, const char* value); extern Dvar_SetCommand_t Dvar_SetCommand; + typedef const char* (__cdecl * Dvar_DisplayableValue_t)(const dvar_t* cvar); + extern Dvar_DisplayableValue_t Dvar_DisplayableValue; + typedef bool(__cdecl * Encode_Init_t)(const char* ); extern Encode_Init_t Encode_Init; @@ -359,6 +362,9 @@ namespace Game typedef iwd_t*(__cdecl * FS_IsShippedIWD_t)(const char* fullpath, const char* iwd); extern FS_IsShippedIWD_t FS_IsShippedIWD; + typedef int(__cdecl* FS_Delete_t)(const char* fileName); + extern FS_Delete_t FS_Delete; + typedef int(__cdecl* G_GetWeaponIndexForName_t)(char*); extern G_GetWeaponIndexForName_t G_GetWeaponIndexForName; diff --git a/src/Utils/IO.cpp b/src/Utils/IO.cpp index 7310b529..c150ff7b 100644 --- a/src/Utils/IO.cpp +++ b/src/Utils/IO.cpp @@ -63,6 +63,11 @@ namespace Utils return false; } + bool RemoveFile(const std::string& file) + { + return DeleteFileA(file.data()) == TRUE; + } + size_t FileSize(const std::string& file) { if (FileExists(file)) diff --git a/src/Utils/IO.hpp b/src/Utils/IO.hpp index a4e92afd..16c0198c 100644 --- a/src/Utils/IO.hpp +++ b/src/Utils/IO.hpp @@ -8,6 +8,7 @@ namespace Utils bool WriteFile(const std::string& file, const std::string& data, bool append = false); bool ReadFile(const std::string& file, std::string* data); std::string ReadFile(const std::string& file); + bool RemoveFile(const std::string& file); size_t FileSize(const std::string& file); bool CreateDir(const std::string& dir); bool DirectoryExists(const std::string& file);