Merge pull request #134 from diamante0018/feature/reset-dvars
[Dvar] Reset dvars changed by server when disconnecting
This commit is contained in:
commit
3fdadb45a5
@ -3,6 +3,7 @@
|
|||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
Utils::Signal<Scheduler::Callback> Dvar::RegistrationSignal;
|
Utils::Signal<Scheduler::Callback> Dvar::RegistrationSignal;
|
||||||
|
const char* Dvar::ArchiveDvarPath = "userraw/archivedvars.cfg";
|
||||||
|
|
||||||
Dvar::Var::Var(const std::string& dvarName) : Var()
|
Dvar::Var::Var(const std::string& dvarName) : Var()
|
||||||
{
|
{
|
||||||
@ -189,6 +190,16 @@ namespace Components
|
|||||||
Dvar::RegistrationSignal.connect(callback);
|
Dvar::RegistrationSignal.connect(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Dvar::ResetDvarsValue()
|
||||||
|
{
|
||||||
|
if (!Utils::IO::FileExists(Dvar::ArchiveDvarPath))
|
||||||
|
return
|
||||||
|
|
||||||
|
Command::Execute("exec archivedvars.cfg", true);
|
||||||
|
// Clean up
|
||||||
|
Utils::IO::RemoveFile(Dvar::ArchiveDvarPath);
|
||||||
|
}
|
||||||
|
|
||||||
Game::dvar_t* Dvar::RegisterName(const char* name, const char* /*default*/, Game::dvar_flag flag, const char* description)
|
Game::dvar_t* Dvar::RegisterName(const char* name, const char* /*default*/, Game::dvar_flag flag, const char* description)
|
||||||
{
|
{
|
||||||
// Run callbacks
|
// Run callbacks
|
||||||
@ -261,6 +272,30 @@ namespace Components
|
|||||||
return Game::Dvar_SetFromStringByNameFromSource(dvar, value, Game::DvarSetSource::DVAR_SOURCE_EXTERNAL);
|
return Game::Dvar_SetFromStringByNameFromSource(dvar, value, Game::DvarSetSource::DVAR_SOURCE_EXTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Dvar::SaveArchiveDvar(const Game::dvar_t* var)
|
||||||
|
{
|
||||||
|
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<void(const char*, const char*)>(0x4F52E0)(dvarName, value);
|
||||||
|
}
|
||||||
|
|
||||||
Dvar::Dvar()
|
Dvar::Dvar()
|
||||||
{
|
{
|
||||||
// set flags of cg_drawFPS to archive
|
// set flags of cg_drawFPS to archive
|
||||||
@ -328,10 +363,21 @@ namespace Components
|
|||||||
|
|
||||||
// Entirely block setting cheat dvars internally without sv_cheats
|
// Entirely block setting cheat dvars internally without sv_cheats
|
||||||
//Utils::Hook(0x4F52EC, Dvar::SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
//Utils::Hook(0x4F52EC, Dvar::SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
// 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 dvars would not have been restored
|
||||||
|
|
||||||
|
Dvar::OnInit([]
|
||||||
|
{
|
||||||
|
Dvar::ResetDvarsValue();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Dvar::~Dvar()
|
Dvar::~Dvar()
|
||||||
{
|
{
|
||||||
Dvar::RegistrationSignal.clear();
|
Dvar::RegistrationSignal.clear();
|
||||||
|
Utils::IO::RemoveFile(Dvar::ArchiveDvarPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,12 +50,18 @@ namespace Components
|
|||||||
template<typename T> static Var Register(const char* name, T value, Flag flag, const char* description);
|
template<typename T> static Var Register(const char* name, T value, Flag flag, const char* description);
|
||||||
template<typename T> static Var Register(const char* name, T value, T min, T max, Flag flag, const char* description);
|
template<typename T> static Var Register(const char* name, T value, T min, T max, Flag flag, const char* description);
|
||||||
|
|
||||||
|
static void ResetDvarsValue();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Utils::Signal<Scheduler::Callback> RegistrationSignal;
|
static Utils::Signal<Scheduler::Callback> RegistrationSignal;
|
||||||
|
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* 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* SetFromStringByNameExternal(const char* dvar, const char* value);
|
||||||
static Game::dvar_t* SetFromStringByNameSafeExternal(const char* dvar, const char* value);
|
static Game::dvar_t* SetFromStringByNameSafeExternal(const char* dvar, const char* value);
|
||||||
|
|
||||||
|
static void SaveArchiveDvar(const Game::dvar_t* var);
|
||||||
|
static void DvarSetFromStringByNameStub(const char* dvarName, const char* value);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -458,7 +458,10 @@ namespace Components
|
|||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
pushad
|
pushad
|
||||||
|
|
||||||
call Friends::ClearServer
|
call Friends::ClearServer
|
||||||
|
call Dvar::ResetDvarsValue
|
||||||
|
|
||||||
popad
|
popad
|
||||||
|
|
||||||
push 467CC0h
|
push 467CC0h
|
||||||
|
@ -116,12 +116,14 @@ namespace Game
|
|||||||
Dvar_FindVar_t Dvar_FindVar = Dvar_FindVar_t(0x4D5390);
|
Dvar_FindVar_t Dvar_FindVar = Dvar_FindVar_t(0x4D5390);
|
||||||
Dvar_InfoString_Big_t Dvar_InfoString_Big = Dvar_InfoString_Big_t(0x4D98A0);
|
Dvar_InfoString_Big_t Dvar_InfoString_Big = Dvar_InfoString_Big_t(0x4D98A0);
|
||||||
Dvar_SetCommand_t Dvar_SetCommand = Dvar_SetCommand_t(0x4EE430);
|
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);
|
Encode_Init_t Encode_Init = Encode_Init_t(0x462AB0);
|
||||||
|
|
||||||
Field_Clear_t Field_Clear = Field_Clear_t(0x437EB0);
|
Field_Clear_t Field_Clear = Field_Clear_t(0x437EB0);
|
||||||
|
|
||||||
FreeMemory_t FreeMemory = FreeMemory_t(0x4D6640);
|
FreeMemory_t FreeMemory = FreeMemory_t(0x4D6640);
|
||||||
|
Free_String_t Free_String = Free_String_t(0x470E80);
|
||||||
|
|
||||||
FS_FileExists_t FS_FileExists = FS_FileExists_t(0x4DEFA0);
|
FS_FileExists_t FS_FileExists = FS_FileExists_t(0x4DEFA0);
|
||||||
FS_FreeFile_t FS_FreeFile = FS_FreeFile_t(0x4416B0);
|
FS_FreeFile_t FS_FreeFile = FS_FreeFile_t(0x4416B0);
|
||||||
@ -144,6 +146,7 @@ namespace Game
|
|||||||
FS_Restart_t FS_Restart = FS_Restart_t(0x461A50);
|
FS_Restart_t FS_Restart = FS_Restart_t(0x461A50);
|
||||||
FS_BuildPathToFile_t FS_BuildPathToFile = FS_BuildPathToFile_t(0x4702C0);
|
FS_BuildPathToFile_t FS_BuildPathToFile = FS_BuildPathToFile_t(0x4702C0);
|
||||||
FS_IsShippedIWD_t FS_IsShippedIWD = FS_IsShippedIWD_t(0x642440);
|
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_GetWeaponIndexForName_t G_GetWeaponIndexForName = G_GetWeaponIndexForName_t(0x49E540);
|
||||||
G_SpawnEntitiesFromString_t G_SpawnEntitiesFromString = G_SpawnEntitiesFromString_t(0x4D8840);
|
G_SpawnEntitiesFromString_t G_SpawnEntitiesFromString = G_SpawnEntitiesFromString_t(0x4D8840);
|
||||||
@ -1493,5 +1496,28 @@ namespace Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void Dvar_SetVariant(dvar_t*, DvarValue, DvarSetSource)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
pushad
|
||||||
|
|
||||||
|
mov eax, [esp + 0x4 + 0x20] // dvar
|
||||||
|
push[esp + 0x18 + 0x20] // source
|
||||||
|
push[esp + 0x18 + 0x20] // value
|
||||||
|
push[esp + 0x18 + 0x20] // value
|
||||||
|
push[esp + 0x18 + 0x20] // value
|
||||||
|
push[esp + 0x18 + 0x20] // value
|
||||||
|
|
||||||
|
mov ebx, 0x647400
|
||||||
|
call ebx
|
||||||
|
add esp, 0x14
|
||||||
|
|
||||||
|
popad
|
||||||
|
|
||||||
|
retn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma optimize("", on)
|
#pragma optimize("", on)
|
||||||
}
|
}
|
||||||
|
@ -289,6 +289,9 @@ namespace Game
|
|||||||
typedef dvar_t* (__cdecl * Dvar_SetCommand_t)(const char* name, const char* value);
|
typedef dvar_t* (__cdecl * Dvar_SetCommand_t)(const char* name, const char* value);
|
||||||
extern Dvar_SetCommand_t Dvar_SetCommand;
|
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* );
|
typedef bool(__cdecl * Encode_Init_t)(const char* );
|
||||||
extern Encode_Init_t Encode_Init;
|
extern Encode_Init_t Encode_Init;
|
||||||
|
|
||||||
@ -298,6 +301,9 @@ namespace Game
|
|||||||
typedef void(__cdecl * FreeMemory_t)(void* buffer);
|
typedef void(__cdecl * FreeMemory_t)(void* buffer);
|
||||||
extern FreeMemory_t FreeMemory;
|
extern FreeMemory_t FreeMemory;
|
||||||
|
|
||||||
|
typedef void (__cdecl * Free_String_t)(const char* string);
|
||||||
|
extern Free_String_t Free_String;
|
||||||
|
|
||||||
typedef void(__cdecl * FS_FreeFile_t)(void* buffer);
|
typedef void(__cdecl * FS_FreeFile_t)(void* buffer);
|
||||||
extern FS_FreeFile_t FS_FreeFile;
|
extern FS_FreeFile_t FS_FreeFile;
|
||||||
|
|
||||||
@ -356,6 +362,9 @@ namespace Game
|
|||||||
typedef iwd_t*(__cdecl * FS_IsShippedIWD_t)(const char* fullpath, const char* iwd);
|
typedef iwd_t*(__cdecl * FS_IsShippedIWD_t)(const char* fullpath, const char* iwd);
|
||||||
extern FS_IsShippedIWD_t FS_IsShippedIWD;
|
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*);
|
typedef int(__cdecl* G_GetWeaponIndexForName_t)(char*);
|
||||||
extern G_GetWeaponIndexForName_t G_GetWeaponIndexForName;
|
extern G_GetWeaponIndexForName_t G_GetWeaponIndexForName;
|
||||||
|
|
||||||
@ -1078,4 +1087,6 @@ namespace Game
|
|||||||
|
|
||||||
void AimAssist_UpdateTweakables(int localClientNum);
|
void AimAssist_UpdateTweakables(int localClientNum);
|
||||||
void AimAssist_UpdateAdsLerp(const AimInput* input);
|
void AimAssist_UpdateAdsLerp(const AimInput* input);
|
||||||
|
|
||||||
|
void Dvar_SetVariant(dvar_t* var, DvarValue value, DvarSetSource source);
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,11 @@ namespace Utils
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RemoveFile(const std::string& file)
|
||||||
|
{
|
||||||
|
return DeleteFileA(file.data()) == TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
size_t FileSize(const std::string& file)
|
size_t FileSize(const std::string& file)
|
||||||
{
|
{
|
||||||
if (FileExists(file))
|
if (FileExists(file))
|
||||||
|
@ -8,6 +8,7 @@ namespace Utils
|
|||||||
bool WriteFile(const std::string& file, const std::string& data, bool append = false);
|
bool WriteFile(const std::string& file, const std::string& data, bool append = false);
|
||||||
bool ReadFile(const std::string& file, std::string* data);
|
bool ReadFile(const std::string& file, std::string* data);
|
||||||
std::string ReadFile(const std::string& file);
|
std::string ReadFile(const std::string& file);
|
||||||
|
bool RemoveFile(const std::string& file);
|
||||||
size_t FileSize(const std::string& file);
|
size_t FileSize(const std::string& file);
|
||||||
bool CreateDir(const std::string& dir);
|
bool CreateDir(const std::string& dir);
|
||||||
bool DirectoryExists(const std::string& file);
|
bool DirectoryExists(const std::string& file);
|
||||||
|
Loading…
Reference in New Issue
Block a user