RCON system light refactor

* Used 'htonl'/'ntohl' for constructing the length prefix.
* Used static socket/address members instead of pointers.
* Used const qualifier where possible.
* Changed length prefix field type to 'u_long'.
* Removed extraneous include.
* Properly escaped percentage characters on the RCON game client for the ImGui console.
This commit is contained in:
Kawe Mazidjatari 2022-11-14 21:00:41 +01:00
parent 9533afc628
commit 4b1c5dd5a3
8 changed files with 148 additions and 170 deletions

View File

@ -31,14 +31,14 @@ class CConnectedNetConsoleData
{ {
public: public:
SocketHandle_t m_hSocket; SocketHandle_t m_hSocket;
int m_nPayloadLen; // Num bytes for this message. u_long m_nPayloadLen; // Num bytes for this message.
int m_nPayloadRead; // Num read bytes from input buffer. u_long m_nPayloadRead; // Num read bytes from input buffer.
int m_nFailedAttempts; // Num failed authentication attempts. int m_nFailedAttempts; // Num failed authentication attempts.
int m_nIgnoredMessage; // Count how many times client ignored the no-auth message. int m_nIgnoredMessage; // Count how many times client ignored the no-auth message.
bool m_bValidated; // Revalidates netconsole if false. bool m_bValidated; // Revalidates netconsole if false.
bool m_bAuthorized; // Set to true after successful netconsole auth. bool m_bAuthorized; // Set to true after successful netconsole auth.
bool m_bInputOnly; // If set, don't send spew to this net console. bool m_bInputOnly; // If set, don't send spew to this net console.
std::vector<uint8_t> m_RecvBuffer; vector<uint8_t> m_RecvBuffer;
CConnectedNetConsoleData(SocketHandle_t hSocket = -1) CConnectedNetConsoleData(SocketHandle_t hSocket = -1)
{ {
@ -50,7 +50,7 @@ public:
m_bValidated = false; m_bValidated = false;
m_bAuthorized = false; m_bAuthorized = false;
m_bInputOnly = false; m_bInputOnly = false;
m_RecvBuffer.resize(sizeof(int)); // Reserve enough for length-prefix. m_RecvBuffer.resize(sizeof(u_long)); // Reserve enough for length-prefix.
} }
}; };

View File

@ -22,9 +22,8 @@
CRConClient::CRConClient() CRConClient::CRConClient()
: m_bInitialized(false) : m_bInitialized(false)
, m_bConnEstablished(false) , m_bConnEstablished(false)
, m_NetAdr2("localhost", "37015")
{ {
m_pNetAdr2 = new CNetAdr2("localhost", "37015");
m_pSocket = new CSocketCreator();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -32,8 +31,6 @@ CRConClient::CRConClient()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
CRConClient::~CRConClient(void) CRConClient::~CRConClient(void)
{ {
delete m_pNetAdr2;
delete m_pSocket;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -66,7 +63,7 @@ void CRConClient::Shutdown(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConClient::SetPassword(const char* pszPassword) bool CRConClient::SetPassword(const char* pszPassword)
{ {
size_t nLen = std::strlen(pszPassword); const size_t nLen = std::strlen(pszPassword);
if (nLen < 8) if (nLen < 8)
{ {
if (nLen > 0) if (nLen > 0)
@ -98,15 +95,15 @@ bool CRConClient::Connect(void)
if (strlen(rcon_address->GetString()) > 0) if (strlen(rcon_address->GetString()) > 0)
{ {
// Default is [127.0.0.1]:37015 // Default is [127.0.0.1]:37015
m_pNetAdr2->SetIPAndPort(rcon_address->GetString()); m_NetAdr2.SetIPAndPort(rcon_address->GetString());
} }
if (m_pSocket->ConnectSocket(*m_pNetAdr2, true) == SOCKET_ERROR) if (m_Socket.ConnectSocket(m_NetAdr2, true) == SOCKET_ERROR)
{ {
Warning(eDLL_T::CLIENT, "Connection to RCON server failed: (SOCKET_ERROR)\n"); Warning(eDLL_T::CLIENT, "Connection to RCON server failed: (%s)\n", "SOCKET_ERROR");
return false; return false;
} }
DevMsg(eDLL_T::CLIENT, "Connected to: %s\n", m_pNetAdr2->GetIPAndPort().c_str()); DevMsg(eDLL_T::CLIENT, "Connected to: %s\n", m_NetAdr2.GetIPAndPort().c_str());
m_bConnEstablished = true; m_bConnEstablished = true;
return true; return true;
@ -123,15 +120,15 @@ bool CRConClient::Connect(const std::string& svInAdr, const std::string& svInPor
if (!svInAdr.empty() && !svInPort.empty()) if (!svInAdr.empty() && !svInPort.empty())
{ {
// Default is [127.0.0.1]:37015 // Default is [127.0.0.1]:37015
m_pNetAdr2->SetIPAndPort(svInAdr, svInPort); m_NetAdr2.SetIPAndPort(svInAdr, svInPort);
} }
if (m_pSocket->ConnectSocket(*m_pNetAdr2, true) == SOCKET_ERROR) if (m_Socket.ConnectSocket(m_NetAdr2, true) == SOCKET_ERROR)
{ {
Warning(eDLL_T::CLIENT, "Connection to RCON server failed: (SOCKET_ERROR)\n"); Warning(eDLL_T::CLIENT, "Connection to RCON server failed: (%s)\n", "SOCKET_ERROR");
return false; return false;
} }
DevMsg(eDLL_T::CLIENT, "Connected to: %s\n", m_pNetAdr2->GetIPAndPort().c_str()); DevMsg(eDLL_T::CLIENT, "Connected to: %s\n", m_NetAdr2.GetIPAndPort().c_str());
m_bConnEstablished = true; m_bConnEstablished = true;
return true; return true;
@ -142,7 +139,7 @@ bool CRConClient::Connect(const std::string& svInAdr, const std::string& svInPor
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConClient::Disconnect(void) void CRConClient::Disconnect(void)
{ {
m_pSocket->CloseAcceptedSocket(0); m_Socket.CloseAcceptedSocket(0);
m_bConnEstablished = false; m_bConnEstablished = false;
} }
@ -153,18 +150,16 @@ void CRConClient::Disconnect(void)
void CRConClient::Send(const std::string& svMessage) const void CRConClient::Send(const std::string& svMessage) const
{ {
std::ostringstream ssSendBuf; std::ostringstream ssSendBuf;
const u_long nLen = htonl(svMessage.size());
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24); ssSendBuf.write(reinterpret_cast<const char*>(&nLen), sizeof(u_long));
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16); ssSendBuf.write(svMessage.data(), svMessage.size());
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, int nSendResult = ::send(m_Socket.GetAcceptedSocketData(0)->m_hSocket,
ssSendBuf.str().data(), static_cast<int>(ssSendBuf.str().size()), MSG_NOSIGNAL); ssSendBuf.str().data(), static_cast<int>(ssSendBuf.str().size()), MSG_NOSIGNAL);
if (nSendResult == SOCKET_ERROR) if (nSendResult == SOCKET_ERROR)
{ {
Warning(eDLL_T::CLIENT, "Failed to send RCON message: (SOCKET_ERROR)\n"); Warning(eDLL_T::CLIENT, "Failed to send RCON message: (%s)\n", "SOCKET_ERROR");
} }
} }
@ -174,11 +169,11 @@ void CRConClient::Send(const std::string& svMessage) const
void CRConClient::Recv(void) void CRConClient::Recv(void)
{ {
static char szRecvBuf[1024]; static char szRecvBuf[1024];
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(0); CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(0);
{////////////////////////////////////////////// {//////////////////////////////////////////////
int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK); const int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
if (nPendingLen == SOCKET_ERROR && m_pSocket->IsSocketBlocking()) if (nPendingLen == SOCKET_ERROR && m_Socket.IsSocketBlocking())
{ {
return; return;
} }
@ -195,14 +190,14 @@ void CRConClient::Recv(void)
while (nReadLen > 0) while (nReadLen > 0)
{ {
int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL); const int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
if (nRecvLen == 0 && m_bConnEstablished) // Socket was closed. if (nRecvLen == 0 && m_bConnEstablished) // Socket was closed.
{ {
this->Disconnect(); this->Disconnect();
DevMsg(eDLL_T::CLIENT, "Server closed RCON connection\n"); DevMsg(eDLL_T::CLIENT, "Server closed RCON connection\n");
break; break;
} }
if (nRecvLen < 0 && !m_pSocket->IsSocketBlocking()) if (nRecvLen < 0 && !m_Socket.IsSocketBlocking())
{ {
Error(eDLL_T::CLIENT, NO_ERROR, "RCON Cmd: recv error (%s)\n", NET_ErrorString(WSAGetLastError())); Error(eDLL_T::CLIENT, NO_ERROR, "RCON Cmd: recv error (%s)\n", NET_ErrorString(WSAGetLastError()));
break; break;
@ -241,7 +236,7 @@ void CRConClient::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
pData->m_nPayloadRead = 0; pData->m_nPayloadRead = 0;
} }
} }
else if (pData->m_nPayloadRead < sizeof(int)) // Read size field. else if (pData->m_nPayloadRead < sizeof(u_long)) // Read size field.
{ {
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf; pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
@ -250,11 +245,7 @@ void CRConClient::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
} }
else // Build prefix. else // Build prefix.
{ {
pData->m_nPayloadLen = static_cast<int>( pData->m_nPayloadLen = ntohl(*reinterpret_cast<u_long*>(&pData->m_RecvBuffer[0]));
pData->m_RecvBuffer[0] << 24 |
pData->m_RecvBuffer[1] << 16 |
pData->m_RecvBuffer[2] << 8 |
pData->m_RecvBuffer[3]);
pData->m_nPayloadRead = 0; pData->m_nPayloadRead = 0;
if (pData->m_nPayloadLen < 0 || if (pData->m_nPayloadLen < 0 ||
@ -279,15 +270,13 @@ void CRConClient::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConClient::ProcessMessage(const sv_rcon::response& sv_response) const void CRConClient::ProcessMessage(const sv_rcon::response& sv_response) const
{ {
std::string svOut = sv_response.responsebuf();
switch (sv_response.responsetype()) switch (sv_response.responsetype())
{ {
case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH: case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH:
{ {
if (!sv_response.responseval().empty()) if (!sv_response.responseval().empty())
{ {
long i = strtol(sv_response.responseval().c_str(), NULL, NULL); const long i = strtol(sv_response.responseval().c_str(), NULL, NULL);
if (!i) // sv_rcon_sendlogs is not set. if (!i) // sv_rcon_sendlogs is not set.
{ {
if (cl_rcon_request_sendlogs->GetBool()) if (cl_rcon_request_sendlogs->GetBool())
@ -298,12 +287,12 @@ void CRConClient::ProcessMessage(const sv_rcon::response& sv_response) const
} }
} }
DevMsg(eDLL_T::NETCON, "%s", svOut.c_str()); DevMsg(eDLL_T::NETCON, "%s", PrintPercentageEscape(sv_response.responsebuf()).c_str());
break; break;
} }
case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG: case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG:
{ {
NetMsg(static_cast<EGlobalContext_t>(sv_response.responseid()), svOut.c_str()); NetMsg(static_cast<EGlobalContext_t>(sv_response.responseid()), PrintPercentageEscape(sv_response.responsebuf()).c_str());
break; break;
} }
default: default:
@ -320,7 +309,7 @@ void CRConClient::ProcessMessage(const sv_rcon::response& sv_response) const
// request_t - // request_t -
// Output : serialized results as string // Output : serialized results as string
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
std::string CRConClient::Serialize(const std::string& svReqBuf, const std::string& svReqVal, cl_rcon::request_t request_t) const std::string CRConClient::Serialize(const std::string& svReqBuf, const std::string& svReqVal, const cl_rcon::request_t request_t) const
{ {
cl_rcon::request cl_request; cl_rcon::request cl_request;
@ -376,8 +365,8 @@ bool CRConClient::IsConnected(void) const
return m_bConnEstablished; return m_bConnEstablished;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
CRConClient* g_pRConClient = new CRConClient(); CRConClient g_RCONClient;
CRConClient* RCONClient() CRConClient* RCONClient() // Singleton RCON Client.
{ {
return g_pRConClient; return &g_RCONClient;
} }

View File

@ -26,18 +26,18 @@ public:
void ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetConsoleData* pData); void ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetConsoleData* pData);
void ProcessMessage(const sv_rcon::response& sv_response) const; 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; std::string Serialize(const std::string& svReqBuf, const std::string& svReqVal, const cl_rcon::request_t request_t) const;
sv_rcon::response Deserialize(const std::string& svBuf) const; sv_rcon::response Deserialize(const std::string& svBuf) const;
bool IsInitialized(void) const; bool IsInitialized(void) const;
bool IsConnected(void) const; bool IsConnected(void) const;
private: private:
CNetAdr2* m_pNetAdr2;
CSocketCreator* m_pSocket;
bool m_bInitialized = false; bool m_bInitialized = false;
bool m_bConnEstablished = false; bool m_bConnEstablished = false;
CNetAdr2 m_NetAdr2;
CSocketCreator m_Socket;
}; };
extern CRConClient* g_pRConClient;
CRConClient* RCONClient(); CRConClient* RCONClient();

View File

@ -25,8 +25,6 @@ CRConServer::CRConServer(void)
: m_bInitialized(false) : m_bInitialized(false)
, m_nConnIndex(0) , m_nConnIndex(0)
{ {
m_pAdr2 = new CNetAdr2();
m_pSocket = new CSocketCreator();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -34,8 +32,6 @@ CRConServer::CRConServer(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
CRConServer::~CRConServer(void) CRConServer::~CRConServer(void)
{ {
delete m_pAdr2;
delete m_pSocket;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -51,8 +47,8 @@ void CRConServer::Init(void)
} }
} }
m_pAdr2->SetIPAndPort(rcon_address->GetString(), hostport->GetString()); m_Adr2.SetIPAndPort(rcon_address->GetString(), hostport->GetString());
m_pSocket->CreateListenSocket(*m_pAdr2, false); m_Socket.CreateListenSocket(m_Adr2, false);
DevMsg(eDLL_T::SERVER, "Remote server access initialized\n"); DevMsg(eDLL_T::SERVER, "Remote server access initialized\n");
m_bInitialized = true; m_bInitialized = true;
@ -63,9 +59,9 @@ void CRConServer::Init(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Shutdown(void) void CRConServer::Shutdown(void)
{ {
if (m_pSocket->IsListening()) if (m_Socket.IsListening())
{ {
m_pSocket->CloseListenSocket(); m_Socket.CloseListenSocket();
} }
m_bInitialized = false; m_bInitialized = false;
} }
@ -75,17 +71,17 @@ void CRConServer::Shutdown(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Think(void) void CRConServer::Think(void)
{ {
int nCount = m_pSocket->GetAcceptedSocketCount(); const int nCount = m_Socket.GetAcceptedSocketCount();
// Close redundant sockets if there are too many except for whitelisted and authenticated. // Close redundant sockets if there are too many except for whitelisted and authenticated.
if (nCount >= sv_rcon_maxsockets->GetInt()) if (nCount >= sv_rcon_maxsockets->GetInt())
{ {
for (m_nConnIndex = nCount - 1; m_nConnIndex >= 0; m_nConnIndex--) for (m_nConnIndex = nCount - 1; m_nConnIndex >= 0; m_nConnIndex--)
{ {
CNetAdr2 netAdr2 = m_pSocket->GetAcceptedSocketAddress(m_nConnIndex); const CNetAdr2 netAdr2 = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
if (netAdr2.GetIP(true).compare(sv_rcon_whitelist_address->GetString()) != 0) if (netAdr2.GetIP(true).compare(sv_rcon_whitelist_address->GetString()) != 0)
{ {
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(m_nConnIndex); const CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
if (!pData->m_bAuthorized) if (!pData->m_bAuthorized)
{ {
this->CloseConnection(); this->CloseConnection();
@ -97,9 +93,9 @@ void CRConServer::Think(void)
// Create a new listen socket if authenticated connection is closed. // Create a new listen socket if authenticated connection is closed.
if (nCount == 0) if (nCount == 0)
{ {
if (!m_pSocket->IsListening()) if (!m_Socket.IsListening())
{ {
m_pSocket->CreateListenSocket(*m_pAdr2, false); m_Socket.CreateListenSocket(m_Adr2, false);
} }
} }
} }
@ -112,9 +108,9 @@ void CRConServer::Think(void)
bool CRConServer::SetPassword(const char* pszPassword) bool CRConServer::SetPassword(const char* pszPassword)
{ {
m_bInitialized = false; m_bInitialized = false;
m_pSocket->CloseAllAcceptedSockets(); m_Socket.CloseAllAcceptedSockets();
size_t nLen = std::strlen(pszPassword); const size_t nLen = std::strlen(pszPassword);
if (nLen < 8) if (nLen < 8)
{ {
if (nLen > 0) if (nLen > 0)
@ -140,7 +136,7 @@ void CRConServer::RunFrame(void)
{ {
if (m_bInitialized) if (m_bInitialized)
{ {
m_pSocket->RunFrame(); m_Socket.RunFrame();
this->Think(); this->Think();
this->Recv(); this->Recv();
} }
@ -152,19 +148,17 @@ void CRConServer::RunFrame(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Send(const std::string& svMessage) const void CRConServer::Send(const std::string& svMessage) const
{ {
if (int nCount = m_pSocket->GetAcceptedSocketCount()) if (const int nCount = m_Socket.GetAcceptedSocketCount())
{ {
std::ostringstream ssSendBuf; std::ostringstream ssSendBuf;
const u_long nLen = htonl(svMessage.size());
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24); ssSendBuf.write(reinterpret_cast<const char*>(&nLen), sizeof(u_long));
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16); ssSendBuf.write(svMessage.data(), svMessage.size());
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--) for (int i = nCount - 1; i >= 0; i--)
{ {
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(i); CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(i);
if (pData->m_bAuthorized) if (pData->m_bAuthorized)
{ {
@ -179,15 +173,13 @@ void CRConServer::Send(const std::string& svMessage) const
// Input : hSocket - // Input : hSocket -
// *svMessage - // *svMessage -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Send(SocketHandle_t hSocket, const std::string& svMessage) const void CRConServer::Send(const SocketHandle_t hSocket, const std::string& svMessage) const
{ {
std::ostringstream ssSendBuf; std::ostringstream ssSendBuf;
const u_long nLen = htonl(svMessage.size());
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24); ssSendBuf.write(reinterpret_cast<const char*>(&nLen), sizeof(u_long));
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16); ssSendBuf.write(svMessage.data(), svMessage.size());
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); ::send(hSocket, ssSendBuf.str().data(), static_cast<int>(ssSendBuf.str().size()), MSG_NOSIGNAL);
} }
@ -199,7 +191,7 @@ void CRConServer::Send(SocketHandle_t hSocket, const std::string& svMessage) con
// responseType - // responseType -
// nResponseId - // nResponseId -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Send(const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId) void CRConServer::Send(const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId)
{ {
if (responseType == sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG) if (responseType == sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG)
{ {
@ -219,7 +211,7 @@ void CRConServer::Send(const std::string& svRspBuf, const std::string& svRspVal,
// responseType - // responseType -
// nResponseId - // nResponseId -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Send(SocketHandle_t hSocket, const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId) void CRConServer::Send(const SocketHandle_t hSocket, const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId)
{ {
if (responseType == sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG) if (responseType == sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG)
{ {
@ -236,12 +228,12 @@ void CRConServer::Send(SocketHandle_t hSocket, const std::string& svRspBuf, cons
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Recv(void) void CRConServer::Recv(void)
{ {
int nCount = m_pSocket->GetAcceptedSocketCount(); const int nCount = m_Socket.GetAcceptedSocketCount();
static char szRecvBuf[1024]; static char szRecvBuf[1024];
for (m_nConnIndex = nCount - 1; m_nConnIndex >= 0; m_nConnIndex--) for (m_nConnIndex = nCount - 1; m_nConnIndex >= 0; m_nConnIndex--)
{ {
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(m_nConnIndex); CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
{////////////////////////////////////////////// {//////////////////////////////////////////////
if (this->CheckForBan(pData)) if (this->CheckForBan(pData))
{ {
@ -250,8 +242,8 @@ void CRConServer::Recv(void)
continue; continue;
} }
int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK); const int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
if (nPendingLen == SOCKET_ERROR && m_pSocket->IsSocketBlocking()) if (nPendingLen == SOCKET_ERROR && m_Socket.IsSocketBlocking())
{ {
continue; continue;
} }
@ -267,13 +259,13 @@ void CRConServer::Recv(void)
while (nReadLen > 0) while (nReadLen > 0)
{ {
int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL); const int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
if (nRecvLen == 0) // Socket was closed. if (nRecvLen == 0) // Socket was closed.
{ {
this->CloseConnection(); this->CloseConnection();
break; break;
} }
if (nRecvLen < 0 && !m_pSocket->IsSocketBlocking()) if (nRecvLen < 0 && !m_Socket.IsSocketBlocking())
{ {
Error(eDLL_T::SERVER, NO_ERROR, "RCON Cmd: recv error (%s)\n", NET_ErrorString(WSAGetLastError())); Error(eDLL_T::SERVER, NO_ERROR, "RCON Cmd: recv error (%s)\n", NET_ErrorString(WSAGetLastError()));
break; break;
@ -292,7 +284,7 @@ void CRConServer::Recv(void)
// responseType - // responseType -
// Output : serialized results as string // Output : serialized results as string
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
std::string CRConServer::Serialize(const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId) const std::string CRConServer::Serialize(const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId) const
{ {
sv_rcon::response sv_response; sv_rcon::response sv_response;
@ -350,14 +342,14 @@ void CRConServer::Authenticate(const cl_rcon::request& cl_request, CConnectedNet
if (this->Comparator(cl_request.requestbuf())) if (this->Comparator(cl_request.requestbuf()))
{ {
pData->m_bAuthorized = true; pData->m_bAuthorized = true;
m_pSocket->CloseListenSocket(); m_Socket.CloseListenSocket();
this->CloseNonAuthConnection(); this->CloseNonAuthConnection();
this->Send(pData->m_hSocket, this->Serialize(s_pszAuthMessage, sv_rcon_sendlogs->GetString(), sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(EGlobalContext_t::NETCON_S))); this->Send(pData->m_hSocket, this->Serialize(s_pszAuthMessage, sv_rcon_sendlogs->GetString(), sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(EGlobalContext_t::NETCON_S)));
} }
else // Bad password. else // Bad password.
{ {
CNetAdr2 netAdr2 = m_pSocket->GetAcceptedSocketAddress(m_nConnIndex); const CNetAdr2 netAdr2 = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
if (sv_rcon_debug->GetBool()) if (sv_rcon_debug->GetBool())
{ {
DevMsg(eDLL_T::SERVER, "Bad RCON password attempt from '%s'\n", netAdr2.GetIPAndPort().c_str()); DevMsg(eDLL_T::SERVER, "Bad RCON password attempt from '%s'\n", netAdr2.GetIPAndPort().c_str());
@ -422,7 +414,7 @@ void CRConServer::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
pData->m_nPayloadRead = 0; pData->m_nPayloadRead = 0;
} }
} }
else if (pData->m_nPayloadRead < sizeof(int)) // Read size field. else if (pData->m_nPayloadRead < sizeof(u_long)) // Read size field.
{ {
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf; pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
@ -431,11 +423,7 @@ void CRConServer::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
} }
else // Build prefix. else // Build prefix.
{ {
pData->m_nPayloadLen = static_cast<int>( pData->m_nPayloadLen = ntohl(*reinterpret_cast<u_long*>(&pData->m_RecvBuffer[0]));
pData->m_RecvBuffer[0] << 24 |
pData->m_RecvBuffer[1] << 16 |
pData->m_RecvBuffer[2] << 8 |
pData->m_RecvBuffer[3]);
pData->m_nPayloadRead = 0; pData->m_nPayloadRead = 0;
if (!pData->m_bAuthorized) if (!pData->m_bAuthorized)
@ -469,7 +457,7 @@ void CRConServer::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::ProcessMessage(const cl_rcon::request& cl_request) void CRConServer::ProcessMessage(const cl_rcon::request& cl_request)
{ {
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(m_nConnIndex); CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
if (!pData->m_bAuthorized if (!pData->m_bAuthorized
&& cl_request.requesttype() != cl_rcon::request_t::SERVERDATA_REQUEST_AUTH) && cl_request.requesttype() != cl_rcon::request_t::SERVERDATA_REQUEST_AUTH)
@ -524,7 +512,7 @@ void CRConServer::ProcessMessage(const cl_rcon::request& cl_request)
// Input : *cl_request - // Input : *cl_request -
// bConVar - // bConVar -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Execute(const cl_rcon::request& cl_request, bool bConVar) const void CRConServer::Execute(const cl_rcon::request& cl_request, const bool bConVar) const
{ {
if (bConVar) if (bConVar)
{ {
@ -552,20 +540,20 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData* pData)
} }
pData->m_bValidated = true; pData->m_bValidated = true;
CNetAdr2 netAdr2 = m_pSocket->GetAcceptedSocketAddress(m_nConnIndex); CNetAdr2 netAdr2 = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
// Check if IP is in the ban vector. // Check if IP is in the banned list.
if (std::find(m_vBannedAddress.begin(), m_vBannedAddress.end(), if (std::find(m_vBannedList.begin(), m_vBannedList.end(),
netAdr2.GetIP(true)) != m_vBannedAddress.end()) netAdr2.GetIP(true)) != m_vBannedList.end())
{ {
return true; return true;
} }
// Check if net console has reached maximum number of attempts and add to ban vector. // Check if net console has reached maximum number of attempts > add to banned list.
if (pData->m_nFailedAttempts >= sv_rcon_maxfailures->GetInt() if (pData->m_nFailedAttempts >= sv_rcon_maxfailures->GetInt()
|| pData->m_nIgnoredMessage >= sv_rcon_maxignores->GetInt()) || pData->m_nIgnoredMessage >= sv_rcon_maxignores->GetInt())
{ {
// Don't add whitelisted address to ban vector. // Don't add white listed address to banned list.
if (netAdr2.GetIP(true).compare(sv_rcon_whitelist_address->GetString()) == 0) if (netAdr2.GetIP(true).compare(sv_rcon_whitelist_address->GetString()) == 0)
{ {
pData->m_nFailedAttempts = 0; pData->m_nFailedAttempts = 0;
@ -574,7 +562,7 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData* pData)
} }
DevMsg(eDLL_T::SERVER, "Banned '%s' for RCON hacking attempts\n", netAdr2.GetIPAndPort().c_str()); DevMsg(eDLL_T::SERVER, "Banned '%s' for RCON hacking attempts\n", netAdr2.GetIPAndPort().c_str());
m_vBannedAddress.push_back(netAdr2.GetIP(true)); m_vBannedList.push_back(netAdr2.GetIP(true));
return true; return true;
} }
return false; return false;
@ -585,14 +573,14 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData* pData)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::CloseConnection(void) // NETMGR void CRConServer::CloseConnection(void) // NETMGR
{ {
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(m_nConnIndex); CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
if (pData->m_bAuthorized) if (pData->m_bAuthorized)
{ {
// Inform server owner when authenticated connection has been closed. // Inform server owner when authenticated connection has been closed.
CNetAdr2 netAdr2 = m_pSocket->GetAcceptedSocketAddress(m_nConnIndex); CNetAdr2 netAdr2 = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
DevMsg(eDLL_T::SERVER, "Net console '%s' closed RCON connection\n", netAdr2.GetIPAndPort().c_str()); DevMsg(eDLL_T::SERVER, "Net console '%s' closed RCON connection\n", netAdr2.GetIPAndPort().c_str());
} }
m_pSocket->CloseAcceptedSocket(m_nConnIndex); m_Socket.CloseAcceptedSocket(m_nConnIndex);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -600,14 +588,14 @@ void CRConServer::CloseConnection(void) // NETMGR
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::CloseNonAuthConnection(void) void CRConServer::CloseNonAuthConnection(void)
{ {
int nCount = m_pSocket->GetAcceptedSocketCount(); int nCount = m_Socket.GetAcceptedSocketCount();
for (int i = nCount - 1; i >= 0; i--) for (int i = nCount - 1; i >= 0; i--)
{ {
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(i); CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(i);
if (!pData->m_bAuthorized) if (!pData->m_bAuthorized)
{ {
m_pSocket->CloseAcceptedSocket(i); m_Socket.CloseAcceptedSocket(i);
} }
} }
} }
@ -622,8 +610,8 @@ bool CRConServer::IsInitialized(void) const
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
CRConServer* g_pRConServer = new CRConServer(); CRConServer g_RCONServer;
CRConServer* RCONServer() CRConServer* RCONServer() // Singleton RCON Server.
{ {
return g_pRConServer; return &g_RCONServer;
} }

View File

@ -23,12 +23,12 @@ public:
void RunFrame(void); void RunFrame(void);
void Send(const std::string& svMessage) const; void Send(const std::string& svMessage) const;
void Send(SocketHandle_t hSocket, const std::string& svMessage) const; void Send(const SocketHandle_t hSocket, const std::string& svMessage) const;
void Send(const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId = -4); void Send(const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId = -4);
void Send(SocketHandle_t hSocket, const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId = -4); void Send(const SocketHandle_t hSocket, const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId = -4);
void Recv(void); void Recv(void);
std::string Serialize(const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId = -4) const; std::string Serialize(const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId = -4) const;
cl_rcon::request Deserialize(const std::string& svBuf) const; cl_rcon::request Deserialize(const std::string& svBuf) const;
void Authenticate(const cl_rcon::request& cl_request, CConnectedNetConsoleData* pData); void Authenticate(const cl_rcon::request& cl_request, CConnectedNetConsoleData* pData);
@ -37,7 +37,7 @@ public:
void ProcessBuffer(const char* pszIn, int nRecvLen, CConnectedNetConsoleData* pData); void ProcessBuffer(const char* pszIn, int nRecvLen, CConnectedNetConsoleData* pData);
void ProcessMessage(const cl_rcon::request& cl_request); void ProcessMessage(const cl_rcon::request& cl_request);
void Execute(const cl_rcon::request& cl_request, bool bConVar) const; void Execute(const cl_rcon::request& cl_request, const bool bConVar) const;
bool CheckForBan(CConnectedNetConsoleData* pData); bool CheckForBan(CConnectedNetConsoleData* pData);
void CloseConnection(void); void CloseConnection(void);
@ -49,10 +49,10 @@ private:
bool m_bInitialized; bool m_bInitialized;
int m_nConnIndex; int m_nConnIndex;
CNetAdr2* m_pAdr2; std::vector<std::string> m_vBannedList;
CSocketCreator* m_pSocket;
std::vector<std::string> m_vBannedAddress;
std::string m_svPasswordHash; std::string m_svPasswordHash;
CNetAdr2 m_Adr2;
CSocketCreator m_Socket;
}; };
extern CRConServer* g_pRConServer;
CRConServer* RCONServer(); CRConServer* RCONServer();

View File

@ -23,9 +23,8 @@ CNetCon::CNetCon(void)
, m_bQuitApplication(false) , m_bQuitApplication(false)
, m_abPromptConnect(true) , m_abPromptConnect(true)
, m_abConnEstablished(false) , m_abConnEstablished(false)
, m_NetAdr2("localhost", "37015")
{ {
m_pNetAdr2 = new CNetAdr2("localhost", "37015");
m_pSocket = new CSocketCreator();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -33,8 +32,6 @@ CNetCon::CNetCon(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
CNetCon::~CNetCon(void) CNetCon::~CNetCon(void)
{ {
delete m_pNetAdr2;
delete m_pSocket;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -43,8 +40,8 @@ CNetCon::~CNetCon(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetCon::Init(void) bool CNetCon::Init(void)
{ {
WSAData wsaData{}; WSAData wsaData;
int nError = ::WSAStartup(MAKEWORD(2, 2), &wsaData); const int nError = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
if (nError != 0) if (nError != 0)
{ {
@ -72,10 +69,10 @@ bool CNetCon::Init(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetCon::Shutdown(void) bool CNetCon::Shutdown(void)
{ {
m_pSocket->CloseAllAcceptedSockets(); m_Socket.CloseAllAcceptedSockets();
m_abConnEstablished = false; m_abConnEstablished = false;
int nError = ::WSACleanup(); const int nError = ::WSACleanup();
if (nError != 0) if (nError != 0)
{ {
std::cerr << "Failed to stop Winsock via WSACleanup: (" << NET_ErrorString(WSAGetLastError()) << ")" << std::endl; std::cerr << "Failed to stop Winsock via WSACleanup: (" << NET_ErrorString(WSAGetLastError()) << ")" << std::endl;
@ -114,7 +111,6 @@ void CNetCon::TermSetup(void)
} }
CONSOLE_SCREEN_BUFFER_INFOEX sbInfoEx{}; CONSOLE_SCREEN_BUFFER_INFOEX sbInfoEx{};
COLORREF storedBG = sbInfoEx.ColorTable[0];
sbInfoEx.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); sbInfoEx.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
GetConsoleScreenBufferInfoEx(hOutput, &sbInfoEx); GetConsoleScreenBufferInfoEx(hOutput, &sbInfoEx);
@ -146,7 +142,7 @@ void CNetCon::UserInput(void)
return; return;
} }
vector<string> vSubStrings = StringSplit(svInput, ' ', 2); const std::vector<std::string> vSubStrings = StringSplit(svInput, ' ', 2);
if (vSubStrings.size() > 1) if (vSubStrings.size() > 1)
{ {
if (vSubStrings[0].compare("PASS") == 0) // Auth with RCON server. if (vSubStrings[0].compare("PASS") == 0) // Auth with RCON server.
@ -178,7 +174,7 @@ void CNetCon::UserInput(void)
{ {
if (!svInput.empty()) if (!svInput.empty())
{ {
string::size_type nPos = svInput.find(' '); const string::size_type nPos = svInput.find(' ');
if (nPos > 0 if (nPos > 0
&& nPos < svInput.size() && nPos < svInput.size()
&& nPos != svInput.size()) && nPos != svInput.size())
@ -244,15 +240,15 @@ bool CNetCon::Connect(const std::string& svInAdr, const std::string& svInPort)
if (!svInAdr.empty() && !svInPort.empty()) if (!svInAdr.empty() && !svInPort.empty())
{ {
// Default is [127.0.0.1]:37015 // Default is [127.0.0.1]:37015
m_pNetAdr2->SetIPAndPort(svInAdr, svInPort); m_NetAdr2.SetIPAndPort(svInAdr, svInPort);
} }
if (m_pSocket->ConnectSocket(*m_pNetAdr2, true) == SOCKET_ERROR) if (m_Socket.ConnectSocket(m_NetAdr2, true) == SOCKET_ERROR)
{ {
std::cerr << "Failed to connect. Error: (SOCKET_ERROR). Verify IP and PORT." << std::endl; std::cerr << "Failed to connect. Error: (SOCKET_ERROR). Verify IP and PORT." << std::endl;
return false; return false;
} }
std::cout << "Connected to: " << m_pNetAdr2->GetIPAndPort() << std::endl; std::cout << "Connected to: " << m_NetAdr2.GetIPAndPort() << std::endl;
m_abConnEstablished = true; m_abConnEstablished = true;
return true; return true;
@ -263,7 +259,7 @@ bool CNetCon::Connect(const std::string& svInAdr, const std::string& svInPort)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CNetCon::Disconnect(void) void CNetCon::Disconnect(void)
{ {
m_pSocket->CloseAcceptedSocket(0); m_Socket.CloseAcceptedSocket(0);
m_abPromptConnect = true; m_abPromptConnect = true;
m_abConnEstablished = false; m_abConnEstablished = false;
} }
@ -275,14 +271,12 @@ void CNetCon::Disconnect(void)
void CNetCon::Send(const std::string& svMessage) const void CNetCon::Send(const std::string& svMessage) const
{ {
std::ostringstream ssSendBuf; std::ostringstream ssSendBuf;
const u_long nLen = htonl(svMessage.size());
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24); ssSendBuf.write(reinterpret_cast<const char*>(&nLen), sizeof(u_long));
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16); ssSendBuf.write(svMessage.data(), svMessage.size());
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, const int nSendResult = ::send(m_Socket.GetAcceptedSocketData(0)->m_hSocket,
ssSendBuf.str().data(), static_cast<int>(ssSendBuf.str().size()), MSG_NOSIGNAL); ssSendBuf.str().data(), static_cast<int>(ssSendBuf.str().size()), MSG_NOSIGNAL);
if (nSendResult == SOCKET_ERROR) if (nSendResult == SOCKET_ERROR)
{ {
@ -296,11 +290,11 @@ void CNetCon::Send(const std::string& svMessage) const
void CNetCon::Recv(void) void CNetCon::Recv(void)
{ {
static char szRecvBuf[1024]; static char szRecvBuf[1024];
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(0); CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(0);
{////////////////////////////////////////////// {//////////////////////////////////////////////
int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK); const int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
if (nPendingLen == SOCKET_ERROR && m_pSocket->IsSocketBlocking()) if (nPendingLen == SOCKET_ERROR && m_Socket.IsSocketBlocking())
{ {
return; return;
} }
@ -317,14 +311,14 @@ void CNetCon::Recv(void)
while (nReadLen > 0) while (nReadLen > 0)
{ {
int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL); const int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
if (nRecvLen == 0 && m_abConnEstablished) // Socket was closed. if (nRecvLen == 0 && m_abConnEstablished) // Socket was closed.
{ {
this->Disconnect(); this->Disconnect();
std::cout << "Server closed connection" << std::endl; std::cout << "Server closed connection" << std::endl;
break; break;
} }
if (nRecvLen < 0 && !m_pSocket->IsSocketBlocking()) if (nRecvLen < 0 && !m_Socket.IsSocketBlocking())
{ {
std::cout << "RCON Cmd: recv error (" << NET_ErrorString(WSAGetLastError()) << ")" << std::endl; std::cout << "RCON Cmd: recv error (" << NET_ErrorString(WSAGetLastError()) << ")" << std::endl;
break; break;
@ -372,11 +366,7 @@ void CNetCon::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetCon
} }
else // Build prefix. else // Build prefix.
{ {
pData->m_nPayloadLen = static_cast<int>( pData->m_nPayloadLen = ntohl(*reinterpret_cast<u_long*>(&pData->m_RecvBuffer[0]));
pData->m_RecvBuffer[0] << 24 |
pData->m_RecvBuffer[1] << 16 |
pData->m_RecvBuffer[2] << 8 |
pData->m_RecvBuffer[3]);
pData->m_nPayloadRead = 0; pData->m_nPayloadRead = 0;
if (pData->m_nPayloadLen < 0 || if (pData->m_nPayloadLen < 0 ||
@ -401,14 +391,13 @@ void CNetCon::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetCon
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CNetCon::ProcessMessage(const sv_rcon::response& sv_response) const void CNetCon::ProcessMessage(const sv_rcon::response& sv_response) const
{ {
static std::regex rxAnsiExp("\\\033\\[.*?m");
switch (sv_response.responsetype()) switch (sv_response.responsetype())
{ {
case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH: case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH:
{ {
if (!sv_response.responseval().empty()) if (!sv_response.responseval().empty())
{ {
long i = strtol(sv_response.responseval().c_str(), NULL, NULL); const long i = strtol(sv_response.responseval().c_str(), NULL, NULL);
if (!i) // sv_rcon_sendlogs is not set. if (!i) // sv_rcon_sendlogs is not set.
{ {
string svLogQuery = this->Serialize("", "", cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG); string svLogQuery = this->Serialize("", "", cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
@ -422,7 +411,7 @@ void CNetCon::ProcessMessage(const sv_rcon::response& sv_response) const
std::string svOut = sv_response.responsebuf(); std::string svOut = sv_response.responsebuf();
if (m_bNoColor) if (m_bNoColor)
{ {
svOut = std::regex_replace(svOut, rxAnsiExp, ""); svOut = std::regex_replace(svOut, std::regex("\\\033\\[.*?m"), "");
} }
else else
{ {
@ -445,7 +434,7 @@ void CNetCon::ProcessMessage(const sv_rcon::response& sv_response) const
// request_t - // request_t -
// Output : serialized results as string // Output : serialized results as string
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
std::string CNetCon::Serialize(const std::string& svReqBuf, const std::string& svReqVal, cl_rcon::request_t request_t) const std::string CNetCon::Serialize(const std::string& svReqBuf, const std::string& svReqVal, const cl_rcon::request_t request_t) const
{ {
cl_rcon::request cl_request; cl_rcon::request cl_request;
@ -490,31 +479,39 @@ sv_rcon::response CNetCon::Deserialize(const std::string& svBuf) const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
CNetCon* pNetCon = new CNetCon();
std::cout << "R5Reloaded TCP net console [Version " << NETCON_VERSION << "]" << std::endl; std::cout << "R5Reloaded TCP net console [Version " << NETCON_VERSION << "]" << std::endl;
if (!pNetCon->Init()) if (!NetConsole()->Init())
{ {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (argc >= 3) // Get IP and Port from command line. if (argc >= 3) // Get IP and Port from command line.
{ {
if (!pNetCon->Connect(argv[1], argv[2])) if (!NetConsole()->Connect(argv[1], argv[2]))
{ {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
while (!pNetCon->ShouldQuit()) while (!NetConsole()->ShouldQuit())
{ {
pNetCon->UserInput(); NetConsole()->UserInput();
} }
if (!pNetCon->Shutdown()) if (!NetConsole()->Shutdown())
{ {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
//-----------------------------------------------------------------------------
// singleton
//-----------------------------------------------------------------------------
CNetCon g_NetCon;
inline CNetCon* NetConsole()
{
return &g_NetCon;
}

View File

@ -33,18 +33,23 @@ public:
void ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetConsoleData* pData); void ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetConsoleData* pData);
void ProcessMessage(const sv_rcon::response& sv_response) const; 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; std::string Serialize(const std::string& svReqBuf, const std::string& svReqVal, const cl_rcon::request_t request_t) const;
sv_rcon::response Deserialize(const std::string& svBuf) const; sv_rcon::response Deserialize(const std::string& svBuf) const;
private: private:
CNetAdr2* m_pNetAdr2;
CSocketCreator* m_pSocket;
bool m_bInitialized; bool m_bInitialized;
bool m_bNoColor; bool m_bNoColor;
bool m_bQuitApplication; bool m_bQuitApplication;
std::atomic<bool> m_abPromptConnect; std::atomic<bool> m_abPromptConnect;
std::atomic<bool> m_abConnEstablished; std::atomic<bool> m_abConnEstablished;
CNetAdr2 m_NetAdr2;
CSocketCreator m_Socket;
mutable std::mutex m_Mutex; mutable std::mutex m_Mutex;
}; };
//-----------------------------------------------------------------------------
// singleton
//-----------------------------------------------------------------------------
extern CNetCon* NetConsole();

View File

@ -11,7 +11,6 @@
#include <engine/sys_utils.h> #include <engine/sys_utils.h>
#endif // !NETCONSOLE #endif // !NETCONSOLE
#include <engine/net.h> #include <engine/net.h>
#include <netconsole/netconsole.h>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: Constructor // Purpose: Constructor