Add OnSpectatorChatMessage forwards to catch chat
Messages and chatgroups can be changed or blocked.
This commit is contained in:
		
							parent
							
								
									2c88455744
								
							
						
					
					
						commit
						e5db34a3e3
					
				
							
								
								
									
										11
									
								
								AMBuilder
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								AMBuilder
									
									
									
									
									
								
							| @ -6,11 +6,14 @@ projectName = 'sourcetvmanager' | ||||
| # smsdk_ext.cpp will be automatically added later | ||||
| sourceFiles = [ | ||||
|   'extension.cpp', | ||||
|   'commonhooks.cpp', | ||||
|   'natives.cpp', | ||||
|   'forwards.cpp', | ||||
|   'hltvserverwrapper.cpp', | ||||
|   'hltvdirectorwrapper.cpp', | ||||
|   'hltvclientwrapper.cpp' | ||||
|   'hltvclientwrapper.cpp', | ||||
|   os.path.join(Extension.sm_root, 'public', 'CDetour', 'detours.cpp'), | ||||
|   os.path.join(Extension.sm_root, 'public', 'asm', 'asm.c') | ||||
| ] | ||||
| 
 | ||||
| ############### | ||||
| @ -36,12 +39,6 @@ for sdk_name in ['css', 'tf2', 'dods', 'hl2dm', 'csgo']: | ||||
|   binary = Extension.HL2Config(project, projectName + '.ext.' + sdk.ext, sdk) | ||||
|   compiler = binary.compiler | ||||
|    | ||||
|   if builder.target_platform == 'linux': | ||||
|     binary.sources += [ | ||||
|       os.path.join(Extension.sm_root, 'public', 'CDetour', 'detours.cpp'), | ||||
| 	  os.path.join(Extension.sm_root, 'public', 'asm', 'asm.c') | ||||
|     ] | ||||
|    | ||||
|   if sdk.name == 'csgo': | ||||
|     compiler.cxxincludes += [ | ||||
|       os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'), | ||||
|  | ||||
							
								
								
									
										63
									
								
								commonhooks.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								commonhooks.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| /**
 | ||||
| * vim: set ts=4 : | ||||
| * ============================================================================= | ||||
| * SourceMod SourceTV Manager Extension | ||||
| * Copyright (C) 2004-2016 AlliedModders LLC.  All rights reserved. | ||||
| * ============================================================================= | ||||
| * | ||||
| * This program is free software; you can redistribute it and/or modify it under | ||||
| * the terms of the GNU General Public License, version 3.0, as published by the | ||||
| * Free Software Foundation. | ||||
| * | ||||
| * This program is distributed in the hope that it will be useful, but WITHOUT | ||||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||||
| * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more | ||||
| * details. | ||||
| * | ||||
| * You should have received a copy of the GNU General Public License along with | ||||
| * this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| * | ||||
| * As a special exception, AlliedModders LLC gives you permission to link the | ||||
| * code of this program (as well as its derivative works) to "Half-Life 2," the | ||||
| * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software | ||||
| * by the Valve Corporation.  You must obey the GNU General Public License in | ||||
| * all respects for all other code used.  Additionally, AlliedModders LLC grants | ||||
| * this exception to all derivative works.  AlliedModders LLC defines further | ||||
| * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), | ||||
| * or <http://www.sourcemod.net/license.php>.
 | ||||
| * | ||||
| * Version: $Id$ | ||||
| */ | ||||
| 
 | ||||
| #include "extension.h" | ||||
| #include "commonhooks.h" | ||||
| #include "forwards.h" | ||||
| #include "hltvserverwrapper.h" | ||||
| 
 | ||||
| CCommonHooks g_pSTVCommonHooks; | ||||
| 
 | ||||
| // Declare the hook here so we can use it in hltvserverwrapper to fix crashes with the "status" command and host_client.
 | ||||
| // And use it in forwards to hook spectator chat messages.
 | ||||
| SH_DECL_HOOK1(IClient, ExecuteStringCommand, SH_NOATTRIB, 0, bool, const char *); | ||||
| 
 | ||||
| void CCommonHooks::AddSpectatorHook(CForwardManager *fwdmgr, IClient *client) | ||||
| { | ||||
| 	SH_ADD_HOOK(IClient, ExecuteStringCommand, client, SH_MEMBER(fwdmgr, &CForwardManager::OnSpectatorExecuteStringCommand), false); | ||||
| } | ||||
| 
 | ||||
| void CCommonHooks::RemoveSpectatorHook(CForwardManager *fwdmgr, IClient *client) | ||||
| { | ||||
| 	SH_REMOVE_HOOK(IClient, ExecuteStringCommand, client, SH_MEMBER(fwdmgr, &CForwardManager::OnSpectatorExecuteStringCommand), false); | ||||
| } | ||||
| 
 | ||||
| void CCommonHooks::AddHLTVClientHook(HLTVServerWrapper *wrapper, IClient *client) | ||||
| { | ||||
| 	SH_ADD_HOOK(IClient, ExecuteStringCommand, client, SH_MEMBER(wrapper, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand), false); | ||||
| 	SH_ADD_HOOK(IClient, ExecuteStringCommand, client, SH_MEMBER(wrapper, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand_Post), true); | ||||
| } | ||||
| 
 | ||||
| void CCommonHooks::RemoveHLTVClientHook(HLTVServerWrapper *wrapper, IClient *client) | ||||
| { | ||||
| 	SH_REMOVE_HOOK(IClient, ExecuteStringCommand, client, SH_MEMBER(wrapper, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand), false); | ||||
| 	SH_REMOVE_HOOK(IClient, ExecuteStringCommand, client, SH_MEMBER(wrapper, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand_Post), true); | ||||
| } | ||||
							
								
								
									
										52
									
								
								commonhooks.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								commonhooks.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| /**
 | ||||
| * vim: set ts=4 : | ||||
| * ============================================================================= | ||||
| * SourceMod SourceTV Manager Extension | ||||
| * Copyright (C) 2004-2016 AlliedModders LLC.  All rights reserved. | ||||
| * ============================================================================= | ||||
| * | ||||
| * This program is free software; you can redistribute it and/or modify it under | ||||
| * the terms of the GNU General Public License, version 3.0, as published by the | ||||
| * Free Software Foundation. | ||||
| * | ||||
| * This program is distributed in the hope that it will be useful, but WITHOUT | ||||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||||
| * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more | ||||
| * details. | ||||
| * | ||||
| * You should have received a copy of the GNU General Public License along with | ||||
| * this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| * | ||||
| * As a special exception, AlliedModders LLC gives you permission to link the | ||||
| * code of this program (as well as its derivative works) to "Half-Life 2," the | ||||
| * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software | ||||
| * by the Valve Corporation.  You must obey the GNU General Public License in | ||||
| * all respects for all other code used.  Additionally, AlliedModders LLC grants | ||||
| * this exception to all derivative works.  AlliedModders LLC defines further | ||||
| * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), | ||||
| * or <http://www.sourcemod.net/license.php>.
 | ||||
| * | ||||
| * Version: $Id$ | ||||
| */ | ||||
| 
 | ||||
| #ifndef _INCLUDE_SOURCEMOD_EXTENSION_COMMON_HOOKS_H_ | ||||
| #define _INCLUDE_SOURCEMOD_EXTENSION_COMMON_HOOKS_H_ | ||||
| 
 | ||||
| class IClient; | ||||
| class CForwardManager; | ||||
| class HLTVServerWrapper; | ||||
| 
 | ||||
| class CCommonHooks { | ||||
| public: | ||||
| 	// For forwards
 | ||||
| 	void AddSpectatorHook(CForwardManager *fwdmgr, IClient *client); | ||||
| 	void RemoveSpectatorHook(CForwardManager *fwdmgr, IClient *client); | ||||
| 
 | ||||
| 	// For host_client and status fix
 | ||||
| 	void AddHLTVClientHook(HLTVServerWrapper *wrapper, IClient *client); | ||||
| 	void RemoveHLTVClientHook(HLTVServerWrapper *wrapper, IClient *client); | ||||
| }; | ||||
| 
 | ||||
| extern CCommonHooks g_pSTVCommonHooks; | ||||
| 
 | ||||
| #endif // _INCLUDE_SOURCEMOD_EXTENSION_COMMON_HOOKS_H_
 | ||||
| @ -95,9 +95,7 @@ bool SourceTVManager::SDK_OnLoad(char *error, size_t maxlength, bool late) | ||||
| 
 | ||||
| 	g_HLTVServers.InitHooks(); | ||||
| 
 | ||||
| #ifndef WIN32 | ||||
| 	CDetourManager::Init(smutils->GetScriptingEngine(), g_pGameConf); | ||||
| #endif | ||||
| 
 | ||||
| 	sharesys->AddNatives(myself, sourcetv_natives); | ||||
| 	sharesys->RegisterLibrary(myself, "sourcetvmanager"); | ||||
|  | ||||
| @ -40,9 +40,7 @@ | ||||
| #include "smsdk_ext.h" | ||||
| #include <IBinTools.h> | ||||
| #include <ISDKTools.h> | ||||
| #ifndef WIN32 | ||||
| #include "CDetour/detours.h" | ||||
| #endif | ||||
| #include "ihltvdirector.h" | ||||
| #include "ihltv.h" | ||||
| #include "iserver.h" | ||||
|  | ||||
							
								
								
									
										140
									
								
								forwards.cpp
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								forwards.cpp
									
									
									
									
									
								
							| @ -32,6 +32,7 @@ | ||||
| #include "extension.h" | ||||
| #include "forwards.h" | ||||
| #include "hltvserverwrapper.h" | ||||
| #include "commonhooks.h" | ||||
| 
 | ||||
| CForwardManager g_pSTVForwards; | ||||
| 
 | ||||
| @ -128,6 +129,8 @@ void CForwardManager::Init() | ||||
| 	m_SpectatorDisconnectFwd = forwards->CreateForward("SourceTV_OnSpectatorDisconnect", ET_Ignore, 2, NULL, Param_Cell, Param_String); | ||||
| 	m_SpectatorDisconnectedFwd = forwards->CreateForward("SourceTV_OnSpectatorDisconnected", ET_Ignore, 2, NULL, Param_Cell, Param_String); | ||||
| 	m_SpectatorPutInServerFwd = forwards->CreateForward("SourceTV_OnSpectatorPutInServer", ET_Ignore, 1, NULL, Param_Cell); | ||||
| 	m_SpectatorChatMessageFwd = forwards->CreateForward("SourceTV_OnSpectatorChatMessage", ET_Hook, 3, NULL, Param_Cell, Param_String, Param_String); | ||||
| 	m_SpectatorChatMessagePostFwd = forwards->CreateForward("SourceTV_OnSpectatorChatMessage_Post", ET_Ignore, 3, NULL, Param_Cell, Param_String, Param_String); | ||||
| 
 | ||||
| 	m_ServerStartFwd = forwards->CreateForward("SourceTV_OnServerStart", ET_Ignore, 1, NULL, Param_Cell); | ||||
| 	m_ServerShutdownFwd = forwards->CreateForward("SourceTV_OnServerShutdown", ET_Ignore, 1, NULL, Param_Cell); | ||||
| @ -142,6 +145,8 @@ void CForwardManager::Shutdown() | ||||
| 	forwards->ReleaseForward(m_SpectatorDisconnectFwd); | ||||
| 	forwards->ReleaseForward(m_SpectatorDisconnectedFwd); | ||||
| 	forwards->ReleaseForward(m_SpectatorPutInServerFwd); | ||||
| 	forwards->ReleaseForward(m_SpectatorChatMessageFwd); | ||||
| 	forwards->ReleaseForward(m_SpectatorChatMessagePostFwd); | ||||
| 
 | ||||
| 	forwards->ReleaseForward(m_ServerStartFwd); | ||||
| 	forwards->ReleaseForward(m_ServerShutdownFwd); | ||||
| @ -206,6 +211,9 @@ void CForwardManager::UnhookServer(HLTVServerWrapper *wrapper) | ||||
| 
 | ||||
| void CForwardManager::HookClient(IClient *client) | ||||
| { | ||||
| 	// Hook ExecuteStringCommand for chat messages
 | ||||
| 	g_pSTVCommonHooks.AddSpectatorHook(this, client); | ||||
| 
 | ||||
| 	void *pGameClient = (void *)((intptr_t)client - 4); | ||||
| 	if (m_bHasActivatePlayerOffset) | ||||
| 		SH_ADD_MANUALHOOK(CBaseClient_ActivatePlayer, pGameClient, SH_MEMBER(this, &CForwardManager::OnSpectatorPutInServer), true); | ||||
| @ -221,6 +229,9 @@ void CForwardManager::HookClient(IClient *client) | ||||
| 
 | ||||
| void CForwardManager::UnhookClient(IClient *client) | ||||
| { | ||||
| 	// Remove ExecuteStringCommand hook
 | ||||
| 	g_pSTVCommonHooks.RemoveSpectatorHook(this, client); | ||||
| 
 | ||||
| 	void *pGameClient = (void *)((intptr_t)client - 4); | ||||
| 	if (m_bHasActivatePlayerOffset) | ||||
| 		SH_REMOVE_MANUALHOOK(CBaseClient_ActivatePlayer, pGameClient, SH_MEMBER(this, &CForwardManager::OnSpectatorPutInServer), true); | ||||
| @ -421,6 +432,119 @@ void CForwardManager::OnSpectatorPutInServer() | ||||
| 	RETURN_META(MRES_IGNORED); | ||||
| } | ||||
| 
 | ||||
| bool CForwardManager::OnSpectatorExecuteStringCommand(const char *s) | ||||
| { | ||||
| 	IClient *client = META_IFACEPTR(IClient); | ||||
| 	if (!s || !s[0]) | ||||
| 		RETURN_META_VALUE(MRES_IGNORED, true); | ||||
| 
 | ||||
| 	CCommand args; | ||||
| 	if (!args.Tokenize(s)) | ||||
| 		RETURN_META_VALUE(MRES_IGNORED, true); | ||||
| 
 | ||||
| 	// See if the client wants to chat.
 | ||||
| 	if (!Q_stricmp(args[0], "say") && args.ArgC() > 1) | ||||
| 	{ | ||||
| 		// TODO find correct hltvserver this client is connected to!
 | ||||
| 
 | ||||
| 		// Save the client index and message.
 | ||||
| 		hltvserver->SetLastChatClient(client); | ||||
| 		hltvserver->SetLastChatMessage(args[1]); | ||||
| 
 | ||||
| 		/*bool ret = SH_CALL(client, &IClient::ExecuteStringCommand)(s);
 | ||||
| 
 | ||||
| 		hltvserver->SetLastChatClient(0); | ||||
| 		hltvserver->SetLastChatMessage(nullptr); | ||||
| 		RETURN_META_VALUE(MRES_SUPERCEDE, ret);*/ | ||||
| 	} | ||||
| 
 | ||||
| 	RETURN_META_VALUE(MRES_IGNORED, true); | ||||
| } | ||||
| 
 | ||||
| DETOUR_DECL_MEMBER2(DetourHLTVServer_BroadcastLocalChat, void, const char *, chat, const char *, chatgroup) | ||||
| { | ||||
| 	// IServer is +8 from CHLTVServer due to multiple inheritance
 | ||||
| 	IServer *server = (IServer *)((intptr_t)this + 8); | ||||
| 	HLTVServerWrapper *wrapper = g_HLTVServers.GetWrapper(server); | ||||
| 
 | ||||
| 	char chatBuffer[256], groupBuffer[256]; | ||||
| 	// TODO: Use saved wrapper->GetLastChatMessage() and add "name : " manually again after plugins are done.
 | ||||
| 	ke::SafeStrcpy(chatBuffer, sizeof(chatBuffer), chat); | ||||
| 	ke::SafeStrcpy(groupBuffer, sizeof(groupBuffer), chatgroup); | ||||
| 
 | ||||
| 	if (wrapper) | ||||
| 	{ | ||||
| 		// Call the forward for this message.
 | ||||
| 		bool supercede = g_pSTVForwards.CallOnSpectatorChatMessage(wrapper, chatBuffer, sizeof(chatBuffer), groupBuffer, sizeof(groupBuffer)); | ||||
| 		if (supercede) | ||||
| 			return; | ||||
| 	} | ||||
| 
 | ||||
| 	// Call the engine function with our modified parameters.
 | ||||
| 	DETOUR_MEMBER_CALL(DetourHLTVServer_BroadcastLocalChat)(chatBuffer, groupBuffer); | ||||
| 
 | ||||
| 	if (wrapper) | ||||
| 	{ | ||||
| 		g_pSTVForwards.CallOnSpectatorChatMessage_Post(wrapper, chatBuffer, groupBuffer); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void CForwardManager::CreateBroadcastLocalChatDetour() | ||||
| { | ||||
| 	if (m_bBroadcastLocalChatDetoured) | ||||
| 		return; | ||||
| 
 | ||||
| 	m_DBroadcastLocalChat = DETOUR_CREATE_MEMBER(DetourHLTVServer_BroadcastLocalChat, "CHLTVServer::BroadcastLocalChat"); | ||||
| 
 | ||||
| 	if (m_DBroadcastLocalChat != nullptr) | ||||
| 	{ | ||||
| 		m_DBroadcastLocalChat->EnableDetour(); | ||||
| 		m_bBroadcastLocalChatDetoured = true; | ||||
| 		return; | ||||
| 	} | ||||
| 	smutils->LogError(myself, "CHLTVServer::BroadcastLocalChat detour could not be initialized."); | ||||
| } | ||||
| 
 | ||||
| void CForwardManager::RemoveBroadcastLocalChatDetour() | ||||
| { | ||||
| 	if (m_DBroadcastLocalChat != nullptr) | ||||
| 	{ | ||||
| 		m_DBroadcastLocalChat->Destroy(); | ||||
| 		m_DBroadcastLocalChat = nullptr; | ||||
| 	} | ||||
| 	m_bBroadcastLocalChatDetoured = false; | ||||
| } | ||||
| 
 | ||||
| bool CForwardManager::CallOnSpectatorChatMessage(HLTVServerWrapper *server, char *msg, int msglen, char *chatgroup, int grouplen) | ||||
| { | ||||
| 	int clientIndex = 0; | ||||
| 	IClient *client = server->GetLastChatClient(); | ||||
| 	if (client) | ||||
| 		clientIndex = client->GetPlayerSlot() + 1; | ||||
| 
 | ||||
| 	m_SpectatorChatMessageFwd->PushCell(clientIndex); | ||||
| 	m_SpectatorChatMessageFwd->PushStringEx(msg, msglen, SM_PARAM_STRING_UTF8 | SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); | ||||
| 	m_SpectatorChatMessageFwd->PushStringEx(chatgroup, grouplen, SM_PARAM_STRING_UTF8 | SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); | ||||
| 
 | ||||
| 	cell_t res = Pl_Continue; | ||||
| 	m_SpectatorChatMessageFwd->Execute(&res); | ||||
| 	if (res >= Pl_Handled) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| void CForwardManager::CallOnSpectatorChatMessage_Post(HLTVServerWrapper *server, const char *msg, const char *chatgroup) | ||||
| { | ||||
| 	int clientIndex = 0; | ||||
| 	IClient *client = server->GetLastChatClient(); | ||||
| 	if (client) | ||||
| 		clientIndex = client->GetPlayerSlot() + 1; | ||||
| 
 | ||||
| 	m_SpectatorChatMessagePostFwd->PushCell(clientIndex); | ||||
| 	m_SpectatorChatMessagePostFwd->PushString(msg); | ||||
| 	m_SpectatorChatMessagePostFwd->PushString(chatgroup); | ||||
| 	m_SpectatorChatMessagePostFwd->Execute(); | ||||
| } | ||||
| 
 | ||||
| // These two hooks are actually only hooked on windows.
 | ||||
| void CForwardManager::OnStartRecording_Post(const char *filename, bool bContinuously) | ||||
| @ -506,10 +630,10 @@ DETOUR_DECL_MEMBER0(DetourHLTVStopRecording, void) | ||||
| #endif	 | ||||
| } | ||||
| 
 | ||||
| bool CForwardManager::CreateStartRecordingDetour() | ||||
| void CForwardManager::CreateStartRecordingDetour() | ||||
| { | ||||
| 	if (m_bStartRecordingDetoured) | ||||
| 		return true; | ||||
| 		return; | ||||
| 
 | ||||
| 	m_DStartRecording = DETOUR_CREATE_MEMBER(DetourHLTVStartRecording, "CHLTVDemoRecorder::StartRecording"); | ||||
| 
 | ||||
| @ -517,10 +641,10 @@ bool CForwardManager::CreateStartRecordingDetour() | ||||
| 	{ | ||||
| 		m_DStartRecording->EnableDetour(); | ||||
| 		m_bStartRecordingDetoured = true; | ||||
| 		return true; | ||||
| 		return; | ||||
| 	} | ||||
| 	smutils->LogError(myself, "CHLTVDemoRecorder::StartRecording detour could not be initialized."); | ||||
| 	return false; | ||||
| 	return; | ||||
| } | ||||
| 
 | ||||
| void CForwardManager::RemoveStartRecordingDetour() | ||||
| @ -533,10 +657,10 @@ void CForwardManager::RemoveStartRecordingDetour() | ||||
| 	m_bStartRecordingDetoured = false; | ||||
| } | ||||
| 
 | ||||
| bool CForwardManager::CreateStopRecordingDetour() | ||||
| void CForwardManager::CreateStopRecordingDetour() | ||||
| { | ||||
| 	if (m_bStopRecordingDetoured) | ||||
| 		return true; | ||||
| 		return; | ||||
| 
 | ||||
| 	m_DStopRecording = DETOUR_CREATE_MEMBER(DetourHLTVStopRecording, "CHLTVDemoRecorder::StopRecording"); | ||||
| 
 | ||||
| @ -544,10 +668,10 @@ bool CForwardManager::CreateStopRecordingDetour() | ||||
| 	{ | ||||
| 		m_DStopRecording->EnableDetour(); | ||||
| 		m_bStopRecordingDetoured = true; | ||||
| 		return true; | ||||
| 		return; | ||||
| 	} | ||||
| 	smutils->LogError(myself, "CHLTVDemoRecorder::StopRecording detour could not be initialized."); | ||||
| 	return false; | ||||
| 	return; | ||||
| } | ||||
| 
 | ||||
| void CForwardManager::RemoveStopRecordingDetour() | ||||
|  | ||||
							
								
								
									
										16
									
								
								forwards.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								forwards.h
									
									
									
									
									
								
							| @ -70,9 +70,9 @@ public: | ||||
| 	void UnhookServer(HLTVServerWrapper *server); | ||||
| 
 | ||||
| #ifndef WIN32 | ||||
| 	bool CreateStartRecordingDetour(); | ||||
| 	void CreateStartRecordingDetour(); | ||||
| 	void RemoveStartRecordingDetour(); | ||||
| 	bool CreateStopRecordingDetour(); | ||||
| 	void CreateStopRecordingDetour(); | ||||
| 	void RemoveStopRecordingDetour(); | ||||
| #endif | ||||
| 
 | ||||
| @ -82,6 +82,13 @@ public: | ||||
| 	void CallOnStartRecording(IDemoRecorder *recorder, const char *filename, bool bContinuously); | ||||
| 	void CallOnStopRecording(IDemoRecorder *recorder); | ||||
| 
 | ||||
| 	bool CallOnSpectatorChatMessage(HLTVServerWrapper *server, char *msg, int msglen, char *chatgroup, int grouplen); | ||||
| 	void CallOnSpectatorChatMessage_Post(HLTVServerWrapper *server, const char *msg, const char *chatgroup); | ||||
| 
 | ||||
| 	bool OnSpectatorExecuteStringCommand(const char *s); | ||||
| 	void CreateBroadcastLocalChatDetour(); | ||||
| 	void RemoveBroadcastLocalChatDetour(); | ||||
| 
 | ||||
| private: | ||||
| 	void HookClient(IClient *client); | ||||
| 	void UnhookClient(IClient *client); | ||||
| @ -112,6 +119,8 @@ private: | ||||
| 	IForward *m_SpectatorDisconnectFwd; | ||||
| 	IForward *m_SpectatorDisconnectedFwd; | ||||
| 	IForward *m_SpectatorPutInServerFwd; | ||||
| 	IForward *m_SpectatorChatMessageFwd; | ||||
| 	IForward *m_SpectatorChatMessagePostFwd; | ||||
| 
 | ||||
| 	IForward *m_ServerStartFwd; | ||||
| 	IForward *m_ServerShutdownFwd; | ||||
| @ -122,6 +131,9 @@ private: | ||||
| 	bool m_bHasActivatePlayerOffset = false; | ||||
| 	bool m_bHasDisconnectOffset = false; | ||||
| 
 | ||||
| 	bool m_bBroadcastLocalChatDetoured = false; | ||||
| 	CDetour *m_DBroadcastLocalChat = nullptr; | ||||
| 
 | ||||
| 	// Only need the detours on linux. Windows always uses its vtables..
 | ||||
| #ifndef WIN32 | ||||
| 	bool m_bStartRecordingDetoured = false; | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| #include "hltvserverwrapper.h" | ||||
| #include "forwards.h" | ||||
| #include "commonhooks.h" | ||||
| 
 | ||||
| void *old_host_client = nullptr; | ||||
| bool g_HostClientOverridden = false; | ||||
| 
 | ||||
| SH_DECL_HOOK1(IClient, ExecuteStringCommand, SH_NOATTRIB, 0, bool, const char *); | ||||
| SH_DECL_MANUALHOOK0_void(CHLTVServer_Shutdown, 0, 0, 0); | ||||
| 
 | ||||
| #if SOURCE_ENGINE != SE_CSGO | ||||
| @ -30,6 +30,7 @@ HLTVServerWrapper::HLTVServerWrapper(IHLTVServer *hltvserver) | ||||
| 	m_HLTVServer = hltvserver; | ||||
| 	m_DemoRecorder = g_HLTVServers.GetDemoRecorderPtr(hltvserver); | ||||
| 	m_Connected = true; | ||||
| 	m_LastChatClient = nullptr; | ||||
| 
 | ||||
| 	Hook(); | ||||
| 
 | ||||
| @ -84,6 +85,26 @@ int HLTVServerWrapper::GetInstanceNumber() | ||||
| 	return g_HLTVServers.GetInstanceNumber(m_HLTVServer); | ||||
| } | ||||
| 
 | ||||
| IClient *HLTVServerWrapper::GetLastChatClient() | ||||
| { | ||||
| 	return m_LastChatClient; | ||||
| } | ||||
| 
 | ||||
| void HLTVServerWrapper::SetLastChatClient(IClient *client) | ||||
| { | ||||
| 	m_LastChatClient = client; | ||||
| } | ||||
| 
 | ||||
| const char *HLTVServerWrapper::GetLastChatMessage() | ||||
| { | ||||
| 	return m_LastChatMessage; | ||||
| } | ||||
| 
 | ||||
| void HLTVServerWrapper::SetLastChatMessage(const char *msg) | ||||
| { | ||||
| 	m_LastChatMessage = msg; | ||||
| } | ||||
| 
 | ||||
| HLTVClientWrapper *HLTVServerWrapper::GetClient(int index) | ||||
| { | ||||
| 	// Grow the vector with null pointers
 | ||||
| @ -123,8 +144,8 @@ void HLTVServerWrapper::Hook() | ||||
| 		IClient *pClient = iserver->GetClient(m_HLTVServer->GetHLTVSlot()); | ||||
| 		if (pClient) | ||||
| 		{ | ||||
| 			SH_ADD_HOOK(IClient, ExecuteStringCommand, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand), false); | ||||
| 			SH_ADD_HOOK(IClient, ExecuteStringCommand, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand_Post), true); | ||||
| 			// Hook ExecuteStringCommand
 | ||||
| 			g_pSTVCommonHooks.AddHLTVClientHook(this, pClient); | ||||
| #if SOURCE_ENGINE != SE_CSGO | ||||
| 			SH_ADD_HOOK(IClient, ClientPrintf, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnIClient_ClientPrintf_Post), false); | ||||
| #ifndef WIN32 | ||||
| @ -155,8 +176,8 @@ void HLTVServerWrapper::Unhook() | ||||
| 		IClient *pClient = iserver->GetClient(m_HLTVServer->GetHLTVSlot()); | ||||
| 		if (pClient) | ||||
| 		{ | ||||
| 			SH_REMOVE_HOOK(IClient, ExecuteStringCommand, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand), false); | ||||
| 			SH_REMOVE_HOOK(IClient, ExecuteStringCommand, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand_Post), true); | ||||
| 			// Remove ExecuteStringCommand hook
 | ||||
| 			g_pSTVCommonHooks.RemoveHLTVClientHook(this, pClient); | ||||
| #if SOURCE_ENGINE != SE_CSGO | ||||
| 			SH_REMOVE_HOOK(IClient, ClientPrintf, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnIClient_ClientPrintf_Post), false); | ||||
| #ifndef WIN32 | ||||
| @ -327,6 +348,7 @@ void HLTVServerWrapperManager::InitHooks() | ||||
| 
 | ||||
| void HLTVServerWrapperManager::ShutdownHooks() | ||||
| { | ||||
| 	g_pSTVForwards.RemoveBroadcastLocalChatDetour(); | ||||
| #ifndef WIN32 | ||||
| 	g_pSTVForwards.RemoveStartRecordingDetour(); | ||||
| 	g_pSTVForwards.RemoveStopRecordingDetour(); | ||||
| @ -343,8 +365,9 @@ void HLTVServerWrapperManager::ShutdownHooks() | ||||
| 
 | ||||
| void HLTVServerWrapperManager::AddServer(IHLTVServer *hltvserver) | ||||
| { | ||||
| #ifndef WIN32 | ||||
| 	// Create the detours once the first sourcetv server is created.
 | ||||
| 	g_pSTVForwards.CreateBroadcastLocalChatDetour(); | ||||
| #ifndef WIN32 | ||||
| 	g_pSTVForwards.CreateStartRecordingDetour(); | ||||
| 	g_pSTVForwards.CreateStopRecordingDetour(); | ||||
| #endif | ||||
|  | ||||
| @ -48,13 +48,19 @@ public: | ||||
| 	HLTVClientWrapper *GetClient(int index); | ||||
| 	int GetInstanceNumber(); | ||||
| 
 | ||||
| 	IClient *GetLastChatClient(); | ||||
| 	void SetLastChatClient(IClient *client); | ||||
| 	const char *GetLastChatMessage(); | ||||
| 	void SetLastChatMessage(const char *msg); | ||||
| 
 | ||||
| 	bool OnHLTVBotExecuteStringCommand(const char *s); | ||||
| 	bool OnHLTVBotExecuteStringCommand_Post(const char *s); | ||||
| 
 | ||||
| private: | ||||
| 	void Hook(); | ||||
| 	void Unhook(); | ||||
| 
 | ||||
| 	// Hooks
 | ||||
| 	bool OnHLTVBotExecuteStringCommand(const char *s); | ||||
| 	bool OnHLTVBotExecuteStringCommand_Post(const char *s); | ||||
| 	void OnHLTVServerShutdown(); | ||||
| 
 | ||||
| #if SOURCE_ENGINE != SE_CSGO | ||||
| @ -68,6 +74,9 @@ private: | ||||
| 	IHLTVServer *m_HLTVServer = nullptr; | ||||
| 	IDemoRecorder *m_DemoRecorder = nullptr; | ||||
| 	ke::Vector<ke::AutoPtr<HLTVClientWrapper>> m_Clients; | ||||
| 
 | ||||
| 	IClient *m_LastChatClient = nullptr; | ||||
| 	const char *m_LastChatMessage = nullptr; | ||||
| }; | ||||
| 
 | ||||
| class HLTVServerWrapperManager | ||||
|  | ||||
| @ -87,6 +87,17 @@ public SourceTV_OnSpectatorDisconnected(client, const String:reason[255]) | ||||
| 	PrintToServer("SourceTV client %d disconnected (isconnected %d) with reason -> %s.", client, SourceTV_IsClientConnected(client), reason); | ||||
| } | ||||
| 
 | ||||
| public Action:SourceTV_OnSpectatorChatMessage(client, String:message[255], String:chatgroup[255]) | ||||
| { | ||||
| 	PrintToServer("SourceTV client %d (chatgroup \"%s\") writes: %s", client, chatgroup, message); | ||||
| 	return Plugin_Continue; | ||||
| } | ||||
| 
 | ||||
| public SourceTV_OnSpectatorChatMessage_Post(client, const String:message[], const String:chatgroup[]) | ||||
| { | ||||
| 	PrintToServer("SourceTV client %d (chatgroup \"%s\") wrote: %s", client, chatgroup, message); | ||||
| } | ||||
| 
 | ||||
| public Action:Cmd_GetServerCount(client, args) | ||||
| { | ||||
| 	ReplyToCommand(client, "SourceTV server count: %d", SourceTV_GetServerInstanceCount()); | ||||
|  | ||||
| @ -115,6 +115,14 @@ | ||||
| 				"windows"	"\x55\x8B\xEC\x83\xEC\x4C\x53\x8B\xD9\xC7\x45\xB4\x2A\x2A\x2A\x2A\x56\x8D" | ||||
| 			} | ||||
| 			 | ||||
| 			"CHLTVServer::BroadcastLocalChat" | ||||
| 			{ | ||||
| 				"library"	"engine" | ||||
| 				"linux"	"@_ZN11CHLTVServer18BroadcastLocalChatEPKcS1_" | ||||
| 				// "hltv_chat" | ||||
| 				"windows"	"\x55\x8B\xEC\x83\xEC\x54\xA1\x2A\x2A\x2A\x2A\x53" | ||||
| 			} | ||||
| 			 | ||||
| 			"CHLTVServer::GetRecordingDemoFilename" | ||||
| 			{ | ||||
| 				"library"	"engine" | ||||
| @ -274,6 +282,14 @@ | ||||
| 				"windows"	"\x55\x8B\xEC\x81\xEC\x44\x04\x00\x00\x53" | ||||
| 			} | ||||
| 			 | ||||
| 			"CHLTVServer::BroadcastLocalChat" | ||||
| 			{ | ||||
| 				"library"	"engine" | ||||
| 				"linux"	"@_ZN11CHLTVServer18BroadcastLocalChatEPKcS1_" | ||||
| 				// "hltv_chat" | ||||
| 				"windows"	"\x55\x8B\xEC\x81\xEC\x4C\x04\x00\x00\x53\x8B\xD9" | ||||
| 			} | ||||
| 			 | ||||
| 			"CHLTVServer::Shutdown" | ||||
| 			{ | ||||
| 				"library"	"engine" | ||||
|  | ||||
| @ -434,6 +434,29 @@ forward SourceTV_OnSpectatorDisconnected(client, const String:reason[255]); | ||||
|  */ | ||||
| forward SourceTV_OnSpectatorPutInServer(client); | ||||
| 
 | ||||
| /** | ||||
|  * Called before a spectator's chat message is sent. | ||||
|  * The message and chat group can be changed. | ||||
|  * Only called for directly connected clients - no proxies. | ||||
|  * | ||||
|  * @param client     The spectator client index. | ||||
|  * @param message    The message the client typed. | ||||
|  * @param chatgroup  The chatgroup this message is sent to (tv_chatgroup). | ||||
|  * @return >= Plugin_Handled to block the message, Plugin_Continue to let it through. | ||||
|  */ | ||||
| forward Action:SourceTV_OnSpectatorChatMessage(client, String:message[255], String:chatgroup[255]); | ||||
| 
 | ||||
| /** | ||||
|  * Called after a spectator wrote a chat message. | ||||
|  * Only called for directly connected clients - no proxies. | ||||
|  * | ||||
|  * @param client     The spectator client index. | ||||
|  * @param message    The message the client typed. | ||||
|  * @param chatgroup  The chatgroup this message is sent to (tv_chatgroup). | ||||
|  * @noreturn | ||||
|  */ | ||||
| forward SourceTV_OnSpectatorChatMessage_Post(client, const String:message[], const String:chatgroup[]); | ||||
| 
 | ||||
| /** | ||||
|  * Do not edit below this line! | ||||
|  */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user