This commit is contained in:
quaK 2022-09-23 01:04:20 +03:00
parent 29a3b864fa
commit 98e95347d5
12 changed files with 634 additions and 52 deletions

View File

@ -154,7 +154,7 @@ namespace command
void client_println(int client_num, const std::string& text)
{
if (game::Com_GameMode_GetActiveGameMode() == game::GAME_TYPE_SP)
if (game::Com_GameMode_GetActiveGameMode() == game::GAME_MODE_SP)
{
game::CG_Utils_GameMessage(client_num, text.data(), 0); // why is nothing printed?
}
@ -167,6 +167,11 @@ namespace command
bool cheats_ok(int client_num)
{
if (game::Com_GameMode_GetActiveGameMode() == game::GAME_MODE_SP)
{
return true;
}
const auto sv_cheats = game::Dvar_FindVar("sv_cheats");
if (!sv_cheats || !sv_cheats->current.enabled)
{
@ -176,6 +181,87 @@ namespace command
return true;
}
void start_map_for_party()
{
auto* mapname = game::Dvar_FindVar("ui_mapname");
auto* gametype = game::Dvar_FindVar("ui_gametype");
auto* clients = game::Dvar_FindVar("ui_maxclients");
auto* private_clients = game::Dvar_FindVar("ui_privateClients");
auto* hardcore = game::Dvar_FindVar("ui_hardcore");
game::Com_FrontEndScene_ShutdownAndDisable();
if (!game::environment::is_dedi() && !game::Com_FrontEndScene_IsActive())
{
game::Com_Shutdown("EXE_ENDOFGAME");
}
game::SV_CmdsMP_StartMapForParty(
mapname->current.string,
gametype->current.string,
clients->current.integer,
private_clients->current.integer,
hardcore->current.enabled,
false,
false);
}
void perform_game_initialization()
{
command::execute("onlinegame 1", true);
command::execute("xstartprivatematch", true); //command::execute("xstartprivateparty", true);
command::execute("xblive_privatematch 1", true);
}
bool start_map(const std::string& mapname, bool dev)
{
if (game::Com_GameMode_GetActiveGameMode() == game::GAME_MODE_SP)
{
console::info("Starting sp map: %s\n", mapname.data());
command::execute(utils::string::va("spmap %s", mapname.data()), true);
return true;
}
if (mapname.empty())
{
console::error("No map specified.\n");
return false;
}
if (!game::SV_MapExists(mapname.data()))
{
console::error("Map \"%s\" doesn't exist.\n", mapname.data());
return false;
}
if (!game::Com_GameMode_SupportsMap(mapname.data()))
{
console::error("Cannot load map \"%s\" in current game mode.\n", mapname.data());
return false;
}
auto* current_mapname = game::Dvar_FindVar("mapname");
command::execute((dev ? "set sv_cheats 1" : "set sv_cheats 0"), true);
if (current_mapname && utils::string::to_lower(current_mapname->current.string) ==
utils::string::to_lower(mapname) && (game::SV_Loaded() && !game::Com_FrontEndScene_IsActive()))
{
console::info("Restarting map: %s\n", mapname.data());
command::execute("map_restart", false);
return true;
}
command::execute(utils::string::va("ui_mapname %s", mapname.data()), true);
console::info("Starting map: %s\n", mapname.data());
perform_game_initialization();
game::Cbuf_AddCall(0, start_map_for_party);
return true;
}
}
params::params()
@ -316,8 +402,8 @@ namespace command
void post_unpack() override
{
utils::hook::jump(0xBB1DC0_b, dvar_command_stub, true);
//client_command_mp_hook.create(0xB105D0_b, &client_command_mp);
//client_command_sp_hook.create(0x483130_b, &client_command_sp);
client_command_mp_hook.create(0xB105D0_b, &client_command_mp);
client_command_sp_hook.create(0x483130_b, &client_command_sp);
add_commands();
}
@ -331,72 +417,175 @@ namespace command
*reinterpret_cast<int*>(1) = 0;
});
add("god", []()
add("noMode", []()
{
if (!game::SV_Loaded())
game::Com_GameMode_SetDesiredGameMode(game::GAME_MODE_NONE);
});
add("spMode", []()
{
game::Com_GameMode_SetDesiredGameMode(game::GAME_MODE_SP);
});
add("mpMode", []()
{
game::Com_GameMode_SetDesiredGameMode(game::GAME_MODE_MP);
});
add("cpMode", []()
{
game::Com_GameMode_SetDesiredGameMode(game::GAME_MODE_CP);
});
static const char* a1 = "map_sp";
static const char* a2 = "map_restart_sp";
static const char* a3 = "fast_restart_sp";
// patch singleplayer "map" -> "map_sp"
utils::hook::set(0x1BBA800_b + 0, a1);
utils::hook::set(0x1BBA800_b + 24, a1);
utils::hook::set(0x1BBA800_b + 56, a1);
// patch singleplayer map_restart -> "map_restart_sp"
utils::hook::set(0x1BBA740_b + 0, a2);
utils::hook::set(0x1BBA740_b + 24, a2);
utils::hook::set(0x1BBA740_b + 56, a2);
// patch singleplayer fast_restart -> "fast_restart_sp"
utils::hook::set(0x1BBA700_b + 0, a3);
utils::hook::set(0x1BBA700_b + 24, a3);
utils::hook::set(0x1BBA700_b + 56, a3);
add("map", [](const params& args)
{
if (args.size() != 2)
{
return;
}
game::g_entities[0].flags ^= 1;
client_println(0,
game::g_entities[0].flags & 1
if (game::Com_GameMode_GetActiveGameMode() == game::GAME_MODE_SP)
{
command::execute(utils::string::va("spmap %s", args.get(1)));
return;
}
start_map(args.get(1), false);
});
add("devmap", [](const params& args)
{
if (args.size() != 2)
{
return;
}
if (game::Com_GameMode_GetActiveGameMode() == game::GAME_MODE_SP)
{
command::execute(utils::string::va("spmap %s", args.get(1)));
return;
}
start_map(args.get(1), true);
});
add("map_restart", [](const params&)
{
if (!game::SV_Loaded() || game::Com_FrontEnd_IsInFrontEnd())
{
return;
}
if (game::Com_GameMode_GetActiveGameMode() == game::GAME_MODE_SP)
{
game::Cbuf_AddCall(0, game::SV_CmdsSP_MapRestart_f);
return;
}
game::SV_CmdsMP_RequestMapRestart(1, 0);
});
add("fast_restart", [](const params&)
{
if (!game::SV_Loaded() || game::Com_FrontEnd_IsInFrontEnd())
{
return;
}
if (game::Com_GameMode_GetActiveGameMode() == game::GAME_MODE_SP)
{
game::Cbuf_AddCall(0, game::SV_CmdsSP_FastRestart_f);
return;
}
game::SV_CmdsMP_RequestMapRestart(0, 0);
});
add_sv("god", [](const int client_num, const params_sv&)
{
if (!cheats_ok(client_num))
{
return;
}
game::g_entities[client_num].flags ^= 1;
client_println(client_num,
game::g_entities[client_num].flags & 1
? "GAME_GODMODE_ON"
: "GAME_GODMODE_OFF");
});
add("demigod", []()
add_sv("demigod", [](const int client_num, const params_sv&)
{
if (!game::SV_Loaded())
if (!cheats_ok(client_num))
{
return;
}
game::g_entities[0].flags ^= 2;
client_println(0,
game::g_entities[0].flags & 2
game::g_entities[client_num].flags ^= 2;
client_println(client_num,
game::g_entities[client_num].flags & 2
? "GAME_DEMI_GODMODE_ON"
: "GAME_DEMI_GODMODE_OFF");
});
add("notarget", []()
add_sv("notarget", [](const int client_num, const params_sv&)
{
if (!game::SV_Loaded())
if (!cheats_ok(client_num))
{
return;
}
game::g_entities[0].flags ^= 4;
client_println(0,
game::g_entities[0].flags & 4
game::g_entities[client_num].flags ^= 4;
client_println(client_num,
game::g_entities[client_num].flags & 4
? "GAME_NOTARGETON"
: "GAME_NOTARGETOFF");
});
add("noclip", []()
add_sv("noclip", [](const int client_num, const params_sv&)
{
if (!game::SV_Loaded())
if (!cheats_ok(client_num))
{
return;
}
game::g_entities[0].client->flags ^= 1;
client_println(0,
game::g_entities[0].client->flags & 1
game::g_entities[client_num].client->flags ^= 1;
client_println(client_num,
game::g_entities[client_num].client->flags & 1
? "GAME_NOCLIPON"
: "GAME_NOCLIPOFF");
});
add("ufo", []()
add_sv("ufo", [](const int client_num, const params_sv&)
{
if (!game::SV_Loaded())
if (!cheats_ok(client_num))
{
return;
}
game::g_entities[0].client->flags ^= 1;
client_println(0,
game::g_entities[0].client->flags & 1
game::g_entities[client_num].client->flags ^= 1;
client_println(client_num,
game::g_entities[client_num].client->flags & 1
? "GAME_UFOON"
: "GAME_UFOOFF");
});

View File

@ -14,7 +14,7 @@ namespace command
const char* operator[](const int index) const
{
return this->get(index); //
return this->get(index);
}
private:
@ -33,7 +33,7 @@ namespace command
const char* operator[](const int index) const
{
return this->get(index); //
return this->get(index);
}
private:

View File

@ -95,9 +95,6 @@ namespace logger
if (!game::environment::is_dedi())
{
// LUI_Interface_DebugPrint
utils::hook::jump(0x61C430_b, print_debug);
// R_WarnOncePerFrame
utils::hook::call(0xE4B121_b, r_warn_once_per_frame_vsnprintf_stub);
}

View File

@ -0,0 +1,118 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include "game/dvars.hpp"
#include "command.hpp"
#include "console.hpp"
#include <utils/hook.hpp>
#include <utils/string.hpp>
namespace lui
{
void print_debug_lui(const char* msg, ...)
{
if (!dvars::lui_debug || !dvars::lui_debug->current.enabled)
{
return;
}
char buffer[0x1000]{ 0 };
va_list ap;
va_start(ap, msg);
vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, msg, ap);
va_end(ap);
console::debug(buffer);
}
class component final : public component_interface
{
public:
void post_unpack() override
{
if (game::environment::is_dedi())
{
return;
}
dvars::lui_debug = game::Dvar_RegisterBool("lui_debug", false, game::DvarFlags::DVAR_FLAG_SAVED,
"Print LUI DebugPrint to console. (DEV)");
// LUI_Interface_DebugPrint
utils::hook::jump(0x61C430_b, print_debug_lui);
command::add("luiOpenMenu", [](const command::params& params)
{
if (params.size() == 2)
{
game::LUI_OpenMenu(0, params.get(1), 0, 0, 0);
}
else
{
auto command = params.get(0);
console::error("Incorrect number of arguments for \"%s\".\n", command);
}
});
command::add("luiOpenPopup", [](const command::params& params)
{
if (params.size() == 2)
{
game::LUI_OpenMenu(0, params.get(1), 1, 0, 0);
}
else
{
auto command = params.get(0);
console::error("Incorrect number of arguments for \"%s\".\n", command);
}
});
command::add("luiOpenModalPopup", [](const command::params& params)
{
if (params.size() == 2)
{
game::LUI_OpenMenu(0, params.get(1), 1, 1, 0);
}
else
{
auto command = params.get(0);
console::error("Incorrect number of arguments for \"%s\".\n", command);
}
});
command::add("luiLeaveMenu", [](const command::params& params)
{
if (params.size() == 2)
{
game::LUI_CloseMenu(0, params.get(1), 0);
}
else
{
auto command = params.get(0);
console::error("Incorrect number of arguments for \"%s\".\n", command);
}
});
command::add("luiCloseAll", []()
{
game::LUI_CoD_CLoseAll(0);
});
command::add("luiReload", []()
{
game::CL_Keys_RemoveCatcher(0, -65);
game::LUI_CoD_Shutdown();
game::LUI_CoD_Init(game::Com_FrontEnd_IsInFrontEnd(), false);
});
}
};
}
REGISTER_COMPONENT(lui::component)

View File

@ -15,6 +15,7 @@ namespace patches
namespace
{
utils::hook::detour com_register_common_dvars_hook;
utils::hook::detour com_game_mode_supports_feature_hook;
utils::hook::detour cg_set_client_dvar_from_server_hook;
utils::hook::detour live_get_map_index_hook;
utils::hook::detour content_do_we_have_content_pack_hook;
@ -31,12 +32,13 @@ namespace patches
return std::string{ username, username_len - 1 };
}
game::dvar_t* name_dvar;
game::dvar_t* com_maxfps;
game::dvar_t* cg_fov;
game::dvar_t* cg_fovScale;
void com_register_common_dvars_stub()
{
game::dvar_t* name_dvar;
game::dvar_t* com_maxfps;
game::dvar_t* cg_fov;
game::dvar_t* cg_fovScale;
name_dvar = game::Dvar_RegisterString("name", get_login_username().data(), game::DVAR_FLAG_SAVED, "Player name.");
com_maxfps = game::Dvar_RegisterInt("com_maxfps", 0, 0, 1000, game::DVAR_FLAG_SAVED, "Cap frames per second");
cg_fov = game::Dvar_RegisterFloat("cg_fov", 65.0f, 1.0f, 160.f, game::DVAR_FLAG_SAVED,
@ -59,6 +61,16 @@ namespace patches
return com_register_common_dvars_hook.invoke<void>();
}
bool com_game_mode_supports_feature_stub(game::Com_GameMode_Feature feature)
{
if (feature == game::FEATURE_TIMESCALE)
{
return true;
}
return com_game_mode_supports_feature_hook.invoke<bool>(feature);
}
const char* live_get_local_client_name()
{
return game::Dvar_FindVar("name")->current.string;
@ -168,6 +180,9 @@ namespace patches
// register custom dvars
com_register_common_dvars_hook.create(0xBADF30_b, com_register_common_dvars_stub);
// patch some features
com_game_mode_supports_feature_hook.create(0x5AFDE0_b, com_game_mode_supports_feature_stub);
// get client name from dvar
utils::hook::jump(0xD32770_b, live_get_local_client_name);
@ -193,6 +208,9 @@ namespace patches
// don't reset our fov
utils::hook::set<uint8_t>(0x8A6160_b, 0xC3);
// some [data validation] anti tamper thing that kills performance
dvars::override::register_int("dvl", 0, 0, 0, game::DVAR_FLAG_READ);
}
};
}

View File

@ -0,0 +1,198 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include "game_module.hpp"
#include <utils/hook.hpp>
#include <utils/nt.hpp>
namespace splash
{
namespace
{
HANDLE load_splash_image()
{
const auto self = game_module::get_host_module();
return LoadImageA(self, MAKEINTRESOURCE(IMAGE_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
}
}
class component final : public component_interface
{
public:
component()
: image_(load_splash_image())
{
this->window_thread_ = std::thread([this]
{
this->draw();
});
}
~component()
{
if (this->window_thread_.joinable())
{
this->window_thread_.detach();
}
}
void pre_destroy() override
{
this->destroy();
}
void post_unpack() override
{
utils::hook::set<uint8_t>(0xD58240_b, 0xC3); // disable splash
this->destroy();
}
void hide()
{
if (this->window_ && IsWindow(this->window_))
{
ShowWindow(this->window_, SW_HIDE);
UpdateWindow(this->window_);
}
this->destroy();
}
private:
std::atomic_bool join_safe_{ false };
HWND window_{};
HANDLE image_{};
std::thread window_thread_{};
void destroy()
{
if (this->window_ && IsWindow(this->window_))
{
ShowWindow(this->window_, SW_HIDE);
DestroyWindow(this->window_);
this->window_ = nullptr;
if (this->window_thread_.joinable())
{
this->window_thread_.join();
}
this->window_ = nullptr;
}
else if (this->window_thread_.joinable())
{
this->window_thread_.detach();
}
}
void draw()
{
this->show();
while (this->draw_frame())
{
std::this_thread::sleep_for(1ms);
}
this->window_ = nullptr;
UnregisterClassA("IW7 Splash Screen", game_module::get_host_module());
}
bool draw_frame() const
{
if (!this->window_)
{
return false;
}
MSG msg{};
bool success = true;
while (PeekMessageW(&msg, nullptr, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
if (msg.message == WM_DESTROY && msg.hwnd == this->window_)
{
PostQuitMessage(0);
}
if (msg.message == WM_QUIT)
{
success = false;
}
}
return success;
}
void show()
{
WNDCLASSA wnd_class;
const utils::nt::library host = game_module::get_host_module();
wnd_class.style = CS_DROPSHADOW;
wnd_class.cbClsExtra = 0;
wnd_class.cbWndExtra = 0;
wnd_class.lpszMenuName = nullptr;
wnd_class.lpfnWndProc = DefWindowProcA;
wnd_class.hInstance = host;
wnd_class.hIcon = LoadIconA(host, MAKEINTRESOURCEA(1));
wnd_class.hCursor = LoadCursorA(nullptr, IDC_APPSTARTING);
wnd_class.hbrBackground = reinterpret_cast<HBRUSH>(6);
wnd_class.lpszClassName = "IW7 Splash Screen";
if (RegisterClassA(&wnd_class))
{
const auto x_pixels = GetSystemMetrics(SM_CXFULLSCREEN);
const auto y_pixels = GetSystemMetrics(SM_CYFULLSCREEN);
if (image_)
{
this->window_ = CreateWindowExA(WS_EX_APPWINDOW, "IW7 Splash Screen", "IW7",
WS_POPUP | WS_SYSMENU,
(x_pixels - 320) / 2, (y_pixels - 100) / 2, 320, 100, nullptr,
nullptr,
host, nullptr);
if (this->window_)
{
auto* const image_window = CreateWindowExA(0, "Static", nullptr, WS_CHILD | WS_VISIBLE | 0xEu,
0, 0,
320, 100, this->window_, nullptr, host, nullptr);
if (image_window)
{
RECT rect;
SendMessageA(image_window, 0x172u, 0, reinterpret_cast<LPARAM>(image_));
GetWindowRect(image_window, &rect);
const int width = rect.right - rect.left;
rect.left = (x_pixels - width) / 2;
const int height = rect.bottom - rect.top;
rect.top = (y_pixels - height) / 2;
rect.right = rect.left + width;
rect.bottom = rect.top + height;
AdjustWindowRect(&rect, WS_CHILD | WS_VISIBLE | 0xEu, 0);
SetWindowPos(this->window_, nullptr, rect.left, rect.top, rect.right - rect.left,
rect.bottom - rect.top, SWP_NOZORDER);
SetWindowRgn(this->window_,
CreateRoundRectRgn(0, 0, rect.right - rect.left, rect.bottom - rect.top, 15,
15), TRUE);
ShowWindow(this->window_, SW_SHOW);
UpdateWindow(this->window_);
}
}
}
}
}
};
}
REGISTER_COMPONENT(splash::component)

View File

@ -21,6 +21,8 @@ namespace dvars
game::dvar_t* branding = nullptr;
game::dvar_t* lui_debug = nullptr;
game::dvar_t* r_fullbright = nullptr;
std::string dvar_get_vector_domain(const int components, const game::DvarLimits& domain)
@ -131,7 +133,7 @@ namespace dvars
}
}
std::unordered_map<const game::dvar_t*, std::string> dvar_names;
std::unordered_map<const game::dvar_t*, const char*> dvar_names;
std::string dvar_get_name(const game::dvar_t* dvar)
{
@ -144,12 +146,12 @@ namespace dvars
return "";
}
void dvar_set_name(const game::dvar_t* dvar, const std::string& name)
void dvar_set_name(const game::dvar_t* dvar, const char* name)
{
dvar_names[dvar] = name;
}
std::unordered_map<const game::dvar_t*, std::string> dvar_descriptions;
std::unordered_map<const game::dvar_t*, const char*> dvar_descriptions;
std::string dvar_get_description(const game::dvar_t* dvar)
{
@ -162,7 +164,7 @@ namespace dvars
return "";
}
void dvar_set_description(const game::dvar_t* dvar, const std::string& description)
void dvar_set_description(const game::dvar_t* dvar, const char* description)
{
dvar_descriptions[dvar] = description;
}

View File

@ -17,12 +17,14 @@ namespace dvars
extern game::dvar_t* branding;
extern game::dvar_t* lui_debug;
extern game::dvar_t* r_fullbright;
std::string dvar_get_vector_domain(const int components, const game::DvarLimits& domain);
std::string dvar_get_domain(const game::DvarType type, const game::DvarLimits& domain);
std::string dvar_get_name(const game::dvar_t* dvar);
std::string dvar_get_description(const game::dvar_t* dvar);
void dvar_set_name(const game::dvar_t* dvar, const std::string& name);
void dvar_set_description(const game::dvar_t* dvar, const std::string& description);
void dvar_set_name(const game::dvar_t* dvar, const char* name);
void dvar_set_description(const game::dvar_t* dvar, const char* description);
}

View File

@ -13,6 +13,15 @@ namespace game
base_address = reinterpret_cast<uint64_t>(module);
}
namespace environment
{
bool is_dedi()
{
static const auto dedicated = utils::flags::has_flag("dedicated");
return dedicated;
}
}
int Cmd_Argc()
{
return cmd_args->argc[cmd_args->nesting];
@ -131,12 +140,16 @@ namespace game
}), &callback);
}
namespace environment
void SV_CmdsMP_RequestMapRestart(bool loadScripts, bool migrate)
{
bool is_dedi()
if (!Com_IsAnyLocalServerStarting())
{
static const auto dedicated = utils::flags::has_flag("dedicated");
return dedicated;
SND_StopSounds(2);
SND_SetMusicState("\0");
*sv_map_restart = 1;
*sv_loadScripts = loadScripts;
*sv_migrate = migrate;
Cbuf_AddCall(0, SV_CmdsMP_CheckLoadGame);
}
}
}

View File

@ -51,6 +51,8 @@ namespace game
extern const char* g_assetNames[ASSET_TYPE_COUNT];
const char* DB_GetXAssetName(const XAsset* asset);
void DB_EnumXAssets(const std::int32_t type, const std::function<void(XAssetHeader)>& callback);
void SV_CmdsMP_RequestMapRestart(bool loadScripts, bool migrate);
}
uintptr_t operator"" _b(const uintptr_t ptr);

View File

@ -16,10 +16,15 @@ namespace game
enum GameModeType : std::uint32_t
{
GAME_TYPE_NONE = 0x0,
GAME_TYPE_SP = 0x1,
GAME_TYPE_MP = 0x2,
GAME_TYPE_CP = 0x3,
GAME_MODE_NONE = 0x0,
GAME_MODE_SP = 0x1,
GAME_MODE_MP = 0x2,
GAME_MODE_CP = 0x3,
};
enum Com_GameMode_Feature : std::int32_t
{
FEATURE_TIMESCALE = 69,
};
enum errorParm
@ -55,6 +60,14 @@ namespace game
void(__cdecl* function)();
};
struct SvCommandInfo
{
const char* name;
void(__fastcall* func)();
cmd_function_s clvar;
cmd_function_s svvar;
};
enum DvarSetSource : std::uint32_t
{
DVAR_SOURCE_INTERNAL = 0x0,

View File

@ -12,14 +12,26 @@ namespace game
WEAK symbol<void()> Com_Quit_f{ 0xBADC90 };
WEAK symbol<bool()> Com_FrontEnd_IsInFrontEnd{ 0x5AE6C0 };
WEAK symbol<bool()> Com_FrontEndScene_IsActive{ 0x5AEBA0 };
WEAK symbol<void()> Com_FrontEndScene_ShutdownAndDisable{ 0x5AEFB0 };
WEAK symbol<void(GameModeType)> Com_GameMode_SetDesiredGameMode{ 0x5AFDA0 };
WEAK symbol<GameModeType()> Com_GameMode_GetActiveGameMode{ 0x5AFD50 };
WEAK symbol<bool(const char* name)> Com_GameMode_SupportsMap{ 0x5AFE10 };
WEAK symbol<bool()> Com_IsAnyLocalServerStarting{ 0xBAD9C0 };
WEAK symbol<bool()> Com_IsAnyLocalServerRunning{ 0xBAD9A0 };
WEAK symbol<void(const char* finalmsg)> Com_Shutdown{ 0xBAFEA0 };
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{ 0xB7C290 };
WEAK symbol<void(int localClientNum, void(*))> Cbuf_AddCall{ 0xB7C220 };
WEAK symbol<void(int localClientNum, const char* msg, int flags)> CG_Utils_GameMessage{ 0x1D7FC0 };
WEAK symbol<void(int localClientNum, const char* msg, int flags)> CG_Utils_BoldGameMessage{ 0x1D7F10 };
WEAK symbol<void(int localClientNum, int andMask)> CL_Keys_RemoveCatcher{ 0x9A9B00 };
WEAK symbol<void(int localClientNum, int controllerIndex, const char* text)> Cmd_ExecuteSingleCommand{ 0xB7D040 };
WEAK symbol<void(const char* cmdName, void(), cmd_function_s* allocedCmd)> Cmd_AddCommandInternal{ 0xB7C8F0 };
@ -49,7 +61,7 @@ namespace game
WEAK symbol<dvar_t* (const char* name, float x, float y, float z,
float w, float min, float max, unsigned int flags, const char* description)> Dvar_RegisterVec4{ 0xCEC110 };
WEAK symbol<dvar_t*(unsigned int checksum, const char* string, DvarSetSource source)> Dvar_SetFromStringByChecksum{ 0xCECDB0 };
WEAK symbol<dvar_t* (unsigned int checksum, const char* string, DvarSetSource source)> Dvar_SetFromStringByChecksum{ 0xCECDB0 };
WEAK symbol<dvar_t* (const char* name, const char* string, DvarSetSource source)> Dvar_SetFromStringByName{ 0xCECF30 };
WEAK symbol<void(dvar_t* dvar, const char* string, DvarSetSource source)> Dvar_SetFromStringFromSource{ 0xCECFF0 };
@ -67,6 +79,11 @@ namespace game
WEAK symbol<const char* (int, int, int)> Key_KeynumToString{ 0x9A95E0 };
WEAK symbol<bool()> LUI_CoD_InFrontEnd{ 0x615080 };
WEAK symbol<void(bool frontend, bool errorRecovery)> LUI_CoD_Init{ 0x615090 };
WEAK symbol<void()> LUI_CoD_Shutdown{ 0x617610 };
WEAK symbol<void(int localClientNum, const char* menuName, int isPopup, int isModal, int isExclusive)> LUI_OpenMenu{ 0xCC0CA0 };
WEAK symbol<void(int localClientNum, const char* menuName, int immediate)> LUI_CloseMenu{ 0xCC0C40 };
WEAK symbol<void(int localClientNum)> LUI_CoD_CLoseAll{ 0x6135C0 };
WEAK symbol<unsigned int(int controllerIndex)> Live_SyncOnlineDataFlags{ 0xDC5CE0 };
@ -95,8 +112,17 @@ namespace game
WEAK symbol<void(const char* string)> SV_Cmd_TokenizeString{ 0xB7DD00 };
WEAK symbol<void()> SV_Cmd_EndTokenizedString{ 0xB7DCC0 };
WEAK symbol<void(const char* map, const char* gameType, int clientCount, int agentCount, bool hardcore,
bool mapIsPreloaded, bool migrate)> SV_CmdsMP_StartMapForParty{ 0xC4D150 };
WEAK symbol<void()> SV_CmdsMP_CheckLoadGame{ 0xC4C9E0 };
WEAK symbol<void()> SV_CmdsSP_MapRestart_f{ 0xC12B30 };
WEAK symbol<void()> SV_CmdsSP_FastRestart_f{ 0xC12AF0 };
WEAK symbol<void(int clientNum, svscmd_type type, const char* text)> SV_GameSendServerCommand{ 0xC54780 };
WEAK symbol<bool()> SV_Loaded{ 0xC114C0 };
WEAK symbol<bool(const char* name)> SV_MapExists{ 0xCDB620 };
WEAK symbol<void(int)> SND_StopSounds{ 0xCA06E0 };
WEAK symbol<void(const char*)> SND_SetMusicState{ 0xC9E110 };
/***************************************************************
* Variables
@ -119,4 +145,8 @@ namespace game
WEAK symbol<int> svs_numclients{ 0x6B229E0 };
WEAK symbol<client_t> svs_clients{ 0x6B22950 };
WEAK symbol<int> sv_map_restart{ 0x6B2C9D4 };
WEAK symbol<int> sv_loadScripts{ 0x6B2C9D8 };
WEAK symbol<int> sv_migrate{ 0x6B2C9DC };
}