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; | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										63
									
								
								natives.cpp
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								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) | ||||||
| 
 |  | ||||||
| 	if (!pBroadcastPrintf) |  | ||||||
| 	{ |  | ||||||
| 		int offset = -1; |  | ||||||
| 		if (!g_pGameConf->GetOffset("CBaseServer::BroadcastPrintf", &offset) || offset == -1) |  | ||||||
| 		{ |  | ||||||
| 			pContext->ReportError("Failed to get CBaseServer::BroadcastPrintf offset."); |  | ||||||
| 		return 0; | 		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