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