Extract player name in ConnectClient hook in CS:GO
CS:GO doesn't send the client name in plain text, but wraps it in some protobuf construct. Parse that list of client convars for the player name and use it in the SourceTV_OnSpectatorPreConnect forward
This commit is contained in:
		
							parent
							
								
									4bb751afaf
								
							
						
					
					
						commit
						10f7fa56a1
					
				
							
								
								
									
										35
									
								
								AMBuilder
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								AMBuilder
									
									
									
									
									
								
							@ -7,7 +7,8 @@ projectName = 'sourcetvmanager'
 | 
				
			|||||||
sourceFiles = [
 | 
					sourceFiles = [
 | 
				
			||||||
  'extension.cpp',
 | 
					  'extension.cpp',
 | 
				
			||||||
  'natives.cpp',
 | 
					  'natives.cpp',
 | 
				
			||||||
  'forwards.cpp'
 | 
					  'forwards.cpp',
 | 
				
			||||||
 | 
					  'hltvdirectorwrapper.cpp'
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###############
 | 
					###############
 | 
				
			||||||
@ -31,5 +32,37 @@ for sdk_name in ['css', 'csgo']:
 | 
				
			|||||||
  sdk = Extension.sdks[sdk_name]
 | 
					  sdk = Extension.sdks[sdk_name]
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  binary = Extension.HL2Config(project, projectName + '.ext.' + sdk.ext, sdk)
 | 
					  binary = Extension.HL2Config(project, projectName + '.ext.' + sdk.ext, sdk)
 | 
				
			||||||
 | 
					  compiler = binary.compiler
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if sdk.name == 'csgo':
 | 
				
			||||||
 | 
					    compiler.cxxincludes += [
 | 
				
			||||||
 | 
					      os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'),
 | 
				
			||||||
 | 
					      os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
 | 
				
			||||||
 | 
					      os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf')
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if builder.target_platform == 'linux':
 | 
				
			||||||
 | 
					      lib_path = os.path.join(sdk.path, 'lib', 'linux32', 'release', 'libprotobuf.a')
 | 
				
			||||||
 | 
					    elif builder.target_platform == 'mac':
 | 
				
			||||||
 | 
					      lib_path = os.path.join(sdk.path, 'lib', 'osx32', 'release', 'libprotobuf.a')
 | 
				
			||||||
 | 
					    elif builder.target_platform == 'windows':
 | 
				
			||||||
 | 
					      msvc_ver = compiler.version
 | 
				
			||||||
 | 
					      vs_year = ''
 | 
				
			||||||
 | 
					      if msvc_ver == 1800:
 | 
				
			||||||
 | 
					        vs_year = '2013'
 | 
				
			||||||
 | 
					      else:
 | 
				
			||||||
 | 
					        raise Exception('Cannot find libprotobuf for MSVC version "' + str(compiler.version) + '"')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if 'DEBUG' in compiler.defines:
 | 
				
			||||||
 | 
					        lib_path = os.path.join(sdk.path, 'lib', 'win32', 'debug', 'vs' + vs_year, 'libprotobuf.lib')
 | 
				
			||||||
 | 
					      else:
 | 
				
			||||||
 | 
					        lib_path = os.path.join(sdk.path, 'lib', 'win32', 'release', 'vs' + vs_year, 'libprotobuf.lib')
 | 
				
			||||||
 | 
					    compiler.linkflags.insert(0, binary.Dep(lib_path))
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    binary.sources += [
 | 
				
			||||||
 | 
					      os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'netmessages.pb.cc'),
 | 
				
			||||||
 | 
					      os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessages.pb.cc'),
 | 
				
			||||||
 | 
					      os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessage_helpers.cpp'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Extension.extensions = builder.Add(project)
 | 
					Extension.extensions = builder.Add(project)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										39
									
								
								forwards.cpp
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								forwards.cpp
									
									
									
									
									
								
							@ -42,7 +42,7 @@ SH_DECL_HOOK0_void(IDemoRecorder, StopRecording, SH_NOATTRIB, 0)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if SOURCE_ENGINE == SE_CSGO
 | 
					#if SOURCE_ENGINE == SE_CSGO
 | 
				
			||||||
SH_DECL_MANUALHOOK13(CHLTVServer_ConnectClient, 0, 0, 0, IClient *, netadr_s &, int, int, int, const char *, const char *, const char *, int, CUtlVector<INetMessage *> &, bool, CrossPlayPlatform_t, const unsigned char *, int);
 | 
					SH_DECL_MANUALHOOK13(CHLTVServer_ConnectClient, 0, 0, 0, IClient *, netadr_s &, int, int, int, const char *, const char *, const char *, int, CUtlVector<NetMsg_SplitPlayerConnect *> &, bool, CrossPlayPlatform_t, const unsigned char *, int);
 | 
				
			||||||
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);
 | 
				
			||||||
@ -188,6 +188,31 @@ static void RejectConnection(IServer *server, netadr_t &address, char *pchReason
 | 
				
			|||||||
		pRejectConnection->Execute(vstk, NULL);
 | 
							pRejectConnection->Execute(vstk, NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool ExtractPlayerName(CUtlVector<NetMsg_SplitPlayerConnect *> &pSplitPlayerConnectVector, char *name, int maxlen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for (int i = 0; i < pSplitPlayerConnectVector.Count(); i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							NetMsg_SplitPlayerConnect *split = pSplitPlayerConnectVector[i];
 | 
				
			||||||
 | 
							if (!split->has_convars())
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const CMsg_CVars cvars = split->convars();
 | 
				
			||||||
 | 
							for (int c = 0; c < cvars.cvars_size(); c++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								const CMsg_CVars_CVar cvar = cvars.cvars(c);
 | 
				
			||||||
 | 
								if (!cvar.has_name() || !cvar.has_value())
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (!strcmp(cvar.name().c_str(), "name"))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									strncpy(name, cvar.value().c_str(), maxlen);
 | 
				
			||||||
 | 
									return true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static void RejectConnection(IServer *server, netadr_t &address, int iClientChallenge, char *pchReason)
 | 
					static void RejectConnection(IServer *server, netadr_t &address, int iClientChallenge, char *pchReason)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -239,7 +264,7 @@ static void RejectConnection(IServer *server, netadr_t &address, int iClientChal
 | 
				
			|||||||
char passwordBuffer[255];
 | 
					char passwordBuffer[255];
 | 
				
			||||||
#if SOURCE_ENGINE == SE_CSGO
 | 
					#if SOURCE_ENGINE == SE_CSGO
 | 
				
			||||||
// CHLTVServer::ConnectClient(ns_address const&, int, int, int, char const*, char const*, char const*, int, CUtlVector<CNetMessagePB<16, CCLCMsg_SplitPlayerConnect, 0, true> *, CUtlMemory<CNetMessagePB<16, CCLCMsg_SplitPlayerConnect, 0, true> *, int>> &, bool, CrossPlayPlatform_t, unsigned char const*, int)
 | 
					// CHLTVServer::ConnectClient(ns_address const&, int, int, int, char const*, char const*, char const*, int, CUtlVector<CNetMessagePB<16, CCLCMsg_SplitPlayerConnect, 0, true> *, CUtlMemory<CNetMessagePB<16, CCLCMsg_SplitPlayerConnect, 0, true> *, int>> &, bool, CrossPlayPlatform_t, unsigned char const*, int)
 | 
				
			||||||
IClient *CForwardManager::OnSpectatorConnect(netadr_s & address, int nProtocol, int iChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie, CUtlVector<INetMessage *> &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char *pUnknown, int iUnknown)
 | 
					IClient *CForwardManager::OnSpectatorConnect(netadr_s & address, int nProtocol, int iChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie, CUtlVector<NetMsg_SplitPlayerConnect *> &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char *pUnknown, int iUnknown)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
IClient *CForwardManager::OnSpectatorConnect(netadr_t & address, int nProtocol, int iChallenge, int iClientChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie)
 | 
					IClient *CForwardManager::OnSpectatorConnect(netadr_t & address, int nProtocol, int iChallenge, int iClientChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -247,6 +272,14 @@ IClient *CForwardManager::OnSpectatorConnect(netadr_t & address, int nProtocol,
 | 
				
			|||||||
	if (!pCookie || cbCookie < sizeof(uint64))
 | 
						if (!pCookie || cbCookie < sizeof(uint64))
 | 
				
			||||||
		RETURN_META_VALUE(MRES_IGNORED, nullptr);
 | 
							RETURN_META_VALUE(MRES_IGNORED, nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if SOURCE_ENGINE == SE_CSGO
 | 
				
			||||||
 | 
						// CS:GO doesn't send the player name in pchName, but only in the client info convars.
 | 
				
			||||||
 | 
						// Try to extract the name from the protobuf msg.
 | 
				
			||||||
 | 
						char playerName[MAX_PLAYER_NAME_LENGTH];
 | 
				
			||||||
 | 
						if (ExtractPlayerName(pSplitPlayerConnectVector, playerName, sizeof(playerName)))
 | 
				
			||||||
 | 
							pchName = playerName;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char ipString[16];
 | 
						char ipString[16];
 | 
				
			||||||
	V_snprintf(ipString, sizeof(ipString), "%u.%u.%u.%u", address.ip[0], address.ip[1], address.ip[2], address.ip[3]);
 | 
						V_snprintf(ipString, sizeof(ipString), "%u.%u.%u.%u", address.ip[0], address.ip[1], address.ip[2], address.ip[3]);
 | 
				
			||||||
	V_strncpy(passwordBuffer, pchPassword, 255);
 | 
						V_strncpy(passwordBuffer, pchPassword, 255);
 | 
				
			||||||
@ -283,7 +316,7 @@ IClient *CForwardManager::OnSpectatorConnect(netadr_t & address, int nProtocol,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if SOURCE_ENGINE == SE_CSGO
 | 
					#if SOURCE_ENGINE == SE_CSGO
 | 
				
			||||||
IClient *CForwardManager::OnSpectatorConnect_Post(netadr_s & address, int nProtocol, int iChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie, CUtlVector<INetMessage *> &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char * pUnknown, int iUnknown)
 | 
					IClient *CForwardManager::OnSpectatorConnect_Post(netadr_s & address, int nProtocol, int iChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie, CUtlVector<NetMsg_SplitPlayerConnect *> &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char * pUnknown, int iUnknown)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
IClient *CForwardManager::OnSpectatorConnect_Post(netadr_t & address, int nProtocol, int iChallenge, int iClientChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie)
 | 
					IClient *CForwardManager::OnSpectatorConnect_Post(netadr_t & address, int nProtocol, int iChallenge, int iClientChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										18
									
								
								forwards.h
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								forwards.h
									
									
									
									
									
								
							@ -35,6 +35,20 @@
 | 
				
			|||||||
#include "extension.h"
 | 
					#include "extension.h"
 | 
				
			||||||
#include "netadr.h"
 | 
					#include "netadr.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if SOURCE_ENGINE == SE_CSGO
 | 
				
			||||||
 | 
					#include "netmessages.pb.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <int Type, class NetMessage, int Group, bool reliable>
 | 
				
			||||||
 | 
					class CNetMessagePB : public INetMessage, public NetMessage {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						~CNetMessagePB() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef CNetMessagePB<16, CCLCMsg_SplitPlayerConnect, 0, true>	NetMsg_SplitPlayerConnect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CGameInfo;
 | 
					class CGameInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CForwardManager
 | 
					class CForwardManager
 | 
				
			||||||
@ -57,8 +71,8 @@ private:
 | 
				
			|||||||
	void OnStartRecording_Post(const char *filename, bool bContinuously);
 | 
						void OnStartRecording_Post(const char *filename, bool bContinuously);
 | 
				
			||||||
#if SOURCE_ENGINE == SE_CSGO
 | 
					#if SOURCE_ENGINE == SE_CSGO
 | 
				
			||||||
	void OnStopRecording_Post(CGameInfo const *info);
 | 
						void OnStopRecording_Post(CGameInfo const *info);
 | 
				
			||||||
	IClient *OnSpectatorConnect(netadr_s & address, int nProtocol, int iChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie, CUtlVector<INetMessage *> &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char *pUnknown, int iUnknown);
 | 
						IClient *OnSpectatorConnect(netadr_s & address, int nProtocol, int iChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie, CUtlVector<NetMsg_SplitPlayerConnect *> &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char *pUnknown, int iUnknown);
 | 
				
			||||||
	IClient *OnSpectatorConnect_Post(netadr_s & address, int nProtocol, int iChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie, CUtlVector<INetMessage *> &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char *pUnknown, int iUnknown);
 | 
						IClient *OnSpectatorConnect_Post(netadr_s & address, int nProtocol, int iChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie, CUtlVector<NetMsg_SplitPlayerConnect *> &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char *pUnknown, int iUnknown);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	void OnStopRecording_Post();
 | 
						void OnStopRecording_Post();
 | 
				
			||||||
	IClient *OnSpectatorConnect(netadr_t &address, int nProtocol, int iChallenge, int iClientChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie);
 | 
						IClient *OnSpectatorConnect(netadr_t &address, int nProtocol, int iChallenge, int iClientChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie);
 | 
				
			||||||
 | 
				
			|||||||
@ -303,7 +303,7 @@ native SourceTV_KickClient(client, const String:sReason[]);
 | 
				
			|||||||
 * This is called before any other validation has happened.
 | 
					 * This is called before any other validation has happened.
 | 
				
			||||||
 * Similar to the OnClientPreConnectEx forward in the Connect extension by asherkin.
 | 
					 * Similar to the OnClientPreConnectEx forward in the Connect extension by asherkin.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @param name		The player name (always empty in CS:GO).
 | 
					 * @param name		The player name.
 | 
				
			||||||
 * @param password	The password the client used to connect. Can be overwritten.
 | 
					 * @param password	The password the client used to connect. Can be overwritten.
 | 
				
			||||||
 * @param ip		The ip address of the client.
 | 
					 * @param ip		The ip address of the client.
 | 
				
			||||||
 * @param rejectReason	Buffer to write the reject reason to, if you want to reject the client from connecting.
 | 
					 * @param rejectReason	Buffer to write the reject reason to, if you want to reject the client from connecting.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user