diff --git a/managed/CounterStrikeSharp.API/Core/Listeners.g.cs b/managed/CounterStrikeSharp.API/Core/Listeners.g.cs
index 6141fb2b4..0bcdbeefe 100644
--- a/managed/CounterStrikeSharp.API/Core/Listeners.g.cs
+++ b/managed/CounterStrikeSharp.API/Core/Listeners.g.cs
@@ -192,6 +192,16 @@ public class Listeners
[ListenerName("OnPlayerButtonsChanged")]
public delegate void OnPlayerButtonsChanged(CCSPlayerController player, PlayerButtons pressed, PlayerButtons released);
+
+ ///
+ /// Called when a player sends a chat message.
+ ///
+ /// The player who sent the chat message.
+ /// The content of the chat message.
+ /// If the chat message was sent to team only.
+ [ListenerName("OnPlayerChat")]
+ public delegate void OnPlayerChat(CCSPlayerController player, string message, bool teamChat);
+
///
/// Called when all metamod plugins are loaded.
///
diff --git a/src/core/managers/chat_manager.cpp b/src/core/managers/chat_manager.cpp
index 3c288e3b2..0811b36aa 100644
--- a/src/core/managers/chat_manager.cpp
+++ b/src/core/managers/chat_manager.cpp
@@ -48,25 +48,14 @@ void ChatManager::OnAllInitialized()
auto m_hook = funchook_create();
funchook_prepare(m_hook, (void**)&m_pHostSay, (void*)&DetourHostSay);
funchook_install(m_hook, 0);
+
+ on_player_chat_callback = globals::callbackManager.CreateCallback("OnPlayerChat");
}
-void ChatManager::OnShutdown() {}
+void ChatManager::OnShutdown() { globals::callbackManager.ReleaseCallback(on_player_chat_callback); }
void DetourHostSay(CEntityInstance* pController, CCommand& args, bool teamonly, int unk1, const char* unk2)
{
- if (pController)
- {
- auto pEvent = globals::gameEventManager->CreateEvent("player_chat", true);
- if (pEvent)
- {
- pEvent->SetBool("teamonly", teamonly);
- pEvent->SetInt("userid", pController->GetEntityIndex().Get() - 1);
- pEvent->SetString("text", args[1]);
-
- globals::gameEventManager->FireEvent(pEvent, true);
- }
- }
-
std::string prefix;
bool bSilent = globals::coreConfig->IsSilentChatTrigger(args[1], prefix);
bool bCommand = globals::coreConfig->IsPublicChatTrigger(args[1], prefix) || bSilent;
@@ -97,6 +86,30 @@ void DetourHostSay(CEntityInstance* pController, CCommand& args, bool teamonly,
globals::chatManager.OnSayCommandPost(pController, args);
}
+
+ if (pController)
+ {
+ auto callback = globals::chatManager.on_player_chat_callback;
+
+ if (callback && callback->GetFunctionCount())
+ {
+ callback->ScriptContext().Reset();
+ callback->ScriptContext().Push(pController);
+ callback->ScriptContext().Push(args.Arg(1));
+ callback->ScriptContext().Push(teamonly);
+ callback->Execute();
+ }
+
+ auto pEvent = globals::gameEventManager->CreateEvent("player_chat", true);
+ if (pEvent)
+ {
+ pEvent->SetBool("teamonly", teamonly);
+ pEvent->SetInt("userid", pController->GetEntityIndex().Get() - 1);
+ pEvent->SetString("text", args[1]);
+
+ globals::gameEventManager->FireEvent(pEvent, false);
+ }
+ }
}
bool ChatManager::OnSayCommandPre(CEntityInstance* pController, CCommand& command) { return false; }
diff --git a/src/core/managers/chat_manager.h b/src/core/managers/chat_manager.h
index d18ad3a9b..44fe46f76 100644
--- a/src/core/managers/chat_manager.h
+++ b/src/core/managers/chat_manager.h
@@ -55,6 +55,8 @@ class ChatManager : public GlobalClass
bool OnSayCommandPre(CEntityInstance* pController, CCommand& args);
void OnSayCommandPost(CEntityInstance* pController, CCommand& args);
+ ScriptCallback* on_player_chat_callback = nullptr;
+
private:
void InternalDispatch(CEntityInstance* pPlayerController, const char* szTriggerPhrase, CCommand& pFullCommand);