mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
RCON system overhaul
* Implemented robust length-prefix framing logic for non-blocking sockets (previously used character sequences to determine length, but you cannot use character sequences on protocol buffers as its binary data. This logic should fix all problems regarding some commands not getting networked properly to the server and stuff not getting printed on the client). * Increased buffer size to std::vector::max_size when netconsole is authenticated (MAX_NETCONSOLE_INPUT_LEN still remains enforced on accepted but not authenticated connections to prevent attackers from crashing the server). * Process max 1024 bytes each recv buffer iteration. * Additional optimizations and cleanup.
This commit is contained in:
parent
5795d15c83
commit
9775fc4bba
@ -30,21 +30,27 @@ enum class ServerDataResponseType_t : int
|
||||
class CConnectedNetConsoleData
|
||||
{
|
||||
public:
|
||||
SocketHandle_t m_hSocket {};
|
||||
int m_nCharsInCommandBuffer {};
|
||||
char m_pszInputCommandBuffer[MAX_NETCONSOLE_INPUT_LEN] {};
|
||||
bool m_bValidated {}; // Revalidates netconsole if false.
|
||||
bool m_bAuthorized {}; // Set to true after netconsole successfully authed.
|
||||
bool m_bInputOnly {}; // If set, don't send spew to this net console.
|
||||
int m_nFailedAttempts {}; // Num failed authentication attempts.
|
||||
int m_nIgnoredMessage {}; // Count how many times client ignored the no-auth message.
|
||||
SocketHandle_t m_hSocket;
|
||||
int m_nPayloadLen; // Num bytes for this message.
|
||||
int m_nPayloadRead; // Num read bytes from input buffer.
|
||||
int m_nFailedAttempts; // Num failed authentication attempts.
|
||||
int m_nIgnoredMessage; // Count how many times client ignored the no-auth message.
|
||||
bool m_bValidated; // Revalidates netconsole if false.
|
||||
bool m_bAuthorized; // Set to true after successfull netconsole auth.
|
||||
bool m_bInputOnly; // If set, don't send spew to this net console.
|
||||
std::vector<uint8_t> m_RecvBuffer;
|
||||
|
||||
CConnectedNetConsoleData(SocketHandle_t hSocket = -1)
|
||||
{
|
||||
m_nCharsInCommandBuffer = 0;
|
||||
m_bAuthorized = false;
|
||||
m_hSocket = hSocket;
|
||||
m_bInputOnly = false;
|
||||
m_hSocket = hSocket;
|
||||
m_nPayloadLen = 0;
|
||||
m_nPayloadRead = 0;
|
||||
m_nFailedAttempts = 0;
|
||||
m_nIgnoredMessage = 0;
|
||||
m_bValidated = false;
|
||||
m_bAuthorized = false;
|
||||
m_bInputOnly = false;
|
||||
m_RecvBuffer.reserve(sizeof(int)); // Reserve enough for length-prefix.
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,9 +11,31 @@
|
||||
#include "protoc/sv_rcon.pb.h"
|
||||
#include "protoc/cl_rcon.pb.h"
|
||||
#include "engine/client/cl_rcon.h"
|
||||
#include "engine/net.h"
|
||||
#include "squirrel/sqvm.h"
|
||||
#include "common/igameserverdata.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CRConClient::CRConClient()
|
||||
: m_bInitialized(false)
|
||||
, m_bConnEstablished(false)
|
||||
{
|
||||
m_pNetAdr2 = new CNetAdr2("localhost", "37015");
|
||||
m_pSocket = new CSocketCreator();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CRConClient::~CRConClient(void)
|
||||
{
|
||||
delete m_pNetAdr2;
|
||||
delete m_pSocket;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: NETCON systems init
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -119,7 +141,7 @@ bool CRConClient::Connect(const std::string& svInAdr, const std::string& svInPor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::Disconnect(void)
|
||||
{
|
||||
::closesocket(m_pSocket->GetAcceptedSocketHandle(0));
|
||||
m_pSocket->CloseAcceptedSocket(0);
|
||||
m_bConnEstablished = false;
|
||||
}
|
||||
|
||||
@ -129,7 +151,16 @@ void CRConClient::Disconnect(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::Send(const std::string& svMessage) const
|
||||
{
|
||||
int nSendResult = ::send(m_pSocket->GetAcceptedSocketData(0)->m_hSocket, svMessage.c_str(), svMessage.size(), MSG_NOSIGNAL);
|
||||
std::ostringstream ssSendBuf;
|
||||
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24);
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16);
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 8 );
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()));
|
||||
ssSendBuf << svMessage;
|
||||
|
||||
int nSendResult = ::send(m_pSocket->GetAcceptedSocketData(0)->m_hSocket,
|
||||
ssSendBuf.str().data(), static_cast<int>(ssSendBuf.str().size()), MSG_NOSIGNAL);
|
||||
if (nSendResult == SOCKET_ERROR)
|
||||
{
|
||||
Warning(eDLL_T::CLIENT, "Failed to send RCON message: (SOCKET_ERROR)\n");
|
||||
@ -141,10 +172,11 @@ void CRConClient::Send(const std::string& svMessage) const
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::Recv(void)
|
||||
{
|
||||
static char szRecvBuf[MAX_NETCONSOLE_INPUT_LEN]{};
|
||||
static char szRecvBuf[1024];
|
||||
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(0);
|
||||
|
||||
{//////////////////////////////////////////////
|
||||
int nPendingLen = ::recv(m_pSocket->GetAcceptedSocketData(0)->m_hSocket, szRecvBuf, sizeof(szRecvBuf), MSG_PEEK);
|
||||
int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
|
||||
if (nPendingLen == SOCKET_ERROR && m_pSocket->IsSocketBlocking())
|
||||
{
|
||||
return;
|
||||
@ -158,13 +190,11 @@ void CRConClient::Recv(void)
|
||||
}//////////////////////////////////////////////
|
||||
|
||||
u_long nReadLen; // Find out how much we have to read.
|
||||
::ioctlsocket(m_pSocket->GetAcceptedSocketData(0)->m_hSocket, FIONREAD, &nReadLen);
|
||||
::ioctlsocket(pData->m_hSocket, FIONREAD, &nReadLen);
|
||||
|
||||
while (nReadLen > 0)
|
||||
{
|
||||
memset(szRecvBuf, '\0', sizeof(szRecvBuf));
|
||||
int nRecvLen = ::recv(m_pSocket->GetAcceptedSocketData(0)->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
|
||||
|
||||
int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
|
||||
if (nRecvLen == 0 && m_bConnEstablished) // Socket was closed.
|
||||
{
|
||||
this->Disconnect();
|
||||
@ -173,50 +203,71 @@ void CRConClient::Recv(void)
|
||||
}
|
||||
if (nRecvLen < 0 && !m_pSocket->IsSocketBlocking())
|
||||
{
|
||||
Error(eDLL_T::CLIENT, "RCON Cmd: recv error (%s)\n", NET_ErrorString(WSAGetLastError()));
|
||||
break;
|
||||
}
|
||||
|
||||
nReadLen -= nRecvLen; // Process what we've got.
|
||||
this->ProcessBuffer(szRecvBuf, nRecvLen);
|
||||
this->ProcessBuffer(szRecvBuf, nRecvLen, pData);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: handles input response buffer
|
||||
// Purpose: parses input response buffer using length-prefix framing
|
||||
// Input : *pszIn -
|
||||
// nRecvLen -
|
||||
// *pData -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::ProcessBuffer(const char* pszIn, int nRecvLen) const
|
||||
void CRConClient::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetConsoleData* pData)
|
||||
{
|
||||
int nCharsInRespondBuffer = 0;
|
||||
char szInputRespondBuffer[MAX_NETCONSOLE_INPUT_LEN]{};
|
||||
|
||||
while (nRecvLen)
|
||||
while (nRecvLen > 0)
|
||||
{
|
||||
switch (*pszIn)
|
||||
if (pData->m_nPayloadLen)
|
||||
{
|
||||
case '\r':
|
||||
{
|
||||
if (nCharsInRespondBuffer)
|
||||
if (pData->m_nPayloadRead < pData->m_nPayloadLen)
|
||||
{
|
||||
sv_rcon::response sv_response = this->Deserialize(szInputRespondBuffer);
|
||||
this->ProcessMessage(sv_response);
|
||||
}
|
||||
nCharsInRespondBuffer = 0;
|
||||
break;
|
||||
}
|
||||
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
|
||||
|
||||
default:
|
||||
{
|
||||
if (nCharsInRespondBuffer < MAX_NETCONSOLE_INPUT_LEN - 1)
|
||||
{
|
||||
szInputRespondBuffer[nCharsInRespondBuffer++] = *pszIn;
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
if (pData->m_nPayloadRead == pData->m_nPayloadLen)
|
||||
{
|
||||
this->ProcessMessage(this->Deserialize(std::string(
|
||||
reinterpret_cast<char*>(pData->m_RecvBuffer.data()), pData->m_nPayloadLen)));
|
||||
|
||||
pData->m_nPayloadLen = 0;
|
||||
pData->m_nPayloadRead = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (pData->m_nPayloadRead < sizeof(int)) // Read size field.
|
||||
{
|
||||
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
|
||||
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
else // Build prefix.
|
||||
{
|
||||
pData->m_nPayloadLen = static_cast<int>(
|
||||
pData->m_RecvBuffer[0] << 24 |
|
||||
pData->m_RecvBuffer[1] << 16 |
|
||||
pData->m_RecvBuffer[2] << 8 |
|
||||
pData->m_RecvBuffer[3]);
|
||||
pData->m_nPayloadRead = 0;
|
||||
|
||||
if (pData->m_nPayloadLen < 0)
|
||||
{
|
||||
Error(eDLL_T::CLIENT, "RCON Cmd: sync error (%d)\n", pData->m_nPayloadLen);
|
||||
this->Disconnect(); // Out of sync (irrecoverable).
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->m_RecvBuffer.resize(pData->m_nPayloadLen);
|
||||
}
|
||||
}
|
||||
pszIn++;
|
||||
nRecvLen--;
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,7 +370,7 @@ std::string CRConClient::Serialize(const std::string& svReqBuf, const std::strin
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cl_request.SerializeAsString().append("\r");
|
||||
return cl_request.SerializeAsString();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -330,7 +381,7 @@ std::string CRConClient::Serialize(const std::string& svReqBuf, const std::strin
|
||||
sv_rcon::response CRConClient::Deserialize(const std::string& svBuf) const
|
||||
{
|
||||
sv_rcon::response sv_response;
|
||||
sv_response.ParseFromArray(svBuf.c_str(), static_cast<int>(svBuf.size()));
|
||||
sv_response.ParseFromArray(svBuf.data(), static_cast<int>(svBuf.size()));
|
||||
|
||||
return sv_response;
|
||||
}
|
||||
|
@ -7,8 +7,8 @@
|
||||
class CRConClient
|
||||
{
|
||||
public:
|
||||
CRConClient(void){};
|
||||
~CRConClient(void) { delete m_pNetAdr2; delete m_pSocket; };
|
||||
CRConClient(void);
|
||||
~CRConClient(void);
|
||||
|
||||
void Init(void);
|
||||
void Shutdown(void);
|
||||
@ -23,7 +23,7 @@ public:
|
||||
void Send(const std::string& svMessage) const;
|
||||
void Recv(void);
|
||||
|
||||
void ProcessBuffer(const char* pszIn, int nRecvLen) const;
|
||||
void ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetConsoleData* pData);
|
||||
void ProcessMessage(const sv_rcon::response& sv_response) const;
|
||||
|
||||
std::string Serialize(const std::string& svReqBuf, const std::string& svReqVal, cl_rcon::request_t request_t) const;
|
||||
@ -33,8 +33,8 @@ public:
|
||||
bool IsConnected(void) const;
|
||||
|
||||
private:
|
||||
CNetAdr2* m_pNetAdr2 = new CNetAdr2("localhost", "37015");
|
||||
CSocketCreator* m_pSocket = new CSocketCreator();
|
||||
CNetAdr2* m_pNetAdr2;
|
||||
CSocketCreator* m_pSocket;
|
||||
|
||||
bool m_bInitialized = false;
|
||||
bool m_bConnEstablished = false;
|
||||
|
@ -10,12 +10,25 @@
|
||||
#include "tier1/IConVar.h"
|
||||
#include "tier1/NetAdr2.h"
|
||||
#include "tier2/socketcreator.h"
|
||||
#include "engine/net.h"
|
||||
#include "engine/server/sv_rcon.h"
|
||||
#include "protoc/sv_rcon.pb.h"
|
||||
#include "protoc/cl_rcon.pb.h"
|
||||
#include "mathlib/sha256.h"
|
||||
#include "common/igameserverdata.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: NETCON systems init
|
||||
//-----------------------------------------------------------------------------
|
||||
CRConServer::CRConServer()
|
||||
: m_bInitialized(false)
|
||||
, m_nConnIndex(0)
|
||||
{
|
||||
m_pAdr2 = new CNetAdr2();
|
||||
m_pSocket = new CSocketCreator();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: NETCON systems init
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -122,32 +135,70 @@ void CRConServer::RunFrame(void)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: send message
|
||||
// Purpose: send message to all connected sockets
|
||||
// Input : *svMessage -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Send(const std::string& svMessage) const
|
||||
{
|
||||
int nCount = m_pSocket->GetAcceptedSocketCount();
|
||||
|
||||
for (int i = nCount - 1; i >= 0; i--)
|
||||
if (int nCount = m_pSocket->GetAcceptedSocketCount())
|
||||
{
|
||||
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(i);
|
||||
std::ostringstream ssSendBuf;
|
||||
|
||||
if (pData->m_bAuthorized)
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24);
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16);
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 8 );
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()));
|
||||
ssSendBuf << svMessage;
|
||||
|
||||
for (int i = nCount - 1; i >= 0; i--)
|
||||
{
|
||||
std::string svFinal = this->Serialize(svMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG);
|
||||
::send(pData->m_hSocket, svFinal.c_str(), static_cast<int>(svFinal.size()), MSG_NOSIGNAL);
|
||||
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(i);
|
||||
|
||||
if (pData->m_bAuthorized)
|
||||
{
|
||||
size_t nMsgCount = (ssSendBuf.str().size() + MAX_NETCONSOLE_INPUT_LEN - 1) / MAX_NETCONSOLE_INPUT_LEN;
|
||||
size_t nDataSize = ssSendBuf.str().size();
|
||||
size_t nPos = 0;
|
||||
|
||||
for (size_t j = 0; j < nMsgCount; j++)
|
||||
{
|
||||
size_t nSize = std::min<uint64_t>(MAX_NETCONSOLE_INPUT_LEN, nDataSize);
|
||||
nDataSize -= nSize;
|
||||
string svFinal = ssSendBuf.str().substr(nPos, nSize);
|
||||
|
||||
::send(pData->m_hSocket, svFinal.data(), static_cast<int>(svFinal.size()), MSG_NOSIGNAL);
|
||||
nPos += nSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: send message to specific connected socket
|
||||
// Input : hSocket -
|
||||
// *svMessage -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Send(SocketHandle_t hSocket, const std::string& svMessage) const
|
||||
{
|
||||
std::ostringstream ssSendBuf;
|
||||
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24);
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16);
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 8 );
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()));
|
||||
ssSendBuf << svMessage;
|
||||
|
||||
::send(hSocket, ssSendBuf.str().data(), static_cast<int>(ssSendBuf.str().size()), MSG_NOSIGNAL);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: receive message
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Recv(void)
|
||||
{
|
||||
int nCount = m_pSocket->GetAcceptedSocketCount();
|
||||
static char szRecvBuf[MAX_NETCONSOLE_INPUT_LEN]{};
|
||||
static char szRecvBuf[1024]{};
|
||||
|
||||
for (m_nConnIndex = nCount - 1; m_nConnIndex >= 0; m_nConnIndex--)
|
||||
{
|
||||
@ -155,13 +206,12 @@ void CRConServer::Recv(void)
|
||||
{//////////////////////////////////////////////
|
||||
if (this->CheckForBan(pData))
|
||||
{
|
||||
std::string svNoAuth = this->Serialize(s_pszBannedMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH);
|
||||
::send(pData->m_hSocket, svNoAuth.c_str(), static_cast<int>(svNoAuth.size()), MSG_NOSIGNAL);
|
||||
this->Send(pData->m_hSocket, this->Serialize(s_pszBannedMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH));
|
||||
this->CloseConnection();
|
||||
continue;
|
||||
}
|
||||
|
||||
int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(szRecvBuf), MSG_PEEK);
|
||||
int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
|
||||
if (nPendingLen == SOCKET_ERROR && m_pSocket->IsSocketBlocking())
|
||||
{
|
||||
continue;
|
||||
@ -178,9 +228,7 @@ void CRConServer::Recv(void)
|
||||
|
||||
while (nReadLen > 0)
|
||||
{
|
||||
memset(szRecvBuf, '\0', sizeof(szRecvBuf));
|
||||
int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
|
||||
|
||||
if (nRecvLen == 0) // Socket was closed.
|
||||
{
|
||||
this->CloseConnection();
|
||||
@ -188,6 +236,7 @@ void CRConServer::Recv(void)
|
||||
}
|
||||
if (nRecvLen < 0 && !m_pSocket->IsSocketBlocking())
|
||||
{
|
||||
Error(eDLL_T::SERVER, "RCON Cmd: recv error (%s)\n", NET_ErrorString(WSAGetLastError()));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -229,7 +278,7 @@ std::string CRConServer::Serialize(const std::string& svRspBuf, const std::strin
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sv_response.SerializeAsString().append("\r");
|
||||
return sv_response.SerializeAsString();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -240,7 +289,7 @@ std::string CRConServer::Serialize(const std::string& svRspBuf, const std::strin
|
||||
cl_rcon::request CRConServer::Deserialize(const std::string& svBuf) const
|
||||
{
|
||||
cl_rcon::request cl_request;
|
||||
cl_request.ParseFromArray(svBuf.c_str(), static_cast<int>(svBuf.size()));
|
||||
cl_request.ParseFromArray(svBuf.data(), static_cast<int>(svBuf.size()));
|
||||
|
||||
return cl_request;
|
||||
}
|
||||
@ -249,9 +298,6 @@ cl_rcon::request CRConServer::Deserialize(const std::string& svBuf) const
|
||||
// Purpose: authenticate new connections
|
||||
// Input : *cl_request -
|
||||
// *pData -
|
||||
// Todo : implement logic for key exchange instead so we never network our
|
||||
// password in plain text over the wire. create a cvar for this so user could
|
||||
// also opt out and use legacy authentication instead for older RCON clients
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Authenticate(const cl_rcon::request& cl_request, CConnectedNetConsoleData* pData)
|
||||
{
|
||||
@ -259,16 +305,15 @@ void CRConServer::Authenticate(const cl_rcon::request& cl_request, CConnectedNet
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
else // Authorize.
|
||||
{
|
||||
if (this->Comparator(cl_request.requestbuf()))
|
||||
{
|
||||
pData->m_bAuthorized = true;
|
||||
m_pSocket->CloseListenSocket();
|
||||
this->CloseNonAuthConnection();
|
||||
|
||||
std::string svAuth = this->Serialize(s_pszAuthMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH);
|
||||
::send(pData->m_hSocket, svAuth.c_str(), static_cast<int>(svAuth.size()), MSG_NOSIGNAL);
|
||||
this->CloseNonAuthConnection();
|
||||
this->Send(pData->m_hSocket, this->Serialize(s_pszAuthMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH));
|
||||
}
|
||||
else // Bad password.
|
||||
{
|
||||
@ -278,8 +323,7 @@ void CRConServer::Authenticate(const cl_rcon::request& cl_request, CConnectedNet
|
||||
DevMsg(eDLL_T::SERVER, "Bad RCON password attempt from '%s'\n", netAdr2.GetIPAndPort().c_str());
|
||||
}
|
||||
|
||||
std::string svWrongPass = this->Serialize(s_pszWrongPwMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH);
|
||||
::send(pData->m_hSocket, svWrongPass.c_str(), static_cast<int>(svWrongPass.size()), MSG_NOSIGNAL);
|
||||
this->Send(pData->m_hSocket, this->Serialize(s_pszWrongPwMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH));
|
||||
|
||||
pData->m_bAuthorized = false;
|
||||
pData->m_bValidated = false;
|
||||
@ -311,38 +355,70 @@ bool CRConServer::Comparator(std::string svPassword) const
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: handles input command buffer
|
||||
// Input : *pszIn -
|
||||
// Purpose: parses input response buffer using length-prefix framing
|
||||
// Input : *pRecvBuf -
|
||||
// nRecvLen -
|
||||
// *pData -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::ProcessBuffer(const char* pszIn, int nRecvLen, CConnectedNetConsoleData* pData)
|
||||
void CRConServer::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetConsoleData* pData)
|
||||
{
|
||||
while (nRecvLen)
|
||||
while (nRecvLen > 0)
|
||||
{
|
||||
switch (*pszIn)
|
||||
if (pData->m_nPayloadLen)
|
||||
{
|
||||
case '\r':
|
||||
{
|
||||
if (pData->m_nCharsInCommandBuffer)
|
||||
if (pData->m_nPayloadRead < pData->m_nPayloadLen)
|
||||
{
|
||||
cl_rcon::request cl_request = this->Deserialize(pData->m_pszInputCommandBuffer);
|
||||
this->ProcessMessage(cl_request);
|
||||
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
|
||||
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
pData->m_nCharsInCommandBuffer = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (pData->m_nCharsInCommandBuffer < MAX_NETCONSOLE_INPUT_LEN - 1)
|
||||
if (pData->m_nPayloadRead == pData->m_nPayloadLen)
|
||||
{
|
||||
pData->m_pszInputCommandBuffer[pData->m_nCharsInCommandBuffer++] = *pszIn;
|
||||
this->ProcessMessage(this->Deserialize(std::string(
|
||||
reinterpret_cast<char*>(pData->m_RecvBuffer.data()), pData->m_nPayloadLen)));
|
||||
|
||||
pData->m_nPayloadLen = 0;
|
||||
pData->m_nPayloadRead = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (pData->m_nPayloadRead < sizeof(int)) // Read size field.
|
||||
{
|
||||
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
|
||||
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
else // Build prefix.
|
||||
{
|
||||
pData->m_nPayloadLen = static_cast<int>(
|
||||
pData->m_RecvBuffer[0] << 24 |
|
||||
pData->m_RecvBuffer[1] << 16 |
|
||||
pData->m_RecvBuffer[2] << 8 |
|
||||
pData->m_RecvBuffer[3]);
|
||||
pData->m_nPayloadRead = 0;
|
||||
|
||||
if (!pData->m_bAuthorized)
|
||||
{
|
||||
if (pData->m_nPayloadLen > MAX_NETCONSOLE_INPUT_LEN)
|
||||
{
|
||||
this->CloseConnection(); // Sending large messages while not authenticated.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pData->m_nPayloadLen < 0)
|
||||
{
|
||||
Error(eDLL_T::SERVER, "RCON Cmd: sync error (%d)\n", pData->m_nPayloadLen);
|
||||
this->CloseConnection(); // Out of sync (irrecoverable).
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->m_RecvBuffer.resize(pData->m_nPayloadLen);
|
||||
}
|
||||
}
|
||||
pszIn++;
|
||||
nRecvLen--;
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,8 +434,7 @@ void CRConServer::ProcessMessage(const cl_rcon::request& cl_request)
|
||||
&& cl_request.requesttype() != cl_rcon::request_t::SERVERDATA_REQUEST_AUTH)
|
||||
{
|
||||
// Notify net console that authentication is required.
|
||||
std::string svMessage = this->Serialize(s_pszNoAuthMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH);
|
||||
::send(pData->m_hSocket, svMessage.c_str(), static_cast<int>(svMessage.size()), MSG_NOSIGNAL);
|
||||
this->Send(pData->m_hSocket, this->Serialize(s_pszNoAuthMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH));
|
||||
|
||||
pData->m_bValidated = false;
|
||||
pData->m_nIgnoredMessage++;
|
||||
@ -373,12 +448,18 @@ void CRConServer::ProcessMessage(const cl_rcon::request& cl_request)
|
||||
break;
|
||||
}
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND:
|
||||
{
|
||||
if (pData->m_bAuthorized) // Only execute if auth was succesfull.
|
||||
{
|
||||
this->Execute(cl_request, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_SETVALUE:
|
||||
{
|
||||
// Only execute if auth was succesfull.
|
||||
if (pData->m_bAuthorized)
|
||||
{
|
||||
this->Execute(cl_request);
|
||||
this->Execute(cl_request, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -400,15 +481,16 @@ void CRConServer::ProcessMessage(const cl_rcon::request& cl_request)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: execute commands issued from net console
|
||||
// Input : *cl_request -
|
||||
// bConVar -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Execute(const cl_rcon::request& cl_request) const
|
||||
void CRConServer::Execute(const cl_rcon::request& cl_request, bool bConVar) const
|
||||
{
|
||||
ConVar* pConVar = g_pCVar->FindVar(cl_request.requestbuf().c_str());
|
||||
if (pConVar)
|
||||
if (pConVar) // Set value without running the callback.
|
||||
{
|
||||
pConVar->SetValue(cl_request.requestval().c_str());
|
||||
}
|
||||
else // Execute command with "<val>".
|
||||
else if (!bConVar) // Execute command with "<val>".
|
||||
{
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), cl_request.requestbuf().c_str(), cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_Execute();
|
||||
|
@ -4,14 +4,15 @@
|
||||
#include "protoc/sv_rcon.pb.h"
|
||||
#include "protoc/cl_rcon.pb.h"
|
||||
|
||||
constexpr char s_pszNoAuthMessage[] = "This server is password protected for console access. Must send 'PASS <password>' command.\n\r";
|
||||
constexpr char s_pszWrongPwMessage[] = "Password incorrect.\n\r";
|
||||
constexpr char s_pszBannedMessage[] = "Go away.\n\r";
|
||||
constexpr char s_pszAuthMessage[] = "RCON authentication succesfull.\n\r";
|
||||
constexpr char s_pszNoAuthMessage[] = "This server is password protected for console access. Authenticate with 'PASS <password>' command.\n";
|
||||
constexpr char s_pszWrongPwMessage[] = "Admin password incorrect.\n";
|
||||
constexpr char s_pszBannedMessage[] = "Go away.\n";
|
||||
constexpr char s_pszAuthMessage[] = "RCON authentication successfull.\n";
|
||||
|
||||
class CRConServer
|
||||
{
|
||||
public:
|
||||
CRConServer();
|
||||
~CRConServer() { delete m_pAdr2; delete m_pSocket; }
|
||||
|
||||
void Init(void);
|
||||
@ -22,6 +23,7 @@ public:
|
||||
void RunFrame(void);
|
||||
|
||||
void Send(const std::string& svMessage) const;
|
||||
void Send(SocketHandle_t hSocket, const std::string& svMessage) const;
|
||||
void Recv(void);
|
||||
|
||||
std::string Serialize(const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t response_t) const;
|
||||
@ -33,7 +35,7 @@ public:
|
||||
void ProcessBuffer(const char* pszIn, int nRecvLen, CConnectedNetConsoleData* pData);
|
||||
void ProcessMessage(const cl_rcon::request& cl_request);
|
||||
|
||||
void Execute(const cl_rcon::request& cl_request) const;
|
||||
void Execute(const cl_rcon::request& cl_request, bool bConVar) const;
|
||||
bool CheckForBan(CConnectedNetConsoleData* pData);
|
||||
|
||||
void CloseConnection(void);
|
||||
@ -41,10 +43,10 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
bool m_bInitialized = false;
|
||||
int m_nConnIndex = 0;
|
||||
CNetAdr2* m_pAdr2 = new CNetAdr2();
|
||||
CSocketCreator* m_pSocket = new CSocketCreator();
|
||||
bool m_bInitialized;
|
||||
int m_nConnIndex;
|
||||
CNetAdr2* m_pAdr2;
|
||||
CSocketCreator* m_pSocket;
|
||||
std::vector<std::string> m_vBannedAddress;
|
||||
std::string m_svPasswordHash;
|
||||
};
|
||||
|
@ -14,6 +14,29 @@
|
||||
#include "engine/net.h"
|
||||
#include "netconsole/netconsole.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CNetCon::CNetCon(void)
|
||||
: m_bInitialized(false)
|
||||
, m_bNoColor(false)
|
||||
, m_bQuitApplication(false)
|
||||
, m_abPromptConnect(true)
|
||||
, m_abConnEstablished(false)
|
||||
{
|
||||
m_pNetAdr2 = new CNetAdr2("localhost", "37015");
|
||||
m_pSocket = new CSocketCreator();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CNetCon::~CNetCon(void)
|
||||
{
|
||||
delete m_pNetAdr2;
|
||||
delete m_pSocket;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: WSA and NETCON systems init
|
||||
// Output : true on success, false otherwise
|
||||
@ -127,9 +150,6 @@ void CNetCon::UserInput(void)
|
||||
{
|
||||
if (vSubStrings.size() > 2)
|
||||
{
|
||||
printf("%s\n", vSubStrings[1].c_str());
|
||||
printf("%s\n", vSubStrings[2].c_str());
|
||||
|
||||
std::string svSerialized = this->Serialize(vSubStrings[1], vSubStrings[2], cl_rcon::request_t::SERVERDATA_REQUEST_SETVALUE);
|
||||
this->Send(svSerialized);
|
||||
}
|
||||
@ -236,8 +256,8 @@ bool CNetCon::Connect(const std::string& svInAdr, const std::string& svInPort)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetCon::Disconnect(void)
|
||||
{
|
||||
::closesocket(m_pSocket->GetAcceptedSocketHandle(0));
|
||||
m_abPromptConnect = true;
|
||||
m_pSocket->CloseAcceptedSocket(0);
|
||||
m_abPromptConnect = true;
|
||||
m_abConnEstablished = false;
|
||||
}
|
||||
|
||||
@ -247,7 +267,16 @@ void CNetCon::Disconnect(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetCon::Send(const std::string& svMessage) const
|
||||
{
|
||||
int nSendResult = ::send(m_pSocket->GetAcceptedSocketData(0)->m_hSocket, svMessage.c_str(), svMessage.size(), MSG_NOSIGNAL);
|
||||
std::ostringstream ssSendBuf;
|
||||
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24);
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16);
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 8 );
|
||||
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()));
|
||||
ssSendBuf << svMessage;
|
||||
|
||||
int nSendResult = ::send(m_pSocket->GetAcceptedSocketData(0)->m_hSocket,
|
||||
ssSendBuf.str().data(), static_cast<int>(ssSendBuf.str().size()), MSG_NOSIGNAL);
|
||||
if (nSendResult == SOCKET_ERROR)
|
||||
{
|
||||
std::cout << "Failed to send message: (SOCKET_ERROR)" << std::endl;
|
||||
@ -259,10 +288,11 @@ void CNetCon::Send(const std::string& svMessage) const
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetCon::Recv(void)
|
||||
{
|
||||
static char szRecvBuf[MAX_NETCONSOLE_INPUT_LEN]{};
|
||||
static char szRecvBuf[1024];
|
||||
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(0);
|
||||
|
||||
{//////////////////////////////////////////////
|
||||
int nPendingLen = ::recv(m_pSocket->GetAcceptedSocketData(0)->m_hSocket, szRecvBuf, sizeof(szRecvBuf), MSG_PEEK);
|
||||
int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
|
||||
if (nPendingLen == SOCKET_ERROR && m_pSocket->IsSocketBlocking())
|
||||
{
|
||||
return;
|
||||
@ -276,13 +306,11 @@ void CNetCon::Recv(void)
|
||||
}//////////////////////////////////////////////
|
||||
|
||||
u_long nReadLen; // Find out how much we have to read.
|
||||
::ioctlsocket(m_pSocket->GetAcceptedSocketData(0)->m_hSocket, FIONREAD, &nReadLen);
|
||||
::ioctlsocket(pData->m_hSocket, FIONREAD, &nReadLen);
|
||||
|
||||
while (nReadLen > 0)
|
||||
{
|
||||
memset(szRecvBuf, '\0', sizeof(szRecvBuf));
|
||||
int nRecvLen = ::recv(m_pSocket->GetAcceptedSocketData(0)->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
|
||||
|
||||
int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
|
||||
if (nRecvLen == 0 && m_abConnEstablished) // Socket was closed.
|
||||
{
|
||||
this->Disconnect();
|
||||
@ -291,50 +319,71 @@ void CNetCon::Recv(void)
|
||||
}
|
||||
if (nRecvLen < 0 && !m_pSocket->IsSocketBlocking())
|
||||
{
|
||||
std::cout << "RCON Cmd: recv error (" << NET_ErrorString(WSAGetLastError()) << ")" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
nReadLen -= nRecvLen; // Process what we've got.
|
||||
this->ProcessBuffer(szRecvBuf, nRecvLen);
|
||||
this->ProcessBuffer(szRecvBuf, nRecvLen, pData);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: handles input response buffer
|
||||
// Input : *pszIn -
|
||||
// Purpose: parses input response buffer using length-prefix framing
|
||||
// Input : *pRecvBuf -
|
||||
// nRecvLen -
|
||||
// *pData -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetCon::ProcessBuffer(const char* pszIn, int nRecvLen) const
|
||||
void CNetCon::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetConsoleData* pData)
|
||||
{
|
||||
int nCharsInRespondBuffer = 0;
|
||||
char szInputRespondBuffer[MAX_NETCONSOLE_INPUT_LEN]{};
|
||||
|
||||
while (nRecvLen)
|
||||
while (nRecvLen > 0)
|
||||
{
|
||||
switch (*pszIn)
|
||||
if (pData->m_nPayloadLen)
|
||||
{
|
||||
case '\r':
|
||||
{
|
||||
if (nCharsInRespondBuffer)
|
||||
if (pData->m_nPayloadRead < pData->m_nPayloadLen)
|
||||
{
|
||||
sv_rcon::response sv_response = this->Deserialize(szInputRespondBuffer);
|
||||
this->ProcessMessage(sv_response);
|
||||
}
|
||||
nCharsInRespondBuffer = 0;
|
||||
break;
|
||||
}
|
||||
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
|
||||
|
||||
default:
|
||||
{
|
||||
if (nCharsInRespondBuffer < MAX_NETCONSOLE_INPUT_LEN - 1)
|
||||
{
|
||||
szInputRespondBuffer[nCharsInRespondBuffer++] = *pszIn;
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
if (pData->m_nPayloadRead == pData->m_nPayloadLen)
|
||||
{
|
||||
this->ProcessMessage(this->Deserialize(std::string(
|
||||
reinterpret_cast<char*>(pData->m_RecvBuffer.data()), pData->m_nPayloadLen)));
|
||||
|
||||
pData->m_nPayloadLen = 0;
|
||||
pData->m_nPayloadRead = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (pData->m_nPayloadRead < sizeof(int)) // Read size field.
|
||||
{
|
||||
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
|
||||
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
else // Build prefix.
|
||||
{
|
||||
pData->m_nPayloadLen = static_cast<int>(
|
||||
pData->m_RecvBuffer[0] << 24 |
|
||||
pData->m_RecvBuffer[1] << 16 |
|
||||
pData->m_RecvBuffer[2] << 8 |
|
||||
pData->m_RecvBuffer[3]);
|
||||
pData->m_nPayloadRead = 0;
|
||||
|
||||
if (pData->m_nPayloadLen < 0)
|
||||
{
|
||||
std::cout << "RCON Cmd: sync error (" << pData->m_nPayloadLen << ")" << std::endl;
|
||||
this->Disconnect(); // Out of sync (irrecoverable).
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->m_RecvBuffer.resize(pData->m_nPayloadLen);
|
||||
}
|
||||
}
|
||||
pszIn++;
|
||||
nRecvLen--;
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,25 +396,25 @@ void CNetCon::ProcessMessage(const sv_rcon::response& sv_response) const
|
||||
static std::regex rxAnsiExp("\\\033\\[.*?m");
|
||||
switch (sv_response.responsetype())
|
||||
{
|
||||
case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH:
|
||||
case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG:
|
||||
case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH:
|
||||
case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG:
|
||||
{
|
||||
std::string svOut = sv_response.responsebuf();
|
||||
if (m_bNoColor)
|
||||
{
|
||||
std::string svOut = sv_response.responsebuf();
|
||||
if (m_bNoColor)
|
||||
{
|
||||
svOut = std::regex_replace(svOut, rxAnsiExp, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
svOut.append(g_svReset.c_str());
|
||||
}
|
||||
std::cout << svOut.c_str();
|
||||
break;
|
||||
svOut = std::regex_replace(svOut, rxAnsiExp, "");
|
||||
}
|
||||
default:
|
||||
else
|
||||
{
|
||||
break;
|
||||
svOut.append(g_svReset);
|
||||
}
|
||||
std::cout << svOut;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,20 +434,20 @@ std::string CNetCon::Serialize(const std::string& svReqBuf, const std::string& s
|
||||
|
||||
switch (request_t)
|
||||
{
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_SETVALUE:
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_AUTH:
|
||||
{
|
||||
cl_request.set_requestbuf(svReqBuf);
|
||||
cl_request.set_requestval(svReqVal);
|
||||
break;
|
||||
}
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND:
|
||||
{
|
||||
cl_request.set_requestbuf(svReqBuf);
|
||||
break;
|
||||
}
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_SETVALUE:
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_AUTH:
|
||||
{
|
||||
cl_request.set_requestbuf(svReqBuf);
|
||||
cl_request.set_requestval(svReqVal);
|
||||
break;
|
||||
}
|
||||
return cl_request.SerializeAsString().append("\r");
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND:
|
||||
{
|
||||
cl_request.set_requestbuf(svReqBuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cl_request.SerializeAsString();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -409,7 +458,7 @@ std::string CNetCon::Serialize(const std::string& svReqBuf, const std::string& s
|
||||
sv_rcon::response CNetCon::Deserialize(const std::string& svBuf) const
|
||||
{
|
||||
sv_rcon::response sv_response;
|
||||
sv_response.ParseFromArray(svBuf.c_str(), static_cast<int>(svBuf.size()));
|
||||
sv_response.ParseFromArray(svBuf.data(), static_cast<int>(svBuf.size()));
|
||||
|
||||
return sv_response;
|
||||
}
|
||||
|
@ -12,7 +12,8 @@ constexpr const char* NETCON_VERSION = "2.0.0.1";
|
||||
class CNetCon
|
||||
{
|
||||
public:
|
||||
~CNetCon() { delete m_pNetAdr2; delete m_pSocket; }
|
||||
CNetCon(void);
|
||||
~CNetCon(void);
|
||||
|
||||
bool Init(void);
|
||||
bool Shutdown(void);
|
||||
@ -29,19 +30,19 @@ public:
|
||||
void Send(const std::string& svMessage) const;
|
||||
void Recv(void);
|
||||
|
||||
void ProcessBuffer(const char* pszIn, int nRecvLen) const;
|
||||
void ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetConsoleData* pData);
|
||||
void ProcessMessage(const sv_rcon::response& sv_response) const;
|
||||
|
||||
std::string Serialize(const std::string& svReqBuf, const std::string& svReqVal, cl_rcon::request_t request_t) const;
|
||||
sv_rcon::response Deserialize(const std::string& svBuf) const;
|
||||
|
||||
private:
|
||||
CNetAdr2* m_pNetAdr2 = new CNetAdr2("localhost", "37015");
|
||||
CSocketCreator* m_pSocket = new CSocketCreator();
|
||||
CNetAdr2* m_pNetAdr2;
|
||||
CSocketCreator* m_pSocket;
|
||||
|
||||
bool m_bInitialized = false;
|
||||
bool m_bNoColor = false;
|
||||
bool m_bQuitApplication = false;
|
||||
std::atomic<bool> m_abPromptConnect{ true };
|
||||
std::atomic<bool> m_abConnEstablished{ false };
|
||||
bool m_bInitialized;
|
||||
bool m_bNoColor;
|
||||
bool m_bQuitApplication;
|
||||
std::atomic<bool> m_abPromptConnect;
|
||||
std::atomic<bool> m_abConnEstablished;
|
||||
};
|
@ -89,7 +89,7 @@ SQRESULT SQVM_PrintFunc(HSQUIRRELVM v, SQChar* fmt, ...)
|
||||
{
|
||||
wconsole->debug(vmStr);
|
||||
#ifdef DEDICATED
|
||||
RCONServer()->Send(vmStr);
|
||||
RCONServer()->Send(RCONServer()->Serialize(vmStr, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG));
|
||||
#endif // DEDICATED
|
||||
}
|
||||
else
|
||||
@ -135,7 +135,7 @@ SQRESULT SQVM_PrintFunc(HSQUIRRELVM v, SQChar* fmt, ...)
|
||||
vmStrAnsi.append(buf);
|
||||
wconsole->debug(vmStrAnsi);
|
||||
#ifdef DEDICATED
|
||||
RCONServer()->Send(vmStrAnsi);
|
||||
RCONServer()->Send(RCONServer()->Serialize(vmStrAnsi, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG));
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
@ -229,7 +229,7 @@ SQRESULT SQVM_WarningFunc(HSQUIRRELVM v, SQInteger a2, SQInteger a3, SQInteger*
|
||||
{
|
||||
wconsole->debug(vmStr);
|
||||
#ifdef DEDICATED
|
||||
RCONServer()->Send(vmStr);
|
||||
RCONServer()->Send(RCONServer()->Serialize(vmStr, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG));
|
||||
#endif // DEDICATED
|
||||
}
|
||||
else
|
||||
@ -239,7 +239,7 @@ SQRESULT SQVM_WarningFunc(HSQUIRRELVM v, SQInteger a2, SQInteger a3, SQInteger*
|
||||
vmStrAnsi.append(svConstructor);
|
||||
wconsole->debug(vmStrAnsi);
|
||||
#ifdef DEDICATED
|
||||
RCONServer()->Send(vmStrAnsi);
|
||||
RCONServer()->Send(RCONServer()->Serialize(vmStrAnsi, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG));
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ void DevMsg(eDLL_T context, const char* fmt, ...)
|
||||
{
|
||||
wconsole->debug(svOut);
|
||||
#ifdef DEDICATED
|
||||
RCONServer()->Send(svOut);
|
||||
RCONServer()->Send(RCONServer()->Serialize(svOut, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG));
|
||||
#endif // DEDICATED
|
||||
}
|
||||
else
|
||||
@ -147,7 +147,7 @@ void DevMsg(eDLL_T context, const char* fmt, ...)
|
||||
}
|
||||
wconsole->debug(svAnsiOut);
|
||||
#ifdef DEDICATED
|
||||
RCONServer()->Send(svAnsiOut);
|
||||
RCONServer()->Send(RCONServer()->Serialize(svAnsiOut, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG));
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
@ -240,7 +240,7 @@ void Warning(eDLL_T context, const char* fmt, ...)
|
||||
{
|
||||
wconsole->debug(svOut);
|
||||
#ifdef DEDICATED
|
||||
RCONServer()->Send(svOut);
|
||||
RCONServer()->Send(RCONServer()->Serialize(svOut, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG));
|
||||
#endif // DEDICATED
|
||||
}
|
||||
else
|
||||
@ -256,7 +256,7 @@ void Warning(eDLL_T context, const char* fmt, ...)
|
||||
}
|
||||
wconsole->debug(svAnsiOut);
|
||||
#ifdef DEDICATED
|
||||
RCONServer()->Send(svAnsiOut);
|
||||
RCONServer()->Send(RCONServer()->Serialize(svAnsiOut, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG));
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
@ -317,7 +317,7 @@ void Error(eDLL_T context, const char* fmt, ...)
|
||||
{
|
||||
wconsole->debug(svOut);
|
||||
#ifdef DEDICATED
|
||||
RCONServer()->Send(svOut);
|
||||
RCONServer()->Send(RCONServer()->Serialize(svOut, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG));
|
||||
#endif // DEDICATED
|
||||
}
|
||||
else
|
||||
@ -333,7 +333,7 @@ void Error(eDLL_T context, const char* fmt, ...)
|
||||
}
|
||||
wconsole->debug(svAnsiOut);
|
||||
#ifdef DEDICATED
|
||||
RCONServer()->Send(svAnsiOut);
|
||||
RCONServer()->Send(RCONServer()->Serialize(svAnsiOut, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG));
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
|
@ -303,6 +303,8 @@ void CSocketCreator::CloseAcceptedSocket(int nIndex)
|
||||
|
||||
AcceptedSocket_t& connected = m_hAcceptedSockets[nIndex];
|
||||
::closesocket(connected.m_hSocket);
|
||||
delete connected.m_pData;
|
||||
|
||||
m_hAcceptedSockets.erase(m_hAcceptedSockets.begin() + nIndex);
|
||||
}
|
||||
|
||||
@ -315,6 +317,8 @@ void CSocketCreator::CloseAllAcceptedSockets(void)
|
||||
{
|
||||
AcceptedSocket_t& connected = m_hAcceptedSockets[i];
|
||||
::closesocket(connected.m_hSocket);
|
||||
|
||||
delete connected.m_pData;
|
||||
}
|
||||
m_hAcceptedSockets.clear();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user