[Dvar]: Protect saved dvars by default (#694)
This commit is contained in:
parent
9f39834090
commit
406499d919
@ -39,7 +39,7 @@
|
||||
| `-version` | Print IW4x build info on startup. |
|
||||
| `-zonebuilder` | Start the interactive zonebuilder tool console instead of starting the game. |
|
||||
| `-nosteam` | Disable friends feature and do not update Steam about the game's current status just like an invisible mode. |
|
||||
| `-protect-saved-dvars` | Block the server from modifying saved/archive dvars. |
|
||||
| `-unprotect-dvars` | Allow the server to modify saved/archive dvars. |
|
||||
|
||||
|
||||
## Disclaimer
|
||||
|
@ -2,14 +2,11 @@
|
||||
|
||||
namespace Components
|
||||
{
|
||||
const char* Dvar::ArchiveDvarPath = "userraw/archivedvars.cfg";
|
||||
|
||||
Dvar::Var Dvar::Name;
|
||||
|
||||
Dvar::Var::Var(const std::string& dvarName)
|
||||
: dvar_(Game::Dvar_FindVar(dvarName.data()))
|
||||
{
|
||||
this->dvar_ = Game::Dvar_FindVar(dvarName.data());
|
||||
|
||||
// If the dvar can't be found it will be registered as an empty string dvar
|
||||
if (this->dvar_ == nullptr)
|
||||
{
|
||||
@ -206,16 +203,6 @@ namespace Components
|
||||
return Game::Dvar_RegisterFloat(dvarName, value, min, max, flag, description);
|
||||
}
|
||||
|
||||
void Dvar::ResetDvarsValue()
|
||||
{
|
||||
if (!Utils::IO::FileExists(ArchiveDvarPath))
|
||||
return;
|
||||
|
||||
Command::Execute("exec archivedvars.cfg", true);
|
||||
// Clean up
|
||||
Utils::IO::RemoveFile(ArchiveDvarPath);
|
||||
}
|
||||
|
||||
Game::dvar_t* Dvar::Dvar_RegisterName(const char* name, const char* /*default*/, std::uint16_t flags, const char* description)
|
||||
{
|
||||
// Name watcher
|
||||
@ -291,44 +278,31 @@ namespace Components
|
||||
Game::Dvar_SetFromStringByNameFromSource(dvarName, string, Game::DVAR_SOURCE_EXTERNAL);
|
||||
}
|
||||
|
||||
bool Dvar::AreArchiveDvarsProtected()
|
||||
bool Dvar::AreArchiveDvarsUnprotected()
|
||||
{
|
||||
static std::optional<bool> flag;
|
||||
|
||||
if (!flag.has_value())
|
||||
{
|
||||
flag.emplace(Flags::HasFlag("protect-saved-dvars"));
|
||||
flag.emplace(Flags::HasFlag("unprotect-dvars"));
|
||||
}
|
||||
|
||||
return flag.value();
|
||||
}
|
||||
|
||||
void Dvar::SaveArchiveDvar(const Game::dvar_t* var)
|
||||
{
|
||||
if (!Utils::IO::FileExists(ArchiveDvarPath))
|
||||
{
|
||||
Utils::IO::WriteFile(ArchiveDvarPath, "// generated by IW4x, do not modify\n", false);
|
||||
}
|
||||
|
||||
Utils::IO::WriteFile(ArchiveDvarPath, std::format("set {} \"{}\"\n", var->name, Game::Dvar_DisplayableValue(var)), true);
|
||||
}
|
||||
|
||||
void Dvar::DvarSetFromStringByName_Stub(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_ARCHIVE)
|
||||
{
|
||||
if (AreArchiveDvarsProtected())
|
||||
if (!AreArchiveDvarsUnprotected())
|
||||
{
|
||||
Logger::Print(Game::CON_CHANNEL_CONSOLEONLY, "Not allowing server to override saved dvar '{}'\n", dvar->name);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DVARS
|
||||
Logger::Print(Game::CON_CHANNEL_CONSOLEONLY, "Server is overriding saved dvar '{}'\n", dvarName);
|
||||
#endif
|
||||
SaveArchiveDvar(dvar);
|
||||
}
|
||||
|
||||
if (dvar != nullptr && std::strcmp(dvar->name, "com_errorResolveCommand") == 0)
|
||||
@ -467,12 +441,6 @@ namespace Components
|
||||
// Hook Dvar_SetFromStringByName inside CG_SetClientDvarFromServer so we can reset dvars when the player leaves the server
|
||||
Utils::Hook(0x59386A, DvarSetFromStringByName_Stub, HOOK_CALL).install()->quick();
|
||||
|
||||
// If the game closed abruptly, the dvars would not have been restored
|
||||
Scheduler::Once(ResetDvarsValue, Scheduler::Pipeline::MAIN);
|
||||
|
||||
// Reset archive dvars when client leaves a server
|
||||
Events::OnSteamDisconnect(ResetDvarsValue);
|
||||
|
||||
// For debugging
|
||||
Utils::Hook(0x6483FA, Dvar_RegisterVariant_Stub, HOOK_JUMP).install()->quick();
|
||||
Utils::Hook(0x648438, Dvar_RegisterVariant_Stub, HOOK_JUMP).install()->quick();
|
||||
@ -480,9 +448,4 @@ namespace Components
|
||||
// Fix crash
|
||||
Utils::Hook(0x4B7120, Dvar_EnumToString_Stub, HOOK_JUMP).install()->quick();
|
||||
}
|
||||
|
||||
Dvar::~Dvar()
|
||||
{
|
||||
Utils::IO::RemoveFile(ArchiveDvarPath);
|
||||
}
|
||||
}
|
||||
|
@ -32,16 +32,12 @@ namespace Components
|
||||
};
|
||||
|
||||
Dvar();
|
||||
~Dvar();
|
||||
|
||||
// Only strings and bools use this type of declaration
|
||||
template<typename T> static Var Register(const char* dvarName, T value, std::uint16_t flag, const char* description);
|
||||
template<typename T> static Var Register(const char* dvarName, T value, T min, T max, std::uint16_t flag, const char* description);
|
||||
|
||||
static void ResetDvarsValue();
|
||||
|
||||
private:
|
||||
static const char* ArchiveDvarPath;
|
||||
static Var Name;
|
||||
|
||||
static Game::dvar_t* Dvar_RegisterName(const char* name, const char* defaultVal, std::uint16_t flags, const char* description);
|
||||
@ -49,8 +45,7 @@ namespace Components
|
||||
static void SetFromStringByNameExternal(const char* dvarName, const char* string);
|
||||
static void SetFromStringByNameSafeExternal(const char* dvarName, const char* string);
|
||||
|
||||
static bool AreArchiveDvarsProtected();
|
||||
static void SaveArchiveDvar(const Game::dvar_t* var);
|
||||
static bool AreArchiveDvarsUnprotected();
|
||||
static void DvarSetFromStringByName_Stub(const char* dvarName, const char* value);
|
||||
|
||||
static void OnRegisterVariant(Game::dvar_t* dvar);
|
||||
|
Loading…
Reference in New Issue
Block a user