diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 65520c5b..85fa6298 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -181,87 +181,6 @@ 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() @@ -437,89 +356,6 @@ namespace command 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; - } - - 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)) diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp new file mode 100644 index 00000000..c2a7dc4a --- /dev/null +++ b/src/client/component/dedicated.cpp @@ -0,0 +1,283 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include "dvars.hpp" +#include "command.hpp" +#include "console.hpp" +#include "scheduler.hpp" + +#include +#include + +#include "game/dvars.hpp" + +namespace dedicated +{ + namespace + { + void sync_gpu_stub() + { + std::this_thread::sleep_for(1ms); + } + + void init_dedicated_server() + { + static bool initialized = false; + if (initialized) return; + initialized = true; + + // R_RegisterDvars + //utils::hook::invoke(0xDF62C0_b); + + // R_RegisterCmds + //utils::hook::invoke(0xDD7E50_b); + + // R_LoadGraphicsAssets + utils::hook::invoke(0xE06220_b); + } + + utils::hook::detour dvar_set_float_from_source_hook; + void dvar_set_float_from_source_stub(const game::dvar_t* dvar, double value, game::DvarSetSource source) + { + if (dvar) + { + printf("%s\n", dvars::dvar_get_name(dvar).data()); + } + else + { + printf("fuck\n"); + return; + } + dvar_set_float_from_source_hook.invoke(dvar, value, source); + } + + utils::hook::detour cmd_add_client_command_list_hook; + void cmd_add_client_command_list_stub(game::SvCommandInfo* cmds, unsigned int size) + { + printf("add: %p, %d\n", cmds, size); + + for (auto i = 0u; i < size; i++) + { + /*printf("cmd[%d]: name: %s, func: %p, svvar.name: %s, svvar.func: %p, svvar.next: %p\n", + i, + cmds[i].name, + cmds[i].function, + cmds[i].svvar.name, + cmds[i].svvar.function, + cmds[i].svvar.next);*/ + + //memset(&cmds[i].svvar, 0, sizeof(game::cmd_function_s)); + } + + cmd_add_client_command_list_hook.invoke(cmds, size); + } + } + + DWORD __stdcall wait_for_single_object_stub(HANDLE handle, DWORD ms) + { + if (handle == *reinterpret_cast(0x8B1BC98_b)) + { + //printf("not waiting for mutex\n"); + return 0; + } + + return WaitForSingleObject(handle, ms); + } + + void initialize() + { + //command::execute("exec default_xboxlive.cfg", true); + command::execute("onlinegame 1", true); + command::execute("xblive_privatematch 1", true); + } + + class component final : public component_interface + { + public: + void* load_import(const std::string& library, const std::string& function) override + { + if (game::environment::is_dedi()) + { + if (function == "WaitForSingleObject") + { + return wait_for_single_object_stub; + } + } + + return nullptr; + } + + void post_unpack() override + { + if (!game::environment::is_dedi()) + { + return; + } + +#ifdef DEBUG + printf("Starting dedicated server\n"); +#endif + + dvar_set_float_from_source_hook.create(0xCECD00_b, dvar_set_float_from_source_stub); + cmd_add_client_command_list_hook.create(0xB7C840_b, cmd_add_client_command_list_stub); + //utils::hook::set(0xB7C840_b, 0xC3); + + // Register dedicated dvar + game::Dvar_RegisterBool("dedicated", true, game::DVAR_FLAG_READ, "Dedicated server"); + + // Add lanonly mode + game::Dvar_RegisterBool("sv_lanOnly", false, game::DVAR_FLAG_NONE, "Don't send heartbeat"); + + // Disable frontend + dvars::override::register_bool("frontEndSceneEnabled", false, game::DVAR_FLAG_READ); + + // Disable shader preload + dvars::override::register_bool("r_preloadShaders", false, game::DVAR_FLAG_READ); + + // Disable renderer + dvars::override::register_bool("r_loadForRenderer", false, game::DVAR_FLAG_READ); + + // Preload game mode fastfiles on launch + dvars::override::register_bool("fastfilePreloadGamemode", true, game::DVAR_FLAG_NONE); + + dvars::override::register_bool("intro", false, game::DVAR_FLAG_READ); + + // Hook R_SyncGpu + utils::hook::jump(0xE08AE0_b, sync_gpu_stub, true); + + utils::hook::jump(0x341B60_b, init_dedicated_server, true); + + utils::hook::nop(0xCDD5D3_b, 5); // don't load config file + utils::hook::nop(0xB7CE46_b, 5); // ^ + utils::hook::set(0xBB0930_b, 0xC3); // don't save config file + + utils::hook::set(0x9D49C0_b, 0xC3); // disable self-registration // done + //utils::hook::set(0xD597C0_b, 0xC3); // init sound system (1) // done Voice_Init + //utils::hook::set(0x701820_b, 0xC3); // init sound system (2) // can't find ( arxan'd ) SND_Init? + utils::hook::set(0xE574E0_b, 0xC3); // render thread // done RB_RenderThread + utils::hook::set(0x3471A0_b, 0xC3); // called from Com_Frame, seems to do renderer stuff // done CL_Screen_Update + utils::hook::set(0x9AA9A0_b, 0xC3); // CL_CheckForResend, which tries to connect to the local server constantly // done CL_MainMP_CheckForResend + //utils::hook::set(0x67ADCE_b, 0x00); // r_loadForRenderer default to 0 // done via dvar override + utils::hook::set(0xD2EBB0_b, 0xC3); // recommended settings check // done + //utils::hook::set(0x5BE850_b, 0xC3); // some mixer-related function called on shutdown // not needed, only called from Voice_Init + //utils::hook::set(0x4DEA50_b, 0xC3); // dont load ui gametype stuff // don't add this for now + + utils::hook::nop(0xC5007B_b, 6); // unknown check in SV_ExecuteClientMessage // done + utils::hook::nop(0xC4F407_b, 3); // allow first slot to be occupied // done + utils::hook::nop(0x3429A7_b, 2); // properly shut down dedicated servers // done + utils::hook::nop(0x34296F_b, 2); // ^ // done + utils::hook::nop(0x3429CD_b, 5); // don't shutdown renderer // done ( maybe need to add R_ShutdownWorld to this too? ) + + //utils::hook::set(0xAA290_b, 0xC3); // something to do with blendShapeVertsView // not a thing in iw7 + //utils::hook::nop(0x70465D_b, 8); // sound thing // dunno if needed + + //utils::hook::set(0x1D8A20_b, 0xC3); // cpu detection stuff? // can't find + //utils::hook::set(0x690F30_b, 0xC3); // gfx stuff during fastfile loading // not there + //utils::hook::set(0x690E00_b, 0xC3); // ^ + //utils::hook::set(0x690ED0_b, 0xC3); // ^ + //utils::hook::set(0x39B980_b, 0xC3); // ^ + //utils::hook::set(0x690E50_b, 0xC3); // ^ + //utils::hook::set(0xDD26E0_b, 0xC3); // directx stuff // done + //utils::hook::set(0xE00FC0_b, 0xC3); // ^ + //utils::hook::set(0x6CE390_b, 0xC3); // ^ - mutex // not done + //utils::hook::set(0x681ED0_b, 0xC3); // ^ + + //utils::hook::set(0x0A3CD0_b, 0xC3); // rendering stuff // not done + //utils::hook::set(0x682150_b, 0xC3); // ^ + //utils::hook::set(0x682260_b, 0xC3); // ^ + //utils::hook::set(0x6829C0_b, 0xC3); // ^ + //utils::hook::set(0x6834A0_b, 0xC3); // ^ + //utils::hook::set(0x683B40_b, 0xC3); // ^ + + // shaders + //utils::hook::set(0x5F0610_b, 0xC3); // ^ // done + //utils::hook::set(0x5F0580_b, 0xC3); // ^ // done + //utils::hook::set(0xE51020_b, 0xC3); // ^ - mutex // done + + //utils::hook::set(0x5BFD10_b, 0xC3); // idk // not done + //utils::hook::set(0xDD4430_b, 0xC3); // ^ // R_ReleaseBuffer + + //utils::hook::set(0xE08360_b, 0xC3); // R_Shutdown + //utils::hook::set(0x652BA0_b, 0xC3); // shutdown stuff // not done + //utils::hook::set(0x687DF0_b, 0xC3); // ^ // not done + //utils::hook::set(0x686DE0_b, 0xC3); // ^ // not done + + // utils::hook::set(0x1404B67E0, 0xC3); // sound crashes (H1 - questionable, function looks way different) + + utils::hook::set(0xC5A200_b, 0xC3); // disable host migration // done SV_MigrationStart + + //utils::hook::set(0xBB66B0_b, 0xC3); // render synchronization lock // done + //utils::hook::set(0xBB64A0_b, 0xC3); // render synchronization unlock // done + + //utils::hook::set(0x615359_b, 0xEB); // LUI: Unable to start the LUI system due to errors in main.lua // done + //utils::hook::set(0x27AAC5_b, 0xEB); // LUI: Unable to start the LUI system due to errors in depot.lua // no + //utils::hook::set(0x27AADC_b, 0xEB); // ^ + + //utils::hook::nop(0xCFDA7E_b, 5); // Disable sound pak file loading // done + //utils::hook::nop(0xCFDA97_b, 2); // ^ // done + //utils::hook::set(0x3A0BA0_b, 0xC3); // Disable image pak file loading // not done + + // Reduce min required memory + //utils::hook::set(0x5B7F37_b, 0x80000000); // not done + + //utils::hook::set(0x399E10_b, 0xC3); // some loop // not done + //utils::hook::set(0x1D48B0_b, 0xC3); // related to shader caching / techsets / fastfilesc // not done + //utils::hook::set(0x3A1940_b, 0xC3); // DB_ReadPackedLoadedSounds // not done + + // iw7 patches + utils::hook::set(0xE06060_b, 0xC3); // directx + utils::hook::set(0xE05B80_b, 0xC3); // ^ + utils::hook::set(0xDD2760_b, 0xC3); // ^ + utils::hook::set(0xE05E20_b, 0xC3); // ^ buffer + utils::hook::set(0xE11270_b, 0xC3); // ^ + utils::hook::set(0xDD3C50_b, 0xC3); // ^ + utils::hook::set(0x0C1210_b, 0xC3); // ^ idk + utils::hook::set(0x0C12B0_b, 0xC3); // ^ idk + utils::hook::set(0xE423A0_b, 0xC3); // directx + utils::hook::set(0xE04680_b, 0xC3); // ^ + + utils::hook::set(0xE00ED0_b, 0xC3); // Image_Create1DTexture_PC + utils::hook::set(0xE00FC0_b, 0xC3); // Image_Create2DTexture_PC + utils::hook::set(0xE011A0_b, 0xC3); // Image_Create3DTexture_PC + utils::hook::set(0xE015C0_b, 0xC3); // Image_CreateCubeTexture_PC + utils::hook::set(0xE01300_b, 0xC3); // Image_CreateArrayTexture_PC + + utils::hook::set(0x5F1EA0_b, 0xC3); // renderer + utils::hook::set(0x0C1370_b, 0xC3); // ^ + utils::hook::set(0xDD26E0_b, 0xC3); // directx + utils::hook::set(0x5F0610_b, 0xC3); // ^ + utils::hook::set(0x5F0580_b, 0xC3); // ^ + utils::hook::set(0x5F0820_b, 0xC3); // ^ + utils::hook::set(0x5F0790_b, 0xC3); // ^ + + utils::hook::set(0x3B9E72_b, 0xEB); // skip R_GetFrameIndex check in DB_LoadLevelXAssets + + // release buffer + utils::hook::set(0xDD4430_b, 0xEB); + + // R_LoadWorld + utils::hook::set(0xDD14C0_b, 0xC3); + + scheduler::loop([]() // maybe not needed + { + // snd_enabled + *reinterpret_cast(0x7201A88_b) = 0; + + + }, scheduler::pipeline::async); + + command::add("startserver", []() + { + initialize(); + + console::info("==================================\n"); + console::info("Server started!\n"); + console::info("==================================\n"); + }); + } + }; +} + +REGISTER_COMPONENT(dedicated::component) \ No newline at end of file diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index e2a7eb54..437581bb 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -28,6 +28,14 @@ namespace party bool hostDefined{ false }; } connect_state; + void perform_game_initialization() + { + command::execute("onlinegame 1", true); + command::execute("xblive_privatematch 1", true); + command::execute("xstartprivateparty", true); + //command::execute("xstartprivatematch", true); + } + void connect_to_party(const game::netadr_s& target, const std::string& mapname, const std::string& gametype) { if (game::Com_GameMode_GetActiveGameMode() != game::GAME_MODE_MP && @@ -60,7 +68,7 @@ namespace party } }*/ - //perform_game_initialization(); + perform_game_initialization(); // shutdown frontend game::Com_FrontEndScene_ShutdownAndDisable(); @@ -104,6 +112,85 @@ namespace party } } + 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); + } + + 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()), false); + 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; + } + + int get_client_num_by_name(const std::string& name) + { + return 0; + } + int get_client_count() { return 0; @@ -145,6 +232,94 @@ namespace party public: void post_unpack() override { + command::add("live", []() + { + console::info("%d\n", game::Live_SyncOnlineDataFlags(0)); + }); + + 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); + + command::add("map", [](const command::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), false); + }); + + command::add("devmap", [](const command::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); + }); + + command::add("map_restart", []() + { + 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); + }); + + command::add("fast_restart", []() + { + 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); + }); + command::add("connect", [](const command::params& argument) { if (argument.size() != 2) @@ -152,6 +327,12 @@ namespace party return; } + if (game::CL_IsGameClientActive(0)) + { + console::info("Cannot use \"connect\" command while ingame.\n"); + return; + } + game::netadr_s target{}; if (game::NET_StringToAdr(argument[1], &target)) { diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp index e770a426..958b1866 100644 --- a/src/client/component/party.hpp +++ b/src/client/component/party.hpp @@ -3,12 +3,12 @@ namespace party { - void menu_error(const std::string& error); + void info_response_error(const std::string& error); void reset_connect_state(); void connect(const game::netadr_s& target); - void start_map(const std::string& mapname, bool dev = false); + bool start_map(const std::string& mapname, bool dev = false); void clear_sv_motd(); game::netadr_s get_state_host(); diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index d483f2e3..060e3e4f 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -42,6 +42,15 @@ namespace game return sv_cmd_args->argv[sv_cmd_args->nesting][index]; } + bool CL_IsGameClientActive(const int localClientNum) + { + if (game::clientUIActives[localClientNum].frontEndSceneState[0]) + { + return false; + } + return game::clientUIActives[localClientNum].cgameInitialized; + } + const char* g_assetNames[ASSET_TYPE_COUNT] = { "physicslibrary", diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp index 2d73914c..1c7bcd4a 100644 --- a/src/client/game/game.hpp +++ b/src/client/game/game.hpp @@ -48,6 +48,8 @@ namespace game int SV_Cmd_Argc(); const char* SV_Cmd_Argv(int index); + bool CL_IsGameClientActive(const int localClientNum); + 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& callback); diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index db5e86f5..e6b2cf81 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -57,14 +57,13 @@ namespace game { cmd_function_s* next; const char* name; - void(__cdecl* function)(); + void(__fastcall* function)(); }; struct SvCommandInfo { const char* name; - void(__fastcall* func)(); - cmd_function_s clvar; + void(__fastcall* function)(); cmd_function_s svvar; }; @@ -409,6 +408,37 @@ namespace game namespace entity { + enum connstate_t : std::uint32_t + { + CA_DISCONNECTED = 0x0, + CA_CONNECTING = 0x1, + CA_CHALLENGING = 0x2, + CA_CONNECTED = 0x3, + CA_SENDINGSTATS = 0x4, + CA_REQUESTING_MATCH_RULES = 0x5, + CA_STARTING = 0x6, + CA_LOADING = 0x7, + CA_PRIMED = 0x8, + CA_ACTIVE = 0x9, + CA_MAP_RESTART = 0xA, + }; + + struct clientUIActive_t + { + bool active; + bool isRunning; + int keyCatchers; + connstate_t connectionState; + char __pad0[20]; + BYTE frontEndSceneState[1]; + bool cgameInitialized; + bool cgameInitCalled; + char __pad1[161]; + }; static_assert(sizeof(clientUIActive_t) == 196); + static_assert(offsetof(clientUIActive_t, connectionState) == 8); + static_assert(offsetof(clientUIActive_t, frontEndSceneState) == 32); + static_assert(offsetof(clientUIActive_t, cgameInitialized) == 33); + struct entityState_t { __int16 number; // 0 diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 91e8823a..9c70fbcd 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -162,6 +162,8 @@ namespace game WEAK symbol svs_numclients{ 0x6B229E0 }; WEAK symbol svs_clients{ 0x6B22950 }; + WEAK symbol clientUIActives{ 0x2246C30 }; + WEAK symbol sv_map_restart{ 0x6B2C9D4 }; WEAK symbol sv_loadScripts{ 0x6B2C9D8 }; WEAK symbol sv_migrate{ 0x6B2C9DC };