[General] Reduce usage of dvar lookup func

This commit is contained in:
Diavolo 2022-08-10 23:03:26 +02:00
parent 49ed76807b
commit d67e6ce686
No known key found for this signature in database
GPG Key ID: FA77F074E98D98A5
26 changed files with 186 additions and 131 deletions

View File

@ -225,7 +225,7 @@ namespace Components
{
Command::Add("banClient", [](Command::Params* params)
{
if (!Dvar::Var("sv_running").get<bool>())
if (!(*Game::com_sv_running)->current.enabled)
{
Logger::Print("Server is not running.\n");
return;
@ -269,7 +269,7 @@ namespace Components
Command::Add("unbanClient", [](Command::Params* params)
{
if (!Dvar::Var("sv_running").get<bool>())
if (!(*Game::com_sv_running)->current.enabled)
{
Logger::Print("Server is not running.\n");
return;

View File

@ -5,7 +5,6 @@ namespace Components
Dvar::Var Branding::CGDrawVersion;
Dvar::Var Branding::CGDrawVersionX;
Dvar::Var Branding::CGDrawVersionY;
Game::dvar_t** Branding::Version = reinterpret_cast<Game::dvar_t**>(0x1AD7930);
#ifdef _DEBUG
constexpr auto* BUILD_TYPE = "IW4x_DEV MP";
@ -25,12 +24,12 @@ namespace Components
auto* const placement = Game::ScrPlace_GetUnsafeFullPlacement();
auto* const font = Game::UI_GetFontHandle(placement, 0, 0.583f);
const auto width = Game::UI_TextWidth((*Version)->current.string, 0, font, fontScale);
const auto width = Game::UI_TextWidth((*Game::version)->current.string, 0, font, fontScale);
const auto height = Game::UI_TextHeight(font, fontScale);
Game::UI_DrawText(placement, (*Version)->current.string, maxChars, font, 1.0f - (CGDrawVersionX.get<float>() + static_cast<float>(width)),
Game::UI_DrawText(placement, (*Game::version)->current.string, maxChars, font, 1.0f - (CGDrawVersionX.get<float>() + static_cast<float>(width)),
1.0f - (CGDrawVersionY.get<float>() + static_cast<float>(height)), 3, 3, fontScale, shadowColor, 0);
Game::UI_DrawText(placement, (*Version)->current.string, maxChars, font, (0.0f - static_cast<float>(width)) - CGDrawVersionX.get<float>(),
Game::UI_DrawText(placement, (*Game::version)->current.string, maxChars, font, (0.0f - static_cast<float>(width)) - CGDrawVersionX.get<float>(),
(0.0f - static_cast<float>(height)) - CGDrawVersionY.get<float>(), 3, 3, fontScale, color, 0);
}

View File

@ -14,7 +14,6 @@ namespace Components
static Dvar::Var CGDrawVersion;
static Dvar::Var CGDrawVersionX;
static Dvar::Var CGDrawVersionY;
static Game::dvar_t** Version;
static void CG_DrawVersion();
static void CG_DrawVersion_Hk(int localClientNum);

View File

@ -7,10 +7,10 @@ namespace Components
float Bullet::BG_GetSurfacePenetrationDepthStub(const Game::WeaponDef* weapDef, int surfaceType)
{
assert(weapDef != nullptr);
assert(weapDef->penetrateType != Game::PenetrateType::PENETRATE_TYPE_NONE);
assert(weapDef->penetrateType < Game::PenetrateType::PENETRATE_TYPE_COUNT);
assert(static_cast<size_t>(surfaceType) < Game::materialSurfType_t::SURF_TYPE_COUNT);
assert(weapDef);
assert(weapDef->penetrateType != Game::PENETRATE_TYPE_NONE);
AssertIn(weapDef->penetrateType, Game::PENETRATE_TYPE_COUNT);
AssertIn(surfaceType, Game::SURF_TYPE_COUNT);
const auto penetrationDepth = BGSurfacePenetration.get<float>();
if (penetrationDepth > 0.0f)

View File

@ -287,7 +287,7 @@ namespace Components
{
Command::AddSV("muteClient", [](Command::Params* params)
{
if (!Dvar::Var("sv_running").get<bool>())
if (!(*Game::com_sv_running)->current.enabled)
{
Logger::Print("Server is not running.\n");
return;
@ -309,7 +309,7 @@ namespace Components
Command::AddSV("unmute", [](Command::Params* params)
{
if (!Dvar::Var("sv_running").get<bool>())
if (!(*Game::com_sv_running)->current.enabled)
{
Logger::Print("Server is not running.\n");
return;

View File

@ -9,7 +9,7 @@ namespace Components
const char* ClanTags::GetClanTagWithName(int clientNum, const char* playerName)
{
assert(static_cast<std::size_t>(clientNum) < Game::MAX_CLIENTS);
AssertIn(clientNum, Game::MAX_CLIENTS);
if (ClientState[clientNum][0] == '\0')
{
@ -96,7 +96,7 @@ namespace Components
char* ClanTags::GamerProfile_GetClanName(int controllerIndex)
{
assert(static_cast<std::size_t>(controllerIndex) < Game::MAX_LOCAL_CLIENTS);
AssertIn(controllerIndex, Game::MAX_LOCAL_CLIENTS);
assert(ClanName);
CL_SanitizeClanName();
@ -115,7 +115,7 @@ namespace Components
void ClanTags::ClientUserinfoChanged(const char* s, int clientNum)
{
assert(static_cast<std::size_t>(clientNum) < Game::MAX_CLIENTS);
AssertIn(clientNum, Game::MAX_CLIENTS);
auto* clanAbbrev = Game::Info_ValueForKey(s, "clanAbbrev");
@ -224,7 +224,7 @@ namespace Components
Game::PlayerCardData* ClanTags::PlayerCards_GetLiveProfileDataForController_Stub(const unsigned int controllerIndex)
{
auto* result = Utils::Hook::Call<Game::PlayerCardData*(unsigned int)>(0x463B90)(controllerIndex);
// controllerIndex should always be 0
AssertIn(controllerIndex, Game::MAX_LOCAL_CLIENTS);
Game::I_strncpyz(result->clanAbbrev, GamerProfile_GetClanName(static_cast<int>(controllerIndex)), sizeof(Game::PlayerCardData::clanAbbrev));
return result;

View File

@ -9,7 +9,7 @@ namespace Components
{
const auto entNum = ent->s.number;
if (!Dvar::Var("sv_cheats").get<bool>())
if (!(*Game::g_cheats)->current.enabled)
{
Logger::Debug("Cheats are disabled!");
Game::SV_GameSendServerCommand(entNum, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"GAME_CHEATSNOTENABLED\"", 0x65));
@ -359,6 +359,8 @@ namespace Components
ClientCommand::ClientCommand()
{
AssertOffset(Game::playerState_s, stats, 0x150);
// Hook call to ClientCommand in SV_ExecuteClientCommand so we may add custom commands
Utils::Hook(0x6259FA, ClientCommand::ClientCommandStub, HOOK_CALL).install()->quick();

View File

@ -44,8 +44,8 @@ namespace Components
void Console::RefreshStatus()
{
const auto mapname = Dvar::Var("mapname").get<std::string>();
const auto hostname = TextRenderer::StripColors(Dvar::Var("sv_hostname").get<std::string>());
const std::string mapname = (*Game::sv_mapname)->current.string;
const auto hostname = TextRenderer::StripColors((*Game::sv_hostname)->current.string);
if (Console::HasConsole)
{

View File

@ -104,12 +104,12 @@ namespace Components
Scheduler::Once([]
{
const auto partyEnable = Dvar::Var("party_enable").get<bool>();
auto mapname = Dvar::Var("mapname").get<std::string>();
std::string mapname = (*Game::sv_mapname)->current.string;
if (!partyEnable) // Time wrapping should not occur in party servers, but yeah...
{
if (mapname.empty()) mapname = "mp_rust";
Command::Execute(Utils::String::VA("map %s", mapname.data()), false);
Command::Execute(Utils::String::VA("map %s", mapname.data()), true);
}
}, Scheduler::Pipeline::SERVER);
@ -330,7 +330,7 @@ namespace Components
Scheduler::Loop([]
{
if (Dvar::Var("sv_running").get<bool>())
if ((*Game::com_sv_running)->current.enabled)
{
Dedicated::TransmitGuids();
}

View File

@ -354,9 +354,9 @@ namespace Components
// Run this on the main thread
Scheduler::Once([]
{
auto fsGame = Dvar::Var("fs_game");
fsGame.set(mod);
fsGame.get<Game::dvar_t*>()->modified = true;
Game::Dvar_SetString(*Game::fs_gameDirVar, mod.data());
const_cast<Game::dvar_t*>(*Game::fs_gameDirVar)->modified = true;
mod.clear();
Command::Execute("closemenu mod_download_popmenu", false);
@ -594,7 +594,7 @@ namespace Components
static std::string fsGamePre;
static nlohmann::json jsonList;
std::string fsGame = Dvar::Var("fs_game").get<std::string>();
const std::string fsGame = (*Game::fs_gameDirVar)->current.string;
if (!fsGame.empty() && fsGame != fsGamePre)
{
@ -698,7 +698,7 @@ namespace Components
}
std::string file;
std::string fsGame = Dvar::Var("fs_game").get<std::string>();
const std::string fsGame = (*Game::fs_gameDirVar)->current.string;
std::string path = Dvar::Var("fs_basepath").get<std::string>() + "\\" + (isMap ? "" : fsGame + "\\") + url;
if ((!isMap && fsGame.empty()) || !Utils::IO::ReadFile(path, &file))
@ -750,7 +750,7 @@ namespace Components
playerInfo["ping"] = 0;
playerInfo["name"] = "";
if (Dvar::Var("sv_running").get<bool>())
if ((*Game::com_sv_running)->current.enabled)
{
if (Game::svs_clients[i].state < 3) continue;

View File

@ -4,33 +4,33 @@ namespace Components
{
const char* Dvar::ArchiveDvarPath = "userraw/archivedvars.cfg";
Dvar::Var::Var(const std::string& dvarName) : Var()
Dvar::Var::Var(const std::string& dvarName)
{
this->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)
if (this->dvar_ == nullptr)
{
this->dvar = const_cast<Game::dvar_t*>(Game::Dvar_SetFromStringByNameFromSource(dvarName.data(), "",
this->dvar_ = const_cast<Game::dvar_t*>(Game::Dvar_SetFromStringByNameFromSource(dvarName.data(), "",
Game::DvarSetSource::DVAR_SOURCE_INTERNAL));
}
}
template <> Game::dvar_t* Dvar::Var::get()
{
return this->dvar;
return this->dvar_;
}
template <> const char* Dvar::Var::get()
{
if (this->dvar == nullptr)
if (this->dvar_ == nullptr)
return "";
if (this->dvar->type == Game::dvar_type::DVAR_TYPE_STRING
|| this->dvar->type == Game::dvar_type::DVAR_TYPE_ENUM)
if (this->dvar_->type == Game::DVAR_TYPE_STRING
|| this->dvar_->type == Game::DVAR_TYPE_ENUM)
{
if (this->dvar->current.string != nullptr)
return this->dvar->current.string;
if (this->dvar_->current.string != nullptr)
return this->dvar_->current.string;
}
return "";
@ -38,12 +38,12 @@ namespace Components
template <> int Dvar::Var::get()
{
if (this->dvar == nullptr)
if (this->dvar_ == nullptr)
return 0;
if (this->dvar->type == Game::dvar_type::DVAR_TYPE_INT || this->dvar->type == Game::dvar_type::DVAR_TYPE_ENUM)
if (this->dvar_->type == Game::DVAR_TYPE_INT || this->dvar_->type == Game::DVAR_TYPE_ENUM)
{
return this->dvar->current.integer;
return this->dvar_->current.integer;
}
return 0;
@ -51,12 +51,12 @@ namespace Components
template <> unsigned int Dvar::Var::get()
{
if (this->dvar == nullptr)
if (this->dvar_ == nullptr)
return 0;
if (this->dvar->type == Game::dvar_type::DVAR_TYPE_INT)
if (this->dvar_->type == Game::DVAR_TYPE_INT)
{
return this->dvar->current.unsignedInt;
return this->dvar_->current.unsignedInt;
}
return 0;
@ -64,12 +64,12 @@ namespace Components
template <> float Dvar::Var::get()
{
if (this->dvar == nullptr)
if (this->dvar_ == nullptr)
return 0.f;
if (this->dvar->type == Game::dvar_type::DVAR_TYPE_FLOAT)
if (this->dvar_->type == Game::DVAR_TYPE_FLOAT)
{
return this->dvar->current.value;
return this->dvar_->current.value;
}
return 0.f;
@ -79,13 +79,13 @@ namespace Components
{
static Game::vec4_t vector{0.f, 0.f, 0.f, 0.f};
if (this->dvar == nullptr)
if (this->dvar_ == nullptr)
return vector;
if (this->dvar->type == Game::dvar_type::DVAR_TYPE_FLOAT_2 || this->dvar->type == Game::dvar_type::DVAR_TYPE_FLOAT_3
|| this->dvar->type == Game::dvar_type::DVAR_TYPE_FLOAT_4)
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)
{
return this->dvar->current.vector;
return this->dvar_->current.vector;
}
return vector;
@ -93,12 +93,12 @@ namespace Components
template <> bool Dvar::Var::get()
{
if (this->dvar == nullptr)
if (this->dvar_ == nullptr)
return false;
if (this->dvar->type == Game::dvar_type::DVAR_TYPE_BOOL)
if (this->dvar_->type == Game::DVAR_TYPE_BOOL)
{
return this->dvar->current.enabled;
return this->dvar_->current.enabled;
}
return false;
@ -111,10 +111,10 @@ namespace Components
void Dvar::Var::set(const char* string)
{
assert(this->dvar->type == Game::DVAR_TYPE_STRING);
if (this->dvar)
assert(this->dvar_->type == Game::DVAR_TYPE_STRING);
if (this->dvar_)
{
Game::Dvar_SetString(this->dvar, string);
Game::Dvar_SetString(this->dvar_, string);
}
}
@ -125,58 +125,64 @@ namespace Components
void Dvar::Var::set(int integer)
{
assert(this->dvar->type == Game::DVAR_TYPE_INT);
if (this->dvar)
assert(this->dvar_->type == Game::DVAR_TYPE_INT);
if (this->dvar_)
{
Game::Dvar_SetInt(this->dvar, integer);
Game::Dvar_SetInt(this->dvar_, integer);
}
}
void Dvar::Var::set(float value)
{
assert(this->dvar->type == Game::DVAR_TYPE_FLOAT);
if (this->dvar)
assert(this->dvar_->type == Game::DVAR_TYPE_FLOAT);
if (this->dvar_)
{
Game::Dvar_SetFloat(this->dvar, value);
Game::Dvar_SetFloat(this->dvar_, value);
}
}
void Dvar::Var::set(bool enabled)
{
assert(this->dvar->type == Game::DVAR_TYPE_BOOL);
if (this->dvar)
assert(this->dvar_->type == Game::DVAR_TYPE_BOOL);
if (this->dvar_)
{
Game::Dvar_SetBool(this->dvar, enabled);
Game::Dvar_SetBool(this->dvar_, enabled);
}
}
void Dvar::Var::setRaw(int integer)
{
assert(this->dvar->type == Game::DVAR_TYPE_INT);
if (this->dvar)
assert(this->dvar_->type == Game::DVAR_TYPE_INT);
if (this->dvar_)
{
this->dvar->current.integer = integer;
this->dvar->latched.integer = integer;
this->dvar_->current.integer = integer;
this->dvar_->latched.integer = integer;
}
}
void Dvar::Var::setRaw(float value)
{
assert(this->dvar->type == Game::DVAR_TYPE_FLOAT);
if (this->dvar)
assert(this->dvar_->type == Game::DVAR_TYPE_FLOAT);
if (this->dvar_)
{
this->dvar->current.value = value;
this->dvar->latched.value = value;
this->dvar_->current.value = value;
this->dvar_->latched.value = value;
}
}
void Dvar::Var::setRaw(bool enabled)
{
assert(this->dvar->type == Game::DVAR_TYPE_BOOL);
if (this->dvar)
assert(this->dvar_->type == Game::DVAR_TYPE_BOOL);
if (this->dvar_)
{
this->dvar->current.enabled = enabled;
this->dvar->latched.enabled = enabled;
this->dvar_->current.enabled = enabled;
this->dvar_->latched.enabled = enabled;
}
}

View File

@ -17,9 +17,9 @@ namespace Components
class Var
{
public:
Var() : dvar(nullptr) {}
Var(const Var& obj) { this->dvar = obj.dvar; }
Var(Game::dvar_t* _dvar) : dvar(_dvar) {}
Var() : dvar_(nullptr) {}
Var(const Var& obj) { this->dvar_ = obj.dvar_; }
Var(Game::dvar_t* dvar) : dvar_(dvar) {}
Var(DWORD ppdvar) : Var(*reinterpret_cast<Game::dvar_t**>(ppdvar)) {}
Var(const std::string& dvarName);
@ -37,7 +37,7 @@ namespace Components
void setRaw(bool enabled);
private:
Game::dvar_t* dvar;
Game::dvar_t* dvar_;
};
Dvar();

View File

@ -50,12 +50,10 @@ namespace Components
void Script::RuntimeError(const char* codePos, unsigned int index, const char* msg, const char* dialogMessage)
{
const auto developer = Dvar::Var("developer").get<int>();
// Allow error messages to be printed if developer mode is on
// Should check scrVarPub.developer but it's absent
// in this version of the game so let's check the dvar
if (!Game::scrVmPub->terminal_error && !developer)
if (!Game::scrVmPub->terminal_error && !(*Game::com_developer)->current.integer)
return;
// If were are developing let's call RuntimeErrorInternal
@ -630,7 +628,7 @@ namespace Components
Utils::Hook(0x61E92E, Script::VMExecuteInternalStub, HOOK_JUMP).install()->quick();
Utils::Hook::Nop(0x61E933, 1);
Scheduler::Loop([]()
Scheduler::Loop([]
{
if (!Game::SV_Loaded())
return;
@ -639,11 +637,12 @@ namespace Components
if (Script::LastFrameTime != -1)
{
const auto timeScale = Dvar::Var("timescale").get<float>();
const auto timeTaken = static_cast<int>((nowMs - Script::LastFrameTime) * timeScale);
const auto timeTaken = (nowMs - Script::LastFrameTime) * static_cast<int>((*Game::com_timescale)->current.value);
if (timeTaken >= 500)
{
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "Hitch warning: {} msec frame time\n", timeTaken);
}
}
Script::LastFrameTime = nowMs;

View File

@ -5,10 +5,6 @@ namespace Components
Dvar::Var MapRotation::SVRandomMapRotation;
Dvar::Var MapRotation::SVDontRotate;
Game::dvar_t** MapRotation::SVMapRotation = reinterpret_cast<Game::dvar_t**>(0x62C7C44);
Game::dvar_t** MapRotation::SVMapRotationCurrent = reinterpret_cast<Game::dvar_t**>(0x2098DF0);
Game::dvar_t** MapRotation::SVMapname = reinterpret_cast<Game::dvar_t**>(0x2098DDC);
MapRotation::RotationData MapRotation::DedicatedRotation;
MapRotation::RotationData::RotationData()
@ -107,7 +103,7 @@ namespace Components
}
catch (const std::exception& ex)
{
Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: {} contains invalid data!\n", ex.what(), (*SVMapRotation)->name);
Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: {} contains invalid data!\n", ex.what(), (*Game::sv_mapRotation)->name);
}
Logger::Debug("DedicatedRotation size after parsing is '{}'", DedicatedRotation.getEntriesSize());
@ -178,7 +174,7 @@ namespace Components
void MapRotation::RestartCurrentMap()
{
std::string svMapname = (*SVMapname)->current.string;
std::string svMapname = (*Game::sv_mapname)->current.string;
if (svMapname.empty())
{
@ -224,24 +220,24 @@ namespace Components
assert(!data.empty());
// Ook, ook, eek
Logger::Warning(Game::CON_CHANNEL_SERVER, "You are using deprecated {}", (*SVMapRotationCurrent)->name);
Logger::Warning(Game::CON_CHANNEL_SERVER, "You are using deprecated {}", (*Game::sv_mapRotationCurrent)->name);
RotationData rotationCurrent;
try
{
Logger::Debug("Parsing {}", (*SVMapRotationCurrent)->name);
Logger::Debug("Parsing {}", (*Game::sv_mapRotationCurrent)->name);
rotationCurrent.parse(data);
}
catch (const std::exception& ex)
{
Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: {} contains invalid data!\n", ex.what(), (*SVMapRotationCurrent)->name);
Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: {} contains invalid data!\n", ex.what(), (*Game::sv_mapRotationCurrent)->name);
}
Game::Dvar_SetString(*SVMapRotationCurrent, "");
Game::Dvar_SetString(*Game::sv_mapRotationCurrent, "");
if (rotationCurrent.getEntriesSize() == 0)
{
Logger::Print(Game::CON_CHANNEL_SERVER, "{} is empty or contains invalid data. Restarting map\n", (*SVMapRotationCurrent)->name);
Logger::Print(Game::CON_CHANNEL_SERVER, "{} is empty or contains invalid data. Restarting map\n", (*Game::sv_mapRotationCurrent)->name);
RestartCurrentMap();
return;
}
@ -272,15 +268,15 @@ namespace Components
Logger::Print(Game::CON_CHANNEL_SERVER, "Rotating map...\n");
// This takes priority because of backwards compatibility
const std::string mapRotationCurrent = (*SVMapRotationCurrent)->current.string;
const std::string mapRotationCurrent = (*Game::sv_mapRotationCurrent)->current.string;
if (!mapRotationCurrent.empty())
{
Logger::Debug("Applying {}", (*SVMapRotationCurrent)->name);
Logger::Debug("Applying {}", (*Game::sv_mapRotationCurrent)->name);
ApplyMapRotationCurrent(mapRotationCurrent);
return;
}
const std::string mapRotation = (*SVMapRotation)->current.string;
const std::string mapRotation = (*Game::sv_mapRotation)->current.string;
// People may have sv_mapRotation empty because they only use 'addMap' or 'addGametype'
if (!mapRotation.empty())
{
@ -290,7 +286,7 @@ namespace Components
if (DedicatedRotation.getEntriesSize() == 0)
{
Logger::Print(Game::CON_CHANNEL_SERVER, "{} is empty or contains invalid data. Restarting map\n", (*SVMapRotation)->name);
Logger::Print(Game::CON_CHANNEL_SERVER, "{} is empty or contains invalid data. Restarting map\n", (*Game::sv_mapRotation)->name);
RestartCurrentMap();
return;
}

View File

@ -45,10 +45,6 @@ namespace Components
// Rotation Dvars
static Dvar::Var SVRandomMapRotation;
static Dvar::Var SVDontRotate;
// Game Dvars
static Game::dvar_t** SVMapRotation;
static Game::dvar_t** SVMapRotationCurrent;
static Game::dvar_t** SVMapname;
// Holds the parsed data from sv_mapRotation
static RotationData DedicatedRotation;

View File

@ -139,7 +139,7 @@ namespace Components
bool Party::IsInLobby()
{
return (!Dvar::Var("sv_running").get<bool>() && PartyEnable.get<bool>() && Dvar::Var("party_host").get<bool>());
return (!(*Game::com_sv_running)->current.enabled && PartyEnable.get<bool>() && Dvar::Var("party_host").get<bool>());
}
bool Party::IsInUserMapLobby()
@ -338,9 +338,9 @@ namespace Components
Utils::InfoString info;
info.set("challenge", Utils::ParseChallenge(data));
info.set("gamename", "IW4");
info.set("hostname", Dvar::Var("sv_hostname").get<const char*>());
info.set("gametype", Dvar::Var("g_gametype").get<const char*>());
info.set("fs_game", Dvar::Var("fs_game").get<const char*>());
info.set("hostname", (*Game::sv_hostname)->current.string);
info.set("gametype", (*Game::sv_gametype)->current.string);
info.set("fs_game", (*Game::fs_gameDirVar)->current.string);
info.set("xuid", Utils::String::VA("%llX", Steam::SteamUser()->GetSteamID().bits));
info.set("clients", Utils::String::VA("%i", clientCount));
info.set("bots", Utils::String::VA("%i", botCount));
@ -416,7 +416,7 @@ namespace Components
bool isUsermap = !info.get("usermaphash").empty();
unsigned int usermapHash = atoi(info.get("usermaphash").data());
std::string mod = Dvar::Var("fs_game").get<std::string>();
std::string mod = (*Game::fs_gameDirVar)->current.string;
// set fast server stuff here so its updated when we go to download stuff
if (info.get("wwwDownload") == "1"s)
@ -468,7 +468,7 @@ namespace Components
}
else if (!Dvar::Var("fs_game").get<std::string>().empty() && info.get("fs_game").empty())
{
Dvar::Var("fs_game").set("");
Game::Dvar_SetString(*Game::fs_gameDirVar, "");
if (Dvar::Var("cl_modVidRestart").get<bool>())
{

View File

@ -266,9 +266,8 @@ namespace Components
float playerPosition[3]{ clientEntity->r.currentOrigin[0], clientEntity->r.currentOrigin[1], clientEntity->r.currentOrigin[2] };
const auto mapName = Dvar::Var("mapname").get<const char*>();
auto scene = Game::scene;
auto gfxAsset = Game::DB_FindXAssetEntry(Game::XAssetType::ASSET_TYPE_GFXWORLD, Utils::String::VA("maps/mp/%s.d3dbsp", mapName));
auto gfxAsset = Game::DB_FindXAssetEntry(Game::XAssetType::ASSET_TYPE_GFXWORLD, Utils::String::VA("maps/mp/%s.d3dbsp", (*Game::sv_mapname)->current.string));
if (gfxAsset == nullptr)
{
@ -368,9 +367,8 @@ namespace Components
float playerPosition[3]{ clientEntity->r.currentOrigin[0], clientEntity->r.currentOrigin[1], clientEntity->r.currentOrigin[2] };
const auto mapName = Dvar::Var("mapname").get<const char*>();
auto scene = Game::scene;
auto gfxAsset = Game::DB_FindXAssetEntry(Game::XAssetType::ASSET_TYPE_GFXWORLD, Utils::String::VA("maps/mp/%s.d3dbsp", mapName));
auto gfxAsset = Game::DB_FindXAssetEntry(Game::XAssetType::ASSET_TYPE_GFXWORLD, Utils::String::VA("maps/mp/%s.d3dbsp", (*Game::sv_mapname)->current.string));
if (gfxAsset == nullptr)
{

View File

@ -139,7 +139,7 @@ namespace Components
info.set("sv_maxclients", Utils::String::VA("%i", maxClientCount));
info.set("protocol", Utils::String::VA("%i", PROTOCOL));
info.set("shortversion", SHORTVERSION);
info.set("mapname", Dvar::Var("mapname").get<const char*>());
info.set("mapname", (*Game::sv_mapname)->current.string);
info.set("isPrivate", (Dvar::Var("g_password").get<std::string>().empty() ? "0" : "1"));
info.set("checksum", Utils::String::VA("%X", Utils::Cryptography::JenkinsOneAtATime::Compute(Utils::String::VA("%u", Game::Sys_Milliseconds()))));
@ -158,7 +158,7 @@ namespace Components
{
info.set("matchtype", "1");
}
else if (Dvar::Var("sv_running").get<bool>()) // Match hosting
else if ((*Game::com_sv_running)->current.enabled) // Match hosting
{
info.set("matchtype", "2");
}
@ -202,7 +202,7 @@ namespace Components
auto ping = 0;
std::string name;
if (Dvar::Var("sv_running").get<bool>())
if ((*Game::com_sv_running)->current.enabled)
{
if (Game::svs_clients[i].state < 3) continue;

View File

@ -65,11 +65,11 @@ namespace Components
int Stats::SaveStats(char* dest, const char* folder, const char* buffer, size_t length)
{
const auto fs_game = Game::Dvar_FindVar("fs_game");
assert(*Game::fs_gameDirVar);
if (fs_game && fs_game->current.string && strlen(fs_game->current.string) && !strncmp(fs_game->current.string, "mods/", 5))
if (!std::strcmp((*Game::fs_gameDirVar)->current.string, "mods/"))
{
folder = fs_game->current.string;
folder = (*Game::fs_gameDirVar)->current.string;
}
return Utils::Hook::Call<int(char*, const char*, const char*, size_t)>(0x426450)(dest, folder, buffer, length);

View File

@ -1287,7 +1287,7 @@ namespace Components
std::string TextRenderer::StripColors(const std::string& in)
{
char buffer[1000] = { 0 }; // Should be more than enough
char buffer[1024] = {0}; // 1024 is a lucky number in the engine
StripColors(in.data(), buffer, sizeof(buffer));
return std::string(buffer);
}

View File

@ -162,8 +162,8 @@ namespace Components
Game::Com_Printf(channel, message, file);
Theatre::CurrentInfo.name = file;
Theatre::CurrentInfo.mapname = Dvar::Var("mapname").get<const char*>();
Theatre::CurrentInfo.gametype = Dvar::Var("g_gametype").get<const char*>();
Theatre::CurrentInfo.mapname = (*Game::sv_mapname)->current.string;
Theatre::CurrentInfo.gametype = (*Game::sv_gametype)->current.string;
Theatre::CurrentInfo.author = Steam::SteamFriends()->GetPersonaName();
Theatre::CurrentInfo.length = Game::Sys_Milliseconds();
std::time(&Theatre::CurrentInfo.timeStamp);

27
src/Game/Dvars.cpp Normal file
View File

@ -0,0 +1,27 @@
#include <STDInclude.hpp>
namespace Game
{
const dvar_t** com_developer = reinterpret_cast<const dvar_t**>(0x1AD78E8);
const dvar_t** com_developer_script = reinterpret_cast<const dvar_t**>(0x1AD8F10);
const dvar_t** com_timescale = reinterpret_cast<const dvar_t**>(0x1AD7920);
const dvar_t** com_sv_running = reinterpret_cast<const dvar_t**>(0x1AD7934);
const dvar_t** dev_timescale = reinterpret_cast<const dvar_t**>(0x1AD8F20);
const dvar_t** dvar_cheats = reinterpret_cast<const dvar_t**>(0x63F3348);
const dvar_t** fs_gameDirVar = reinterpret_cast<const dvar_t**>(0x63D0CC0);
const dvar_t** sv_hostname = reinterpret_cast<const dvar_t**>(0x2098D98);
const dvar_t** sv_gametype = reinterpret_cast<const dvar_t**>(0x2098DD4);
const dvar_t** sv_mapname = reinterpret_cast<const dvar_t**>(0x2098DDC);
const dvar_t** sv_mapRotation = reinterpret_cast<const dvar_t**>(0x62C7C44);
const dvar_t** sv_mapRotationCurrent = reinterpret_cast<const dvar_t**>(0x2098DF0);
const dvar_t** sv_maxclients = reinterpret_cast<const dvar_t**>(0x2098D90);
const dvar_t** sv_cheats = reinterpret_cast<const dvar_t**>(0x2098DE0);
const dvar_t** g_cheats = reinterpret_cast<const dvar_t**>(0x1A45D54);
const dvar_t** version = reinterpret_cast<const dvar_t**>(0x1AD7930);
}

28
src/Game/Dvars.hpp Normal file
View File

@ -0,0 +1,28 @@
#pragma once
// Put game dvars here
namespace Game
{
extern const dvar_t** com_developer;
extern const dvar_t** com_developer_script;
extern const dvar_t** com_timescale;
extern const dvar_t** com_sv_running;
extern const dvar_t** dev_timescale;
extern const dvar_t** dvar_cheats;
extern const dvar_t** fs_gameDirVar;
extern const dvar_t** sv_hostname;
extern const dvar_t** sv_gametype;
extern const dvar_t** sv_mapname;
extern const dvar_t** sv_mapRotation;
extern const dvar_t** sv_mapRotationCurrent;
extern const dvar_t** sv_maxclients;
extern const dvar_t** sv_cheats;
extern const dvar_t** g_cheats;
extern const dvar_t** version;
}

View File

@ -853,10 +853,9 @@ namespace Game
void SV_GameDropClient(int clientNum, const char* reason)
{
const auto maxClients = Dvar_FindVar("sv_maxclients")->current.integer;
assert(maxClients >= 1 && maxClients <= 18);
assert((*sv_maxclients)->current.integer >= 1 && (*sv_maxclients)->current.integer <= 18);
if (clientNum >= 0 && clientNum < maxClients)
if (clientNum >= 0 && clientNum < (*sv_maxclients)->current.integer)
{
SV_DropClient(&svs_clients[clientNum], reason, true);
}

View File

@ -107,6 +107,10 @@ using namespace std::literals;
static_assert(offsetof(x, y) == (offset), \
#x "::" #y " is not at the right offset. Must be at " #offset)
#define AssertIn(x, y) assert(static_cast<unsigned int>(x) < static_cast<unsigned int>(y))
#define AssertUnreachable assert(0 && "unreachable")
// Protobuf
#include "proto/session.pb.h"
#include "proto/party.pb.h"
@ -143,6 +147,7 @@ using namespace std::literals;
#include "Steam/Steam.hpp" // Some definitions are used in functions and structs
#include "Game/Structs.hpp"
#include "Game/Dvars.hpp"
#include "Game/Functions.hpp"
#include <Game/Scripting/Function.hpp>
#include <Game/Scripting/StackIsolation.hpp>

View File

@ -2,7 +2,7 @@
namespace Utils::Json
{
std::string TypeToString(nlohmann::json::value_t type)
std::string TypeToString(const nlohmann::json::value_t type)
{
switch (type)
{
@ -27,6 +27,7 @@ namespace Utils::Json
case nlohmann::json::value_t::discarded:
return "discarded";
default:
AssertUnreachable;
return "null";
}
}