mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
SV_IsClientBanned is now checked after the creating of CClient, and thus 'CServer::AuthClient' has been inlined into 'CServer::ConnectClient'. Since we have to request the master server to check whether or not this particular client is globally banned, we have to detach it into a separate thread, and process the results back into the main thread once finished. This takes too much time, so we connect the client anyways and if the master server marked it as 'banned', we disconnect it right away.
187 lines
6.2 KiB
C++
187 lines
6.2 KiB
C++
//=============================================================================//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//
|
|
//=============================================================================//
|
|
// server.cpp: implementation of the CServer class.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
#include "core/stdafx.h"
|
|
#include "common/protocol.h"
|
|
#include "tier1/cvar.h"
|
|
#include "engine/server/sv_main.h"
|
|
#include "engine/server/server.h"
|
|
#include "networksystem/pylon.h"
|
|
#include "networksystem/bansystem.h"
|
|
#include "ebisusdk/EbisuSDK.h"
|
|
#include "public/edict.h"
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// Purpose: Gets the number of human players on the server
|
|
// Output : int
|
|
//---------------------------------------------------------------------------------
|
|
int CServer::GetNumHumanPlayers(void) const
|
|
{
|
|
int nHumans = 0;
|
|
for (int i = 0; i < g_ServerGlobalVariables->m_nMaxClients; i++)
|
|
{
|
|
CClient* pClient = g_pClient->GetClient(i);
|
|
if (!pClient)
|
|
continue;
|
|
|
|
if (pClient->IsHumanPlayer())
|
|
nHumans++;
|
|
}
|
|
|
|
return nHumans;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// Purpose: Gets the number of fake clients on the server
|
|
// Output : int
|
|
//---------------------------------------------------------------------------------
|
|
int CServer::GetNumFakeClients(void) const
|
|
{
|
|
int nBots = 0;
|
|
for (int i = 0; i < g_ServerGlobalVariables->m_nMaxClients; i++)
|
|
{
|
|
CClient* pClient = g_pClient->GetClient(i);
|
|
if (!pClient)
|
|
continue;
|
|
|
|
if (pClient->IsConnected() && pClient->IsFakeClient())
|
|
nBots++;
|
|
}
|
|
|
|
return nBots;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// Purpose: Gets the number of clients on the server
|
|
// Output : int
|
|
//---------------------------------------------------------------------------------
|
|
int CServer::GetNumClients(void) const
|
|
{
|
|
int nClients = 0;
|
|
for (int i = 0; i < g_ServerGlobalVariables->m_nMaxClients; i++)
|
|
{
|
|
CClient* pClient = g_pClient->GetClient(i);
|
|
if (!pClient)
|
|
continue;
|
|
|
|
if (pClient->IsConnected())
|
|
nClients++;
|
|
}
|
|
|
|
return nClients;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// Purpose: Initializes a CSVClient for a new net connection. This will only be called
|
|
// once for a player each game, not once for each level change.
|
|
// Input : *pServer -
|
|
// *pInpacket -
|
|
// Output : pointer to client instance on success, nullptr on failure
|
|
//---------------------------------------------------------------------------------
|
|
CClient* CServer::ConnectClient(CServer* pServer, user_creds_s* pChallenge)
|
|
{
|
|
if (pServer->m_State < server_state_t::ss_active)
|
|
return nullptr;
|
|
|
|
char* pszPersonaName = pChallenge->personaName;
|
|
uint64_t nNucleusID = pChallenge->personaId;
|
|
|
|
char pszAddresBuffer[128]; // Render the client's address.
|
|
pChallenge->netAdr.ToString(pszAddresBuffer, sizeof(pszAddresBuffer), true);
|
|
|
|
const bool bEnableLogging = sv_showconnecting->GetBool();
|
|
if (bEnableLogging)
|
|
DevMsg(eDLL_T::SERVER, "Processing connectionless challenge for '%s' ('%llu')\n", pszAddresBuffer, nNucleusID);
|
|
|
|
// Only proceed connection if the client's name is valid and UTF-8 encoded.
|
|
if (!VALID_CHARSTAR(pszPersonaName) || !IsValidUTF8(pszPersonaName) || !IsValidPersonaName(pszPersonaName))
|
|
{
|
|
pServer->RejectConnection(pServer->m_Socket, &pChallenge->netAdr, "#Valve_Reject_Invalid_Name");
|
|
if (bEnableLogging)
|
|
Warning(eDLL_T::SERVER, "Connection rejected for '%s' ('%llu' has an invalid name!)\n", pszAddresBuffer, nNucleusID);
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
if (g_pBanSystem->IsBanListValid())
|
|
{
|
|
if (g_pBanSystem->IsBanned(pszAddresBuffer, nNucleusID))
|
|
{
|
|
pServer->RejectConnection(pServer->m_Socket, &pChallenge->netAdr, "#Valve_Reject_Banned");
|
|
if (bEnableLogging)
|
|
Warning(eDLL_T::SERVER, "Connection rejected for '%s' ('%llu' is banned from this server!)\n", pszAddresBuffer, nNucleusID);
|
|
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
CClient* pClient = v_CServer_ConnectClient(pServer, pChallenge);
|
|
|
|
if (pClient && sv_globalBanlist->GetBool())
|
|
{
|
|
std::thread th(SV_IsClientBanned, pClient, string(pszAddresBuffer), nNucleusID, string(pszPersonaName));
|
|
th.detach();
|
|
}
|
|
|
|
return pClient;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// Purpose: Rejects connection request and sends back a message
|
|
// Input : iSocket -
|
|
// *pChallenge -
|
|
// *szMessage -
|
|
//---------------------------------------------------------------------------------
|
|
void CServer::RejectConnection(int iSocket, netadr_t* pNetAdr, const char* szMessage)
|
|
{
|
|
v_CServer_RejectConnection(this, iSocket, pNetAdr, szMessage);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// Purpose: Runs the server frame job
|
|
// Input : flFrameTime -
|
|
// bRunOverlays -
|
|
// bUniformSnapshotInterval -
|
|
//---------------------------------------------------------------------------------
|
|
void CServer::FrameJob(double flFrameTime, bool bRunOverlays, bool bUniformSnapshotInterval)
|
|
{
|
|
v_CServer_FrameJob(flFrameTime, bRunOverlays, bUniformSnapshotInterval);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// Purpose: Runs the server frame
|
|
// Input : *pServer -
|
|
//---------------------------------------------------------------------------------
|
|
void CServer::RunFrame(CServer* pServer)
|
|
{
|
|
v_CServer_RunFrame(pServer);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void VServer::Attach() const
|
|
{
|
|
DetourAttach(&v_CServer_RunFrame, &CServer::RunFrame);
|
|
#if defined(GAMEDLL_S3)
|
|
DetourAttach((LPVOID*)&v_CServer_ConnectClient, &CServer::ConnectClient);
|
|
DetourAttach((LPVOID*)&v_CServer_FrameJob, &CServer::FrameJob);
|
|
#endif // !TODO: S1 and S2 CServer functions require work.
|
|
}
|
|
|
|
void VServer::Detach() const
|
|
{
|
|
DetourDetach(&v_CServer_RunFrame, &CServer::RunFrame);
|
|
#if defined(GAMEDLL_S3)
|
|
DetourDetach((LPVOID*)&v_CServer_ConnectClient, &CServer::ConnectClient);
|
|
DetourDetach((LPVOID*)&v_CServer_FrameJob, &CServer::FrameJob);
|
|
#endif // !TODO: S1 and S2 CServer functions require work.
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
CServer* g_pServer = nullptr; |