From 2808f351fd56236663a14cf781be515341378621 Mon Sep 17 00:00:00 2001 From: Poggu Date: Sat, 11 Nov 2023 15:38:13 +0100 Subject: [PATCH] hook say command instead of hooking host_say --- gamedata/cs2fixes.games.txt | 8 ----- src/cs2fixes.cpp | 60 ++++++++++++++++++++++++++++++------- src/cs2fixes.h | 3 +- src/detours.cpp | 38 ----------------------- 4 files changed, 52 insertions(+), 57 deletions(-) diff --git a/gamedata/cs2fixes.games.txt b/gamedata/cs2fixes.games.txt index 748169ab..dc04bde9 100644 --- a/gamedata/cs2fixes.games.txt +++ b/gamedata/cs2fixes.games.txt @@ -53,14 +53,6 @@ "windows" "@LoggingSystem_LogAssert" "linux" "@LoggingSystem_LogAssert" } - - // String: "\"Console<0>\" say \"%s\"\n" - "Host_Say" - { - "library" "server" - "windows" "\x44\x89\x4C\x24\x2A\x44\x88\x44\x24\x2A\x55\x53\x56\x57\x41\x54\x41\x55" - "linux" "\x55\x48\x89\xE5\x41\x57\x49\x89\xFF\x41\x56\x41\x55\x41\x54\x4D\x89\xC4" - } // Called from Host_Say "UTIL_SayTextFilter" { diff --git a/src/cs2fixes.cpp b/src/cs2fixes.cpp index 3467bab4..ee153d76 100644 --- a/src/cs2fixes.cpp +++ b/src/cs2fixes.cpp @@ -105,19 +105,10 @@ SH_DECL_HOOK8_void(IGameEventSystem, PostEventAbstract, SH_NOATTRIB, 0, CSplitSc SH_DECL_HOOK3_void(INetworkServerService, StartupServer, SH_NOATTRIB, 0, const GameSessionConfiguration_t&, ISource2WorldSession*, const char*); SH_DECL_HOOK6_void(ISource2GameEntities, CheckTransmit, SH_NOATTRIB, 0, CCheckTransmitInfo **, int, CBitVec<16384> &, const Entity2Networkable_t **, const uint16 *, int); SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, CPlayerSlot, const CCommand &); +SH_DECL_HOOK3_void(ICvar, DispatchConCommand, SH_NOATTRIB, 0, ConCommandHandle, const CCommandContext&, const CCommand&); CS2Fixes g_CS2Fixes; -#if 0 -// Currently unavailable, requires hl2sdk work! -ConVar sample_cvar("sample_cvar", "42", 0); -#endif - -CON_COMMAND_F(sample_command, "Sample command", FCVAR_SPONLY | FCVAR_LINKED_CONCOMMAND) -{ - Message( "Sample command called by %d. Command: %s\n", context.GetPlayerSlot(), args.GetCommandString() ); -} - CON_COMMAND_F(toggle_logs, "Toggle printing most logs and warnings", FCVAR_SPONLY | FCVAR_LINKED_CONCOMMAND) { ToggleLogs(); @@ -168,6 +159,7 @@ bool CS2Fixes::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool SH_ADD_HOOK_MEMFUNC(IGameEventSystem, PostEventAbstract, g_gameEventSystem, this, &CS2Fixes::Hook_PostEvent, false); SH_ADD_HOOK_MEMFUNC(INetworkServerService, StartupServer, g_pNetworkServerService, this, &CS2Fixes::Hook_StartupServer, true); SH_ADD_HOOK_MEMFUNC(ISource2GameEntities, CheckTransmit, g_pSource2GameEntities, this, &CS2Fixes::Hook_CheckTransmit, true); + SH_ADD_HOOK_MEMFUNC(ICvar, DispatchConCommand, g_pCVar, this, &CS2Fixes::Hook_DispatchConCommand, false); META_CONPRINTF( "All hooks started!\n" ); @@ -270,6 +262,7 @@ bool CS2Fixes::Unload(char *error, size_t maxlen) SH_REMOVE_HOOK_MEMFUNC(IGameEventSystem, PostEventAbstract, g_gameEventSystem, this, &CS2Fixes::Hook_PostEvent, false); SH_REMOVE_HOOK_MEMFUNC(INetworkServerService, StartupServer, g_pNetworkServerService, this, &CS2Fixes::Hook_StartupServer, true); SH_REMOVE_HOOK_MEMFUNC(ISource2GameEntities, CheckTransmit, g_pSource2GameEntities, this, &CS2Fixes::Hook_CheckTransmit, true); + SH_REMOVE_HOOK_MEMFUNC(ICvar, DispatchConCommand, g_pCVar, this, &CS2Fixes::Hook_DispatchConCommand, false); ConVar_Unregister(); @@ -292,6 +285,53 @@ bool CS2Fixes::Unload(char *error, size_t maxlen) return true; } +void CS2Fixes::Hook_DispatchConCommand(ConCommandHandle cmdHandle, const CCommandContext& ctx, const CCommand& args) +{ + if (!g_pEntitySystem) + return; + + auto slot = ctx.GetPlayerSlot(); + + bool isSay = V_strcmp(args.Arg(0), "say"); + bool isTeamSay = V_strcmp(args.Arg(0), "say_team"); + + if (slot != -1 && (isSay || isTeamSay)) + { + auto pController = CCSPlayerController::FromSlot(slot); + bool bGagged = pController && pController->GetZEPlayer()->IsGagged(); + bool bFlooding = pController && pController->GetZEPlayer()->IsFlooding(); + + if (!bGagged && *args[1] != '/' && !bFlooding) + { + SH_CALL(g_pCVar, &ICvar::DispatchConCommand)(cmdHandle, ctx, args); + + if (pController) + { + IGameEvent* pEvent = g_gameEventManager->CreateEvent("player_chat"); + + if (pEvent) + { + pEvent->SetBool("teamonly", isTeamSay); + pEvent->SetInt("userid", pController->entindex()); + pEvent->SetString("text", args[1]); + + g_gameEventManager->FireEvent(pEvent, true); + } + } + } + else if (bFlooding) + { + if (pController) + ClientPrint(pController, HUD_PRINTTALK, CHAT_PREFIX "You are flooding the server!"); + } + + if (*args[1] == '!' || *args[1] == '/') + ParseChatCommand(args.ArgS() + 1, pController); // The string returned by ArgS() starts with a \, so skip it + + RETURN_META(MRES_SUPERCEDE); + } +} + void CS2Fixes::Hook_StartupServer(const GameSessionConfiguration_t& config, ISource2WorldSession*, const char*) { g_pNetworkGameServer = g_pNetworkServerService->GetIGameServer(); diff --git a/src/cs2fixes.h b/src/cs2fixes.h index 8e63c19e..729e7e90 100644 --- a/src/cs2fixes.h +++ b/src/cs2fixes.h @@ -33,7 +33,6 @@ class CS2Fixes : public ISmmPlugin, public IMetamodListener void Hook_PostEvent(CSplitScreenSlot nSlot, bool bLocalOnly, int nClientCount, const uint64* clients, INetworkSerializable* pEvent, const void* pData, unsigned long nSize, NetChannelBufType_t bufType); bool Unload(char *error, size_t maxlen); - void Hook_StartupServer(const GameSessionConfiguration_t& config, ISource2WorldSession*, const char*); bool Pause(char *error, size_t maxlen); bool Unpause(char *error, size_t maxlen); void AllPluginsLoaded(); @@ -57,6 +56,8 @@ class CS2Fixes : public ISmmPlugin, public IMetamodListener void Hook_ClientCommand( CPlayerSlot nSlot, const CCommand &_cmd ); void Hook_CheckTransmit(CCheckTransmitInfo **ppInfoList, int infoCount, CBitVec<16384> &unionTransmitEdicts, const Entity2Networkable_t **pNetworkables, const uint16 *pEntityIndicies, int nEntities); + void Hook_DispatchConCommand(ConCommandHandle cmd, const CCommandContext& ctx, const CCommand& args); + void Hook_StartupServer(const GameSessionConfiguration_t& config, ISource2WorldSession*, const char*); public: const char *GetAuthor(); diff --git a/src/detours.cpp b/src/detours.cpp index 6dccad37..e886cc6c 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -47,7 +47,6 @@ extern CEntitySystem *g_pEntitySystem; extern IGameEventManager2 *g_gameEventManager; extern CCSGameRules *g_pGameRules; -DECLARE_DETOUR(Host_Say, Detour_Host_Say); DECLARE_DETOUR(UTIL_SayTextFilter, Detour_UTIL_SayTextFilter); DECLARE_DETOUR(UTIL_SayText2Filter, Detour_UTIL_SayText2Filter); DECLARE_DETOUR(IsHearingClient, Detour_IsHearingClient); @@ -219,39 +218,6 @@ void FASTCALL Detour_UTIL_SayText2Filter( UTIL_SayText2Filter(filter, pEntity, eMessageType, msg_name, param1, param2, param3, param4); } -void FASTCALL Detour_Host_Say(CCSPlayerController *pController, CCommand &args, bool teamonly, int unk1, const char *unk2) -{ - bool bGagged = pController && pController->GetZEPlayer()->IsGagged(); - bool bFlooding = pController && pController->GetZEPlayer()->IsFlooding(); - - if (!bGagged && *args[1] != '/' && !bFlooding) - { - Host_Say(pController, args, teamonly, unk1, unk2); - - if (pController) - { - IGameEvent *pEvent = g_gameEventManager->CreateEvent("player_chat"); - - if (pEvent) - { - pEvent->SetBool("teamonly", teamonly); - pEvent->SetInt("userid", pController->entindex()); - pEvent->SetString("text", args[1]); - - g_gameEventManager->FireEvent(pEvent, true); - } - } - } - else if (bFlooding) - { - if (pController) - ClientPrint(pController, HUD_PRINTTALK, CHAT_PREFIX "You are flooding the server!"); - } - - if (*args[1] == '!' || *args[1] == '/') - ParseChatCommand(args.ArgS() + 1, pController); // The string returned by ArgS() starts with a \, so skip it -} - void Detour_Log() { return; @@ -322,10 +288,6 @@ bool InitDetours(CGameConfig *gameConfig) success = false; UTIL_SayText2Filter.EnableDetour(); - if (!Host_Say.CreateDetour(gameConfig)) - success = false; - Host_Say.EnableDetour(); - if (!IsHearingClient.CreateDetour(gameConfig)) success = false; IsHearingClient.EnableDetour();