r5sdk/r5dev/engine/client/cl_rcon.cpp
Kawe Mazidjatari 75ccebb4b6 Squirrel system restructure
Properly decouple squirrel and game code. This makes it easier to reverse engineer more of this squirrel system, and to compile them as individual libraries later on when moving to CMake to significantly decrease compile times.
2023-05-06 16:23:56 +02:00

208 lines
6.0 KiB
C++

//===========================================================================//
//
// Purpose: Implementation of the rcon client.
//
//===========================================================================//
#include "core/stdafx.h"
#include "tier1/cmd.h"
#include "tier1/cvar.h"
#include "protoc/sv_rcon.pb.h"
#include "protoc/cl_rcon.pb.h"
#include "engine/client/cl_rcon.h"
#include "engine/shared/shared_rcon.h"
#include "engine/net.h"
#include "vscript/languages/squirrel_re/include/sqvm.h"
#include "common/igameserverdata.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CRConClient::CRConClient()
: m_bInitialized(false)
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CRConClient::~CRConClient(void)
{
}
//-----------------------------------------------------------------------------
// Purpose: NETCON systems init
//-----------------------------------------------------------------------------
void CRConClient::Init(void)
{
m_bInitialized = true;
}
//-----------------------------------------------------------------------------
// Purpose: NETCON systems shutdown
//-----------------------------------------------------------------------------
void CRConClient::Shutdown(void)
{
Disconnect("shutdown");
}
//-----------------------------------------------------------------------------
// Purpose: client rcon main processing loop
//-----------------------------------------------------------------------------
void CRConClient::RunFrame(void)
{
if (IsInitialized() && IsConnected())
{
CConnectedNetConsoleData* pData = GetData();
Assert(pData != nullptr);
if (pData)
{
Recv(pData);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: disconnect from current session
//-----------------------------------------------------------------------------
void CRConClient::Disconnect(const char* szReason)
{
if (IsConnected())
{
if (!szReason)
{
szReason = "unknown reason";
}
DevMsg(eDLL_T::CLIENT, "Disconnect: (%s)\n", szReason);
m_Socket.CloseAcceptedSocket(0);
}
}
//-----------------------------------------------------------------------------
// Purpose: processes received message
// Input : *pMsgBug -
// nMsgLen -
//-----------------------------------------------------------------------------
bool CRConClient::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
{
sv_rcon::response response;
bool bSuccess = Decode(&response, pMsgBuf, nMsgLen);
if (!bSuccess)
{
Error(eDLL_T::CLIENT, NO_ERROR, "Failed to decode RCON buffer\n");
return false;
}
switch (response.responsetype())
{
case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH:
{
if (!response.responseval().empty())
{
const long i = strtol(response.responseval().c_str(), NULL, NULL);
const bool bLocalHost = (g_pNetAdr->ComparePort(m_Address) && g_pNetAdr->CompareAdr(m_Address));
const char* szEnable = nullptr;
const SocketHandle_t hSocket = GetSocket();
if (!i) // sv_rcon_sendlogs is not set.
{
if (!bLocalHost && cl_rcon_request_sendlogs->GetBool())
{
szEnable = "1";
}
}
else if (bLocalHost)
{
// Don't send logs to local host, it already gets logged to the same console.
szEnable = "0";
}
if (szEnable)
{
vector<char> vecMsg;
bool ret = Serialize(vecMsg, "", szEnable, cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
if (ret && !Send(hSocket, vecMsg.data(), int(vecMsg.size())))
{
Error(eDLL_T::CLIENT, NO_ERROR, "Failed to send RCON message: (%s)\n", "SOCKET_ERROR");
}
}
}
DevMsg(eDLL_T::NETCON, "%s", response.responsemsg().c_str());
break;
}
case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG:
{
NetMsg(static_cast<LogType_t>(response.messagetype()),
static_cast<eDLL_T>(response.messageid()),
response.responseval().c_str(), "%s", response.responsemsg().c_str());
break;
}
default:
{
break;
}
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: serializes input
// Input : *svReqBuf -
// *svReqVal -
// request_t -
// Output : serialized results as string
//-----------------------------------------------------------------------------
bool CRConClient::Serialize(vector<char>& vecBuf, const char* szReqBuf,
const char* szReqVal, const cl_rcon::request_t requestType) const
{
return CL_NetConSerialize(this, vecBuf, szReqBuf, szReqVal, requestType);
}
//-----------------------------------------------------------------------------
// Purpose: retrieves the remote socket
// Output : SOCKET_ERROR (-1) on failure
//-----------------------------------------------------------------------------
CConnectedNetConsoleData* CRConClient::GetData(void)
{
return SH_GetNetConData(this, 0);
}
//-----------------------------------------------------------------------------
// Purpose: retrieves the remote socket
// Output : SOCKET_ERROR (-1) on failure
//-----------------------------------------------------------------------------
SocketHandle_t CRConClient::GetSocket(void)
{
return SH_GetNetConSocketHandle(this, 0);
}
//-----------------------------------------------------------------------------
// Purpose: checks if client rcon is initialized
//-----------------------------------------------------------------------------
bool CRConClient::IsInitialized(void) const
{
return m_bInitialized;
}
//-----------------------------------------------------------------------------
// Purpose: returns whether the rcon client is connected
//-----------------------------------------------------------------------------
bool CRConClient::IsConnected(void)
{
return (GetSocket() != SOCKET_ERROR);
}
///////////////////////////////////////////////////////////////////////////////
CRConClient* g_RCONClient(new CRConClient());
CRConClient* RCONClient() // Singleton RCON Client.
{
return g_RCONClient;
}