From 2457dd564a96f6094df23269c511cba45f5d949a Mon Sep 17 00:00:00 2001 From: FutureRave Date: Mon, 8 May 2023 12:48:43 +0100 Subject: [PATCH] maint: cleanup --- src/game/game.cpp | 37 ++++++++--------- src/game/game.hpp | 29 ++++++++----- src/module/chat.cpp | 63 ++++++++++++++-------------- src/module/client_command.cpp | 4 +- src/module/command.cpp | 4 +- src/module/gsc/script_error.cpp | 73 +++++++++++++++++++++++++-------- src/module/gsc/script_error.hpp | 15 +++++-- src/module/player_movement.cpp | 30 +++++++++++++- src/module/test_clients.cpp | 5 +-- 9 files changed, 171 insertions(+), 89 deletions(-) diff --git a/src/game/game.cpp b/src/game/game.cpp index 865a04f..ec568e9 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -21,6 +21,7 @@ namespace game DB_EnumXAssets_t DB_EnumXAssets; DB_GetXAssetName_t DB_GetXAssetName; + Dvar_FindVar_t Dvar_FindVar; Dvar_RegisterBool_t Dvar_RegisterBool; Dvar_RegisterFloat_t Dvar_RegisterFloat; Dvar_RegisterInt_t Dvar_RegisterInt; @@ -107,6 +108,7 @@ namespace game PM_WeaponUseAmmo_t PM_WeaponUseAmmo; PM_playerTrace_t PM_playerTrace; PM_trace_t PM_trace; + PM_IsSprinting_t PM_IsSprinting; Jump_ClearState_t Jump_ClearState; @@ -131,6 +133,8 @@ namespace game Key_KeynumToString_t Key_KeynumToString; + I_strncpyz_t I_strncpyz; + decltype(longjmp)* _longjmp; CmdArgs* sv_cmd_args; @@ -199,9 +203,13 @@ namespace game SV_GetGuid_t SV_GetGuid; SV_GameSendServerCommand_t SV_GameSendServerCommand; + ClientCommand_t ClientCommand; + client_t* svs_clients; level_locals_t* level; + + gentity_s* g_entities; } namespace sp @@ -259,11 +267,6 @@ namespace game return scrMemTreeGlob + 12 * size_t(MT_AllocIndex(numBytes, type)); } - dvar_t* Dvar_FindVar(const char* dvarName) - { - return reinterpret_cast(SELECT_VALUE(0x539550, 0x5BDCC0))(dvarName); - } - void IncInParam() { Scr_ClearOutParams(); @@ -397,19 +400,16 @@ namespace game return sl_get_canonical_string(str); } - __declspec(naked) void sv_send_client_game_state_mp(mp::client_t* /*client*/) + void sv_send_client_game_state_mp(mp::client_t* client) { static DWORD func = 0x570FC0; __asm { pushad - - mov esi, [esp + 0x20 + 0x4] + mov esi, client call func - popad - retn } } @@ -461,14 +461,6 @@ namespace game } } - void ClientCommand(int clientNum) - { - if (is_mp()) - { - reinterpret_cast(0x502CB0)(clientNum); - } - } - int GetProtocolVersion() { return 0x507C; @@ -758,6 +750,7 @@ namespace game native::DB_EnumXAssets = native::DB_EnumXAssets_t(SELECT_VALUE(0x50A0D0, 0x4CA2D0)); native::DB_GetXAssetName = native::DB_GetXAssetName_t(SELECT_VALUE(0x438100, 0x4B7C10)); + native::Dvar_FindVar = native::Dvar_FindVar_t(SELECT_VALUE(0x539550, 0x5BDCC0)); native::Dvar_RegisterBool = native::Dvar_RegisterBool_t(SELECT_VALUE(0x4914D0, 0x5BE9F0)); native::Dvar_RegisterFloat = native::Dvar_RegisterFloat_t(SELECT_VALUE(0x4F9CC0, 0x5BEA80)); native::Dvar_RegisterInt = native::Dvar_RegisterInt_t(SELECT_VALUE(0x48CD40, 0x5BEA40)); @@ -835,8 +828,9 @@ namespace game native::SV_Cmd_EndTokenizedString = native::SV_Cmd_EndTokenizedString_t(SELECT_VALUE(0x0, 0x545D70)); native::SV_SpawnServer = native::SV_SpawnServer_t(SELECT_VALUE(0x0, 0x575020)); native::SV_GetConfigstring = native::SV_GetConfigstring_t(SELECT_VALUE(0x4C6E30, 0x573D50)); - native::mp::SV_GameSendServerCommand = native::mp::SV_GameSendServerCommand_t(0x573220); native::mp::SV_GetGuid = native::mp::SV_GetGuid_t(0x573990); + native::mp::SV_GameSendServerCommand = native::mp::SV_GameSendServerCommand_t(0x573220); + native::mp::ClientCommand = native::mp::ClientCommand_t(0x502CB0); native::sp::IsServerRunning = native::sp::IsServerRunning_t(0x45D310); native::sp::SV_GameSendServerCommand = native::sp::SV_GameSendServerCommand_t(0x402130); @@ -853,6 +847,7 @@ namespace game native::PM_WeaponUseAmmo = native::PM_WeaponUseAmmo_t(SELECT_VALUE(0x463F80, 0x42E930)); native::PM_playerTrace = native::PM_playerTrace_t(SELECT_VALUE(0x4CE600, 0x421F00)); native::PM_trace = native::PM_trace_t(SELECT_VALUE(0x544BF0, 0x41CEB0)); + native::PM_IsSprinting = native::PM_IsSprinting_t(SELECT_VALUE(0x451A40, 0x41D330)); native::Jump_ClearState = native::Jump_ClearState_t(SELECT_VALUE(0x514CE0, 0x4160F0)); @@ -877,6 +872,8 @@ namespace game native::Key_KeynumToString = native::Key_KeynumToString_t(SELECT_VALUE(0x4BB000, 0x48C080)); + native::I_strncpyz = native::I_strncpyz_t(SELECT_VALUE(0x53A950, 0x5C2940)); + native::_longjmp = reinterpret_cast(SELECT_VALUE(0x73AC20, 0x7363BC)); native::sv_cmd_args = reinterpret_cast(SELECT_VALUE(0x1757218, 0x1CAA998)); @@ -901,7 +898,7 @@ namespace game native::mp::svs_clients = reinterpret_cast(0x4B5CF90); - native::g_entities = reinterpret_cast(0x1A66E28); + native::mp::g_entities = reinterpret_cast(0x1A66E28); native::sp::g_entities = reinterpret_cast(0x1197AD8); native::sp::g_clients = reinterpret_cast(0x1381D48); diff --git a/src/game/game.hpp b/src/game/game.hpp index bbef7cf..beaca2d 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -44,6 +44,9 @@ namespace game typedef const char* (*DB_GetXAssetName_t)(const XAsset* asset); extern DB_GetXAssetName_t DB_GetXAssetName; + typedef dvar_t* (*Dvar_FindVar_t)(const char* dvarName); + extern Dvar_FindVar_t Dvar_FindVar; + typedef const dvar_t* (*Dvar_RegisterBool_t)(const char* dvarName, bool value, unsigned __int16 flags, const char* description); extern Dvar_RegisterBool_t Dvar_RegisterBool; @@ -225,21 +228,24 @@ namespace game extern SEH_GetLanguageName_t SEH_GetLanguageName; typedef void (*CM_TransformedCapsuleTrace_t)(trace_t* results, const float* start, const float* end, - const Bounds* bounds, const Bounds* capsule, int contents, - const float* origin, const float* angles); + const Bounds* bounds, const Bounds* capsule, int contents, + const float* origin, const float* angles); extern CM_TransformedCapsuleTrace_t CM_TransformedCapsuleTrace; - typedef void (*PM_WeaponUseAmmo_t)(playerState_s* ps, const Weapon weapon, bool isAlternate, int amount, PlayerHandIndex hand); + typedef void (*PM_WeaponUseAmmo_t)(playerState_s* ps, Weapon weapon, bool isAlternate, int amount, PlayerHandIndex hand); extern PM_WeaponUseAmmo_t PM_WeaponUseAmmo; typedef void (*PM_playerTrace_t)(pmove_t* pm, trace_t* results, const float* start, const float* end, - const Bounds* bounds, int passEntityNum, int contentMask); + const Bounds* bounds, int passEntityNum, int contentMask); extern PM_playerTrace_t PM_playerTrace; typedef void (*PM_trace_t)(const pmove_t* pm, trace_t* results, const float* start, const float* end, - const Bounds* bounds, int passEntityNum, int contentMask); + const Bounds* bounds, int passEntityNum, int contentMask); extern PM_trace_t PM_trace; + typedef bool (*PM_IsSprinting_t)(const void* ps); + extern PM_IsSprinting_t PM_IsSprinting; + typedef void (*Jump_ClearState_t)(playerState_s* ps); extern Jump_ClearState_t Jump_ClearState; @@ -282,6 +288,9 @@ namespace game typedef const char* (*Key_KeynumToString_t)(int keynum, int translate); extern Key_KeynumToString_t Key_KeynumToString; + typedef void (*I_strncpyz_t)(char* dest, const char* src, int destsize); + extern I_strncpyz_t I_strncpyz; + extern decltype(longjmp)* _longjmp; constexpr auto CMD_MAX_NESTING = 8; @@ -308,7 +317,6 @@ namespace game constexpr auto MAX_GENTITIES = 2048u; constexpr auto ENTITYNUM_NONE = MAX_GENTITIES - 1u; - extern gentity_s* g_entities; extern DeferredQueue* deferredQueue; @@ -368,9 +376,14 @@ namespace game typedef void (*SV_GameSendServerCommand_t)(int clientNum, svscmd_type type, const char* text); extern SV_GameSendServerCommand_t SV_GameSendServerCommand; + typedef void (*ClientCommand_t)(int clientNum); + extern ClientCommand_t ClientCommand; + extern client_t* svs_clients; extern level_locals_t* level; + + extern gentity_s* g_entities; } namespace sp @@ -396,8 +409,6 @@ namespace game void* MT_Alloc(int numBytes, int type); - dvar_t* Dvar_FindVar(const char* dvarName); - const float* Scr_AllocVector(const float* v); void Scr_ClearOutParams(); scr_entref_t Scr_GetEntityIdRef(unsigned int id); @@ -413,8 +424,6 @@ namespace game void SV_DropClient(mp::client_t* drop, const char* reason, bool tellThem); void SV_DropAllBots(); - void ClientCommand(int clientNum); - int GetProtocolVersion(); void NetAdr_SetType(netadr_s* addr, netadrtype_t type); diff --git a/src/module/chat.cpp b/src/module/chat.cpp index 804652d..a8bd56b 100644 --- a/src/module/chat.cpp +++ b/src/module/chat.cpp @@ -6,43 +6,46 @@ #include -static void notify_on_say(game::native::gentity_s* ent, int mode, const char* message) +namespace { - game::native::Scr_AddString(message + 1); // First character has nothing to do with actual message - game::native::Scr_AddInt(mode); - game::native::Scr_AddEntityNum(ent - game::native::g_entities, 0); - - game::native::Scr_NotifyLevel(game::native::SL_GetString("say", 0), 3); - - const auto* guid = game::native::mp::SV_GetGuid(ent - game::native::g_entities); - const auto* name = game::native::mp::svs_clients[ent - game::native::g_entities].name; - - if (mode == 0) + void notify_on_say(game::native::gentity_s* ent, int mode, const char* message) { - game_log::g_log_printf("say;%s;%d;%s;%s\n", guid, ent - game::native::g_entities, name, message); + game::native::Scr_AddString(message + 1); // First character has nothing to do with actual message + game::native::Scr_AddInt(mode); + game::native::Scr_AddEntityNum(ent - game::native::mp::g_entities, 0); + + game::native::Scr_NotifyLevel(game::native::SL_GetString("say", 0), 3); + + const auto* guid = game::native::mp::SV_GetGuid(ent - game::native::mp::g_entities); + const auto* name = game::native::mp::svs_clients[ent - game::native::mp::g_entities].name; + + if (mode == 0) + { + game_log::g_log_printf("say;%s;%d;%s;%s\n", guid, ent - game::native::mp::g_entities, name, message); + } + else + { + game_log::g_log_printf("sayteam;%s;%d;%s;%s\n", guid, ent - game::native::mp::g_entities, name, message); + } } - else + + __declspec(naked) void g_say_stub() { - game_log::g_log_printf("sayteam;%s;%d;%s;%s\n", guid, ent - game::native::g_entities, name, message); - } -} + __asm + { + pushad -static __declspec(naked) void g_say_stub() -{ - __asm - { - pushad + push [esp + 0x20 + 0x108] // message + push [esp + 0x20 + 0x108] // mode + push ebp // ent + call notify_on_say + add esp, 0xC - push [esp + 0x20 + 0x108] // message - push [esp + 0x20 + 0x108] // mode - push ebp // ent - call notify_on_say - add esp, 0xC + popad - popad - - push 0x5C2940 // I_strncpyz - retn + push 0x5C2940 // I_strncpyz + retn + } } } diff --git a/src/module/client_command.cpp b/src/module/client_command.cpp index 1b1bc23..c3c388f 100644 --- a/src/module/client_command.cpp +++ b/src/module/client_command.cpp @@ -68,13 +68,13 @@ namespace void player_cmd_noclip(game::native::scr_entref_t entref) { - auto* ent = gsc::get_player_entity(entref); + auto* ent = gsc::mp::get_player_entity(entref); cmd_noclip_f(ent, command::params_sv{}); } void player_cmd_ufo(game::native::scr_entref_t entref) { - auto* ent = gsc::get_player_entity(entref); + auto* ent = gsc::mp::get_player_entity(entref); cmd_ufo_f(ent, command::params_sv{}); } } diff --git a/src/module/command.cpp b/src/module/command.cpp index 1c5f50d..b526fdc 100644 --- a/src/module/command.cpp +++ b/src/module/command.cpp @@ -157,7 +157,7 @@ void command::main_handler() void command::client_command_stub(int client_num) { - const auto entity = &game::native::g_entities[client_num]; + const auto entity = &game::native::mp::g_entities[client_num]; if (!entity->client) { @@ -174,7 +174,7 @@ void command::client_command_stub(int client_num) return; } - game::native::ClientCommand(client_num); + game::native::mp::ClientCommand(client_num); } void command::client_command_sp(int client_num, const char* s) diff --git a/src/module/gsc/script_error.cpp b/src/module/gsc/script_error.cpp index b7d2f76..32ff7d2 100644 --- a/src/module/gsc/script_error.cpp +++ b/src/module/gsc/script_error.cpp @@ -430,7 +430,7 @@ namespace gsc void scr_error(const char* error) { - strncpy_s(gsc_error_msg, error, _TRUNCATE); + game::native::I_strncpyz(gsc_error_msg, error, sizeof(gsc_error_msg)); game::native::Scr_ErrorInternal(); } @@ -445,35 +445,72 @@ namespace gsc return nullptr; } - game::native::gentity_s* get_entity(game::native::scr_entref_t entref) + namespace mp { - if (entref.classnum) + game::native::gentity_s* get_entity(const game::native::scr_entref_t entref) { - scr_error("not an entity"); - return nullptr; + if (entref.classnum) + { + scr_error("not an entity"); + return nullptr; + } + + assert(entref.entnum < game::native::MAX_GENTITIES); + return &game::native::mp::g_entities[entref.entnum]; } - assert(entref.entnum < game::native::MAX_GENTITIES); - return &game::native::g_entities[entref.entnum]; + game::native::gentity_s* get_player_entity(const game::native::scr_entref_t entref) + { + if (entref.classnum) + { + scr_error("not an entity"); + return nullptr; + } + + assert(entref.entnum < game::native::MAX_GENTITIES); + auto* ent = &game::native::mp::g_entities[entref.entnum]; + if (!ent->client) + { + scr_error(va("entity %i is not a player", entref.entnum)); + return nullptr; + } + + return ent; + } } - game::native::gentity_s* get_player_entity(game::native::scr_entref_t entref) + namespace sp { - if (entref.classnum) + game::native::sp::gentity_s* get_entity(const game::native::scr_entref_t entref) { - scr_error("not an entity"); - return nullptr; + if (entref.classnum) + { + scr_error("not an entity"); + return nullptr; + } + + assert(entref.entnum < game::native::MAX_GENTITIES); + return &game::native::sp::g_entities[entref.entnum]; } - assert(entref.entnum < game::native::MAX_GENTITIES); - auto* ent = &game::native::g_entities[entref.entnum]; - if (!ent->client) + game::native::sp::gentity_s* get_player_entity(const game::native::scr_entref_t entref) { - scr_error(va("entity %i is not a player", entref.entnum)); - return nullptr; - } + if (entref.classnum) + { + scr_error("not an entity"); + return nullptr; + } - return ent; + assert(entref.entnum < game::native::MAX_GENTITIES); + auto* ent = &game::native::sp::g_entities[entref.entnum]; + if (!ent->client) + { + scr_error(va("entity %i is not a player", entref.entnum)); + return nullptr; + } + + return ent; + } } class error final : public module diff --git a/src/module/gsc/script_error.hpp b/src/module/gsc/script_error.hpp index aba3463..f3295cb 100644 --- a/src/module/gsc/script_error.hpp +++ b/src/module/gsc/script_error.hpp @@ -16,8 +16,17 @@ namespace gsc int scr_get_type(unsigned int index); const char* scr_get_type_name(unsigned int index); - game::native::gentity_s* get_entity(game::native::scr_entref_t entref); - game::native::gentity_s* get_player_entity(game::native::scr_entref_t entref); - void scr_error(const char* error); + + namespace mp + { + game::native::gentity_s* get_entity(game::native::scr_entref_t entref); + game::native::gentity_s* get_player_entity(game::native::scr_entref_t entref); + } + + namespace sp + { + game::native::sp::gentity_s* get_entity(game::native::scr_entref_t entref); + game::native::sp::gentity_s* get_player_entity(game::native::scr_entref_t entref); + } } diff --git a/src/module/player_movement.cpp b/src/module/player_movement.cpp index eca2bfc..6b2526f 100644 --- a/src/module/player_movement.cpp +++ b/src/module/player_movement.cpp @@ -1,10 +1,14 @@ #include #include +#include "game/game.hpp" + #include -#include "game/game.hpp" #include "player_movement.hpp" +#include "gsc/script_extension.hpp" +#include "gsc/script_error.hpp" + const game::native::dvar_t* player_movement::player_sustainAmmo; const game::native::dvar_t* player_movement::player_lastStandCrawlSpeedScale; const game::native::dvar_t* player_movement::player_duckedSpeedScale; @@ -609,6 +613,18 @@ void player_movement::patch_mp() utils::hook(0x4220E5, pm_cmd_scale_crawl_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance utils::hook(0x422104, pm_cmd_scale_ducked_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance utils::hook(0x42210E, pm_cmd_scale_prone_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance + + gsc::register_method("IsSprinting", [](const game::native::scr_entref_t entref) -> void + { + const auto* client = gsc::mp::get_entity(entref)->client; + if (!client) + { + gsc::scr_error("IsSprinting can only be called on a player"); + return; + } + + game::native::Scr_AddInt(game::native::PM_IsSprinting(&client->ps)); + }); } void player_movement::patch_sp() @@ -663,6 +679,18 @@ void player_movement::patch_sp() utils::hook(0x64384F, pm_cmd_scale_crawl_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance utils::hook(0x643859, pm_cmd_scale_ducked_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance utils::hook(0x643863, pm_cmd_scale_prone_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance + + gsc::register_method("IsSprinting", [](const game::native::scr_entref_t entref) -> void + { + const auto* client = gsc::sp::get_entity(entref)->client; + if (!client) + { + gsc::scr_error("IsSprinting can only be called on a player"); + return; + } + + game::native::Scr_AddInt(game::native::PM_IsSprinting(&client->ps)); + }); } void player_movement::register_common_dvars() diff --git a/src/module/test_clients.cpp b/src/module/test_clients.cpp index a06c1e2..9710dd1 100644 --- a/src/module/test_clients.cpp +++ b/src/module/test_clients.cpp @@ -234,9 +234,8 @@ void test_clients::patch_mp() gsc::register_method("IsTestClient", [](const game::native::scr_entref_t entref) { - gsc::get_entity(entref); - - if (game::native::g_entities[entref.entnum].client == nullptr) + const auto* ent = gsc::mp::get_entity(entref); + if (!ent->client) { gsc::scr_error("IsTestClient: entity must be a player entity"); }