mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Initial game client RCON implementation
This commit is contained in:
parent
976e8d9a41
commit
10174a6206
@ -7,6 +7,7 @@
|
||||
#include "client/client.h"
|
||||
#include "client/cdll_engine_int.h"
|
||||
#include "engine/net_chan.h"
|
||||
#include "engine/cl_rcon.h"
|
||||
#include "public/include/bansystem.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "gameui/IConsole.h"
|
||||
@ -31,15 +32,17 @@ void __fastcall HFrameStageNotify(CHLClient* rcx, ClientFrameStage_t frameStage)
|
||||
|
||||
if (!g_pCmdLine->CheckParm("-devsdk"))
|
||||
{
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_server.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_client.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec_server.cfg\"");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec_client.cfg\"");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec.cfg\"");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"rcon_client.cfg\"");
|
||||
}
|
||||
else // Development configs.
|
||||
{
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_server_dev.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_client_dev.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_dev.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec_server_dev.cfg\"");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec_client_dev.cfg\"");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec_dev.cfg\"");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"rcon_client_dev.cfg\"");
|
||||
}
|
||||
|
||||
*(bool*)m_bRestrictServerCommands = true; // Restrict commands.
|
||||
@ -51,6 +54,7 @@ void __fastcall HFrameStageNotify(CHLClient* rcx, ClientFrameStage_t frameStage)
|
||||
HNET_GenerateKey();
|
||||
}
|
||||
g_pCVar->FindVar("net_usesocketsforloopback")->SetValue(1);
|
||||
g_pRConClient->Init();
|
||||
|
||||
bInitialized = true;
|
||||
}
|
||||
@ -96,6 +100,7 @@ void __fastcall HFrameStageNotify(CHLClient* rcx, ClientFrameStage_t frameStage)
|
||||
}
|
||||
}
|
||||
g_pIConsole->Think();
|
||||
g_pRConClient->RunFrame();
|
||||
CHLClient_FrameStageNotify(rcx, (int)frameStage);
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,296 @@
|
||||
//===========================================================================//
|
||||
//
|
||||
// Purpose: Implementation of the rcon client
|
||||
//
|
||||
//
|
||||
// Purpose: Implementation of the rcon client.
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "tier0/IConVar.h"
|
||||
#include "tier0/cmd.h"
|
||||
#include "tier0/cvar.h"
|
||||
#include "protoc/sv_rcon.pb.h"
|
||||
#include "protoc/cl_rcon.pb.h"
|
||||
#include "engine/cl_rcon.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "common/igameserverdata.h"
|
||||
|
||||
// TODO..
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: NETCON systems init
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::Init(void)
|
||||
{
|
||||
if (std::strlen(rcon_password->GetString()) < 8)
|
||||
{
|
||||
if (std::strlen(rcon_password->GetString()) > 0)
|
||||
{
|
||||
DevMsg(eDLL_T::CLIENT, "Remote server access requires a password of at least 8 characters\n");
|
||||
}
|
||||
m_bInitialized = false;
|
||||
}
|
||||
m_bInitialized = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: NETCON systems shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::Shutdown(void)
|
||||
{
|
||||
if (m_bConnEstablished)
|
||||
{
|
||||
this->Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: client rcon main processing loop
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::RunFrame(void)
|
||||
{
|
||||
if (m_bInitialized && m_bConnEstablished)
|
||||
{
|
||||
this->Recv();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: connect to address and port stored in 'rcon_address' cvar
|
||||
// Output : true if connection succeeds, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConClient::Connect(void)
|
||||
{
|
||||
if (strlen(rcon_address->GetString()) > 0)
|
||||
{
|
||||
// Default is [127.0.0.1]:37015
|
||||
m_pNetAdr2->SetIPAndPort(rcon_address->GetString());
|
||||
}
|
||||
|
||||
if (m_pSocket->ConnectSocket(*m_pNetAdr2, true) == SOCKET_ERROR)
|
||||
{
|
||||
DevMsg(eDLL_T::CLIENT, "Connection to RCON server failed: (SOCKET_ERROR)\n");
|
||||
return false;
|
||||
}
|
||||
DevMsg(eDLL_T::CLIENT, "Connected to: %s\n", m_pNetAdr2->GetIPAndPort().c_str());
|
||||
|
||||
m_bConnEstablished = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: connect to specified address and port
|
||||
// Input : *svInAdr -
|
||||
// *svInPort -
|
||||
// Output : true if connection succeeds, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConClient::Connect(const std::string& svInAdr, const std::string& svInPort)
|
||||
{
|
||||
if (svInAdr.size() > 0 && svInPort.size() > 0)
|
||||
{
|
||||
// Default is [127.0.0.1]:37015
|
||||
m_pNetAdr2->SetIPAndPort(svInAdr, svInPort);
|
||||
}
|
||||
|
||||
if (m_pSocket->ConnectSocket(*m_pNetAdr2, true) == SOCKET_ERROR)
|
||||
{
|
||||
DevMsg(eDLL_T::CLIENT, "Connection to RCON server failed: (SOCKET_ERROR)\n");
|
||||
return false;
|
||||
}
|
||||
DevMsg(eDLL_T::CLIENT, "Connected to: %s\n", m_pNetAdr2->GetIPAndPort().c_str());
|
||||
|
||||
m_bConnEstablished = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: disconnect from current session
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::Disconnect(void)
|
||||
{
|
||||
::closesocket(m_pSocket->GetAcceptedSocketHandle(0));
|
||||
m_bConnEstablished = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: send message
|
||||
// Input : *svMessage -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::Send(const std::string& svMessage) const
|
||||
{
|
||||
int nSendResult = ::send(m_pSocket->GetAcceptedSocketData(0)->m_hSocket, svMessage.c_str(), svMessage.size(), MSG_NOSIGNAL);
|
||||
if (nSendResult == SOCKET_ERROR)
|
||||
{
|
||||
DevMsg(eDLL_T::CLIENT, "Failed to send RCON message: (SOCKET_ERROR)\n");
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: receive message
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::Recv(void)
|
||||
{
|
||||
static char szRecvBuf[MAX_NETCONSOLE_INPUT_LEN]{};
|
||||
|
||||
{//////////////////////////////////////////////
|
||||
int nPendingLen = ::recv(m_pSocket->GetAcceptedSocketData(0)->m_hSocket, szRecvBuf, sizeof(szRecvBuf), MSG_PEEK);
|
||||
if (nPendingLen == SOCKET_ERROR && m_pSocket->IsSocketBlocking())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (nPendingLen <= 0 && m_bConnEstablished) // EOF or error.
|
||||
{
|
||||
this->Disconnect();
|
||||
DevMsg(eDLL_T::CLIENT, "Server closed RCON connection\n");
|
||||
return;
|
||||
}
|
||||
}//////////////////////////////////////////////
|
||||
|
||||
u_long nReadLen; // Find out how much we have to read.
|
||||
::ioctlsocket(m_pSocket->GetAcceptedSocketData(0)->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);
|
||||
|
||||
if (nRecvLen == 0 && m_bConnEstablished) // Socket was closed.
|
||||
{
|
||||
this->Disconnect();
|
||||
DevMsg(eDLL_T::CLIENT, "Server closed RCON connection\n");
|
||||
break;
|
||||
}
|
||||
if (nRecvLen < 0 && !m_pSocket->IsSocketBlocking())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
nReadLen -= nRecvLen; // Process what we've got.
|
||||
this->ProcessBuffer(szRecvBuf, nRecvLen);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: handles input response buffer
|
||||
// Input : *pszIn -
|
||||
// nRecvLen -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::ProcessBuffer(const char* pszIn, int nRecvLen) const
|
||||
{
|
||||
int nCharsInRespondBuffer = 0;
|
||||
char szInputRespondBuffer[MAX_NETCONSOLE_INPUT_LEN]{};
|
||||
|
||||
while (nRecvLen)
|
||||
{
|
||||
switch (*pszIn)
|
||||
{
|
||||
case '\r':
|
||||
{
|
||||
if (nCharsInRespondBuffer)
|
||||
{
|
||||
sv_rcon::response sv_response = this->Deserialize(szInputRespondBuffer);
|
||||
this->ProcessMessage(sv_response);
|
||||
}
|
||||
nCharsInRespondBuffer = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (nCharsInRespondBuffer < MAX_NETCONSOLE_INPUT_LEN - 1)
|
||||
{
|
||||
szInputRespondBuffer[nCharsInRespondBuffer++] = *pszIn;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
pszIn++;
|
||||
nRecvLen--;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: processes received message
|
||||
// Input : *sv_response -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::ProcessMessage(const sv_rcon::response& sv_response) const
|
||||
{
|
||||
switch (sv_response.responsetype())
|
||||
{
|
||||
case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH:
|
||||
case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG:
|
||||
{
|
||||
std::string svOut = sv_response.responsebuf();
|
||||
|
||||
// TODO: Manipulate string..
|
||||
DevMsg(eDLL_T::NONE, "%s", svOut.c_str());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: serializes input
|
||||
// Input : *svReqBuf -
|
||||
// *svReqVal -
|
||||
// request_t -
|
||||
// Output : serialized results as string
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string CRConClient::Serialize(const std::string& svReqBuf, const std::string& svReqVal, cl_rcon::request_t request_t) const
|
||||
{
|
||||
cl_rcon::request cl_request;
|
||||
|
||||
cl_request.set_requestid(-1);
|
||||
cl_request.set_requesttype(request_t);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
return cl_request.SerializeAsString().append("\r");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: de-serializes input
|
||||
// Input : *svBuf -
|
||||
// Output : de-serialized object
|
||||
//-----------------------------------------------------------------------------
|
||||
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()));
|
||||
|
||||
return sv_response;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if client rcon is initialized
|
||||
// Output : true if initialized, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConClient::IsInitialized(void) const
|
||||
{
|
||||
return this->m_bInitialized;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if client rcon is connected
|
||||
// Output : true if connected, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConClient::IsConnected(void) const
|
||||
{
|
||||
return this->m_bConnEstablished;
|
||||
}
|
||||
|
||||
CRConClient* g_pRConClient = new CRConClient();
|
@ -1,10 +1,41 @@
|
||||
#pragma once
|
||||
#include "tier1/NetAdr2.h"
|
||||
#include "tier2/SocketCreator.h"
|
||||
#include "protoc/sv_rcon.pb.h"
|
||||
#include "protoc/cl_rcon.pb.h"
|
||||
|
||||
class CRConClient
|
||||
{
|
||||
public:
|
||||
CRConClient(void){};
|
||||
~CRConClient(void){};
|
||||
|
||||
void Authenticate(void){};
|
||||
void ProcessMessage(void){};
|
||||
};
|
||||
void Init(void);
|
||||
void Shutdown(void);
|
||||
|
||||
void RunFrame(void);
|
||||
|
||||
bool Connect(void);
|
||||
bool Connect(const std::string& svInAdr, const std::string& svInPort);
|
||||
void Disconnect(void);
|
||||
|
||||
void Send(const std::string& svMessage) const;
|
||||
void Recv(void);
|
||||
|
||||
void ProcessBuffer(const char* pszIn, int nRecvLen) 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;
|
||||
sv_rcon::response Deserialize(const std::string& svBuf) const;
|
||||
|
||||
bool IsInitialized(void) const;
|
||||
bool IsConnected(void) const;
|
||||
|
||||
private:
|
||||
CNetAdr2* m_pNetAdr2 = new CNetAdr2("localhost", "37015");
|
||||
CSocketCreator* m_pSocket = new CSocketCreator();
|
||||
|
||||
bool m_bInitialized = false;
|
||||
bool m_bConnEstablished = false;
|
||||
};
|
||||
extern CRConClient* g_pRConClient;
|
@ -1,6 +1,6 @@
|
||||
//=============================================================================//
|
||||
//
|
||||
// Purpose: Runs the state machine for the host & server
|
||||
// Purpose: Runs the state machine for the host & server.
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
#include "engine/sys_engine.h"
|
||||
#ifdef DEDICATED
|
||||
#include "engine/sv_rcon.h"
|
||||
#else //
|
||||
#include "engine/cl_rcon.h"
|
||||
#endif // DEDICATED
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -138,28 +140,30 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
|
||||
{
|
||||
if (!g_pCmdLine->CheckParm("-devsdk"))
|
||||
{
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_server.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec rcon_server.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec_server.cfg\"");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"rcon_server.cfg\"");
|
||||
#ifndef DEDICATED
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_client.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec rcon_client.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec_client.cfg\"");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"rcon_client.cfg\"");
|
||||
#endif // !DEDICATED
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec.cfg\"");
|
||||
}
|
||||
else // Development configs.
|
||||
{
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_server_dev.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec rcon_server_dev.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec_server_dev.cfg\"");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"rcon_server_dev.cfg\"");
|
||||
#ifndef DEDICATED
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_client_dev.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec rcon_client_dev.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec_client_dev.cfg\"");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"rcon_client_dev.cfg\"");
|
||||
#endif // !DEDICATED
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_dev.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec \"autoexec_dev.cfg\"");
|
||||
}
|
||||
|
||||
g_pConVar->ClearHostNames();
|
||||
#ifdef DEDICATED
|
||||
g_pRConServer->Init();
|
||||
#else //
|
||||
g_pRConClient->Init();
|
||||
#endif // DEDICATED
|
||||
|
||||
*(bool*)m_bRestrictServerCommands = true; // Restrict commands.
|
||||
@ -195,6 +199,8 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
|
||||
}
|
||||
#ifdef DEDICATED
|
||||
g_pRConServer->RunFrame();
|
||||
#else //
|
||||
g_pRConClient->RunFrame();
|
||||
#endif // DEDICATED
|
||||
|
||||
HostStates_t oldState{};
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "common/igameserverdata.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: creates listen socket for RCON
|
||||
// Purpose: NETCON systems init
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Init(void)
|
||||
{
|
||||
@ -29,11 +29,7 @@ void CRConServer::Init(void)
|
||||
{
|
||||
DevMsg(eDLL_T::SERVER, "Remote server access requires a password of at least 8 characters\n");
|
||||
}
|
||||
if (m_pSocket->IsListening())
|
||||
{
|
||||
m_pSocket->CloseListenSocket();
|
||||
}
|
||||
m_bInitialized = false;
|
||||
this->Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -47,6 +43,18 @@ void CRConServer::Init(void)
|
||||
m_bInitialized = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: NETCON systems shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Shutdown(void)
|
||||
{
|
||||
if (m_pSocket->IsListening())
|
||||
{
|
||||
m_pSocket->CloseListenSocket();
|
||||
}
|
||||
m_bInitialized = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: run tasks for the RCON server
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -65,7 +73,7 @@ void CRConServer::Think(void)
|
||||
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(m_nConnIndex);
|
||||
if (!pData->m_bAuthorized)
|
||||
{
|
||||
CloseConnection();
|
||||
this->CloseConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,7 +134,7 @@ void CRConServer::Recv(void)
|
||||
{
|
||||
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(m_nConnIndex);
|
||||
{//////////////////////////////////////////////
|
||||
if (CheckForBan(pData))
|
||||
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);
|
||||
|
@ -12,6 +12,7 @@ class CRConServer
|
||||
{
|
||||
public:
|
||||
void Init(void);
|
||||
void Shutdown(void);
|
||||
|
||||
void Think(void);
|
||||
void RunFrame(void);
|
||||
|
@ -316,12 +316,14 @@ void CNetCon::ProcessBuffer(const char* pszIn, int nRecvLen) const
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (nCharsInRespondBuffer < MAX_NETCONSOLE_INPUT_LEN - 1)
|
||||
{
|
||||
szInputRespondBuffer[nCharsInRespondBuffer++] = *pszIn;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
pszIn++;
|
||||
nRecvLen--;
|
||||
}
|
||||
|
@ -5,6 +5,71 @@
|
||||
#include "client/client.h"
|
||||
#include "engine/sys_utils.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns max command lenght
|
||||
//-----------------------------------------------------------------------------
|
||||
int CCommand::MaxCommandLength(void)
|
||||
{
|
||||
return COMMAND_MAX_LENGTH - 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns argument count
|
||||
//-----------------------------------------------------------------------------
|
||||
std::int64_t CCommand::ArgC(void) const
|
||||
{
|
||||
return m_nArgc;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns argument vector
|
||||
//-----------------------------------------------------------------------------
|
||||
const char** CCommand::ArgV(void) const
|
||||
{
|
||||
return m_nArgc ? (const char**)m_ppArgv : NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns all args that occur after the 0th arg, in string form
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* CCommand::ArgS(void) const
|
||||
{
|
||||
return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the entire command in string form, including the 0th arg
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* CCommand::GetCommandString(void) const
|
||||
{
|
||||
return m_nArgc ? m_pArgSBuffer : "";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns argument from index as string
|
||||
// Input : nIndex -
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* CCommand::Arg(int nIndex) const
|
||||
{
|
||||
// FIXME: Many command handlers appear to not be particularly careful
|
||||
// about checking for valid argc range. For now, we're going to
|
||||
// do the extra check and return an empty string if it's out of range
|
||||
if (nIndex < 0 || nIndex >= m_nArgc)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return m_ppArgv[nIndex];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets at arguments
|
||||
// Input : nInput -
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* CCommand::operator[](int nIndex) const
|
||||
{
|
||||
return Arg(nIndex);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: construct/allocate
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -140,11 +205,11 @@ bool ConCommandBase::IsFlagSet(ConCommandBase* pCommandBase, int nFlags)
|
||||
return pCommandBase->HasFlags(nFlags) != 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void ConCommand_Attach()
|
||||
{
|
||||
DetourAttach((LPVOID*)&ConCommandBase_IsFlagSet, &ConCommandBase::IsFlagSet);
|
||||
}
|
||||
|
||||
void ConCommand_Detach()
|
||||
{
|
||||
DetourDetach((LPVOID*)&ConCommandBase_IsFlagSet, &ConCommandBase::IsFlagSet);
|
||||
|
@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Command tokenizer
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCommand
|
||||
{
|
||||
private:
|
||||
@ -12,47 +15,13 @@ private:
|
||||
public:
|
||||
CCommand() = delete;
|
||||
|
||||
inline int MaxCommandLength()
|
||||
{
|
||||
return COMMAND_MAX_LENGTH - 1;
|
||||
}
|
||||
|
||||
inline std::int64_t ArgC() const
|
||||
{
|
||||
return m_nArgc;
|
||||
}
|
||||
|
||||
inline const char** ArgV() const
|
||||
{
|
||||
return m_nArgc ? (const char**)m_ppArgv : NULL;
|
||||
}
|
||||
|
||||
inline const char* ArgS() const
|
||||
{
|
||||
return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
|
||||
}
|
||||
|
||||
inline const char* GetCommandString() const
|
||||
{
|
||||
return m_nArgc ? m_pArgSBuffer : "";
|
||||
}
|
||||
|
||||
inline const char* Arg(int nIndex) const
|
||||
{
|
||||
// FIXME: Many command handlers appear to not be particularly careful
|
||||
// about checking for valid argc range. For now, we're going to
|
||||
// do the extra check and return an empty string if it's out of range
|
||||
if (nIndex < 0 || nIndex >= m_nArgc)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return m_ppArgv[nIndex];
|
||||
}
|
||||
|
||||
inline const char* operator[](int nIndex) const
|
||||
{
|
||||
return Arg(nIndex);
|
||||
}
|
||||
int MaxCommandLength();
|
||||
std::int64_t ArgC(void) const;
|
||||
const char** ArgV(void) const;
|
||||
const char* ArgS(void) const;
|
||||
const char* GetCommandString(void) const;
|
||||
const char* Arg(int nIndex) const;
|
||||
const char* operator[](int nIndex) const;
|
||||
|
||||
private:
|
||||
std::int64_t m_nArgc;
|
||||
@ -62,6 +31,9 @@ private:
|
||||
const char* m_ppArgv[COMMAND_MAX_ARGC];
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The console invoked command
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommand
|
||||
{
|
||||
friend class CCVar;
|
||||
@ -72,6 +44,9 @@ public:
|
||||
// TODO
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The base console invoked command/cvar interface
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommandBase
|
||||
{
|
||||
public:
|
||||
|
@ -1,6 +1,6 @@
|
||||
//=============================================================================//
|
||||
//
|
||||
// Purpose: Completion functions for ConCommand callbacks
|
||||
// Purpose: Completion functions for ConCommand callbacks.
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
@ -25,17 +25,32 @@
|
||||
#include "mathlib/crc32.h"
|
||||
|
||||
#ifndef DEDICATED
|
||||
/*
|
||||
=====================
|
||||
_CGameConsole_f_CompletionFunc
|
||||
=====================
|
||||
*/
|
||||
void _CGameConsole_f_CompletionFunc(const CCommand& cmd)
|
||||
{
|
||||
g_pIConsole->m_bActivate = !g_pIConsole->m_bActivate;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_CCompanion_f_CompletionFunc
|
||||
=====================
|
||||
*/
|
||||
void _CCompanion_f_CompletionFunc(const CCommand& cmd)
|
||||
{
|
||||
g_pIBrowser->m_bActivate = !g_pIBrowser->m_bActivate;
|
||||
}
|
||||
#endif // !DEDICATED
|
||||
|
||||
/*
|
||||
=====================
|
||||
_Kick_f_CompletionFunc
|
||||
=====================
|
||||
*/
|
||||
void _Kick_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
@ -77,6 +92,11 @@ void _Kick_f_CompletionFunc(CCommand* cmd)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_KickID_f_CompletionFunc
|
||||
=====================
|
||||
*/
|
||||
void _KickID_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
static auto HasOnlyDigits = [](const std::string& string)
|
||||
@ -169,6 +189,11 @@ void _KickID_f_CompletionFunc(CCommand* cmd)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_Ban_f_CompletionFunc
|
||||
=====================
|
||||
*/
|
||||
void _Ban_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
@ -225,6 +250,11 @@ void _Ban_f_CompletionFunc(CCommand* cmd)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_BanID_f_CompletionFunc
|
||||
=====================
|
||||
*/
|
||||
void _BanID_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
static auto HasOnlyDigits = [](const std::string& string)
|
||||
@ -321,6 +351,11 @@ void _BanID_f_CompletionFunc(CCommand* cmd)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_Unban_f_CompletionFunc
|
||||
=====================
|
||||
*/
|
||||
void _Unban_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
static auto HasOnlyDigits = [](const std::string& string)
|
||||
@ -364,11 +399,21 @@ void _Unban_f_CompletionFunc(CCommand* cmd)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_ReloadBanList_f_CompletionFunc
|
||||
=====================
|
||||
*/
|
||||
void _ReloadBanList_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
g_pBanSystem->Load(); // Reload banlist.
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_RTech_StringToGUID_f_CompletionFunc
|
||||
=====================
|
||||
*/
|
||||
void _RTech_StringToGUID_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
@ -387,6 +432,11 @@ void _RTech_StringToGUID_f_CompletionFunc(CCommand* cmd)
|
||||
DevMsg(eDLL_T::RTECH, "] GUID: '0x%llX'\n", guid);
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_RTech_AsyncLoad_f_CompletionFunc
|
||||
=====================
|
||||
*/
|
||||
void _RTech_AsyncLoad_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
CCommand& args = *cmd; // Get reference.
|
||||
@ -395,6 +445,14 @@ void _RTech_AsyncLoad_f_CompletionFunc(CCommand* cmd)
|
||||
HRtech_AsyncLoad(firstArg);
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_RTech_Decompress_f_CompletionFunc
|
||||
|
||||
Decompresses input RPak file and
|
||||
dumps results to 'paks\Win32\*.rpak'
|
||||
=====================
|
||||
*/
|
||||
void _RTech_Decompress_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
@ -519,6 +577,15 @@ void _RTech_Decompress_f_CompletionFunc(CCommand* cmd)
|
||||
outBlock.close();
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_NET_TraceNetChan_f_CompletionFunc
|
||||
|
||||
Logs all data transmitted and received
|
||||
over the UDP socket to a file on the disk.
|
||||
File: '<mod\logs\net_trace.log>'.
|
||||
=====================
|
||||
*/
|
||||
void _NET_TraceNetChan_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
static bool bTraceNetChannel = false;
|
||||
@ -563,6 +630,14 @@ void _NET_TraceNetChan_f_CompletionFunc(CCommand* cmd)
|
||||
bTraceNetChannel = !bTraceNetChannel;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_VPK_Decompress_f_CompletionFunc
|
||||
|
||||
Decompresses input VPK files and
|
||||
dumps the output to '<mod>\vpk'.
|
||||
=====================
|
||||
*/
|
||||
void _VPK_Decompress_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
@ -598,6 +673,13 @@ void _VPK_Decompress_f_CompletionFunc(CCommand* cmd)
|
||||
DevMsg(eDLL_T::FS, "--------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_NET_SetKey_f_CompletionFunc
|
||||
|
||||
Sets the input netchannel encryption key
|
||||
=====================
|
||||
*/
|
||||
void _NET_SetKey_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
@ -613,13 +695,88 @@ void _NET_SetKey_f_CompletionFunc(CCommand* cmd)
|
||||
HNET_SetKey(firstArg);
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
_NET_GenerateKey_f_CompletionFunc
|
||||
|
||||
Sets a random netchannel encryption key
|
||||
=====================
|
||||
*/
|
||||
void _NET_GenerateKey_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
HNET_GenerateKey();
|
||||
}
|
||||
#ifndef DEDICATED
|
||||
/*
|
||||
=====================
|
||||
_RCON_CmdQuery_f_CompletionFunc
|
||||
|
||||
Issues an RCON command to the
|
||||
RCON server.
|
||||
=====================
|
||||
*/
|
||||
void _RCON_CmdQuery_f_CompletionFunc(CCommand* cmd)
|
||||
{
|
||||
// TODO: CRConClient..
|
||||
return;
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
|
||||
switch (argSize)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
if (g_pRConClient->IsInitialized()
|
||||
&& !g_pRConClient->IsConnected()
|
||||
&& strlen(rcon_address->GetString()) > 0)
|
||||
{
|
||||
g_pRConClient->Connect();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if (!g_pRConClient->IsInitialized())
|
||||
{
|
||||
DevMsg(eDLL_T::CLIENT, "Failed to issue command to RCON server: uninitialized.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
CCommand& args = *cmd; // Get reference.
|
||||
if (!g_pRConClient->IsConnected())
|
||||
{
|
||||
DevMsg(eDLL_T::CLIENT, "Failed to issue command to RCON server: unconnected.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
std::string svCmdQuery = g_pRConClient->Serialize(args[1], "", cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND);
|
||||
g_pRConClient->Send(svCmdQuery);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
if (!g_pRConClient->IsInitialized())
|
||||
{
|
||||
DevMsg(eDLL_T::CLIENT, "Failed to issue command to RCON server: uninitialized.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
CCommand& args = *cmd; // Get reference.
|
||||
if (!g_pRConClient->IsConnected())
|
||||
{
|
||||
DevMsg(eDLL_T::CLIENT, "Failed to issue command to RCON server: unconnected.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (strcmp(args[1], "PASS") == 0)
|
||||
{
|
||||
std::string svCmdQuery = g_pRConClient->Serialize(args[1], args[2], cl_rcon::request_t::SERVERDATA_REQUEST_AUTH);
|
||||
g_pRConClient->Send(svCmdQuery);
|
||||
break;
|
||||
}
|
||||
|
||||
std::string svCmdQuery = g_pRConClient->Serialize(args[1], args[2], cl_rcon::request_t::SERVERDATA_REQUEST_SETVALUE);
|
||||
g_pRConClient->Send(svCmdQuery);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !DEDICATED
|
||||
|
@ -33,7 +33,9 @@ void _VPK_Decompress_f_CompletionFunc(CCommand* cmd);
|
||||
void _NET_TraceNetChan_f_CompletionFunc(CCommand* cmd);
|
||||
void _NET_SetKey_f_CompletionFunc(CCommand* cmd);
|
||||
void _NET_GenerateKey_f_CompletionFunc(CCommand* cmd);
|
||||
#ifndef DEDICATED
|
||||
void _RCON_CmdQuery_f_CompletionFunc(CCommand* cmd);
|
||||
#endif // !DEDICATED
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class HCompletion : public IDetour
|
||||
|
@ -11,34 +11,12 @@
|
||||
#endif // !NETCONSOLE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: constructor (use this when string contains <[IP]:PORT> or 'loopback'/'localhost').
|
||||
// Purpose: constructor (use this when string contains <[IP]:PORT>).
|
||||
// Input : svInAdr -
|
||||
//-----------------------------------------------------------------------------
|
||||
CNetAdr2::CNetAdr2(std::string svInAdr)
|
||||
{
|
||||
SetType(netadrtype_t::NA_IP);
|
||||
if (strcmp(svInAdr.c_str(), "loopback") == 0 || strcmp(svInAdr.c_str(), "::1") == 0)
|
||||
{
|
||||
SetType(netadrtype_t::NA_LOOPBACK);
|
||||
svInAdr = "[127.0.0.1" + GetPort(svInAdr);
|
||||
}
|
||||
else if (strcmp(svInAdr.c_str(), "localhost"))
|
||||
{
|
||||
svInAdr = "[127.0.0.1" + GetPort(svInAdr);
|
||||
}
|
||||
|
||||
// [IP]:PORT
|
||||
m_svip = GetBase(svInAdr);
|
||||
SetVersion();
|
||||
|
||||
if (GetVersion() == netadrversion_t::NA_V4)
|
||||
{
|
||||
reinterpret_cast<sockaddr_in*>(&m_sadr)->sin_port = htons(stoi(GetPort()));
|
||||
}
|
||||
else if (GetVersion() == netadrversion_t::NA_V6)
|
||||
{
|
||||
reinterpret_cast<sockaddr_in6*>(&m_sadr)->sin6_port = htons(stoi(GetPort()));
|
||||
}
|
||||
SetIPAndPort(svInAdr);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -102,15 +80,70 @@ void CNetAdr2::SetPort(const std::string& svInPort)
|
||||
m_svip += ":" + svInPort;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the IP address and port.
|
||||
// Input : *svInAdr -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetAdr2::SetIPAndPort(std::string svInAdr)
|
||||
{
|
||||
SetType(netadrtype_t::NA_IP);
|
||||
if (strstr(svInAdr.c_str(), "loopback") || strstr(svInAdr.c_str(), "::1"))
|
||||
{
|
||||
SetType(netadrtype_t::NA_LOOPBACK);
|
||||
svInAdr = "[127.0.0.1]:" + GetPort(svInAdr);
|
||||
}
|
||||
else if (strstr(svInAdr.c_str(), "localhost"))
|
||||
{
|
||||
svInAdr = "[127.0.0.1]:" + GetPort(svInAdr);
|
||||
}
|
||||
// [IP]:PORT
|
||||
m_svip = svInAdr;
|
||||
SetVersion();
|
||||
|
||||
if (GetVersion() == netadrversion_t::NA_V4)
|
||||
{
|
||||
reinterpret_cast<sockaddr_in*>(&m_sadr)->sin_port = htons(stoi(GetPort()));
|
||||
}
|
||||
else if (GetVersion() == netadrversion_t::NA_V6)
|
||||
{
|
||||
reinterpret_cast<sockaddr_in6*>(&m_sadr)->sin6_port = htons(stoi(GetPort()));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the IP address and port.
|
||||
// Input : *svInAdr -
|
||||
// *svInPort -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetAdr2::SetIPAndPort(const std::string& svInAdr, const std::string& svInPort)
|
||||
void CNetAdr2::SetIPAndPort(std::string svInAdr, std::string svInPort)
|
||||
{
|
||||
SetType(netadrtype_t::NA_IP);
|
||||
|
||||
if (strcmp(svInAdr.c_str(), "loopback") == 0 || strcmp(svInAdr.c_str(), "::1") == 0)
|
||||
{
|
||||
SetType(netadrtype_t::NA_LOOPBACK);
|
||||
}
|
||||
else if (strcmp(svInAdr.c_str(), "localhost") == 0)
|
||||
{
|
||||
svInAdr = "127.0.0.1";
|
||||
}
|
||||
|
||||
if (strstr(svInAdr.c_str(), "["))
|
||||
{
|
||||
svInAdr = GetBase(svInAdr);
|
||||
}
|
||||
|
||||
m_svip = "[" + svInAdr + "]:" + svInPort;
|
||||
SetVersion();
|
||||
|
||||
if (m_version == netadrversion_t::NA_V4)
|
||||
{
|
||||
reinterpret_cast<sockaddr_in*>(&m_sadr)->sin_port = htons(stoi(GetPort()));
|
||||
}
|
||||
else if (m_version == netadrversion_t::NA_V6)
|
||||
{
|
||||
reinterpret_cast<sockaddr_in6*>(&m_sadr)->sin6_port = htons(stoi(GetPort()));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -50,7 +50,8 @@ public:
|
||||
|
||||
void SetIP(const std::string& svInAdr);
|
||||
void SetPort(const std::string& svInPort);
|
||||
void SetIPAndPort(const std::string& svInAdr, const std::string& svInPort);
|
||||
void SetIPAndPort(std::string svInAdr);
|
||||
void SetIPAndPort(std::string svInAdr, std::string svInPort);
|
||||
void SetType(const netadrtype_t& type);
|
||||
void SetVersion(void);
|
||||
void SetFromSocket(const int& hSocket);
|
||||
|
Loading…
x
Reference in New Issue
Block a user