From 3d77a21f3da483a57d0a26d5f719af171a0091aa Mon Sep 17 00:00:00 2001 From: diamante0018 Date: Fri, 24 Jan 2025 13:59:57 +0100 Subject: [PATCH] assets(weapons): cache weapons from code (Code quaK/H1-Mod probably took from Pluto xD) Co-authored-by: H1-Mod Team Co-authored-by: HighTechRedNeck --- src/client/component/assets/weapons.cpp | 61 ++++++++ src/client/component/command.cpp | 76 ++++------ src/client/component/dvar_cheats.cpp | 4 +- src/client/component/party.cpp | 9 +- src/client/component/patches.cpp | 5 + src/client/game/engine/sv_game.cpp | 181 ++++++++++++++++++++++++ src/client/game/engine/sv_game.hpp | 6 + src/client/game/structs.hpp | 42 +++++- src/client/game/symbols.hpp | 7 +- src/client/std_include.hpp | 1 + 10 files changed, 331 insertions(+), 61 deletions(-) create mode 100644 src/client/component/assets/weapons.cpp create mode 100644 src/client/game/engine/sv_game.cpp create mode 100644 src/client/game/engine/sv_game.hpp diff --git a/src/client/component/assets/weapons.cpp b/src/client/component/assets/weapons.cpp new file mode 100644 index 0000000..5e414c1 --- /dev/null +++ b/src/client/component/assets/weapons.cpp @@ -0,0 +1,61 @@ +#include +#include "loader/component_loader.hpp" +#include "game/game.hpp" + +#include "component/console.hpp" + +#include + +namespace weapons +{ + namespace + { + void g_setup_level_weapon_def_stub() + { + game::G_SetupLevelWeaponDef(); + + // The count on most maps is well below 200 + std::array weapons{}; + const auto count = game::DB_GetAllXAssetOfType_FastFile(game::ASSET_TYPE_WEAPON, (void**)weapons.data(), static_cast(weapons.max_size())); + + std::sort(weapons.begin(), weapons.begin() + count, [](game::WeaponCompleteDef* weapon1, game::WeaponCompleteDef* weapon2) + { + assert(weapon1->szInternalName); + assert(weapon2->szInternalName); + + return std::strcmp(weapon1->szInternalName, weapon2->szInternalName) < 0; + }); + +#ifdef _DEBUG + console::info("Found %i weapons to precache\n", count); +#endif + + for (auto i = 0; i < count; ++i) + { +#ifdef _DEBUG + console::info("Precaching weapon \"%s\"\n", weapons[i]->szInternalName); +#endif + (void)game::G_GetWeaponForName(weapons[i]->szInternalName); + } + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_sp()) return; + + // Kill Scr_PrecacheItem (We are going to do this from code) + utils::hook::nop(0x1403BDB10, 4); + utils::hook::set(0x1403BDB10, 0xC3); + + // Load weapons from the DB + utils::hook::call(0x14039F382, g_setup_level_weapon_def_stub); + utils::hook::call(0x1403AE31A, g_setup_level_weapon_def_stub); + } + }; +} + +REGISTER_COMPONENT(weapons::component) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index c7dc997..bfc3218 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -2,6 +2,7 @@ #include "loader/component_loader.hpp" #include "game/game.hpp" #include "game/dvars.hpp" +#include "game/engine/sv_game.hpp" #include "command.hpp" #include "console.hpp" @@ -459,10 +460,7 @@ namespace command } game::sp::g_entities[0].flags ^= game::FL_GODMODE; - game::CG_GameMessage(0, utils::string::va("godmode %s", - game::sp::g_entities[0].flags & game::FL_GODMODE - ? "^2on" - : "^1off")); + game::CG_GameMessage(0, utils::string::va("godmode %s", game::sp::g_entities[0].flags & game::FL_GODMODE ? "^2on" : "^1off")); }); add("notarget", [] @@ -473,10 +471,7 @@ namespace command } game::sp::g_entities[0].flags ^= game::FL_NOTARGET; - game::CG_GameMessage(0, utils::string::va("notarget %s", - game::sp::g_entities[0].flags & game::FL_NOTARGET - ? "^2on" - : "^1off")); + game::CG_GameMessage(0, utils::string::va("notarget %s", game::sp::g_entities[0].flags & game::FL_NOTARGET ? "^2on" : "^1off")); }); add("noclip", [] @@ -487,10 +482,7 @@ namespace command } game::sp::g_entities[0].client->flags ^= 1; - game::CG_GameMessage(0, utils::string::va("noclip %s", - game::sp::g_entities[0].client->flags & 1 - ? "^2on" - : "^1off")); + game::CG_GameMessage(0, utils::string::va("noclip %s", game::sp::g_entities[0].client->flags & 1 ? "^2on" : "^1off")); }); add("ufo", [] @@ -501,10 +493,7 @@ namespace command } game::sp::g_entities[0].client->flags ^= 2; - game::CG_GameMessage(0, utils::string::va("ufo %s", - game::sp::g_entities[0].client->flags & 2 - ? "^2on" - : "^1off")); + game::CG_GameMessage(0, utils::string::va("ufo %s", game::sp::g_entities[0].client->flags & 2 ? "^2on" : "^1off")); }); add("give", [](const params& params) @@ -556,78 +545,65 @@ namespace command { if (!dvars::sv_cheats->current.enabled) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); return; } game::mp::g_entities[client_num].flags ^= game::FL_GODMODE; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"godmode %s\"", - game::mp::g_entities[client_num].flags & game::FL_GODMODE - ? "^2on" - : "^1off")); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, utils::string::va("f \"godmode %s\"", game::mp::g_entities[client_num].flags & game::FL_GODMODE ? "^2on" : "^1off")); }); add_sv("notarget", [](const int client_num, const params_sv&) { if (!dvars::sv_cheats->current.enabled) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); return; } game::mp::g_entities[client_num].flags ^= game::FL_NOTARGET; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"notarget %s\"", - game::mp::g_entities[client_num].flags & game::FL_NOTARGET - ? "^2on" - : "^1off")); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + utils::string::va("f \"notarget %s\"", game::mp::g_entities[client_num].flags & game::FL_NOTARGET ? "^2on" : "^1off")); }); add_sv("noclip", [](const int client_num, const params_sv&) { if (!dvars::sv_cheats->current.enabled) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); return; } game::mp::g_entities[client_num].client->flags ^= 1; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"noclip %s\"", - game::mp::g_entities[client_num].client->flags & 1 - ? "^2on" - : "^1off")); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + utils::string::va("f \"noclip %s\"", game::mp::g_entities[client_num].client->flags & 1 ? "^2on" : "^1off")); }); add_sv("ufo", [](const int client_num, const params_sv&) { if (!dvars::sv_cheats->current.enabled) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); return; } game::mp::g_entities[client_num].client->flags ^= 2; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"ufo %s\"", - game::mp::g_entities[client_num].client->flags & 2 - ? "^2on" - : "^1off")); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + utils::string::va("f \"ufo %s\"", game::mp::g_entities[client_num].client->flags & 2 ? "^2on" : "^1off")); }); add_sv("setviewpos", [](const int client_num, const params_sv& params) { if (!dvars::sv_cheats->current.enabled) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); return; } if (params.size() < 4) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"You did not specify the correct number of coordinates\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + "f \"You did not specify the correct number of coordinates\""); return; } @@ -640,14 +616,14 @@ namespace command { if (!dvars::sv_cheats->current.enabled) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); return; } if (params.size() < 4) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"You did not specify the correct number of coordinates\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + "f \"You did not specify the correct number of coordinates\""); return; } @@ -660,13 +636,13 @@ namespace command { if (!dvars::sv_cheats->current.enabled) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); return; } if (params.size() < 2) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"You did not specify a weapon name\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"You did not specify a weapon name\""); return; } @@ -683,13 +659,13 @@ namespace command { if (!dvars::sv_cheats->current.enabled) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\""); return; } if (params.size() < 2) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"You did not specify a weapon name\""); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"You did not specify a weapon name\""); return; } diff --git a/src/client/component/dvar_cheats.cpp b/src/client/component/dvar_cheats.cpp index 04c4654..72ce8af 100644 --- a/src/client/component/dvar_cheats.cpp +++ b/src/client/component/dvar_cheats.cpp @@ -1,8 +1,8 @@ #include #include "loader/component_loader.hpp" - #include "game/game.hpp" #include "game/dvars.hpp" +#include "game/engine/sv_game.hpp" #include "console.hpp" @@ -136,7 +136,7 @@ namespace dvar_cheats const auto* dvar = game::Scr_GetString(0); // grab the original dvar again since it's never stored on stack const auto* command = utils::string::va("q %s \"%s\"", dvar, value); - game::SV_GameSendServerCommand(entity_num, game::SV_CMD_RELIABLE, command); + game::engine::SV_GameSendServerCommand(entity_num, game::SV_CMD_RELIABLE, command); } const auto player_cmd_set_client_dvar = utils::hook::assemble([](utils::hook::assembler& a) diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index f6ec909..4b964f4 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -2,6 +2,7 @@ #include "loader/component_loader.hpp" #include "game/game.hpp" #include "game/dvars.hpp" +#include "game/engine/sv_game.hpp" #include "command.hpp" #include "console.hpp" @@ -380,7 +381,7 @@ namespace party const auto message = params.join(2); const auto* const name = game::Dvar_FindVar("sv_sayName")->current.string; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s: %s\"", 84, name, message.data())); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s: %s\"", 84, name, message.data())); console::info("%s -> %i: %s\n", name, client_num, message.data()); }); @@ -394,7 +395,7 @@ namespace party const auto client_num = atoi(params.get(1)); const auto message = params.join(2); - game::SV_GameSendServerCommand(client_num, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s\"", 84, message.data())); + game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s\"", 84, message.data())); console::info("%i: %s\n", client_num, message.data()); }); @@ -408,7 +409,7 @@ namespace party const auto message = params.join(1); const auto* const name = game::Dvar_FindVar("sv_sayName")->current.string; - game::SV_GameSendServerCommand(-1, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s: %s\"", 84, name, message.data())); + game::engine::SV_GameSendServerCommand(-1, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s: %s\"", 84, name, message.data())); console::info("%s: %s\n", name, message.data()); }); @@ -421,7 +422,7 @@ namespace party const auto message = params.join(1); - game::SV_GameSendServerCommand(-1, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s\"", 84, message.data())); + game::engine::SV_GameSendServerCommand(-1, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s\"", 84, message.data())); console::info("%s\n", message.data()); }); diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 59afda4..f5c9bb4 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -2,6 +2,7 @@ #include "loader/component_loader.hpp" #include "game/game.hpp" #include "game/dvars.hpp" +#include "game/engine/sv_game.hpp" #include "command.hpp" #include "console.hpp" @@ -290,6 +291,10 @@ namespace patches static void patch_mp() { + // Bypass Arxan function + utils::hook::nop(0x1404758C0, 16); + utils::hook::jump(0x1404758C0, game::engine::SV_GameSendServerCommand, true); + // Register dvars com_register_dvars_hook.create(0x140413A90, &com_register_dvars_stub); diff --git a/src/client/game/engine/sv_game.cpp b/src/client/game/engine/sv_game.cpp new file mode 100644 index 0000000..4f83e3b --- /dev/null +++ b/src/client/game/engine/sv_game.cpp @@ -0,0 +1,181 @@ +#include +#include + +#include "sv_game.hpp" + +#include + +#include + +namespace game::engine +{ + char* SV_ExpandNewlines(char* in) + { + static char string[1024]; + + unsigned int l = 0; + while (*in && l < sizeof(string) - 3) + { + if (*in == '\n') + { + string[l++] = '\\'; + string[l++] = 'n'; + } + else + { + if (*in != '\x14' && *in != '\x15') + { + string[l++] = *in; + } + } + + ++in; + } + + string[l] = '\0'; + return string; + } + + void SV_CullIgnorableServerCommands(mp::client_t* client) + { + int to = client->reliableSent + 1; + for (int from = to; from <= client->reliableSequence; ++from) + { + int from_index = from & 0x7F; + assert(client->netBuf.reliableCommandInfo[from_index].time >= 0); + if (client->netBuf.reliableCommandInfo[from_index].type) + { + int to_index = to & 0x7F; + if (to_index != from_index) + { + client->netBuf.reliableCommandInfo[to_index] = client->netBuf.reliableCommandInfo[from_index]; + } + + ++to; + } + } + + client->reliableSequence = to - 1; + } + + void SV_DelayDropClient(mp::client_t* drop, const char* reason) + { + assert(drop); + assert(reason); + assert(drop->header.state != CS_FREE); + if (drop->header.state == CS_ZOMBIE) + { +#ifdef _DEBUG + console::info("(drop->dropReason) = %s", drop->dropReason); +#endif + } + else if (!drop->dropReason) + { + drop->dropReason = reason; + } + } + + void SV_AddServerCommand(mp::client_t* client, svscmd_type type, const char* cmd) + { + static_assert(offsetof(mp::client_t, netBuf.reliableCommandInfo[0].cmd) == 0xC44); + + if (client->testClient == TC_BOT) + { + return; + } + + if (client->reliableSequence - client->reliableAcknowledge < 64 && client->header.state == CS_ACTIVE || (SV_CullIgnorableServerCommands(client), type)) + { + int len = static_cast(std::strlen(cmd)) + 1; + int to = SV_CanReplaceServerCommand(client, reinterpret_cast(cmd), len); + if (to < 0) + { + ++client->reliableSequence; + } + else + { + int from = to + 1; + while (from <= client->reliableSequence) + { + client->netBuf.reliableCommandInfo[to & 0x7F] = client->netBuf.reliableCommandInfo[from & 0x7F]; + ++from; + ++to; + } + } + + if (client->reliableSequence - client->reliableAcknowledge == 129) + { +#ifdef _DEBUG + console::info("===== pending server commands =====\n"); + int i = 0; + for (i = client->reliableAcknowledge + 1; i <= client->reliableSequence; ++i) + { + console::info("cmd %5d: %8d: %s\n", i, client->netBuf.reliableCommandInfo[i & 0x7F].time, client->netBuf.reliableCommandInfo[i & 0x7F].cmd); + } + console::info("cmd %5d: %8d: %s\n", i, *game::mp::serverTime, cmd); +#endif + NET_OutOfBandPrint(NS_SERVER, &client->header.netchan.remoteAddress, "disconnect"); + SV_DelayDropClient(client, "EXE_SERVERCOMMANDOVERFLOW"); + type = SV_CMD_RELIABLE; + cmd = utils::string::va("%c \"EXE_SERVERCOMMANDOVERFLOW\"", 'r'); + } + + int index = client->reliableSequence & 0x7F; + MSG_WriteReliableCommandToBuffer(cmd, client->netBuf.reliableCommandInfo[index].cmd, sizeof(client->netBuf.reliableCommandInfo[index].cmd)); + client->netBuf.reliableCommandInfo[index].time = *game::mp::serverTime; + client->netBuf.reliableCommandInfo[index].type = type; + } + } + + void SV_SendServerCommand(mp::client_t* cl, svscmd_type type, const char* fmt, ...) + { + mp::client_t* client; + int j, len; + va_list va; + + const auto server_command_buf_large = std::make_unique(0x20000); + + va_start(va, fmt); + len = vsnprintf_s(server_command_buf_large.get(), 0x20000, _TRUNCATE, fmt, va); + va_end(va); + + assert(len >= 0); + + if (cl) + { + SV_AddServerCommand(cl, type, server_command_buf_large.get()); + return; + } + + if (environment::is_dedi() && !std::strncmp(server_command_buf_large.get(), "print", 5)) + { + console::info("broadcast: %s\n", SV_ExpandNewlines(server_command_buf_large.get())); + } + + const auto* sv_maxclients = Dvar_FindVar("sv_maxclients"); + for (j = 0, client = mp::svs_clients; j < sv_maxclients->current.integer; j++, client++) + { + if (client->header.state < CS_CLIENTLOADING) + { + continue; + } + + SV_AddServerCommand(client, type, server_command_buf_large.get()); + } + } + + void SV_GameSendServerCommand(int clientNum, svscmd_type type, const char* text) + { + [[maybe_unused]] const auto* sv_maxclients = Dvar_FindVar("sv_maxclients"); + + if (clientNum == -1) + { + SV_SendServerCommand(nullptr, type, "%s", text); + return; + } + + assert(sv_maxclients->current.integer >= 1 && sv_maxclients->current.integer <= 18); + assert(static_cast(clientNum) < sv_maxclients->current.unsignedInt); + SV_SendServerCommand(&mp::svs_clients[clientNum], type, "%s", text); + } +} diff --git a/src/client/game/engine/sv_game.hpp b/src/client/game/engine/sv_game.hpp new file mode 100644 index 0000000..f1b7b70 --- /dev/null +++ b/src/client/game/engine/sv_game.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace game::engine +{ + void SV_GameSendServerCommand(int clientNum, svscmd_type type, const char* text); +} diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 5f80604..10220df 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1963,6 +1963,12 @@ namespace game const char* buffer; }; + struct WeaponCompleteDef + { + const char* szInternalName; + WeaponDef* weapDef; + }; // Incomplete + union XAssetHeader { void* data; @@ -1998,9 +2004,9 @@ namespace game menuDef_t *menu; AnimationClass *animClass; LocalizeEntry *localize; - WeaponAttachment *attachment; - WeaponCompleteDef *weapon; - SndDriverGlobals *sndDriverGlobals; + WeaponAttachment *attachment;*/ + WeaponCompleteDef* weapon; + /*SndDriverGlobals *sndDriverGlobals; FxEffectDef *fx; FxImpactTable *impactFx; SurfaceFxTable *surfaceFx;*/ @@ -2434,6 +2440,24 @@ namespace game int isInKillcam; }; + struct svscmd_info_t + { + int time; + int type; + char cmd[1024]; + }; + + static_assert(sizeof(svscmd_info_t) == 0x408); + + struct client_net_buffers_t + { + svscmd_info_t reliableCommandInfo[128]; + char netchanOutgoingBuffer[131072]; + char netchanIncomingBuffer[2048]; + }; + + static_assert(sizeof(client_net_buffers_t) == 0x40C00); + struct client_t { clientHeader_t header; @@ -2443,7 +2467,17 @@ namespace game int reliableAcknowledge; int reliableSent; int messageAcknowledge; - char _0xC30[0x41238]; + int largeCommandSequence; + int gamestateMessageNum; + int challenge; + client_net_buffers_t netBuf; + int cumulThinkTime; + int beginCmdIndex; + int currCmdIndex; + usercmd_s lastUsercmd; + usercmd_s cmds[8]; + int lastClientCommand; + char lastClientCommandString[1024]; gentity_s* gentity; char name[16]; int lastPacketTime; diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index a96c362..fdcb525 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -19,6 +19,7 @@ namespace game WEAK symbol AimAssist_AddToTargetList{0, 0x140139D80}; WEAK symbol BG_GetWeaponNameComplete{0, 0x140239370}; + WEAK symbol BG_ClearWeaponDef{0x0, 0x140238D20}; WEAK symbol Com_Frame_Try_Block_Function{0x1403BC980, 0x1404131A0}; WEAK symbol Com_Parse{0x1404313E0, 0x1404F50E0}; @@ -57,6 +58,7 @@ namespace game WEAK symbol DB_GetRawFileLen{0x140272E80, 0x14031FF80}; WEAK symbol DB_GetRawBuffer{0x140272D50, 0x14031FE50}; WEAK symbol DB_IsLocalized{0x140273210, 0x140320360}; + WEAK symbol DB_GetAllXAssetOfType_FastFile{0x0, 0x14031FC00}; WEAK symbol PMem_AllocFromSource_NoDebug{0x140430B80, 0x1404F46C0}; WEAK symbol PMem_Free{0x140430EC0 , 0x1404F4A30}; @@ -96,6 +98,7 @@ namespace game WEAK symbol G_FindItem{0x140462490, 0x14021B7E0}; WEAK symbol G_GivePlayerWeapon{0x140359E20, 0x1403DA5E0}; WEAK symbol G_GetWeaponForName{0x140359890, 0x1403DA060}; + WEAK symbol G_SetupLevelWeaponDef{0x0, 0x1403DA910}; WEAK symbol G_Glass_Update{0x14030E680, 0x140397450}; WEAK symbol G_InitializeAmmo{0x140311F00, 0x14039AEA0}; WEAK symbol G_SelectWeapon{0x14035A200, 0x1403DA880}; @@ -227,7 +230,7 @@ namespace game WEAK symbol SV_GetGuid{0, 0x140475990}; WEAK symbol SV_KickClientNum{0, 0x14046F730}; WEAK symbol SV_SetConfigstring{0, 0x140477450}; - WEAK symbol SV_GameSendServerCommand{0x140490F40, 0x1404758C0}; + WEAK symbol SV_CanReplaceServerCommand{0x0, 0x140478F00}; WEAK symbol Sys_Error{0x14043AC20, 0x1404FF510}; WEAK symbol Sys_IsDatabaseReady2{0x1403C2D40, 0x140423920}; @@ -255,6 +258,8 @@ namespace game WEAK symbol Jump_ClearState{0x0, 0x140213120}; + WEAK symbol MSG_WriteReliableCommandToBuffer{0x0, 0x1404232B0}; + WEAK symbol LargeLocalResetToMark{0x140423B50, 0x1404E4D00}; WEAK symbol longjmp{0x14062E030, 0x140738060}; diff --git a/src/client/std_include.hpp b/src/client/std_include.hpp index 11b7eb2..de4b4d0 100644 --- a/src/client/std_include.hpp +++ b/src/client/std_include.hpp @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include