r5sdk/r5dev/engine/shared/shared_rcon.cpp
Kawe Mazidjatari 179bd31ee6 Initial large refactor of the RCON implementation
* Decoding and encoding is done into a single buffer, from raw buffers to avoid extraneous copies.
* Added base class holding all core logic for encoding, decoding, receiving and processing of the RCON protocol. This code was initially identical between all implementations of RCON, deduplicating this avoids bugs.
* Added more sophisticated error handling, stop right away when decoding for example fails.
* Added ability to have more than one active authenticated net console on the server. Controlled by cvar 'sv_rcon_maxconnections' (default 1).
* Max packet size for accepted, but not authenticated sockets is now controled by cvar 'sv_rcon_maxpacketsize' (default 1024).
2023-04-19 01:35:31 +02:00

115 lines
3.3 KiB
C++

//===========================================================================//
//
// Purpose: Shared rcon utilities.
//
//===========================================================================//
#include "core/stdafx.h"
#include "base_rcon.h"
#include "shared_rcon.h"
//-----------------------------------------------------------------------------
// Purpose: serialize message to vector
// Input : *pBase -
// &vecBuf -
// *szReqBuf -
// *szReqVal -
// *requestType -
// Output : true on success, false otherwise
//-----------------------------------------------------------------------------
bool CL_NetConSerialize(const CNetConBase* pBase, vector<char>& vecBuf, const char* szReqBuf,
const char* szReqVal, const cl_rcon::request_t requestType)
{
cl_rcon::request request;
request.set_messageid(-1);
request.set_requesttype(requestType);
request.set_requestmsg(szReqBuf);
request.set_requestval(szReqVal);
const size_t msgLen = request.ByteSizeLong();
vecBuf.resize(msgLen);
if (!pBase->Encode(&request, &vecBuf[0], msgLen))
{
Error(eDLL_T::CLIENT, NO_ERROR, "Failed to encode RCON buffer\n");
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: attempt to connect to remote
// Input : *pBase -
// *pHostAdr -
// nHostPort -
// Output : true on success, false otherwise
//-----------------------------------------------------------------------------
bool CL_NetConConnect(CNetConBase* pBase, const char* pHostAdr, const int nHostPort)
{
string svLocalHost;
if (nHostPort != -1 && strcmp(pHostAdr, "localhost") == 0)
{
char szHostName[512];
if (!gethostname(szHostName, sizeof(szHostName)))
{
svLocalHost = Format("[%s]:%i", szHostName, nHostPort);
pHostAdr = svLocalHost.c_str();
}
}
CNetAdr* pNetAdr = pBase->GetNetAddress();
if (!pNetAdr->SetFromString(pHostAdr, true))
{
Error(eDLL_T::CLIENT, NO_ERROR, "Failed to set RCON address: %s\n", pHostAdr);
return false;
}
pNetAdr->SetPort(htons(u_short(nHostPort)));
CSocketCreator* pCreator = pBase->GetSocketCreator();
if (pCreator->ConnectSocket(*pNetAdr, true) == SOCKET_ERROR)
{
return false;
}
DevMsg(eDLL_T::CLIENT, "Connected to: %s\n", pNetAdr->ToString());
return true;
}
//-----------------------------------------------------------------------------
// Purpose: gets the netconsole data
// Input : *pBase -
// iSocket -
// Output : nullptr on failure
//-----------------------------------------------------------------------------
CConnectedNetConsoleData* SH_GetNetConData(CNetConBase* pBase, int iSocket)
{
const CSocketCreator* pCreator = pBase->GetSocketCreator();
Assert(iSocket >= 0 && iSocket < pCreator->GetAcceptedSocketCount());
if (!pCreator->GetAcceptedSocketCount())
{
return nullptr;
}
return pCreator->GetAcceptedSocketData(iSocket);
}
//-----------------------------------------------------------------------------
// Purpose: gets the netconsole socket
// Input : *pBase -
// iSocket -
// Output : SOCKET_ERROR (-1) on failure
//-----------------------------------------------------------------------------
SocketHandle_t SH_GetNetConSocketHandle(CNetConBase* pBase, int iSocket)
{
const CConnectedNetConsoleData* pData = SH_GetNetConData(pBase, iSocket);
if (!pData)
{
return SOCKET_ERROR;
}
return pData->m_hSocket;
}