experiments pt6

This commit is contained in:
quaK 2022-09-26 02:58:31 +03:00
parent f2f93efbb5
commit 5d058f79c5
8 changed files with 513 additions and 170 deletions

View File

@ -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))

View File

@ -0,0 +1,283 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include "dvars.hpp"
#include "command.hpp"
#include "console.hpp"
#include "scheduler.hpp"
#include <utils/hook.hpp>
#include <utils/string.hpp>
#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<void>(0xDF62C0_b);
// R_RegisterCmds
//utils::hook::invoke<void>(0xDD7E50_b);
// R_LoadGraphicsAssets
utils::hook::invoke<void>(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<void>(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<void>(cmds, size);
}
}
DWORD __stdcall wait_for_single_object_stub(HANDLE handle, DWORD ms)
{
if (handle == *reinterpret_cast<HANDLE*>(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<uint8_t>(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<uint8_t>(0xBB0930_b, 0xC3); // don't save config file
utils::hook::set<uint8_t>(0x9D49C0_b, 0xC3); // disable self-registration // done
//utils::hook::set<uint8_t>(0xD597C0_b, 0xC3); // init sound system (1) // done Voice_Init
//utils::hook::set<uint8_t>(0x701820_b, 0xC3); // init sound system (2) // can't find ( arxan'd ) SND_Init?
utils::hook::set<uint8_t>(0xE574E0_b, 0xC3); // render thread // done RB_RenderThread
utils::hook::set<uint8_t>(0x3471A0_b, 0xC3); // called from Com_Frame, seems to do renderer stuff // done CL_Screen_Update
utils::hook::set<uint8_t>(0x9AA9A0_b, 0xC3); // CL_CheckForResend, which tries to connect to the local server constantly // done CL_MainMP_CheckForResend
//utils::hook::set<uint8_t>(0x67ADCE_b, 0x00); // r_loadForRenderer default to 0 // done via dvar override
utils::hook::set<uint8_t>(0xD2EBB0_b, 0xC3); // recommended settings check // done
//utils::hook::set<uint8_t>(0x5BE850_b, 0xC3); // some mixer-related function called on shutdown // not needed, only called from Voice_Init
//utils::hook::set<uint8_t>(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<uint8_t>(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<uint8_t>(0x1D8A20_b, 0xC3); // cpu detection stuff? // can't find
//utils::hook::set<uint8_t>(0x690F30_b, 0xC3); // gfx stuff during fastfile loading // not there
//utils::hook::set<uint8_t>(0x690E00_b, 0xC3); // ^
//utils::hook::set<uint8_t>(0x690ED0_b, 0xC3); // ^
//utils::hook::set<uint8_t>(0x39B980_b, 0xC3); // ^
//utils::hook::set<uint8_t>(0x690E50_b, 0xC3); // ^
//utils::hook::set<uint8_t>(0xDD26E0_b, 0xC3); // directx stuff // done
//utils::hook::set<uint8_t>(0xE00FC0_b, 0xC3); // ^
//utils::hook::set<uint8_t>(0x6CE390_b, 0xC3); // ^ - mutex // not done
//utils::hook::set<uint8_t>(0x681ED0_b, 0xC3); // ^
//utils::hook::set<uint8_t>(0x0A3CD0_b, 0xC3); // rendering stuff // not done
//utils::hook::set<uint8_t>(0x682150_b, 0xC3); // ^
//utils::hook::set<uint8_t>(0x682260_b, 0xC3); // ^
//utils::hook::set<uint8_t>(0x6829C0_b, 0xC3); // ^
//utils::hook::set<uint8_t>(0x6834A0_b, 0xC3); // ^
//utils::hook::set<uint8_t>(0x683B40_b, 0xC3); // ^
// shaders
//utils::hook::set<uint8_t>(0x5F0610_b, 0xC3); // ^ // done
//utils::hook::set<uint8_t>(0x5F0580_b, 0xC3); // ^ // done
//utils::hook::set<uint8_t>(0xE51020_b, 0xC3); // ^ - mutex // done
//utils::hook::set<uint8_t>(0x5BFD10_b, 0xC3); // idk // not done
//utils::hook::set<uint8_t>(0xDD4430_b, 0xC3); // ^ // R_ReleaseBuffer
//utils::hook::set<uint8_t>(0xE08360_b, 0xC3); // R_Shutdown
//utils::hook::set<uint8_t>(0x652BA0_b, 0xC3); // shutdown stuff // not done
//utils::hook::set<uint8_t>(0x687DF0_b, 0xC3); // ^ // not done
//utils::hook::set<uint8_t>(0x686DE0_b, 0xC3); // ^ // not done
// utils::hook::set<uint8_t>(0x1404B67E0, 0xC3); // sound crashes (H1 - questionable, function looks way different)
utils::hook::set<uint8_t>(0xC5A200_b, 0xC3); // disable host migration // done SV_MigrationStart
//utils::hook::set<uint8_t>(0xBB66B0_b, 0xC3); // render synchronization lock // done
//utils::hook::set<uint8_t>(0xBB64A0_b, 0xC3); // render synchronization unlock // done
//utils::hook::set<uint8_t>(0x615359_b, 0xEB); // LUI: Unable to start the LUI system due to errors in main.lua // done
//utils::hook::set<uint8_t>(0x27AAC5_b, 0xEB); // LUI: Unable to start the LUI system due to errors in depot.lua // no
//utils::hook::set<uint8_t>(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<uint8_t>(0x3A0BA0_b, 0xC3); // Disable image pak file loading // not done
// Reduce min required memory
//utils::hook::set<uint64_t>(0x5B7F37_b, 0x80000000); // not done
//utils::hook::set<uint8_t>(0x399E10_b, 0xC3); // some loop // not done
//utils::hook::set<uint8_t>(0x1D48B0_b, 0xC3); // related to shader caching / techsets / fastfilesc // not done
//utils::hook::set<uint8_t>(0x3A1940_b, 0xC3); // DB_ReadPackedLoadedSounds // not done
// iw7 patches
utils::hook::set<uint8_t>(0xE06060_b, 0xC3); // directx
utils::hook::set<uint8_t>(0xE05B80_b, 0xC3); // ^
utils::hook::set<uint8_t>(0xDD2760_b, 0xC3); // ^
utils::hook::set<uint8_t>(0xE05E20_b, 0xC3); // ^ buffer
utils::hook::set<uint8_t>(0xE11270_b, 0xC3); // ^
utils::hook::set<uint8_t>(0xDD3C50_b, 0xC3); // ^
utils::hook::set<uint8_t>(0x0C1210_b, 0xC3); // ^ idk
utils::hook::set<uint8_t>(0x0C12B0_b, 0xC3); // ^ idk
utils::hook::set<uint8_t>(0xE423A0_b, 0xC3); // directx
utils::hook::set<uint8_t>(0xE04680_b, 0xC3); // ^
utils::hook::set<uint8_t>(0xE00ED0_b, 0xC3); // Image_Create1DTexture_PC
utils::hook::set<uint8_t>(0xE00FC0_b, 0xC3); // Image_Create2DTexture_PC
utils::hook::set<uint8_t>(0xE011A0_b, 0xC3); // Image_Create3DTexture_PC
utils::hook::set<uint8_t>(0xE015C0_b, 0xC3); // Image_CreateCubeTexture_PC
utils::hook::set<uint8_t>(0xE01300_b, 0xC3); // Image_CreateArrayTexture_PC
utils::hook::set<uint8_t>(0x5F1EA0_b, 0xC3); // renderer
utils::hook::set<uint8_t>(0x0C1370_b, 0xC3); // ^
utils::hook::set<uint8_t>(0xDD26E0_b, 0xC3); // directx
utils::hook::set<uint8_t>(0x5F0610_b, 0xC3); // ^
utils::hook::set<uint8_t>(0x5F0580_b, 0xC3); // ^
utils::hook::set<uint8_t>(0x5F0820_b, 0xC3); // ^
utils::hook::set<uint8_t>(0x5F0790_b, 0xC3); // ^
utils::hook::set<uint8_t>(0x3B9E72_b, 0xEB); // skip R_GetFrameIndex check in DB_LoadLevelXAssets
// release buffer
utils::hook::set<uint8_t>(0xDD4430_b, 0xEB);
// R_LoadWorld
utils::hook::set<uint8_t>(0xDD14C0_b, 0xC3);
scheduler::loop([]() // maybe not needed
{
// snd_enabled
*reinterpret_cast<DWORD*>(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)

View File

@ -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))
{

View File

@ -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();

View File

@ -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",

View File

@ -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<void(XAssetHeader)>& callback);

View File

@ -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

View File

@ -162,6 +162,8 @@ namespace game
WEAK symbol<int> svs_numclients{ 0x6B229E0 };
WEAK symbol<client_t> svs_clients{ 0x6B22950 };
WEAK symbol<clientUIActive_t> clientUIActives{ 0x2246C30 };
WEAK symbol<int> sv_map_restart{ 0x6B2C9D4 };
WEAK symbol<int> sv_loadScripts{ 0x6B2C9D8 };
WEAK symbol<int> sv_migrate{ 0x6B2C9DC };