Add natives to get client ip and connect password
The hltv server doesn't provide a nice IPlayerInfo interface to get stuff. Have to grab it and hold on to it while we can!
This commit is contained in:
parent
10f7fa56a1
commit
c0eb6eb75f
@ -8,7 +8,8 @@ sourceFiles = [
|
||||
'extension.cpp',
|
||||
'natives.cpp',
|
||||
'forwards.cpp',
|
||||
'hltvdirectorwrapper.cpp'
|
||||
'hltvdirectorwrapper.cpp',
|
||||
'hltvclientwrapper.cpp'
|
||||
]
|
||||
|
||||
###############
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <IBinTools.h>
|
||||
#include <ISDKTools.h>
|
||||
#include "hltvdirectorwrapper.h"
|
||||
#include "hltvclientwrapper.h"
|
||||
#include "ihltvdirector.h"
|
||||
#include "ihltv.h"
|
||||
#include "iserver.h"
|
||||
|
33
forwards.cpp
33
forwards.cpp
@ -97,14 +97,18 @@ void CForwardManager::HookServer(IServer *server)
|
||||
return;
|
||||
|
||||
SH_ADD_MANUALHOOK(CHLTVServer_ConnectClient, server, SH_MEMBER(this, &CForwardManager::OnSpectatorConnect), false);
|
||||
SH_ADD_MANUALHOOK(CHLTVServer_ConnectClient, server, SH_MEMBER(this, &CForwardManager::OnSpectatorConnect_Post), true);
|
||||
|
||||
// Hook all already connected clients as well for late loading
|
||||
for (int i = 0; i < server->GetClientCount(); i++)
|
||||
{
|
||||
IClient *client = server->GetClient(i);
|
||||
if (client->IsConnected())
|
||||
{
|
||||
HookClient(client);
|
||||
// Ip and password unknown :(
|
||||
// Could add more gamedata to fetch it if people really lateload the extension and expect it to work :B
|
||||
g_HLTVClientManager.GetClient(i + 1)->Initialize("", "", client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +118,6 @@ void CForwardManager::UnhookServer(IServer *server)
|
||||
return;
|
||||
|
||||
SH_REMOVE_MANUALHOOK(CHLTVServer_ConnectClient, server, SH_MEMBER(this, &CForwardManager::OnSpectatorConnect), false);
|
||||
SH_REMOVE_MANUALHOOK(CHLTVServer_ConnectClient, server, SH_MEMBER(this, &CForwardManager::OnSpectatorConnect_Post), true);
|
||||
|
||||
// Unhook all connected clients as well.
|
||||
for (int i = 0; i < server->GetClientCount(); i++)
|
||||
@ -296,9 +299,9 @@ IClient *CForwardManager::OnSpectatorConnect(netadr_t & address, int nProtocol,
|
||||
cell_t retVal = 1;
|
||||
m_SpectatorPreConnectFwd->Execute(&retVal);
|
||||
|
||||
IServer *server = META_IFACEPTR(IServer);
|
||||
if (retVal == 0)
|
||||
{
|
||||
IServer *server = META_IFACEPTR(IServer);
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
RejectConnection(server, address, rejectReason);
|
||||
#else
|
||||
@ -307,30 +310,26 @@ IClient *CForwardManager::OnSpectatorConnect(netadr_t & address, int nProtocol,
|
||||
RETURN_META_VALUE(MRES_SUPERCEDE, nullptr);
|
||||
}
|
||||
|
||||
pchPassword = passwordBuffer;
|
||||
// Call the original function.
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
RETURN_META_VALUE_MNEWPARAMS(MRES_IGNORED, nullptr, CHLTVServer_ConnectClient, (address, nProtocol, iChallenge, nAuthProtocol, pchName, pchPassword, pCookie, cbCookie, pSplitPlayerConnectVector, bUnknown, platform, pUnknown, iUnknown));
|
||||
IClient *client = SH_MCALL(server, CHLTVServer_ConnectClient)(address, nProtocol, iChallenge, nAuthProtocol, pchName, passwordBuffer, pCookie, cbCookie, pSplitPlayerConnectVector, bUnknown, platform, pUnknown, iUnknown);
|
||||
#else
|
||||
RETURN_META_VALUE_MNEWPARAMS(MRES_IGNORED, nullptr, CHLTVServer_ConnectClient, (address, nProtocol, iChallenge, iClientChallenge, nAuthProtocol, pchName, pchPassword, pCookie, cbCookie));
|
||||
IClient *client = SH_MCALL(server, CHLTVServer_ConnectClient)(address, nProtocol, iChallenge, iClientChallenge, nAuthProtocol, pchName, passwordBuffer, pCookie, cbCookie);
|
||||
#endif
|
||||
}
|
||||
|
||||
#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<NetMsg_SplitPlayerConnect *> &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char * pUnknown, int iUnknown)
|
||||
#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)
|
||||
#endif
|
||||
{
|
||||
IClient *client = META_RESULT_ORIG_RET(IClient *);
|
||||
if (!client)
|
||||
RETURN_META_VALUE(MRES_IGNORED, nullptr);
|
||||
RETURN_META_VALUE(MRES_SUPERCEDE, nullptr);
|
||||
|
||||
HookClient(client);
|
||||
|
||||
m_SpectatorConnectedFwd->PushCell(client->GetPlayerSlot()+1);
|
||||
HLTVClientWrapper *wrapper = g_HLTVClientManager.GetClient(client->GetPlayerSlot() + 1);
|
||||
wrapper->Initialize(ipString, pchPassword, client);
|
||||
|
||||
m_SpectatorConnectedFwd->PushCell(client->GetPlayerSlot() + 1);
|
||||
m_SpectatorConnectedFwd->Execute();
|
||||
|
||||
RETURN_META_VALUE(MRES_IGNORED, nullptr);
|
||||
// Don't call the hooked function again, just return its value.
|
||||
RETURN_META_VALUE(MRES_SUPERCEDE, client);
|
||||
}
|
||||
|
||||
void CForwardManager::OnSpectatorDisconnect(const char *reason)
|
||||
|
@ -72,11 +72,9 @@ private:
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
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<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<NetMsg_SplitPlayerConnect *> &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char *pUnknown, int iUnknown);
|
||||
#else
|
||||
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_Post(netadr_t &address, int nProtocol, int iChallenge, int iClientChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie);
|
||||
#endif
|
||||
void OnSpectatorDisconnect(const char *reason);
|
||||
|
||||
|
69
hltvclientwrapper.cpp
Normal file
69
hltvclientwrapper.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include "hltvclientwrapper.h"
|
||||
|
||||
HLTVClientWrapper::HLTVClientWrapper()
|
||||
{
|
||||
m_Client = nullptr;
|
||||
}
|
||||
|
||||
void HLTVClientWrapper::Initialize(const char *ip, const char *password, IClient *client)
|
||||
{
|
||||
m_Ip = ip;
|
||||
m_Password = password;
|
||||
m_Client = client;
|
||||
}
|
||||
|
||||
const char *HLTVClientWrapper::Name()
|
||||
{
|
||||
return m_Client->GetClientName();
|
||||
}
|
||||
|
||||
const char *HLTVClientWrapper::Ip()
|
||||
{
|
||||
return m_Ip.chars();
|
||||
}
|
||||
|
||||
const char *HLTVClientWrapper::Password()
|
||||
{
|
||||
return m_Password.chars();
|
||||
}
|
||||
|
||||
bool HLTVClientWrapper::IsConnected()
|
||||
{
|
||||
return m_Client && m_Client->IsConnected();
|
||||
}
|
||||
|
||||
IClient *HLTVClientWrapper::BaseClient()
|
||||
{
|
||||
return m_Client;
|
||||
}
|
||||
|
||||
void HLTVClientWrapper::Kick(const char *reason)
|
||||
{
|
||||
// Go this route due to different IClient::Disconnect signatures in games..
|
||||
m_Client->GetServer()->DisconnectClient(m_Client, reason);
|
||||
}
|
||||
|
||||
HLTVClientWrapper *HLTVClientManager::GetClient(int index)
|
||||
{
|
||||
// Grow the vector with null pointers
|
||||
// There might have been clients with lower indexes before we were loaded.
|
||||
if (m_Clients.length() < (size_t)index)
|
||||
{
|
||||
int start = m_Clients.length();
|
||||
m_Clients.resize(index);
|
||||
for (int i = start; i < index; i++)
|
||||
{
|
||||
m_Clients[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_Clients[index - 1])
|
||||
{
|
||||
m_Clients[index - 1] = new HLTVClientWrapper();
|
||||
}
|
||||
|
||||
return m_Clients[index - 1];
|
||||
}
|
||||
|
||||
// FIXME: ClientManager instance for each hltvserver instance in csgo!
|
||||
HLTVClientManager g_HLTVClientManager;
|
71
hltvclientwrapper.h
Normal file
71
hltvclientwrapper.h
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* 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_HLTVCLIENT_H_
|
||||
#define _INCLUDE_SOURCEMOD_EXTENSION_HLTVCLIENT_H_
|
||||
|
||||
#include "extension.h"
|
||||
#include "amtl/am-string.h"
|
||||
#include "amtl/am-vector.h"
|
||||
#include "amtl/am-utility.h"
|
||||
|
||||
class HLTVClientWrapper {
|
||||
public:
|
||||
HLTVClientWrapper();
|
||||
void Initialize(const char *ip, const char *password, IClient *client);
|
||||
|
||||
public:
|
||||
const char *Name();
|
||||
const char *Ip();
|
||||
const char *Password();
|
||||
bool IsConnected();
|
||||
IClient *BaseClient();
|
||||
|
||||
void Kick(const char *reason);
|
||||
|
||||
private:
|
||||
ke::AString m_Ip;
|
||||
ke::AString m_Password;
|
||||
IClient *m_Client;
|
||||
};
|
||||
|
||||
class HLTVClientManager {
|
||||
|
||||
public:
|
||||
HLTVClientWrapper *GetClient(int index);
|
||||
|
||||
private:
|
||||
ke::Vector<ke::AutoPtr<HLTVClientWrapper>> m_Clients;
|
||||
};
|
||||
|
||||
extern HLTVClientManager g_HLTVClientManager;
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_HLTVCLIENT_H_
|
64
natives.cpp
64
natives.cpp
@ -544,7 +544,7 @@ static cell_t Native_IsClientConnected(IPluginContext *pContext, const cell_t *p
|
||||
return 0;
|
||||
}
|
||||
|
||||
IClient *pClient = hltvserver->GetBaseServer()->GetClient(client - 1);
|
||||
HLTVClientWrapper *pClient = g_HLTVClientManager.GetClient(client);
|
||||
return pClient->IsConnected();
|
||||
}
|
||||
|
||||
@ -561,14 +561,62 @@ static cell_t Native_GetSpectatorName(IPluginContext *pContext, const cell_t *pa
|
||||
return 0;
|
||||
}
|
||||
|
||||
IClient *pClient = hltvserver->GetBaseServer()->GetClient(client - 1);
|
||||
if (!pClient || !pClient->IsConnected())
|
||||
HLTVClientWrapper *pClient = g_HLTVClientManager.GetClient(client);
|
||||
if (!pClient->IsConnected())
|
||||
{
|
||||
pContext->ReportError("Client %d is not connected.", client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), pClient->GetClientName(), NULL);
|
||||
pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), pClient->Name(), NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// native SourceTV_GetSpectatorIP(client, String:ip[], maxlen);
|
||||
static cell_t Native_GetSpectatorIP(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
if (hltvserver == nullptr)
|
||||
return 0;
|
||||
|
||||
cell_t client = params[1];
|
||||
if (client < 1 || client > hltvserver->GetBaseServer()->GetClientCount())
|
||||
{
|
||||
pContext->ReportError("Invalid spectator client index %d.", client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HLTVClientWrapper *pClient = g_HLTVClientManager.GetClient(client);
|
||||
if (!pClient->IsConnected())
|
||||
{
|
||||
pContext->ReportError("Client %d is not connected.", client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), pClient->Ip(), NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// native SourceTV_GetSpectatorPassword(client, String:password[], maxlen);
|
||||
static cell_t Native_GetSpectatorPassword(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
if (hltvserver == nullptr)
|
||||
return 0;
|
||||
|
||||
cell_t client = params[1];
|
||||
if (client < 1 || client > hltvserver->GetBaseServer()->GetClientCount())
|
||||
{
|
||||
pContext->ReportError("Invalid spectator client index %d.", client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HLTVClientWrapper *pClient = g_HLTVClientManager.GetClient(client);
|
||||
if (!pClient->IsConnected())
|
||||
{
|
||||
pContext->ReportError("Client %d is not connected.", client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), pClient->Password(), NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -585,8 +633,8 @@ static cell_t Native_KickClient(IPluginContext *pContext, const cell_t *params)
|
||||
return 0;
|
||||
}
|
||||
|
||||
IClient *pClient = hltvserver->GetBaseServer()->GetClient(client - 1);
|
||||
if (!pClient || !pClient->IsConnected())
|
||||
HLTVClientWrapper *pClient = g_HLTVClientManager.GetClient(client);
|
||||
if (!pClient->IsConnected())
|
||||
{
|
||||
pContext->ReportError("Client %d is not connected.", client);
|
||||
return 0;
|
||||
@ -595,7 +643,7 @@ static cell_t Native_KickClient(IPluginContext *pContext, const cell_t *params)
|
||||
char *pReason;
|
||||
pContext->LocalToString(params[2], &pReason);
|
||||
|
||||
hltvserver->GetBaseServer()->DisconnectClient(pClient, pReason);
|
||||
pClient->Kick(pReason);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -626,6 +674,8 @@ const sp_nativeinfo_t sourcetv_natives[] =
|
||||
{ "SourceTV_GetClientCount", Native_GetClientCount },
|
||||
{ "SourceTV_IsClientConnected", Native_IsClientConnected },
|
||||
{ "SourceTV_GetSpectatorName", Native_GetSpectatorName },
|
||||
{ "SourceTV_GetSpectatorIP", Native_GetSpectatorIP },
|
||||
{ "SourceTV_GetSpectatorPassword", Native_GetSpectatorPassword },
|
||||
{ "SourceTV_KickClient", Native_KickClient },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
@ -141,14 +141,15 @@ public Action:Cmd_GetDelay(client, args)
|
||||
public Action:Cmd_Spectators(client, args)
|
||||
{
|
||||
ReplyToCommand(client, "SourceTV spectator count: %d/%d", SourceTV_GetSpectatorCount(), SourceTV_GetClientCount());
|
||||
new String:sName[64];
|
||||
new String:sName[64], String:sIP[16];
|
||||
for (new i=1;i<=SourceTV_GetClientCount();i++)
|
||||
{
|
||||
if (!SourceTV_IsClientConnected(i))
|
||||
continue;
|
||||
|
||||
SourceTV_GetSpectatorName(i, sName, sizeof(sName));
|
||||
ReplyToCommand(client, "Client %d: %s", i, sName);
|
||||
SourceTV_GetSpectatorIP(i, sIP, sizeof(sIP));
|
||||
ReplyToCommand(client, "Client %d: %s - %s", i, sName, sIP);
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
@ -287,6 +287,30 @@ native bool:SourceTV_IsClientConnected(client);
|
||||
*/
|
||||
native SourceTV_GetSpectatorName(client, String:name[], maxlen);
|
||||
|
||||
/**
|
||||
* Get the IP of a SourceTV spectator client.
|
||||
*
|
||||
* @param client The spectator client index.
|
||||
* @param name Buffer for the client ip.
|
||||
* @param maxlen Maximal length of the buffer.
|
||||
* @noreturn
|
||||
* @error Invalid client index or not connected.
|
||||
*/
|
||||
native SourceTV_GetSpectatorIP(client, String:ip[], maxlen);
|
||||
|
||||
/**
|
||||
* Get the password of a SourceTV spectator client.
|
||||
* The password the client tried to connect with.
|
||||
* Ignores changes from the SourceTV_OnSpectatorPreConnect forward.
|
||||
*
|
||||
* @param client The spectator client index.
|
||||
* @param name Buffer for the client ip.
|
||||
* @param maxlen Maximal length of the buffer.
|
||||
* @noreturn
|
||||
* @error Invalid client index or not connected.
|
||||
*/
|
||||
native SourceTV_GetSpectatorPassword(client, String:password[], maxlen);
|
||||
|
||||
/**
|
||||
* Kick a SourceTV spectator client.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user