Clean up some SDK calls to use SourceHook directly
Don't use IBinTools to call virtual functions. We're in C++! Use SourceHook right away. This reduces in less and readable code.
This commit is contained in:
parent
7dd6897067
commit
4d62d77e55
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "extension.h"
|
#include "extension.h"
|
||||||
#include "forwards.h"
|
#include "forwards.h"
|
||||||
|
#include "natives.h"
|
||||||
|
|
||||||
IHLTVDirector *hltvdirector = nullptr;
|
IHLTVDirector *hltvdirector = nullptr;
|
||||||
IHLTVServer *hltvserver = nullptr;
|
IHLTVServer *hltvserver = nullptr;
|
||||||
@ -152,6 +153,7 @@ void SourceTVManager::SDK_OnAllLoaded()
|
|||||||
SM_GET_LATE_IFACE(SDKTOOLS, sdktools);
|
SM_GET_LATE_IFACE(SDKTOOLS, sdktools);
|
||||||
|
|
||||||
g_pSTVForwards.Init();
|
g_pSTVForwards.Init();
|
||||||
|
SetupNativeCalls();
|
||||||
|
|
||||||
iserver = sdktools->GetIServer();
|
iserver = sdktools->GetIServer();
|
||||||
if (!iserver)
|
if (!iserver)
|
||||||
@ -396,6 +398,16 @@ void SourceTVManager::OnSetHLTVServer_Post(IHLTVServer *hltv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// When bots issue a command that would print stuff to their console,
|
||||||
|
// the server might crash, because ExecuteStringCommand doesn't set the
|
||||||
|
// global host_client pointer to the client on whom the command is run.
|
||||||
|
// Host_Client_Printf blatantly tries to call host_client->ClientPrintf
|
||||||
|
// while the pointer might point to some other player or garbage.
|
||||||
|
// This leads to e.g. the output of the "status" command not being
|
||||||
|
// recorded in the SourceTV demo.
|
||||||
|
// The approach here is to set host_client correctly for the SourceTV
|
||||||
|
// bot and reset it to the old value after command execution.
|
||||||
bool SourceTVManager::OnHLTVBotExecuteStringCommand(const char *s)
|
bool SourceTVManager::OnHLTVBotExecuteStringCommand(const char *s)
|
||||||
{
|
{
|
||||||
if (!hltvserver || !iserver || !host_client)
|
if (!hltvserver || !iserver || !host_client)
|
||||||
|
116
forwards.cpp
116
forwards.cpp
@ -43,9 +43,11 @@ SH_DECL_HOOK0_void(IDemoRecorder, StopRecording, SH_NOATTRIB, 0)
|
|||||||
|
|
||||||
#if SOURCE_ENGINE == SE_CSGO
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
SH_DECL_MANUALHOOK13(CHLTVServer_ConnectClient, 0, 0, 0, IClient *, const netadr_t &, int, int, int, const char *, const char *, const char *, int, CUtlVector<NetMsg_SplitPlayerConnect *> &, bool, CrossPlayPlatform_t, const unsigned char *, int);
|
SH_DECL_MANUALHOOK13(CHLTVServer_ConnectClient, 0, 0, 0, IClient *, const netadr_t &, int, int, int, const char *, const char *, const char *, int, CUtlVector<NetMsg_SplitPlayerConnect *> &, bool, CrossPlayPlatform_t, const unsigned char *, int);
|
||||||
|
SH_DECL_MANUALHOOK1_void_vafmt(CHLTVServer_RejectConnection, 0, 0, 0, const netadr_t &);
|
||||||
SH_DECL_HOOK1_void(IClient, Disconnect, SH_NOATTRIB, 0, const char *);
|
SH_DECL_HOOK1_void(IClient, Disconnect, SH_NOATTRIB, 0, const char *);
|
||||||
#else
|
#else
|
||||||
SH_DECL_MANUALHOOK9(CHLTVServer_ConnectClient, 0, 0, 0, IClient *, netadr_t &, int, int, int, int, const char *, const char *, const char *, int);
|
SH_DECL_MANUALHOOK9(CHLTVServer_ConnectClient, 0, 0, 0, IClient *, netadr_t &, int, int, int, int, const char *, const char *, const char *, int);
|
||||||
|
SH_DECL_MANUALHOOK3_void(CHLTVServer_RejectConnection, 0, 0, 0, const netadr_t &, int, const char *);
|
||||||
SH_DECL_HOOK0_void_vafmt(IClient, Disconnect, SH_NOATTRIB, 0);
|
SH_DECL_HOOK0_void_vafmt(IClient, Disconnect, SH_NOATTRIB, 0);
|
||||||
#endif
|
#endif
|
||||||
SH_DECL_MANUALHOOK0_void(CBaseClient_ActivatePlayer, 0, 0, 0);
|
SH_DECL_MANUALHOOK0_void(CBaseClient_ActivatePlayer, 0, 0, 0);
|
||||||
@ -65,6 +67,16 @@ void CForwardManager::Init()
|
|||||||
m_bHasClientConnectOffset = true;
|
m_bHasClientConnectOffset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!g_pGameConf->GetOffset("CHLTVServer::RejectConnection", &offset) || offset == -1)
|
||||||
|
{
|
||||||
|
smutils->LogError(myself, "Failed to get CHLTVServer::RejectConnection offset.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SH_MANUALHOOK_RECONFIGURE(CHLTVServer_RejectConnection, offset, 0, 0);
|
||||||
|
m_bHasRejectConnectionOffset = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!g_pGameConf->GetOffset("CHLTVServer::GetChallengeType", &offset) || offset == -1)
|
if (!g_pGameConf->GetOffset("CHLTVServer::GetChallengeType", &offset) || offset == -1)
|
||||||
{
|
{
|
||||||
smutils->LogError(myself, "Failed to get CHLTVServer::GetChallengeType offset.");
|
smutils->LogError(myself, "Failed to get CHLTVServer::GetChallengeType offset.");
|
||||||
@ -177,59 +189,6 @@ void CForwardManager::UnhookClient(IClient *client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_CSGO
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
// CBaseServer::RejectConnection(ns_address const&, char const*, ...)
|
|
||||||
static void RejectConnection(IServer *server, const netadr_t &address, const char *pchReason)
|
|
||||||
{
|
|
||||||
static ICallWrapper *pRejectConnection = nullptr;
|
|
||||||
|
|
||||||
if (!pRejectConnection)
|
|
||||||
{
|
|
||||||
int offset = -1;
|
|
||||||
if (!g_pGameConf->GetOffset("CHLTVServer::RejectConnection", &offset) || offset == -1)
|
|
||||||
{
|
|
||||||
smutils->LogError(myself, "Failed to get CHLTVServer::RejectConnection offset.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PassInfo pass[4];
|
|
||||||
pass[0].flags = PASSFLAG_BYVAL;
|
|
||||||
pass[0].type = PassType_Basic;
|
|
||||||
pass[0].size = sizeof(void *);
|
|
||||||
pass[1].flags = PASSFLAG_BYVAL;
|
|
||||||
pass[1].type = PassType_Basic;
|
|
||||||
pass[1].size = sizeof(void *);
|
|
||||||
pass[2].flags = PASSFLAG_BYVAL;
|
|
||||||
pass[2].type = PassType_Basic;
|
|
||||||
pass[2].size = sizeof(char *);
|
|
||||||
pass[3].flags = PASSFLAG_BYVAL;
|
|
||||||
pass[3].type = PassType_Basic;
|
|
||||||
pass[3].size = sizeof(char *);
|
|
||||||
|
|
||||||
void **vtable = *(void ***)server;
|
|
||||||
void *func = vtable[offset];
|
|
||||||
|
|
||||||
pRejectConnection = bintools->CreateCall(func, CallConv_Cdecl, NULL, pass, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char fmt[] = "%s";
|
|
||||||
|
|
||||||
if (pRejectConnection)
|
|
||||||
{
|
|
||||||
unsigned char vstk[sizeof(void *) * 2 + sizeof(char *) * 2];
|
|
||||||
unsigned char *vptr = vstk;
|
|
||||||
|
|
||||||
*(void **)vptr = (void *)server;
|
|
||||||
vptr += sizeof(void *);
|
|
||||||
*(void **)vptr = (void *)&address;
|
|
||||||
vptr += sizeof(void *);
|
|
||||||
*(char **)vptr = fmt;
|
|
||||||
vptr += sizeof(char *);
|
|
||||||
*(const char **)vptr = pchReason;
|
|
||||||
|
|
||||||
pRejectConnection->Execute(vstk, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ExtractPlayerName(CUtlVector<NetMsg_SplitPlayerConnect *> &pSplitPlayerConnectVector, char *name, int maxlen)
|
static bool ExtractPlayerName(CUtlVector<NetMsg_SplitPlayerConnect *> &pSplitPlayerConnectVector, char *name, int maxlen)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < pSplitPlayerConnectVector.Count(); i++)
|
for (int i = 0; i < pSplitPlayerConnectVector.Count(); i++)
|
||||||
@ -254,50 +213,6 @@ static bool ExtractPlayerName(CUtlVector<NetMsg_SplitPlayerConnect *> &pSplitPla
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static void RejectConnection(IServer *server, netadr_t &address, int iClientChallenge, char *pchReason)
|
|
||||||
{
|
|
||||||
static ICallWrapper *pRejectConnection = nullptr;
|
|
||||||
|
|
||||||
if (!pRejectConnection)
|
|
||||||
{
|
|
||||||
int offset = -1;
|
|
||||||
if (!g_pGameConf->GetOffset("CHLTVServer::RejectConnection", &offset) || offset == -1)
|
|
||||||
{
|
|
||||||
smutils->LogError(myself, "Failed to get CHLTVServer::RejectConnection offset.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PassInfo pass[3];
|
|
||||||
pass[0].flags = PASSFLAG_BYVAL;
|
|
||||||
pass[0].type = PassType_Basic;
|
|
||||||
pass[0].size = sizeof(netadr_t *);
|
|
||||||
pass[1].flags = PASSFLAG_BYVAL;
|
|
||||||
pass[1].type = PassType_Basic;
|
|
||||||
pass[1].size = sizeof(int);
|
|
||||||
pass[2].flags = PASSFLAG_BYVAL;
|
|
||||||
pass[2].type = PassType_Basic;
|
|
||||||
pass[2].size = sizeof(char *);
|
|
||||||
|
|
||||||
pRejectConnection = bintools->CreateVCall(offset, 0, 0, NULL, pass, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pRejectConnection)
|
|
||||||
{
|
|
||||||
unsigned char vstk[sizeof(void *) + sizeof(netadr_t *) + sizeof(int) + sizeof(char *)];
|
|
||||||
unsigned char *vptr = vstk;
|
|
||||||
|
|
||||||
*(void **)vptr = (void *)server;
|
|
||||||
vptr += sizeof(void *);
|
|
||||||
*(netadr_t **)vptr = &address;
|
|
||||||
vptr += sizeof(netadr_t *);
|
|
||||||
*(int *)vptr = iClientChallenge;
|
|
||||||
vptr += sizeof(int);
|
|
||||||
*(char **)vptr = pchReason;
|
|
||||||
|
|
||||||
pRejectConnection->Execute(vstk, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Mimic Connect extension https://forums.alliedmods.net/showthread.php?t=162489
|
// Mimic Connect extension https://forums.alliedmods.net/showthread.php?t=162489
|
||||||
@ -340,11 +255,14 @@ IClient *CForwardManager::OnSpectatorConnect(netadr_t & address, int nProtocol,
|
|||||||
IServer *server = META_IFACEPTR(IServer);
|
IServer *server = META_IFACEPTR(IServer);
|
||||||
if (retVal == 0)
|
if (retVal == 0)
|
||||||
{
|
{
|
||||||
|
if (m_bHasRejectConnectionOffset)
|
||||||
|
{
|
||||||
#if SOURCE_ENGINE == SE_CSGO
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
RejectConnection(server, address, rejectReason);
|
SH_MCALL(server, CHLTVServer_RejectConnection)(address, rejectReason);
|
||||||
#else
|
#else
|
||||||
RejectConnection(server, address, iClientChallenge, rejectReason);
|
SH_MCALL(server, CHLTVServer_RejectConnection)(address, iClientChallenge, rejectReason);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
RETURN_META_VALUE(MRES_SUPERCEDE, nullptr);
|
RETURN_META_VALUE(MRES_SUPERCEDE, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +98,7 @@ private:
|
|||||||
IForward *m_SpectatorPutInServerFwd;
|
IForward *m_SpectatorPutInServerFwd;
|
||||||
|
|
||||||
bool m_bHasClientConnectOffset = false;
|
bool m_bHasClientConnectOffset = false;
|
||||||
|
bool m_bHasRejectConnectionOffset = false;
|
||||||
bool m_bHasGetChallengeTypeOffset = false;
|
bool m_bHasGetChallengeTypeOffset = false;
|
||||||
bool m_bHasActivatePlayerOffset = false;
|
bool m_bHasActivatePlayerOffset = false;
|
||||||
};
|
};
|
||||||
|
65
natives.cpp
65
natives.cpp
@ -30,12 +30,31 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "extension.h"
|
#include "extension.h"
|
||||||
|
#include "natives.h"
|
||||||
|
|
||||||
#define TICK_INTERVAL (gpGlobals->interval_per_tick)
|
#define TICK_INTERVAL (gpGlobals->interval_per_tick)
|
||||||
#define TIME_TO_TICKS( dt ) ( (int)( 0.5f + (float)(dt) / TICK_INTERVAL ) )
|
#define TIME_TO_TICKS( dt ) ( (int)( 0.5f + (float)(dt) / TICK_INTERVAL ) )
|
||||||
|
|
||||||
extern const sp_nativeinfo_t sourcetv_natives[];
|
extern const sp_nativeinfo_t sourcetv_natives[];
|
||||||
|
|
||||||
|
SH_DECL_MANUALHOOK0_void_vafmt(CBaseServer_BroadcastPrintf, 0, 0, 0);
|
||||||
|
|
||||||
|
bool g_bHasClientPrintfOffset = false;
|
||||||
|
|
||||||
|
void SetupNativeCalls()
|
||||||
|
{
|
||||||
|
int offset = -1;
|
||||||
|
if (!g_pGameConf->GetOffset("CBaseServer::BroadcastPrintf", &offset) || offset == -1)
|
||||||
|
{
|
||||||
|
smutils->LogError(myself, "Failed to get CBaseServer::BroadcastPrintf offset.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SH_MANUALHOOK_RECONFIGURE(CBaseServer_BroadcastPrintf, offset, 0, 0);
|
||||||
|
g_bHasClientPrintfOffset = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// native SourceTV_GetServerInstanceCount();
|
// native SourceTV_GetServerInstanceCount();
|
||||||
static cell_t Native_GetServerInstanceCount(IPluginContext *pContext, const cell_t *params)
|
static cell_t Native_GetServerInstanceCount(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
@ -238,34 +257,8 @@ static cell_t Native_BroadcastConsoleMessage(IPluginContext *pContext, const cel
|
|||||||
if (hltvserver == nullptr)
|
if (hltvserver == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
static ICallWrapper *pBroadcastPrintf = nullptr;
|
if (!g_bHasClientPrintfOffset)
|
||||||
|
return 0;
|
||||||
if (!pBroadcastPrintf)
|
|
||||||
{
|
|
||||||
int offset = -1;
|
|
||||||
if (!g_pGameConf->GetOffset("CBaseServer::BroadcastPrintf", &offset) || offset == -1)
|
|
||||||
{
|
|
||||||
pContext->ReportError("Failed to get CBaseServer::BroadcastPrintf offset.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PassInfo pass[3];
|
|
||||||
pass[0].flags = PASSFLAG_BYVAL;
|
|
||||||
pass[0].type = PassType_Basic;
|
|
||||||
pass[0].size = sizeof(void *);
|
|
||||||
pass[1].flags = PASSFLAG_BYVAL;
|
|
||||||
pass[1].type = PassType_Basic;
|
|
||||||
pass[1].size = sizeof(char *);
|
|
||||||
pass[2].flags = PASSFLAG_BYVAL;
|
|
||||||
pass[2].type = PassType_Basic;
|
|
||||||
pass[2].size = sizeof(char *);
|
|
||||||
|
|
||||||
void *iserver = (void *)hltvserver->GetBaseServer();
|
|
||||||
void **vtable = *(void ***)iserver;
|
|
||||||
void *func = vtable[offset];
|
|
||||||
|
|
||||||
pBroadcastPrintf = bintools->CreateCall(func, CallConv_Cdecl, NULL, pass, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -276,21 +269,7 @@ static cell_t Native_BroadcastConsoleMessage(IPluginContext *pContext, const cel
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char fmt[] = "%s\n";
|
SH_MCALL(hltvserver->GetBaseServer(), CBaseServer_BroadcastPrintf)("%s\n", buffer);
|
||||||
|
|
||||||
if (pBroadcastPrintf)
|
|
||||||
{
|
|
||||||
unsigned char vstk[sizeof(void *) + sizeof(char *) * 2];
|
|
||||||
unsigned char *vptr = vstk;
|
|
||||||
|
|
||||||
*(void **)vptr = (void *)hltvserver->GetBaseServer();
|
|
||||||
vptr += sizeof(void *);
|
|
||||||
*(char **)vptr = fmt;
|
|
||||||
vptr += sizeof(char *);
|
|
||||||
*(char **)vptr = buffer;
|
|
||||||
|
|
||||||
pBroadcastPrintf->Execute(vstk, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
37
natives.h
Normal file
37
natives.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* 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_NATIVES_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_EXTENSION_NATIVES_H_
|
||||||
|
|
||||||
|
void SetupNativeCalls();
|
||||||
|
|
||||||
|
#endif // _INCLUDE_SOURCEMOD_EXTENSION_NATIVES_H_
|
Loading…
Reference in New Issue
Block a user