Remove the most hated callback in the source code

This commit is contained in:
Diavolo 2022-05-27 12:19:28 +02:00
parent 8538de0f96
commit 9cb9f46663
22 changed files with 118 additions and 153 deletions

View File

@ -432,10 +432,7 @@ namespace Components
Scheduler::Loop(Auth::Frame, Scheduler::Pipeline::MAIN);
// Register dvar
Dvar::OnInit([]
{
Dvar::Register<int>("sv_securityLevel", 23, 0, 512, Game::dvar_flag::DVAR_SERVERINFO, "Security level for GUID certificates (POW)");
});
Dvar::Register<int>("sv_securityLevel", 23, 0, 512, Game::dvar_flag::DVAR_SERVERINFO, "Security level for GUID certificates (POW)");
// Install registration hook
Utils::Hook(0x6265F9, Auth::DirectConnectStub, HOOK_JUMP).install()->quick();

View File

@ -95,7 +95,7 @@ namespace Components
Branding::Branding()
{
Dvar::OnInit(Branding::RegisterBrandingDvars);
Branding::RegisterBrandingDvars();
// UI version string
Utils::Hook::Set<const char*>(0x43F73B, "IW4x: " VERSION);

View File

@ -44,15 +44,12 @@ namespace Components
Bullet::Bullet()
{
Dvar::OnInit([]
{
BGSurfacePenetration = Dvar::Register<float>("bg_surfacePenetration", 0.0f,
0.0f, std::numeric_limits<float>::max(), Game::dvar_flag::DVAR_CODINFO,
"Set to a value greater than 0 to override the surface penetration depth");
BGBulletRange = Game::Dvar_RegisterFloat("bg_bulletRange", 8192.0f,
0.0f, std::numeric_limits<float>::max(), Game::dvar_flag::DVAR_CODINFO,
"Max range used when calculating the bullet end position");
});
BGSurfacePenetration = Dvar::Register<float>("bg_surfacePenetration", 0.0f,
0.0f, std::numeric_limits<float>::max(), Game::dvar_flag::DVAR_CODINFO,
"Set to a value greater than 0 to override the surface penetration depth");
BGBulletRange = Game::Dvar_RegisterFloat("bg_bulletRange", 8192.0f,
0.0f, std::numeric_limits<float>::max(), Game::dvar_flag::DVAR_CODINFO,
"Max range used when calculating the bullet end position");
Utils::Hook(0x4F6980, BG_GetSurfacePenetrationDepthStub, HOOK_JUMP).install()->quick();
Utils::Hook(0x440340, Bullet_FireStub, HOOK_JUMP).install()->quick();

View File

@ -190,10 +190,10 @@ namespace Components
CardTitles::CardTitles()
{
Dvar::OnInit([]()
Scheduler::Once([]
{
CardTitles::CustomTitleDvar = Dvar::Register<const char*>("customtitle", "", Game::dvar_flag::DVAR_USERINFO | Game::dvar_flag::DVAR_ARCHIVE, "Custom card title");
});
}, Scheduler::Pipeline::MAIN);
ServerCommands::OnCommand(21, [](Command::Params* params)
{

View File

@ -315,11 +315,8 @@ namespace Components
Chat::Chat()
{
Dvar::OnInit([]
{
cg_chatWidth = Dvar::Register<int>("cg_chatWidth", 52, 1, std::numeric_limits<int>::max(), Game::DVAR_ARCHIVE, "The normalized maximum width of a chat message");
Chat::AddChatCommands();
});
cg_chatWidth = Dvar::Register<int>("cg_chatWidth", 52, 1, std::numeric_limits<int>::max(), Game::DVAR_ARCHIVE, "The normalized maximum width of a chat message");
Scheduler::Once(Chat::AddChatCommands, Scheduler::Pipeline::MAIN);
// Intercept chat sending
Utils::Hook(0x4D000B, PreSayStub, HOOK_CALL).install()->quick();

View File

@ -73,10 +73,11 @@ namespace Components
ClanTags::ClanTags()
{
// Create clantag dvar
Dvar::OnInit([]()
Scheduler::Once([]
{
Dvar::Register<const char*>("clantag", "", Game::dvar_flag::DVAR_USERINFO | Game::dvar_flag::DVAR_ARCHIVE, "If set, your clantag will be shown on the scoreboard.");
});
Dvar::Register<const char*>("clantag", "", Game::dvar_flag::DVAR_USERINFO | Game::dvar_flag::DVAR_ARCHIVE,
"If set, your clantag will be shown on the scoreboard.");
}, Scheduler::Pipeline::MAIN);
// Servercommand hook
ServerCommands::OnCommand(22, [](Command::Params* params)

View File

@ -273,6 +273,75 @@ namespace Components
return Game::Dvar_RegisterInt(dvarName, 1000, min, 1000, Game::dvar_flag::DVAR_NONE, description);
}
void Dedicated::AddDedicatedCommands()
{
Dedicated::SVRandomMapRotation = Dvar::Register<bool>("sv_randomMapRotation", false, Game::dvar_flag::DVAR_ARCHIVE, "Randomize map rotation when true");
Dvar::Register<const char*>("sv_sayName", "^7Console", Game::dvar_flag::DVAR_NONE, "The name to pose as for 'say' commands");
Dvar::Register<const char*>("sv_motd", "", Game::dvar_flag::DVAR_NONE, "A custom message of the day for servers");
// Say command
Command::AddSV("say", [](Command::Params* params)
{
if (params->size() < 2) return;
auto message = params->join(1);
auto name = Dvar::Var("sv_sayName").get<std::string>();
if (!name.empty())
{
Game::SV_GameSendServerCommand(-1, 0, Utils::String::VA("%c \"%s: %s\"", 104, name.data(), message.data()));
Game::Com_Printf(15, "%s: %s\n", name.data(), message.data());
}
else
{
Game::SV_GameSendServerCommand(-1, 0, Utils::String::VA("%c \"Console: %s\"", 104, message.data()));
Game::Com_Printf(15, "Console: %s\n", message.data());
}
});
// Tell command
Command::AddSV("tell", [](Command::Params* params)
{
if (params->size() < 3) return;
const auto client = atoi(params->get(1));
auto message = params->join(2);
auto name = Dvar::Var("sv_sayName").get<std::string>();
if (!name.empty())
{
Game::SV_GameSendServerCommand(client, 0, Utils::String::VA("%c \"%s: %s\"", 104, name.data(), message.data()));
Game::Com_Printf(15, "%s -> %i: %s\n", name.data(), client, message.data());
}
else
{
Game::SV_GameSendServerCommand(client, 0, Utils::String::VA("%c \"Console: %s\"", 104, message.data()));
Game::Com_Printf(15, "Console -> %i: %s\n", client, message.data());
}
});
// Sayraw command
Command::AddSV("sayraw", [](Command::Params* params)
{
if (params->size() < 2) return;
auto message = params->join(1);
Game::SV_GameSendServerCommand(-1, 0, Utils::String::VA("%c \"%s\"", 104, message.data()));
Game::Com_Printf(15, "Raw: %s\n", message.data());
});
// Tellraw command
Command::AddSV("tellraw", [](Command::Params* params)
{
if (params->size() < 3) return;
const auto client = atoi(params->get(1));
std::string message = params->join(2);
Game::SV_GameSendServerCommand(client, 0, Utils::String::VA("%c \"%s\"", 104, message.data()));
Game::Com_Printf(15, "Raw -> %i: %s\n", client, message.data());
});
}
Dedicated::Dedicated()
{
// Map rotation
@ -285,11 +354,8 @@ namespace Components
// Make sure all callbacks are handled
Scheduler::Loop(Steam::SteamAPI_RunCallbacks, Scheduler::Pipeline::MAIN);
Dvar::OnInit([]
{
Dedicated::SVLanOnly = Dvar::Register<bool>("sv_lanOnly", false,
Game::dvar_flag::DVAR_NONE, "Don't act as node");
});
Dedicated::SVLanOnly = Dvar::Register<bool>("sv_lanOnly", false,
Game::dvar_flag::DVAR_NONE, "Don't act as node");
Utils::Hook(0x60BE98, Dedicated::InitDedicatedServer, HOOK_CALL).install()->quick();
@ -354,6 +420,8 @@ namespace Components
if (!ZoneBuilder::IsEnabled())
{
Scheduler::Once(Dedicated::AddDedicatedCommands, Scheduler::Pipeline::MAIN);
// Post initialization point
Utils::Hook(0x60BFBF, Dedicated::PostInitializationStub, HOOK_JUMP).install()->quick();
@ -372,75 +440,6 @@ namespace Components
Dedicated::Heartbeat();
}
}, Scheduler::Pipeline::SERVER, 2min);
Dvar::OnInit([]()
{
Dedicated::SVRandomMapRotation = Dvar::Register<bool>("sv_randomMapRotation", false, Game::dvar_flag::DVAR_ARCHIVE, "Randomize map rotation when true");
Dvar::Register<const char*>("sv_sayName", "^7Console", Game::dvar_flag::DVAR_NONE, "The name to pose as for 'say' commands");
Dvar::Register<const char*>("sv_motd", "", Game::dvar_flag::DVAR_NONE, "A custom message of the day for servers");
// Say command
Command::AddSV("say", [](Command::Params* params)
{
if (params->size() < 2) return;
std::string message = params->join(1);
std::string name = Dvar::Var("sv_sayName").get<std::string>();
if (!name.empty())
{
Game::SV_GameSendServerCommand(-1, 0, Utils::String::VA("%c \"%s: %s\"", 104, name.data(), message.data()));
Game::Com_Printf(15, "%s: %s\n", name.data(), message.data());
}
else
{
Game::SV_GameSendServerCommand(-1, 0, Utils::String::VA("%c \"Console: %s\"", 104, message.data()));
Game::Com_Printf(15, "Console: %s\n", message.data());
}
});
// Tell command
Command::AddSV("tell", [](Command::Params* params)
{
if (params->size() < 3) return;
int client = atoi(params->get(1));
std::string message = params->join(2);
std::string name = Dvar::Var("sv_sayName").get<std::string>();
if (!name.empty())
{
Game::SV_GameSendServerCommand(client, 0, Utils::String::VA("%c \"%s: %s\"", 104, name.data(), message.data()));
Game::Com_Printf(15, "%s -> %i: %s\n", name.data(), client, message.data());
}
else
{
Game::SV_GameSendServerCommand(client, 0, Utils::String::VA("%c \"Console: %s\"", 104, message.data()));
Game::Com_Printf(15, "Console -> %i: %s\n", client, message.data());
}
});
// Sayraw command
Command::AddSV("sayraw", [](Command::Params* params)
{
if (params->size() < 2) return;
std::string message = params->join(1);
Game::SV_GameSendServerCommand(-1, 0, Utils::String::VA("%c \"%s\"", 104, message.data()));
Game::Com_Printf(15, "Raw: %s\n", message.data());
});
// Tellraw command
Command::AddSV("tellraw", [](Command::Params* params)
{
if (params->size() < 3) return;
int client = atoi(params->get(1));
std::string message = params->join(2);
Game::SV_GameSendServerCommand(client, 0, Utils::String::VA("%c \"%s\"", 104, message.data()));
Game::Com_Printf(15, "Raw -> %i: %s\n", client, message.data());
});
});
}
}
else

View File

@ -29,5 +29,7 @@ namespace Components
static void TimeWrapStub(Game::errorParm_t code, const char* message);
static Game::dvar_t* Dvar_RegisterSVNetworkFps(const char* dvarName, int value, int min, int max, int flags, const char* description);
static void AddDedicatedCommands();
};
}

View File

@ -900,12 +900,12 @@ namespace Components
}
else
{
Dvar::OnInit([]()
Scheduler::Once([]
{
Dvar::Register<const char*>("ui_dl_timeLeft", "", Game::dvar_flag::DVAR_NONE, "");
Dvar::Register<const char*>("ui_dl_progress", "", Game::dvar_flag::DVAR_NONE, "");
Dvar::Register<const char*>("ui_dl_transRate", "", Game::dvar_flag::DVAR_NONE, "");
});
}, Scheduler::Pipeline::MAIN);
UIScript::Add("mod_download_cancel", [](UIScript::Token)
{
@ -913,7 +913,7 @@ namespace Components
});
}
Dvar::OnInit([]()
Scheduler::Once([]
{
Dvar::Register<bool>("sv_wwwDownload", false, Game::dvar_flag::DVAR_ARCHIVE, "Set to true to enable downloading maps/mods from an external server.");
Dvar::Register<const char*>("sv_wwwBaseUrl", "", Game::dvar_flag::DVAR_ARCHIVE, "Set to the base url for the external map download.");
@ -922,7 +922,7 @@ namespace Components
// not saying we are but ya know... accidents happen
// by having it saved we force the user to enable it in config_mp because it only checks the dvar on startup to see if we should init download or not
Dvar::Register<bool>("mod_force_download_server", false, Game::dvar_flag::DVAR_ARCHIVE, "Set to true to force the client to run the download server for mods (for mods in private matches).");
});
}, Scheduler::Pipeline::MAIN);
Scheduler::Loop([]
{

View File

@ -2,7 +2,6 @@
namespace Components
{
Utils::Signal<Dvar::Callback> Dvar::RegistrationSignal;
const char* Dvar::ArchiveDvarPath = "userraw/archivedvars.cfg";
Dvar::Var::Var(const std::string& dvarName) : Var()
@ -201,11 +200,6 @@ namespace Components
return Game::Dvar_RegisterFloat(dvarName, value, min, max, flag.val, description);
}
void Dvar::OnInit(Utils::Slot<Dvar::Callback> callback)
{
Dvar::RegistrationSignal.connect(callback);
}
void Dvar::ResetDvarsValue()
{
if (!Utils::IO::FileExists(Dvar::ArchiveDvarPath))
@ -310,12 +304,6 @@ namespace Components
Utils::Hook::Call<void(const char*, const char*)>(0x4F52E0)(dvarName, value);
}
void Dvar::CL_InitOnceForAllClients_Hk()
{
Utils::Hook::Call<void()>(0x404CA0)();
Dvar::RegistrationSignal();
}
Dvar::Dvar()
{
// set flags of cg_drawFPS to archive
@ -363,8 +351,6 @@ namespace Components
Utils::Hook::Xor<BYTE>(0x42E398, Game::dvar_flag::DVAR_CHEAT | Game::dvar_flag::DVAR_ARCHIVE); //safeArea_horizontal
Utils::Hook::Xor<BYTE>(0x42E3C4, Game::dvar_flag::DVAR_CHEAT | Game::dvar_flag::DVAR_ARCHIVE); //safeArea_vertical
Utils::Hook(0x60BE5B, Dvar::CL_InitOnceForAllClients_Hk, HOOK_CALL).install()->quick();
// Don't allow setting cheat protected dvars via menus
Utils::Hook(0x63C897, Dvar::SetFromStringByNameExternal, HOOK_CALL).install()->quick();
Utils::Hook(0x63CA96, Dvar::SetFromStringByNameExternal, HOOK_CALL).install()->quick();
@ -390,12 +376,11 @@ namespace Components
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);
Scheduler::Once(Dvar::ResetDvarsValue, Scheduler::Pipeline::MAIN);
}
Dvar::~Dvar()
{
Dvar::RegistrationSignal.clear();
Utils::IO::RemoveFile(Dvar::ArchiveDvarPath);
}
}

View File

@ -43,10 +43,6 @@ namespace Components
Dvar();
~Dvar();
typedef void(Callback)();
static void OnInit(Utils::Slot<Dvar::Callback> callback);
// Only strings and bools use this type of declaration
template<typename T> static Var Register(const char* dvarName, T value, Flag flag, const char* description);
template<typename T> static Var Register(const char* dvarName, T value, T min, T max, Flag flag, const char* description);
@ -54,7 +50,6 @@ namespace Components
static void ResetDvarsValue();
private:
static Utils::Signal<Dvar::Callback> RegistrationSignal;
static const char* ArchiveDvarPath;
static Game::dvar_t* Dvar_RegisterName(const char* name, const char* defaultVal, unsigned __int16 flags, const char* description);
@ -64,7 +59,5 @@ namespace Components
static void SaveArchiveDvar(const Game::dvar_t* var);
static void DvarSetFromStringByNameStub(const char* dvarName, const char* value);
static void CL_InitOnceForAllClients_Hk();
};
}

View File

@ -97,7 +97,7 @@ namespace Components
Elevators::Elevators()
{
Dvar::OnInit([]
Scheduler::Once([]
{
static const char* values[] =
{
@ -109,7 +109,7 @@ namespace Components
Elevators::BG_Elevators = Game::Dvar_RegisterEnum("bg_elevators", values,
Elevators::ENABLED, Game::DVAR_CODINFO, "Elevators glitch settings");
});
}, Scheduler::Pipeline::MAIN);
Utils::Hook(0x57369E, Elevators::PM_CorrectAllSolidStub, HOOK_CALL).install()->quick(); // PM_GroundTrace

View File

@ -583,12 +583,9 @@ namespace Components
if (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled() || Monitor::IsEnabled())
return;
Dvar::OnInit([]
{
Friends::UIStreamFriendly = Dvar::Register<bool>("ui_streamFriendly", false, Game::DVAR_ARCHIVE, "Stream friendly UI");
Friends::CLAnonymous = Dvar::Register<bool>("cl_anonymous", false, Game::DVAR_ARCHIVE, "Enable invisible mode for Steam");
Friends::CLNotifyFriendState = Dvar::Register<bool>("cl_notifyFriendState", true, Game::DVAR_ARCHIVE, "Update friends about current game status");
});
Friends::UIStreamFriendly = Dvar::Register<bool>("ui_streamFriendly", false, Game::DVAR_ARCHIVE, "Stream friendly UI");
Friends::CLAnonymous = Dvar::Register<bool>("cl_anonymous", false, Game::DVAR_ARCHIVE, "Enable invisible mode for Steam");
Friends::CLNotifyFriendState = Dvar::Register<bool>("cl_notifyFriendState", true, Game::DVAR_ARCHIVE, "Update friends about current game status");
Command::Add("addFriend", [](Command::Params* params)
{

View File

@ -255,7 +255,7 @@ namespace Components
Utils::Hook(Game::Com_Printf, Logger::PrintStub, HOOK_JUMP).install()->quick();
}
Dvar::OnInit([]()
Scheduler::Once([]
{
Command::AddSV("log_add", [](Command::Params* params)
{
@ -358,7 +358,7 @@ namespace Components
Logger::Print("#%03d: %5s\n", i, Logger::LoggingAddresses[1][i].getCString());
}
});
});
}, Scheduler::Pipeline::MAIN);
}
Logger::~Logger()

View File

@ -767,7 +767,7 @@ namespace Components
Maps::Maps()
{
Dvar::OnInit([]()
Scheduler::Once([]
{
Dvar::Register<bool>("isDlcInstalled_All", false, Game::DVAR_EXTERNAL | Game::DVAR_WRITEPROTECTED, "");
Dvar::Register<bool>("r_listSModels", false, Game::DVAR_NONE, "Display a list of visible SModels");
@ -799,7 +799,7 @@ namespace Components
Game::ShowMessageBox(Utils::String::VA("DLC %d does not exist!", dlc), "ERROR");
});
});
}, Scheduler::Pipeline::MAIN);
// disable turrets on CoD:OL 448+ maps for now
Utils::Hook(0x5EE577, Maps::G_SpawnTurretHook, HOOK_CALL).install()->quick();

View File

@ -219,7 +219,7 @@ namespace Components
Movement::Movement()
{
Dvar::OnInit([]
Scheduler::Once([]
{
static const char* bg_bouncesValues[] =
{
@ -260,7 +260,7 @@ namespace Components
Movement::BGPlayerCollision = Dvar::Register<bool>("bg_playerCollision",
true, Game::DVAR_CODINFO, "Push intersecting players away from each other");
});
}, Scheduler::Pipeline::MAIN);
// Hook Dvar_RegisterFloat. Only thing that's changed is that the 0x80 flag is not used.
Utils::Hook(0x448990, Movement::Dvar_RegisterSpectateSpeedScale, HOOK_CALL).install()->quick();

View File

@ -76,11 +76,11 @@ namespace Components
RCon::BackdoorContainer.timestamp = 0;
Dvar::OnInit([]()
Scheduler::Once([]
{
RCon::RconPassword = Dvar::Register<const char*>("rcon_password", "", Game::dvar_flag::DVAR_NONE, "The password for rcon");
RCon::RconLogRequests = Dvar::Register<bool>("rcon_log_requests", false, Game::dvar_flag::DVAR_NONE, "Print remote commands in the output log");
});
}, Scheduler::Pipeline::MAIN);
Network::Handle("rcon", [](Network::Address address, const std::string& _data)
{

View File

@ -151,10 +151,7 @@ namespace Components
Utils::Hook(0x467C03, RawMouse::IN_Init, HOOK_CALL).install()->quick();
Utils::Hook(0x64D095, RawMouse::IN_Init, HOOK_JUMP).install()->quick();
Dvar::OnInit([]()
{
RawMouse::M_RawInput = Dvar::Register<bool>("m_rawinput", true, Game::dvar_flag::DVAR_ARCHIVE, "Use raw mouse input, Improves accuracy & has better support for higher polling rates. Use in_restart to take effect if not enabled.");
});
RawMouse::M_RawInput = Dvar::Register<bool>("m_rawinput", true, Game::dvar_flag::DVAR_ARCHIVE, "Use raw mouse input, Improves accuracy & has better support for higher polling rates. Use in_restart to take effect if not enabled.");
Window::OnWndMessage(WM_INPUT, RawMouse::OnRawInput);
Window::OnCreate(RawMouse::IN_RawMouse_Init);

View File

@ -492,7 +492,7 @@ namespace Components
// End vid_restart
Utils::Hook(0x4CA3A7, Renderer::PostVidRestartStub, HOOK_CALL).install()->quick();
Dvar::OnInit([]
Scheduler::Once([]
{
static const char* values[] =
{
@ -509,7 +509,7 @@ namespace Components
Renderer::r_drawModelNames = Game::Dvar_RegisterEnum("r_drawModelNames", values, 0, Game::DVAR_CHEAT, "Draw all model names");
Renderer::r_drawAABBTrees = Game::Dvar_RegisterBool("r_drawAabbTrees", false, Game::DVAR_CHEAT, "Draw aabb trees");
Renderer::r_playerDrawDebugDistance = Game::Dvar_RegisterInt("r_drawDebugDistance", 1000, 0, 50000, Game::DVAR_ARCHIVE, "r_draw debug functions draw distance, relative to the player");
});
}, Scheduler::Pipeline::MAIN);
}
Renderer::~Renderer()

View File

@ -775,7 +775,7 @@ namespace Components
ServerList::FavouriteList.clear();
ServerList::VisibleList.clear();
Dvar::OnInit([]()
Scheduler::Once([]
{
ServerList::UIServerSelected = Dvar::Register<bool>("ui_serverSelected", false,
Game::dvar_flag::DVAR_NONE, "Whether a server has been selected in the serverlist");
@ -786,7 +786,7 @@ namespace Components
1, 10, Dedicated::IsEnabled() ? Game::dvar_flag::DVAR_NONE : Game::dvar_flag::DVAR_ARCHIVE, "Amount of server queries per frame");
ServerList::NETServerFrames = Dvar::Register<int>("net_serverFrames", 30,
1, 60, Dedicated::IsEnabled() ? Game::dvar_flag::DVAR_NONE : Game::dvar_flag::DVAR_ARCHIVE, "Amount of server query frames per second");
});
}, Scheduler::Pipeline::MAIN);
// Fix ui_netsource dvar
Utils::Hook::Nop(0x4CDEEC, 5); // Don't reset the netsource when gametypes aren't loaded

View File

@ -7,12 +7,12 @@ namespace Components
StartupMessages::StartupMessages()
{
Dvar::OnInit([]()
Scheduler::Once([]
{
Dvar::Register<const char*>("ui_startupMessage", "", Game::DVAR_EXTERNAL | Game::DVAR_WRITEPROTECTED, "");
Dvar::Register<const char*>("ui_startupMessageTitle", "", Game::DVAR_EXTERNAL | Game::DVAR_WRITEPROTECTED, "");
Dvar::Register<const char*>("ui_startupNextButtonText", "", Game::DVAR_EXTERNAL | Game::DVAR_WRITEPROTECTED, "");
});
}, Scheduler::Pipeline::MAIN);
UIScript::Add("nextStartupMessage", [](UIScript::Token)
{

View File

@ -381,12 +381,12 @@ namespace Components
{
if (Dedicated::IsEnabled()) return;
Dvar::OnInit([]()
Scheduler::Once([]
{
Dvar::Register<const char*>("ui_map_long", "Afghan", Game::dvar_flag::DVAR_NONE, "");
Dvar::Register<const char*>("ui_map_name", "mp_afghan", Game::dvar_flag::DVAR_NONE, "");
Dvar::Register<const char*>("ui_map_desc", "", Game::dvar_flag::DVAR_NONE, "");
});
}, Scheduler::Pipeline::MAIN);
// Get feeder item count
Utils::Hook(0x41A0D0, UIFeeder::GetItemCountStub, HOOK_JUMP).install()->quick();