2022-02-27 07:53:44 -05:00
|
|
|
#include <STDInclude.hpp>
|
2017-01-19 16:23:59 -05:00
|
|
|
|
|
|
|
namespace Components
|
|
|
|
{
|
2021-12-04 13:34:19 -05:00
|
|
|
const char* Dvar::ArchiveDvarPath = "userraw/archivedvars.cfg";
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
Dvar::Var Dvar::Name;
|
|
|
|
|
2022-08-10 17:03:26 -04:00
|
|
|
Dvar::Var::Var(const std::string& dvarName)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
this->dvar_ = Game::Dvar_FindVar(dvarName.data());
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2022-02-03 06:44:35 -05:00
|
|
|
// If the dvar can't be found it will be registered as an empty string dvar
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_ == nullptr)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-11-02 09:40:45 -04:00
|
|
|
this->dvar_ = const_cast<Game::dvar_t*>(Game::Dvar_SetFromStringByNameFromSource(dvarName.data(), "", Game::DVAR_SOURCE_INTERNAL));
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <> Game::dvar_t* Dvar::Var::get()
|
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
return this->dvar_;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
2021-09-08 16:54:43 -04:00
|
|
|
|
2022-01-17 12:21:51 -05:00
|
|
|
template <> const char* Dvar::Var::get()
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_ == nullptr)
|
2022-01-17 12:21:51 -05:00
|
|
|
return "";
|
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
if (this->dvar_->type == Game::DVAR_TYPE_STRING || this->dvar_->type == Game::DVAR_TYPE_ENUM)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_->current.string != nullptr)
|
|
|
|
return this->dvar_->current.string;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
|
2022-01-17 12:21:51 -05:00
|
|
|
return "";
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
2021-09-08 16:54:43 -04:00
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
template <> int Dvar::Var::get()
|
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_ == nullptr)
|
2022-02-19 18:06:56 -05:00
|
|
|
return 0;
|
2022-02-03 06:44:35 -05:00
|
|
|
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_->type == Game::DVAR_TYPE_INT || this->dvar_->type == Game::DVAR_TYPE_ENUM)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
return this->dvar_->current.integer;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2021-09-08 16:54:43 -04:00
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
template <> unsigned int Dvar::Var::get()
|
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_ == nullptr)
|
2022-07-02 13:52:57 -04:00
|
|
|
return 0;
|
2022-02-03 06:44:35 -05:00
|
|
|
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_->type == Game::DVAR_TYPE_INT)
|
2022-02-03 06:44:35 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
return this->dvar_->current.unsignedInt;
|
2022-02-03 06:44:35 -05:00
|
|
|
}
|
|
|
|
|
2022-07-02 13:52:57 -04:00
|
|
|
return 0;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
2021-09-08 16:54:43 -04:00
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
template <> float Dvar::Var::get()
|
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_ == nullptr)
|
2022-02-19 18:06:56 -05:00
|
|
|
return 0.f;
|
2022-02-03 06:44:35 -05:00
|
|
|
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_->type == Game::DVAR_TYPE_FLOAT)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
return this->dvar_->current.value;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
|
2022-02-03 06:44:35 -05:00
|
|
|
return 0.f;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
2021-09-08 16:54:43 -04:00
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
template <> float* Dvar::Var::get()
|
|
|
|
{
|
2022-07-02 13:52:57 -04:00
|
|
|
static Game::vec4_t vector{0.f, 0.f, 0.f, 0.f};
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_ == nullptr)
|
2022-02-19 18:06:56 -05:00
|
|
|
return vector;
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
if (this->dvar_->type == Game::DVAR_TYPE_FLOAT_2 || this->dvar_->type == Game::DVAR_TYPE_FLOAT_3 ||
|
|
|
|
this->dvar_->type == Game::DVAR_TYPE_FLOAT_4)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
return this->dvar_->current.vector;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
|
2022-02-03 06:44:35 -05:00
|
|
|
return vector;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
2021-09-08 16:54:43 -04:00
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
template <> bool Dvar::Var::get()
|
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_ == nullptr)
|
2022-02-19 18:06:56 -05:00
|
|
|
return false;
|
2022-02-03 06:44:35 -05:00
|
|
|
|
2022-08-10 17:03:26 -04:00
|
|
|
if (this->dvar_->type == Game::DVAR_TYPE_BOOL)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
return this->dvar_->current.enabled;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2021-09-08 16:54:43 -04:00
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
template <> std::string Dvar::Var::get()
|
|
|
|
{
|
|
|
|
return this->get<const char*>();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Dvar::Var::set(const char* string)
|
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
assert(this->dvar_->type == Game::DVAR_TYPE_STRING);
|
|
|
|
if (this->dvar_)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
Game::Dvar_SetString(this->dvar_, string);
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
}
|
2021-09-08 16:54:43 -04:00
|
|
|
|
2018-12-17 08:29:18 -05:00
|
|
|
void Dvar::Var::set(const std::string& string)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
|
|
|
this->set(string.data());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Dvar::Var::set(int integer)
|
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
assert(this->dvar_->type == Game::DVAR_TYPE_INT);
|
|
|
|
|
|
|
|
if (this->dvar_)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
Game::Dvar_SetInt(this->dvar_, integer);
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
}
|
2021-09-09 04:50:49 -04:00
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
void Dvar::Var::set(float value)
|
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
assert(this->dvar_->type == Game::DVAR_TYPE_FLOAT);
|
|
|
|
|
|
|
|
if (this->dvar_)
|
2017-07-08 19:54:02 -04:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
Game::Dvar_SetFloat(this->dvar_, value);
|
2017-07-08 19:54:02 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-29 11:41:21 -04:00
|
|
|
void Dvar::Var::set(bool enabled)
|
2021-08-21 18:04:30 -04:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
assert(this->dvar_->type == Game::DVAR_TYPE_BOOL);
|
|
|
|
|
|
|
|
if (this->dvar_)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
Game::Dvar_SetBool(this->dvar_, enabled);
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Dvar::Var::setRaw(int integer)
|
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
assert(this->dvar_->type == Game::DVAR_TYPE_INT);
|
|
|
|
|
|
|
|
if (this->dvar_)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
this->dvar_->current.integer = integer;
|
|
|
|
this->dvar_->latched.integer = integer;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-08 19:54:02 -04:00
|
|
|
void Dvar::Var::setRaw(float value)
|
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
assert(this->dvar_->type == Game::DVAR_TYPE_FLOAT);
|
|
|
|
|
|
|
|
if (this->dvar_)
|
2017-07-08 19:54:02 -04:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
this->dvar_->current.value = value;
|
|
|
|
this->dvar_->latched.value = value;
|
2021-09-10 05:40:30 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Dvar::Var::setRaw(bool enabled)
|
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
assert(this->dvar_->type == Game::DVAR_TYPE_BOOL);
|
|
|
|
|
|
|
|
if (this->dvar_)
|
2021-09-10 05:40:30 -04:00
|
|
|
{
|
2022-08-10 17:03:26 -04:00
|
|
|
this->dvar_->current.enabled = enabled;
|
|
|
|
this->dvar_->latched.enabled = enabled;
|
2017-07-08 19:54:02 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
template<> Dvar::Var Dvar::Register(const char* dvarName, bool value, Flag flag, const char* description)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-03-08 07:20:28 -05:00
|
|
|
return Game::Dvar_RegisterBool(dvarName, value, flag.val, description);
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
2021-09-08 16:54:43 -04:00
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
template<> Dvar::Var Dvar::Register(const char* dvarName, const char* value, Flag flag, const char* description)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-03-08 07:20:28 -05:00
|
|
|
return Game::Dvar_RegisterString(dvarName, value, flag.val, description);
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
2021-09-08 16:54:43 -04:00
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
template<> Dvar::Var Dvar::Register(const char* dvarName, int value, int min, int max, Flag flag, const char* description)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-03-08 07:20:28 -05:00
|
|
|
return Game::Dvar_RegisterInt(dvarName, value, min, max, flag.val, description);
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
2021-09-08 16:54:43 -04:00
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
template<> Dvar::Var Dvar::Register(const char* dvarName, float value, float min, float max, Flag flag, const char* description)
|
2020-07-22 23:35:42 -04:00
|
|
|
{
|
2022-03-08 07:20:28 -05:00
|
|
|
return Game::Dvar_RegisterFloat(dvarName, value, min, max, flag.val, description);
|
2020-07-22 23:35:42 -04:00
|
|
|
}
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2021-10-04 16:03:56 -04:00
|
|
|
void Dvar::ResetDvarsValue()
|
|
|
|
{
|
2022-11-02 09:40:45 -04:00
|
|
|
if (!Utils::IO::FileExists(ArchiveDvarPath))
|
2022-01-24 14:56:17 -05:00
|
|
|
return;
|
2021-12-06 07:27:28 -05:00
|
|
|
|
|
|
|
Command::Execute("exec archivedvars.cfg", true);
|
|
|
|
// Clean up
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::IO::RemoveFile(ArchiveDvarPath);
|
2021-10-04 16:03:56 -04:00
|
|
|
}
|
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
Game::dvar_t* Dvar::Dvar_RegisterName(const char* name, const char* /*default*/, std::uint16_t flags, const char* description)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
|
|
|
// Name watcher
|
2022-06-16 10:15:26 -04:00
|
|
|
if (!Dedicated::IsEnabled() && !ZoneBuilder::IsEnabled())
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-06-16 10:15:26 -04:00
|
|
|
Scheduler::Loop([]
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2022-06-16 10:15:26 -04:00
|
|
|
static std::string lastValidName = "Unknown Soldier";
|
2022-11-02 09:40:45 -04:00
|
|
|
auto name = Name.get<std::string>();
|
2022-06-16 10:15:26 -04:00
|
|
|
|
|
|
|
// Don't perform any checks if name didn't change
|
|
|
|
if (name == lastValidName) return;
|
|
|
|
|
2022-11-29 09:18:10 -05:00
|
|
|
Utils::String::Trim(name);
|
|
|
|
std::string saneName = TextRenderer::StripAllTextIcons(TextRenderer::StripColors(name));
|
2022-06-16 10:15:26 -04:00
|
|
|
if (saneName.size() < 3 || (saneName[0] == '[' && saneName[1] == '{'))
|
|
|
|
{
|
2022-11-02 09:40:45 -04:00
|
|
|
Logger::PrintError(Game::CON_CHANNEL_ERROR, "Username '{}' is invalid. It must at least be 3 characters long and not appear empty!\n", name);
|
|
|
|
Name.set(lastValidName);
|
2022-06-16 10:15:26 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastValidName = name;
|
|
|
|
Friends::UpdateName();
|
|
|
|
}
|
|
|
|
}, Scheduler::CLIENT, 3s); // Don't need to do this every frame
|
|
|
|
}
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2017-02-10 04:19:36 -05:00
|
|
|
std::string username = "Unknown Soldier";
|
|
|
|
|
|
|
|
if (Steam::Proxy::SteamFriends)
|
|
|
|
{
|
|
|
|
const char* steamName = Steam::Proxy::SteamFriends->GetPersonaName();
|
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
if (steamName && *steamName != '\0')
|
2017-02-10 04:19:36 -05:00
|
|
|
{
|
|
|
|
username = steamName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
Name = Register<const char*>(name, username.data(), flags | Game::DVAR_ARCHIVE, description);
|
|
|
|
return Name.get<Game::dvar_t*>();
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
|
2022-02-03 06:44:35 -05:00
|
|
|
void Dvar::SetFromStringByNameSafeExternal(const char* dvarName, const char* string)
|
2017-07-09 07:36:13 -04:00
|
|
|
{
|
2022-11-02 09:40:45 -04:00
|
|
|
static std::array<const char*, 8> exceptions =
|
2017-07-09 07:36:13 -04:00
|
|
|
{
|
|
|
|
"ui_showEndOfGame",
|
|
|
|
"systemlink",
|
|
|
|
"splitscreen",
|
|
|
|
"onlinegame",
|
|
|
|
"party_maxplayers",
|
|
|
|
"xblive_privateserver",
|
|
|
|
"xblive_rankedmatch",
|
|
|
|
"ui_mptype",
|
|
|
|
};
|
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
for (const auto& entry : exceptions)
|
2017-07-09 07:36:13 -04:00
|
|
|
{
|
2022-11-02 09:40:45 -04:00
|
|
|
if (Utils::String::Compare(dvarName, entry))
|
2017-07-09 07:36:13 -04:00
|
|
|
{
|
2022-11-02 09:40:45 -04:00
|
|
|
Game::Dvar_SetFromStringByNameFromSource(dvarName, string, Game::DVAR_SOURCE_INTERNAL);
|
2022-02-03 06:44:35 -05:00
|
|
|
return;
|
2017-07-09 07:36:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
SetFromStringByNameExternal(dvarName, string);
|
2017-07-09 07:36:13 -04:00
|
|
|
}
|
|
|
|
|
2022-02-03 06:44:35 -05:00
|
|
|
void Dvar::SetFromStringByNameExternal(const char* dvarName, const char* string)
|
2017-02-18 05:39:01 -05:00
|
|
|
{
|
2022-11-02 09:40:45 -04:00
|
|
|
Game::Dvar_SetFromStringByNameFromSource(dvarName, string, Game::DVAR_SOURCE_EXTERNAL);
|
2017-02-18 05:39:01 -05:00
|
|
|
}
|
|
|
|
|
2022-06-26 08:58:45 -04:00
|
|
|
bool Dvar::AreArchiveDvarsProtected()
|
|
|
|
{
|
|
|
|
static std::optional<bool> flag;
|
|
|
|
|
|
|
|
if (!flag.has_value())
|
|
|
|
{
|
|
|
|
flag.emplace(Flags::HasFlag("protect-saved-dvars"));
|
|
|
|
}
|
|
|
|
|
|
|
|
return flag.value();
|
|
|
|
}
|
|
|
|
|
2021-12-04 13:34:19 -05:00
|
|
|
void Dvar::SaveArchiveDvar(const Game::dvar_t* var)
|
|
|
|
{
|
2022-11-02 09:40:45 -04:00
|
|
|
if (!Utils::IO::FileExists(ArchiveDvarPath))
|
2021-12-04 13:34:19 -05:00
|
|
|
{
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::IO::WriteFile(ArchiveDvarPath, "// generated by IW4x, do not modify\n");
|
2021-12-04 13:34:19 -05:00
|
|
|
}
|
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::IO::WriteFile(ArchiveDvarPath, Utils::String::VA("seta %s \"%s\"\n", var->name, Game::Dvar_DisplayableValue(var)), true);
|
2021-12-04 13:34:19 -05:00
|
|
|
}
|
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
void Dvar::DvarSetFromStringByName_Stub(const char* dvarName, const char* value)
|
2021-10-03 16:23:26 -04:00
|
|
|
{
|
2021-12-04 13:34:19 -05:00
|
|
|
// Save the dvar original value if it has the archive flag
|
|
|
|
const auto* dvar = Game::Dvar_FindVar(dvarName);
|
2022-07-02 13:52:57 -04:00
|
|
|
if (dvar != nullptr && dvar->flags & Game::DVAR_ARCHIVE)
|
2021-12-04 13:34:19 -05:00
|
|
|
{
|
2022-11-02 09:40:45 -04:00
|
|
|
if (AreArchiveDvarsProtected())
|
2022-06-26 08:58:45 -04:00
|
|
|
{
|
|
|
|
Logger::Print(Game::CON_CHANNEL_CONSOLEONLY, "Not allowing server to override saved dvar '{}'\n", dvarName);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG_DVARS
|
|
|
|
Logger::Print(Game::CON_CHANNEL_CONSOLEONLY, "Server is overriding saved dvar '{}'\n", dvarName);
|
|
|
|
#endif
|
2022-11-02 09:40:45 -04:00
|
|
|
SaveArchiveDvar(dvar);
|
2021-12-04 13:34:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
Utils::Hook::Call<void(const char*, const char*)>(0x4F52E0)(dvarName, value);
|
2021-10-03 16:23:26 -04:00
|
|
|
}
|
|
|
|
|
2022-07-02 13:52:57 -04:00
|
|
|
void Dvar::OnRegisterVariant([[maybe_unused]] Game::dvar_t* dvar)
|
|
|
|
{
|
|
|
|
#ifdef _DEBUG
|
|
|
|
dvar->flags &= ~Game::DVAR_CHEAT;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) void Dvar::Dvar_RegisterVariant_Stub()
|
|
|
|
{
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
pushad
|
|
|
|
|
|
|
|
push eax
|
2022-11-02 09:40:45 -04:00
|
|
|
call OnRegisterVariant
|
2022-07-02 13:52:57 -04:00
|
|
|
add esp, 0x4
|
|
|
|
|
|
|
|
popad
|
|
|
|
|
|
|
|
// Game's code
|
|
|
|
pop edi
|
|
|
|
pop esi
|
|
|
|
pop ebp
|
|
|
|
pop ebx
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
const char* Dvar::Dvar_EnumToString_Stub(const Game::dvar_t* dvar)
|
|
|
|
{
|
|
|
|
assert(dvar);
|
|
|
|
assert(dvar->name);
|
|
|
|
assert(dvar->type == Game::DVAR_TYPE_ENUM);
|
|
|
|
assert(dvar->domain.enumeration.strings);
|
|
|
|
assert(dvar->current.integer >= 0 && dvar->current.integer < dvar->domain.enumeration.stringCount || dvar->current.integer == 0);
|
|
|
|
|
|
|
|
// Fix nullptr crash
|
|
|
|
if (!dvar || dvar->domain.enumeration.stringCount == 0)
|
|
|
|
{
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
return dvar->domain.enumeration.strings[dvar->current.integer];
|
|
|
|
}
|
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
Dvar::Dvar()
|
|
|
|
{
|
|
|
|
// set flags of cg_drawFPS to archive
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook::Or<std::uint8_t>(0x4F8F69, Game::DVAR_ARCHIVE);
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2021-03-18 20:02:48 -04:00
|
|
|
// un-cheat camera_thirdPersonCrosshairOffset and add archive flags
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook::Xor<std::uint8_t>(0x447B41, Game::DVAR_CHEAT | Game::DVAR_ARCHIVE);
|
2021-03-18 20:02:48 -04:00
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
// un-cheat cg_fov and add archive flags
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook::Xor<std::uint8_t>(0x4F8E35, Game::DVAR_CHEAT | Game::DVAR_ARCHIVE);
|
2020-12-04 16:04:50 -05:00
|
|
|
|
|
|
|
// un-cheat cg_fovscale and add archive flags
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook::Xor<std::uint8_t>(0x4F8E68, Game::DVAR_CHEAT | Game::DVAR_ARCHIVE);
|
2017-01-19 16:23:59 -05:00
|
|
|
|
|
|
|
// un-cheat cg_debugInfoCornerOffset and add archive flags
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook::Xor<std::uint8_t>(0x4F8FC2, Game::DVAR_CHEAT | Game::DVAR_ARCHIVE);
|
2017-01-19 16:23:59 -05:00
|
|
|
|
|
|
|
// remove archive flags for cg_hudchatposition
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook::Xor<std::uint8_t>(0x4F9992, Game::DVAR_ARCHIVE);
|
2017-01-19 16:23:59 -05:00
|
|
|
|
|
|
|
// remove write protection from fs_game
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook::Xor<std::uint32_t>(0x6431EA, Game::DVAR_INIT);
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2022-03-17 14:50:20 -04:00
|
|
|
// set cg_fov max to 160.0
|
|
|
|
// because that's the max on SP
|
|
|
|
static float cg_Fov = 160.0f;
|
|
|
|
Utils::Hook::Set<float*>(0x4F8E28, &cg_Fov);
|
2017-01-19 16:23:59 -05:00
|
|
|
|
|
|
|
// set max volume to 1
|
|
|
|
static float volume = 1.0f;
|
|
|
|
Utils::Hook::Set<float*>(0x408078, &volume);
|
|
|
|
|
|
|
|
// Uncheat ui_showList
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook::Xor<std::uint8_t>(0x6310DC, Game::DVAR_CHEAT);
|
2017-01-19 16:23:59 -05:00
|
|
|
|
|
|
|
// Uncheat ui_debugMode
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook::Xor<std::uint8_t>(0x6312DE, Game::DVAR_CHEAT);
|
2017-01-19 16:23:59 -05:00
|
|
|
|
|
|
|
// Hook dvar 'name' registration
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook(0x40531C, Dvar_RegisterName, HOOK_CALL).install()->quick();
|
2017-02-18 05:39:01 -05:00
|
|
|
|
2020-10-30 19:08:21 -04:00
|
|
|
// un-cheat safeArea_* and add archive flags
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook::Xor<std::uint32_t>(0x42E3F5, Game::DVAR_ROM | Game::DVAR_ARCHIVE); //safeArea_adjusted_horizontal
|
|
|
|
Utils::Hook::Xor<std::uint32_t>(0x42E423, Game::DVAR_ROM | Game::DVAR_ARCHIVE); //safeArea_adjusted_vertical
|
|
|
|
Utils::Hook::Xor<std::uint8_t>(0x42E398, Game::DVAR_CHEAT | Game::DVAR_ARCHIVE); //safeArea_horizontal
|
|
|
|
Utils::Hook::Xor<std::uint8_t>(0x42E3C4, Game::DVAR_CHEAT | Game::DVAR_ARCHIVE); //safeArea_vertical
|
2020-10-30 19:08:21 -04:00
|
|
|
|
2017-02-18 05:39:01 -05:00
|
|
|
// Don't allow setting cheat protected dvars via menus
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook(0x63C897, SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
|
|
|
Utils::Hook(0x63CA96, SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
|
|
|
Utils::Hook(0x63CDB5, SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
|
|
|
Utils::Hook(0x635E47, SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
2017-07-09 07:36:13 -04:00
|
|
|
|
2022-02-03 06:44:35 -05:00
|
|
|
// Script_SetDvar
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook(0x63444C, SetFromStringByNameSafeExternal, HOOK_CALL).install()->quick();
|
2017-07-09 07:36:13 -04:00
|
|
|
|
|
|
|
// Slider
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook(0x636159, SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
|
|
|
Utils::Hook(0x636189, SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
|
|
|
Utils::Hook(0x6364EA, SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
2017-07-09 07:36:13 -04:00
|
|
|
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook(0x636207, SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
|
|
|
Utils::Hook(0x636608, SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
|
|
|
Utils::Hook(0x636695, SetFromStringByNameExternal, HOOK_CALL).install()->quick();
|
2021-10-04 16:03:56 -04:00
|
|
|
|
|
|
|
// Hook Dvar_SetFromStringByName inside CG_SetClientDvarFromServer so we can reset dvars when the player leaves the server
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook(0x59386A, DvarSetFromStringByName_Stub, HOOK_CALL).install()->quick();
|
2021-12-04 13:34:19 -05:00
|
|
|
|
2021-12-06 07:35:06 -05:00
|
|
|
// If the game closed abruptly, the dvars would not have been restored
|
2022-11-02 09:40:45 -04:00
|
|
|
Scheduler::Once(ResetDvarsValue, Scheduler::Pipeline::MAIN);
|
2022-06-13 14:16:57 -04:00
|
|
|
|
|
|
|
// Reset archive dvars when client leaves a server
|
2022-11-02 09:40:45 -04:00
|
|
|
Events::OnSteamDisconnect(ResetDvarsValue);
|
2022-07-02 13:52:57 -04:00
|
|
|
|
|
|
|
// For debugging
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::Hook(0x6483FA, Dvar_RegisterVariant_Stub, HOOK_JUMP).install()->quick();
|
|
|
|
Utils::Hook(0x648438, Dvar_RegisterVariant_Stub, HOOK_JUMP).install()->quick();
|
|
|
|
|
|
|
|
// Fix crash
|
|
|
|
Utils::Hook(0x4B7120, Dvar_EnumToString_Stub, HOOK_JUMP).install()->quick();
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
Dvar::~Dvar()
|
|
|
|
{
|
2022-11-02 09:40:45 -04:00
|
|
|
Utils::IO::RemoveFile(ArchiveDvarPath);
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
}
|