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
|
# smsdk_ext.cpp will be automatically added later
|
||||||
sourceFiles = [
|
sourceFiles = [
|
||||||
'extension.cpp',
|
'extension.cpp',
|
||||||
|
'commonhooks.cpp',
|
||||||
'natives.cpp',
|
'natives.cpp',
|
||||||
'forwards.cpp',
|
'forwards.cpp',
|
||||||
'hltvserverwrapper.cpp',
|
'hltvserverwrapper.cpp',
|
||||||
'hltvdirectorwrapper.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)
|
binary = Extension.HL2Config(project, projectName + '.ext.' + sdk.ext, sdk)
|
||||||
compiler = binary.compiler
|
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':
|
if sdk.name == 'csgo':
|
||||||
compiler.cxxincludes += [
|
compiler.cxxincludes += [
|
||||||
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'),
|
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();
|
g_HLTVServers.InitHooks();
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
CDetourManager::Init(smutils->GetScriptingEngine(), g_pGameConf);
|
CDetourManager::Init(smutils->GetScriptingEngine(), g_pGameConf);
|
||||||
#endif
|
|
||||||
|
|
||||||
sharesys->AddNatives(myself, sourcetv_natives);
|
sharesys->AddNatives(myself, sourcetv_natives);
|
||||||
sharesys->RegisterLibrary(myself, "sourcetvmanager");
|
sharesys->RegisterLibrary(myself, "sourcetvmanager");
|
||||||
|
@ -40,9 +40,7 @@
|
|||||||
#include "smsdk_ext.h"
|
#include "smsdk_ext.h"
|
||||||
#include <IBinTools.h>
|
#include <IBinTools.h>
|
||||||
#include <ISDKTools.h>
|
#include <ISDKTools.h>
|
||||||
#ifndef WIN32
|
|
||||||
#include "CDetour/detours.h"
|
#include "CDetour/detours.h"
|
||||||
#endif
|
|
||||||
#include "ihltvdirector.h"
|
#include "ihltvdirector.h"
|
||||||
#include "ihltv.h"
|
#include "ihltv.h"
|
||||||
#include "iserver.h"
|
#include "iserver.h"
|
||||||
|
140
forwards.cpp
140
forwards.cpp
@ -32,6 +32,7 @@
|
|||||||
#include "extension.h"
|
#include "extension.h"
|
||||||
#include "forwards.h"
|
#include "forwards.h"
|
||||||
#include "hltvserverwrapper.h"
|
#include "hltvserverwrapper.h"
|
||||||
|
#include "commonhooks.h"
|
||||||
|
|
||||||
CForwardManager g_pSTVForwards;
|
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_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_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_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_ServerStartFwd = forwards->CreateForward("SourceTV_OnServerStart", ET_Ignore, 1, NULL, Param_Cell);
|
||||||
m_ServerShutdownFwd = forwards->CreateForward("SourceTV_OnServerShutdown", 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_SpectatorDisconnectFwd);
|
||||||
forwards->ReleaseForward(m_SpectatorDisconnectedFwd);
|
forwards->ReleaseForward(m_SpectatorDisconnectedFwd);
|
||||||
forwards->ReleaseForward(m_SpectatorPutInServerFwd);
|
forwards->ReleaseForward(m_SpectatorPutInServerFwd);
|
||||||
|
forwards->ReleaseForward(m_SpectatorChatMessageFwd);
|
||||||
|
forwards->ReleaseForward(m_SpectatorChatMessagePostFwd);
|
||||||
|
|
||||||
forwards->ReleaseForward(m_ServerStartFwd);
|
forwards->ReleaseForward(m_ServerStartFwd);
|
||||||
forwards->ReleaseForward(m_ServerShutdownFwd);
|
forwards->ReleaseForward(m_ServerShutdownFwd);
|
||||||
@ -206,6 +211,9 @@ void CForwardManager::UnhookServer(HLTVServerWrapper *wrapper)
|
|||||||
|
|
||||||
void CForwardManager::HookClient(IClient *client)
|
void CForwardManager::HookClient(IClient *client)
|
||||||
{
|
{
|
||||||
|
// Hook ExecuteStringCommand for chat messages
|
||||||
|
g_pSTVCommonHooks.AddSpectatorHook(this, client);
|
||||||
|
|
||||||
void *pGameClient = (void *)((intptr_t)client - 4);
|
void *pGameClient = (void *)((intptr_t)client - 4);
|
||||||
if (m_bHasActivatePlayerOffset)
|
if (m_bHasActivatePlayerOffset)
|
||||||
SH_ADD_MANUALHOOK(CBaseClient_ActivatePlayer, pGameClient, SH_MEMBER(this, &CForwardManager::OnSpectatorPutInServer), true);
|
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)
|
void CForwardManager::UnhookClient(IClient *client)
|
||||||
{
|
{
|
||||||
|
// Remove ExecuteStringCommand hook
|
||||||
|
g_pSTVCommonHooks.RemoveSpectatorHook(this, client);
|
||||||
|
|
||||||
void *pGameClient = (void *)((intptr_t)client - 4);
|
void *pGameClient = (void *)((intptr_t)client - 4);
|
||||||
if (m_bHasActivatePlayerOffset)
|
if (m_bHasActivatePlayerOffset)
|
||||||
SH_REMOVE_MANUALHOOK(CBaseClient_ActivatePlayer, pGameClient, SH_MEMBER(this, &CForwardManager::OnSpectatorPutInServer), true);
|
SH_REMOVE_MANUALHOOK(CBaseClient_ActivatePlayer, pGameClient, SH_MEMBER(this, &CForwardManager::OnSpectatorPutInServer), true);
|
||||||
@ -421,6 +432,119 @@ void CForwardManager::OnSpectatorPutInServer()
|
|||||||
RETURN_META(MRES_IGNORED);
|
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.
|
// These two hooks are actually only hooked on windows.
|
||||||
void CForwardManager::OnStartRecording_Post(const char *filename, bool bContinuously)
|
void CForwardManager::OnStartRecording_Post(const char *filename, bool bContinuously)
|
||||||
@ -506,10 +630,10 @@ DETOUR_DECL_MEMBER0(DetourHLTVStopRecording, void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CForwardManager::CreateStartRecordingDetour()
|
void CForwardManager::CreateStartRecordingDetour()
|
||||||
{
|
{
|
||||||
if (m_bStartRecordingDetoured)
|
if (m_bStartRecordingDetoured)
|
||||||
return true;
|
return;
|
||||||
|
|
||||||
m_DStartRecording = DETOUR_CREATE_MEMBER(DetourHLTVStartRecording, "CHLTVDemoRecorder::StartRecording");
|
m_DStartRecording = DETOUR_CREATE_MEMBER(DetourHLTVStartRecording, "CHLTVDemoRecorder::StartRecording");
|
||||||
|
|
||||||
@ -517,10 +641,10 @@ bool CForwardManager::CreateStartRecordingDetour()
|
|||||||
{
|
{
|
||||||
m_DStartRecording->EnableDetour();
|
m_DStartRecording->EnableDetour();
|
||||||
m_bStartRecordingDetoured = true;
|
m_bStartRecordingDetoured = true;
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
smutils->LogError(myself, "CHLTVDemoRecorder::StartRecording detour could not be initialized.");
|
smutils->LogError(myself, "CHLTVDemoRecorder::StartRecording detour could not be initialized.");
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CForwardManager::RemoveStartRecordingDetour()
|
void CForwardManager::RemoveStartRecordingDetour()
|
||||||
@ -533,10 +657,10 @@ void CForwardManager::RemoveStartRecordingDetour()
|
|||||||
m_bStartRecordingDetoured = false;
|
m_bStartRecordingDetoured = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CForwardManager::CreateStopRecordingDetour()
|
void CForwardManager::CreateStopRecordingDetour()
|
||||||
{
|
{
|
||||||
if (m_bStopRecordingDetoured)
|
if (m_bStopRecordingDetoured)
|
||||||
return true;
|
return;
|
||||||
|
|
||||||
m_DStopRecording = DETOUR_CREATE_MEMBER(DetourHLTVStopRecording, "CHLTVDemoRecorder::StopRecording");
|
m_DStopRecording = DETOUR_CREATE_MEMBER(DetourHLTVStopRecording, "CHLTVDemoRecorder::StopRecording");
|
||||||
|
|
||||||
@ -544,10 +668,10 @@ bool CForwardManager::CreateStopRecordingDetour()
|
|||||||
{
|
{
|
||||||
m_DStopRecording->EnableDetour();
|
m_DStopRecording->EnableDetour();
|
||||||
m_bStopRecordingDetoured = true;
|
m_bStopRecordingDetoured = true;
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
smutils->LogError(myself, "CHLTVDemoRecorder::StopRecording detour could not be initialized.");
|
smutils->LogError(myself, "CHLTVDemoRecorder::StopRecording detour could not be initialized.");
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CForwardManager::RemoveStopRecordingDetour()
|
void CForwardManager::RemoveStopRecordingDetour()
|
||||||
|
16
forwards.h
16
forwards.h
@ -70,9 +70,9 @@ public:
|
|||||||
void UnhookServer(HLTVServerWrapper *server);
|
void UnhookServer(HLTVServerWrapper *server);
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
bool CreateStartRecordingDetour();
|
void CreateStartRecordingDetour();
|
||||||
void RemoveStartRecordingDetour();
|
void RemoveStartRecordingDetour();
|
||||||
bool CreateStopRecordingDetour();
|
void CreateStopRecordingDetour();
|
||||||
void RemoveStopRecordingDetour();
|
void RemoveStopRecordingDetour();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -82,6 +82,13 @@ public:
|
|||||||
void CallOnStartRecording(IDemoRecorder *recorder, const char *filename, bool bContinuously);
|
void CallOnStartRecording(IDemoRecorder *recorder, const char *filename, bool bContinuously);
|
||||||
void CallOnStopRecording(IDemoRecorder *recorder);
|
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:
|
private:
|
||||||
void HookClient(IClient *client);
|
void HookClient(IClient *client);
|
||||||
void UnhookClient(IClient *client);
|
void UnhookClient(IClient *client);
|
||||||
@ -112,6 +119,8 @@ private:
|
|||||||
IForward *m_SpectatorDisconnectFwd;
|
IForward *m_SpectatorDisconnectFwd;
|
||||||
IForward *m_SpectatorDisconnectedFwd;
|
IForward *m_SpectatorDisconnectedFwd;
|
||||||
IForward *m_SpectatorPutInServerFwd;
|
IForward *m_SpectatorPutInServerFwd;
|
||||||
|
IForward *m_SpectatorChatMessageFwd;
|
||||||
|
IForward *m_SpectatorChatMessagePostFwd;
|
||||||
|
|
||||||
IForward *m_ServerStartFwd;
|
IForward *m_ServerStartFwd;
|
||||||
IForward *m_ServerShutdownFwd;
|
IForward *m_ServerShutdownFwd;
|
||||||
@ -122,6 +131,9 @@ private:
|
|||||||
bool m_bHasActivatePlayerOffset = false;
|
bool m_bHasActivatePlayerOffset = false;
|
||||||
bool m_bHasDisconnectOffset = false;
|
bool m_bHasDisconnectOffset = false;
|
||||||
|
|
||||||
|
bool m_bBroadcastLocalChatDetoured = false;
|
||||||
|
CDetour *m_DBroadcastLocalChat = nullptr;
|
||||||
|
|
||||||
// Only need the detours on linux. Windows always uses its vtables..
|
// Only need the detours on linux. Windows always uses its vtables..
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
bool m_bStartRecordingDetoured = false;
|
bool m_bStartRecordingDetoured = false;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#include "hltvserverwrapper.h"
|
#include "hltvserverwrapper.h"
|
||||||
#include "forwards.h"
|
#include "forwards.h"
|
||||||
|
#include "commonhooks.h"
|
||||||
|
|
||||||
void *old_host_client = nullptr;
|
void *old_host_client = nullptr;
|
||||||
bool g_HostClientOverridden = false;
|
bool g_HostClientOverridden = false;
|
||||||
|
|
||||||
SH_DECL_HOOK1(IClient, ExecuteStringCommand, SH_NOATTRIB, 0, bool, const char *);
|
|
||||||
SH_DECL_MANUALHOOK0_void(CHLTVServer_Shutdown, 0, 0, 0);
|
SH_DECL_MANUALHOOK0_void(CHLTVServer_Shutdown, 0, 0, 0);
|
||||||
|
|
||||||
#if SOURCE_ENGINE != SE_CSGO
|
#if SOURCE_ENGINE != SE_CSGO
|
||||||
@ -30,6 +30,7 @@ HLTVServerWrapper::HLTVServerWrapper(IHLTVServer *hltvserver)
|
|||||||
m_HLTVServer = hltvserver;
|
m_HLTVServer = hltvserver;
|
||||||
m_DemoRecorder = g_HLTVServers.GetDemoRecorderPtr(hltvserver);
|
m_DemoRecorder = g_HLTVServers.GetDemoRecorderPtr(hltvserver);
|
||||||
m_Connected = true;
|
m_Connected = true;
|
||||||
|
m_LastChatClient = nullptr;
|
||||||
|
|
||||||
Hook();
|
Hook();
|
||||||
|
|
||||||
@ -84,6 +85,26 @@ int HLTVServerWrapper::GetInstanceNumber()
|
|||||||
return g_HLTVServers.GetInstanceNumber(m_HLTVServer);
|
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)
|
HLTVClientWrapper *HLTVServerWrapper::GetClient(int index)
|
||||||
{
|
{
|
||||||
// Grow the vector with null pointers
|
// Grow the vector with null pointers
|
||||||
@ -123,8 +144,8 @@ void HLTVServerWrapper::Hook()
|
|||||||
IClient *pClient = iserver->GetClient(m_HLTVServer->GetHLTVSlot());
|
IClient *pClient = iserver->GetClient(m_HLTVServer->GetHLTVSlot());
|
||||||
if (pClient)
|
if (pClient)
|
||||||
{
|
{
|
||||||
SH_ADD_HOOK(IClient, ExecuteStringCommand, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand), false);
|
// Hook ExecuteStringCommand
|
||||||
SH_ADD_HOOK(IClient, ExecuteStringCommand, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand_Post), true);
|
g_pSTVCommonHooks.AddHLTVClientHook(this, pClient);
|
||||||
#if SOURCE_ENGINE != SE_CSGO
|
#if SOURCE_ENGINE != SE_CSGO
|
||||||
SH_ADD_HOOK(IClient, ClientPrintf, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnIClient_ClientPrintf_Post), false);
|
SH_ADD_HOOK(IClient, ClientPrintf, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnIClient_ClientPrintf_Post), false);
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@ -155,8 +176,8 @@ void HLTVServerWrapper::Unhook()
|
|||||||
IClient *pClient = iserver->GetClient(m_HLTVServer->GetHLTVSlot());
|
IClient *pClient = iserver->GetClient(m_HLTVServer->GetHLTVSlot());
|
||||||
if (pClient)
|
if (pClient)
|
||||||
{
|
{
|
||||||
SH_REMOVE_HOOK(IClient, ExecuteStringCommand, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand), false);
|
// Remove ExecuteStringCommand hook
|
||||||
SH_REMOVE_HOOK(IClient, ExecuteStringCommand, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand_Post), true);
|
g_pSTVCommonHooks.RemoveHLTVClientHook(this, pClient);
|
||||||
#if SOURCE_ENGINE != SE_CSGO
|
#if SOURCE_ENGINE != SE_CSGO
|
||||||
SH_REMOVE_HOOK(IClient, ClientPrintf, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnIClient_ClientPrintf_Post), false);
|
SH_REMOVE_HOOK(IClient, ClientPrintf, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnIClient_ClientPrintf_Post), false);
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@ -327,6 +348,7 @@ void HLTVServerWrapperManager::InitHooks()
|
|||||||
|
|
||||||
void HLTVServerWrapperManager::ShutdownHooks()
|
void HLTVServerWrapperManager::ShutdownHooks()
|
||||||
{
|
{
|
||||||
|
g_pSTVForwards.RemoveBroadcastLocalChatDetour();
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
g_pSTVForwards.RemoveStartRecordingDetour();
|
g_pSTVForwards.RemoveStartRecordingDetour();
|
||||||
g_pSTVForwards.RemoveStopRecordingDetour();
|
g_pSTVForwards.RemoveStopRecordingDetour();
|
||||||
@ -343,8 +365,9 @@ void HLTVServerWrapperManager::ShutdownHooks()
|
|||||||
|
|
||||||
void HLTVServerWrapperManager::AddServer(IHLTVServer *hltvserver)
|
void HLTVServerWrapperManager::AddServer(IHLTVServer *hltvserver)
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
|
||||||
// Create the detours once the first sourcetv server is created.
|
// Create the detours once the first sourcetv server is created.
|
||||||
|
g_pSTVForwards.CreateBroadcastLocalChatDetour();
|
||||||
|
#ifndef WIN32
|
||||||
g_pSTVForwards.CreateStartRecordingDetour();
|
g_pSTVForwards.CreateStartRecordingDetour();
|
||||||
g_pSTVForwards.CreateStopRecordingDetour();
|
g_pSTVForwards.CreateStopRecordingDetour();
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,13 +48,19 @@ public:
|
|||||||
HLTVClientWrapper *GetClient(int index);
|
HLTVClientWrapper *GetClient(int index);
|
||||||
int GetInstanceNumber();
|
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:
|
private:
|
||||||
void Hook();
|
void Hook();
|
||||||
void Unhook();
|
void Unhook();
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
bool OnHLTVBotExecuteStringCommand(const char *s);
|
|
||||||
bool OnHLTVBotExecuteStringCommand_Post(const char *s);
|
|
||||||
void OnHLTVServerShutdown();
|
void OnHLTVServerShutdown();
|
||||||
|
|
||||||
#if SOURCE_ENGINE != SE_CSGO
|
#if SOURCE_ENGINE != SE_CSGO
|
||||||
@ -68,6 +74,9 @@ private:
|
|||||||
IHLTVServer *m_HLTVServer = nullptr;
|
IHLTVServer *m_HLTVServer = nullptr;
|
||||||
IDemoRecorder *m_DemoRecorder = nullptr;
|
IDemoRecorder *m_DemoRecorder = nullptr;
|
||||||
ke::Vector<ke::AutoPtr<HLTVClientWrapper>> m_Clients;
|
ke::Vector<ke::AutoPtr<HLTVClientWrapper>> m_Clients;
|
||||||
|
|
||||||
|
IClient *m_LastChatClient = nullptr;
|
||||||
|
const char *m_LastChatMessage = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HLTVServerWrapperManager
|
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);
|
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)
|
public Action:Cmd_GetServerCount(client, args)
|
||||||
{
|
{
|
||||||
ReplyToCommand(client, "SourceTV server count: %d", SourceTV_GetServerInstanceCount());
|
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"
|
"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"
|
"CHLTVServer::GetRecordingDemoFilename"
|
||||||
{
|
{
|
||||||
"library" "engine"
|
"library" "engine"
|
||||||
@ -274,6 +282,14 @@
|
|||||||
"windows" "\x55\x8B\xEC\x81\xEC\x44\x04\x00\x00\x53"
|
"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"
|
"CHLTVServer::Shutdown"
|
||||||
{
|
{
|
||||||
"library" "engine"
|
"library" "engine"
|
||||||
|
@ -434,6 +434,29 @@ forward SourceTV_OnSpectatorDisconnected(client, const String:reason[255]);
|
|||||||
*/
|
*/
|
||||||
forward SourceTV_OnSpectatorPutInServer(client);
|
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!
|
* Do not edit below this line!
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user