mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Merge pull request #107 from Mauler125/rcon_improvements
Rcon improvements
This commit is contained in:
commit
ef8173636d
r5dev
@ -909,7 +909,9 @@ RCON_CmdQuery_f
|
||||
*/
|
||||
void RCON_CmdQuery_f(const CCommand& args)
|
||||
{
|
||||
if (args.ArgC() < 2)
|
||||
const int64_t argCount = args.ArgC();
|
||||
|
||||
if (argCount < 2)
|
||||
{
|
||||
const char* pszAddress = rcon_address->GetString();
|
||||
|
||||
@ -935,7 +937,7 @@ void RCON_CmdQuery_f(const CCommand& args)
|
||||
|
||||
if (strcmp(args.Arg(1), "PASS") == 0) // Auth with RCON server using rcon_password ConVar value.
|
||||
{
|
||||
if (args.ArgC() > 2)
|
||||
if (argCount > 2)
|
||||
{
|
||||
bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(2), "", cl_rcon::request_t::SERVERDATA_REQUEST_AUTH);
|
||||
}
|
||||
@ -957,7 +959,7 @@ void RCON_CmdQuery_f(const CCommand& args)
|
||||
return;
|
||||
}
|
||||
|
||||
bSuccess = RCONClient()->Serialize(vecMsg, args.ArgS(), "", cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND);
|
||||
bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(1), args.ArgS(), cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND);
|
||||
if (bSuccess)
|
||||
{
|
||||
RCONClient()->Send(hSocket, vecMsg.data(), int(vecMsg.size()));
|
||||
@ -989,6 +991,18 @@ void RCON_Disconnect_f(const CCommand& args)
|
||||
DevMsg(eDLL_T::CLIENT, "User closed RCON connection\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
RCON_SendLogs_f
|
||||
|
||||
request logs from RCON server
|
||||
=====================
|
||||
*/
|
||||
void RCON_InputOnlyChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue)
|
||||
{
|
||||
RCONClient()->RequestConsoleLog(RCONClient()->ShouldReceive());
|
||||
}
|
||||
#endif // !DEDICATED
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
|
@ -50,6 +50,7 @@ void CON_ClearHistory_f(const CCommand& args);
|
||||
|
||||
void RCON_CmdQuery_f(const CCommand& args);
|
||||
void RCON_Disconnect_f(const CCommand& args);
|
||||
void RCON_InputOnlyChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
|
||||
#endif // !DEDICATED
|
||||
void RCON_PasswordChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
|
||||
#ifndef CLIENT_DLL
|
||||
|
@ -144,7 +144,7 @@ ConVar* bhit_abs_origin = nullptr;
|
||||
//-----------------------------------------------------------------------------
|
||||
// CLIENT |
|
||||
#ifndef DEDICATED
|
||||
ConVar* cl_rcon_request_sendlogs = nullptr;
|
||||
ConVar* cl_rcon_inputonly = nullptr;
|
||||
ConVar* cl_quota_stringCmdsPerSecond = nullptr;
|
||||
|
||||
ConVar* cl_cmdrate = nullptr;
|
||||
@ -322,7 +322,7 @@ void ConVar_StaticInit(void)
|
||||
sv_simulateBots = ConVar::StaticCreate("sv_simulateBots", "1", FCVAR_RELEASE, "Simulate user commands for bots on the server.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
sv_rcon_debug = ConVar::StaticCreate("sv_rcon_debug" , "0" , FCVAR_RELEASE, "Show rcon debug information ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_rcon_sendlogs = ConVar::StaticCreate("sv_rcon_sendlogs" , "0" , FCVAR_RELEASE, "Network console logs to connected and authenticated sockets.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_rcon_sendlogs = ConVar::StaticCreate("sv_rcon_sendlogs" , "1" , FCVAR_RELEASE, "Network console logs to connected and authenticated sockets.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_rcon_banpenalty = ConVar::StaticCreate("sv_rcon_banpenalty" , "10", FCVAR_RELEASE, "Number of minutes to ban users who fail rcon authentication.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_rcon_maxfailures = ConVar::StaticCreate("sv_rcon_maxfailures", "10", FCVAR_RELEASE, "Max number of times a user can fail rcon authentication before being banned.", true, 1.f, false, 0.f, nullptr, nullptr);
|
||||
sv_rcon_maxignores = ConVar::StaticCreate("sv_rcon_maxignores" , "15", FCVAR_RELEASE, "Max number of times a user can ignore the instruction message before being banned.", true, 1.f, false, 0.f, nullptr, nullptr);
|
||||
@ -343,7 +343,7 @@ void ConVar_StaticInit(void)
|
||||
//-------------------------------------------------------------------------
|
||||
// CLIENT |
|
||||
#ifndef DEDICATED
|
||||
cl_rcon_request_sendlogs = ConVar::StaticCreate("cl_rcon_request_sendlogs", "1" , FCVAR_RELEASE, "Request the rcon server to send console logs on connect.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_rcon_inputonly = ConVar::StaticCreate("cl_rcon_inputonly", "0" , FCVAR_RELEASE, "Tells the rcon server whether or not we are input only.", false, 0.f, false, 0.f, RCON_InputOnlyChanged_f, nullptr);
|
||||
cl_quota_stringCmdsPerSecond = ConVar::StaticCreate("cl_quota_stringCmdsPerSecond", "16" , FCVAR_RELEASE, "How many string commands per second user is allowed to submit, 0 to allow all submissions.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
cl_notify_invert_x = ConVar::StaticCreate("cl_notify_invert_x", "0", FCVAR_DEVELOPMENTONLY, "Inverts the X offset for console notify debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
@ -133,7 +133,7 @@ extern ConVar* bhit_abs_origin;
|
||||
//-------------------------------------------------------------------------
|
||||
// CLIENT |
|
||||
#ifndef DEDICATED
|
||||
extern ConVar* cl_rcon_request_sendlogs;
|
||||
extern ConVar* cl_rcon_inputonly;
|
||||
extern ConVar* cl_quota_stringCmdsPerSecond;
|
||||
|
||||
extern ConVar* cl_cmdrate;
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
m_nIgnoredMessage = 0;
|
||||
m_bValidated = false;
|
||||
m_bAuthorized = false;
|
||||
m_bInputOnly = false;
|
||||
m_bInputOnly = true;
|
||||
m_RecvBuffer.resize(sizeof(u_long)); // Reserve enough for length-prefix.
|
||||
}
|
||||
};
|
||||
|
@ -448,7 +448,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
|
||||
// Tier1
|
||||
REGISTER(VCommandLine);
|
||||
REGISTER(VConCommand);
|
||||
REGISTER(VConVar);
|
||||
REGISTER(VCVar);
|
||||
|
||||
// VPC
|
||||
|
@ -59,7 +59,7 @@ void CRConClient::RunFrame(void)
|
||||
|
||||
if (pData)
|
||||
{
|
||||
Recv(pData);
|
||||
Recv(*pData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -103,33 +103,12 @@ bool CRConClient::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
{
|
||||
if (!response.responseval().empty())
|
||||
{
|
||||
const long i = strtol(response.responseval().c_str(), NULL, NULL);
|
||||
const bool bLocalHost = (g_pNetAdr->ComparePort(m_Address) && g_pNetAdr->CompareAdr(m_Address));
|
||||
const char* szEnable = nullptr;
|
||||
const SocketHandle_t hSocket = GetSocket();
|
||||
const int i = atoi(response.responseval().c_str());
|
||||
|
||||
if (!i) // sv_rcon_sendlogs is not set.
|
||||
// '!i' means we are marked 'input only' on the rcon server.
|
||||
if (!i && ShouldReceive())
|
||||
{
|
||||
if (!bLocalHost && cl_rcon_request_sendlogs->GetBool())
|
||||
{
|
||||
szEnable = "1";
|
||||
}
|
||||
}
|
||||
else if (bLocalHost)
|
||||
{
|
||||
// Don't send logs to local host, it already gets logged to the same console.
|
||||
szEnable = "0";
|
||||
}
|
||||
|
||||
if (szEnable)
|
||||
{
|
||||
vector<char> vecMsg;
|
||||
bool ret = Serialize(vecMsg, "", szEnable, cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
|
||||
|
||||
if (ret && !Send(hSocket, vecMsg.data(), int(vecMsg.size())))
|
||||
{
|
||||
Error(eDLL_T::CLIENT, NO_ERROR, "Failed to send RCON message: (%s)\n", "SOCKET_ERROR");
|
||||
}
|
||||
RequestConsoleLog(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,6 +131,31 @@ bool CRConClient::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: request the rcon server to enable/disable sending logs to us
|
||||
// Input : bWantLog -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConClient::RequestConsoleLog(const bool bWantLog)
|
||||
{
|
||||
// If 'IsRemoteLocal()' returns true, and you called this with 'bWantLog'
|
||||
// true, you caused a bug! It means the server address and port are equal
|
||||
// to the global netadr singleton, which ultimately means we are running on
|
||||
// a listen server. Listen server's already log to the same console,
|
||||
// sending logs will cause the print func to get called recursively forever.
|
||||
Assert(!(bWantLog && IsRemoteLocal()));
|
||||
|
||||
const char* szEnable = bWantLog ? "1" : "0";
|
||||
const SocketHandle_t hSocket = GetSocket();
|
||||
|
||||
vector<char> vecMsg;
|
||||
bool ret = Serialize(vecMsg, "", szEnable, cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
|
||||
|
||||
if (ret && !Send(hSocket, vecMsg.data(), int(vecMsg.size())))
|
||||
{
|
||||
Error(eDLL_T::CLIENT, NO_ERROR, "Failed to send RCON message: (%s)\n", "SOCKET_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: serializes input
|
||||
// Input : *svReqBuf -
|
||||
@ -183,6 +187,23 @@ SocketHandle_t CRConClient::GetSocket(void)
|
||||
return SH_GetNetConSocketHandle(this, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns whether or not we should receive logs from the server
|
||||
// Output : SOCKET_ERROR (-1) on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConClient::ShouldReceive(void)
|
||||
{
|
||||
return (!IsRemoteLocal() && !cl_rcon_inputonly->GetBool());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns whether the rcon server is actually our own listen server
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConClient::IsRemoteLocal(void)
|
||||
{
|
||||
return (g_pNetAdr->ComparePort(m_Address) && g_pNetAdr->CompareAdr(m_Address));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if client rcon is initialized
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -21,6 +21,10 @@ public:
|
||||
bool Serialize(vector<char>& vecBuf, const char* szReqBuf,
|
||||
const char* szReqVal, const cl_rcon::request_t requestType) const;
|
||||
|
||||
void RequestConsoleLog(const bool bWantLog);
|
||||
bool ShouldReceive(void);
|
||||
|
||||
bool IsRemoteLocal(void);
|
||||
bool IsInitialized(void) const;
|
||||
bool IsConnected(void);
|
||||
|
||||
|
@ -18,8 +18,11 @@ inline void(*Cbuf_AddText)(ECommandTarget_t eTarget, const char* pText, cmd_sour
|
||||
inline CMemory p_Cbuf_Execute;
|
||||
inline void(*Cbuf_Execute)(void);
|
||||
|
||||
inline CMemory p_Cmd_Dispatch;
|
||||
inline void(*v_Cmd_Dispatch)(ECommandTarget_t eTarget, const ConCommandBase* pCmdBase, const CCommand* pCommand, bool bCallBackupCallback);
|
||||
|
||||
inline CMemory p_Cmd_ForwardToServer;
|
||||
inline bool(*v_Cmd_ForwardToServer)(const CCommand* args);
|
||||
inline bool(*v_Cmd_ForwardToServer)(const CCommand* pCommand);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VCmd : public IDetour
|
||||
@ -28,16 +31,20 @@ class VCmd : public IDetour
|
||||
{
|
||||
LogFunAdr("Cbuf_AddText", p_Cbuf_AddText.GetPtr());
|
||||
LogFunAdr("Cbuf_Execute", p_Cbuf_Execute.GetPtr());
|
||||
LogFunAdr("Cmd_Dispatch", p_Cmd_Dispatch.GetPtr());
|
||||
LogFunAdr("Cmd_ForwardToServer", p_Cmd_ForwardToServer.GetPtr());
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_Cbuf_AddText = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 63 D9 41 8B F8 48 8D 0D ?? ?? ?? ?? 48 8B F2 FF 15 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 41 B9 ?? ?? ?? ??");
|
||||
p_Cbuf_Execute = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 FF 15 ?? ?? ?? ??");
|
||||
|
||||
p_Cmd_Dispatch = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 8B ?? 0C 49 FF C7").FollowNearCallSelf();
|
||||
p_Cmd_ForwardToServer = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 44 8B 59 04");
|
||||
|
||||
Cbuf_AddText = p_Cbuf_AddText.RCast<void (*)(ECommandTarget_t, const char*, cmd_source_t)>(); /*48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 63 D9 41 8B F8 48 8D 0D ?? ?? ?? ?? 48 8B F2 FF 15 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 41 B9 ?? ?? ?? ??*/
|
||||
Cbuf_Execute = p_Cbuf_Execute.RCast<void (*)(void)>(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 FF 15 ?? ?? ?? ??*/
|
||||
v_Cmd_Dispatch = p_Cmd_Dispatch.RCast<void (*)(ECommandTarget_t, const ConCommandBase*, const CCommand*, bool)>();
|
||||
v_Cmd_ForwardToServer = p_Cmd_ForwardToServer.RCast<bool (*)(const CCommand*)>(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 44 8B 59 04*/
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
|
@ -90,15 +90,15 @@ void CRConServer::Think(void)
|
||||
const int nCount = m_Socket.GetAcceptedSocketCount();
|
||||
|
||||
// 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--)
|
||||
{
|
||||
const netadr_t& netAdr = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
|
||||
if (!m_WhiteListAddress.CompareAdr(netAdr))
|
||||
{
|
||||
const CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
if (!pData->m_bAuthorized)
|
||||
const CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
if (!data.m_bAuthorized)
|
||||
{
|
||||
Disconnect("redundant");
|
||||
}
|
||||
@ -169,18 +169,18 @@ void CRConServer::RunFrame(void)
|
||||
const int nCount = m_Socket.GetAcceptedSocketCount();
|
||||
for (m_nConnIndex = nCount - 1; m_nConnIndex >= 0; m_nConnIndex--)
|
||||
{
|
||||
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
|
||||
if (CheckForBan(pData))
|
||||
if (CheckForBan(data))
|
||||
{
|
||||
SendEncode(pData->m_hSocket, s_BannedMessage, "",
|
||||
SendEncode(data.m_hSocket, s_BannedMessage, "",
|
||||
sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, int(eDLL_T::NETCON));
|
||||
|
||||
Disconnect("banned");
|
||||
continue;
|
||||
}
|
||||
|
||||
Recv(pData, sv_rcon_maxpacketsize->GetInt());
|
||||
Recv(data, sv_rcon_maxpacketsize->GetInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,11 +204,11 @@ bool CRConServer::SendToAll(const char* pMsgBuf, const int nMsgLen) const
|
||||
const int nCount = m_Socket.GetAcceptedSocketCount();
|
||||
for (int i = nCount - 1; i >= 0; i--)
|
||||
{
|
||||
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(i);
|
||||
const CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(i);
|
||||
|
||||
if (pData->m_bAuthorized)
|
||||
if (data.m_bAuthorized && !data.m_bInputOnly)
|
||||
{
|
||||
int ret = ::send(pData->m_hSocket, sendbuf.str().data(),
|
||||
int ret = ::send(data.m_hSocket, sendbuf.str().data(),
|
||||
int(sendbuf.str().size()), MSG_NOSIGNAL);
|
||||
|
||||
if (ret == SOCKET_ERROR)
|
||||
@ -315,11 +315,11 @@ bool CRConServer::Serialize(vector<char>& vecBuf, const char* pResponseMsg, cons
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: authenticate new connections
|
||||
// Input : &request -
|
||||
// *pData -
|
||||
// &data -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Authenticate(const cl_rcon::request& request, CConnectedNetConsoleData* pData)
|
||||
void CRConServer::Authenticate(const cl_rcon::request& request, CConnectedNetConsoleData& data)
|
||||
{
|
||||
if (pData->m_bAuthorized)
|
||||
if (data.m_bAuthorized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -327,14 +327,16 @@ void CRConServer::Authenticate(const cl_rcon::request& request, CConnectedNetCon
|
||||
{
|
||||
if (Comparator(request.requestmsg()))
|
||||
{
|
||||
pData->m_bAuthorized = true;
|
||||
data.m_bAuthorized = true;
|
||||
if (++m_nAuthConnections >= sv_rcon_maxconnections->GetInt())
|
||||
{
|
||||
m_Socket.CloseListenSocket();
|
||||
CloseNonAuthConnection();
|
||||
}
|
||||
|
||||
SendEncode(pData->m_hSocket, s_AuthMessage, sv_rcon_sendlogs->GetString(),
|
||||
const char* pSendLogs = (!sv_rcon_sendlogs->GetBool() || data.m_bInputOnly) ? "0" : "1";
|
||||
|
||||
SendEncode(data.m_hSocket, s_AuthMessage, pSendLogs,
|
||||
sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
|
||||
}
|
||||
else // Bad password.
|
||||
@ -345,12 +347,12 @@ void CRConServer::Authenticate(const cl_rcon::request& request, CConnectedNetCon
|
||||
DevMsg(eDLL_T::SERVER, "Bad RCON password attempt from '%s'\n", netAdr.ToString());
|
||||
}
|
||||
|
||||
SendEncode(pData->m_hSocket, s_WrongPwMessage, "",
|
||||
SendEncode(data.m_hSocket, s_WrongPwMessage, "",
|
||||
sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
|
||||
|
||||
pData->m_bAuthorized = false;
|
||||
pData->m_bValidated = false;
|
||||
pData->m_nFailedAttempts++;
|
||||
data.m_bAuthorized = false;
|
||||
data.m_bValidated = false;
|
||||
data.m_nFailedAttempts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -385,7 +387,7 @@ bool CRConServer::Comparator(const string& svPassword) const
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
{
|
||||
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
|
||||
cl_rcon::request request;
|
||||
if (!Decode(&request, pMsgBuf, nMsgLen))
|
||||
@ -394,45 +396,38 @@ bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pData->m_bAuthorized &&
|
||||
if (!data.m_bAuthorized &&
|
||||
request.requesttype() != cl_rcon::request_t::SERVERDATA_REQUEST_AUTH)
|
||||
{
|
||||
// Notify netconsole that authentication is required.
|
||||
SendEncode(pData->m_hSocket, s_NoAuthMessage, "",
|
||||
SendEncode(data.m_hSocket, s_NoAuthMessage, "",
|
||||
sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
|
||||
|
||||
pData->m_bValidated = false;
|
||||
pData->m_nIgnoredMessage++;
|
||||
data.m_bValidated = false;
|
||||
data.m_nIgnoredMessage++;
|
||||
return true;
|
||||
}
|
||||
switch (request.requesttype())
|
||||
{
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_AUTH:
|
||||
{
|
||||
Authenticate(request, pData);
|
||||
Authenticate(request, data);
|
||||
break;
|
||||
}
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND:
|
||||
{
|
||||
if (pData->m_bAuthorized) // Only execute if auth was successful.
|
||||
if (data.m_bAuthorized) // Only execute if auth was successful.
|
||||
{
|
||||
Execute(request, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_SETVALUE:
|
||||
{
|
||||
if (pData->m_bAuthorized)
|
||||
{
|
||||
Execute(request, true);
|
||||
Execute(request);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG:
|
||||
{
|
||||
if (pData->m_bAuthorized)
|
||||
if (data.m_bAuthorized)
|
||||
{
|
||||
sv_rcon_sendlogs->SetValue(request.requestval().c_str());
|
||||
// "0" means the netconsole is input only.
|
||||
data.m_bInputOnly = !atoi(request.requestval().c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -446,33 +441,44 @@ bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: execute commands issued from netconsole
|
||||
// Input : *request -
|
||||
// bConVar -
|
||||
// Purpose: execute commands issued from netconsole (ignores all protection flags)
|
||||
// Input : &request -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Execute(const cl_rcon::request& request, const bool bConVar) const
|
||||
void CRConServer::Execute(const cl_rcon::request& request) const
|
||||
{
|
||||
if (bConVar)
|
||||
const char* pCommandString = request.requestmsg().c_str();
|
||||
ConCommandBase* pCommandBase = g_pCVar->FindCommandBase(pCommandString);
|
||||
|
||||
if (!pCommandBase)
|
||||
{
|
||||
ConVar* pConVar = g_pCVar->FindVar(request.requestmsg().c_str());
|
||||
if (pConVar) // Only run if this is a ConVar.
|
||||
{
|
||||
pConVar->SetValue(request.requestval().c_str());
|
||||
}
|
||||
// Found nothing.
|
||||
return;
|
||||
}
|
||||
else // Execute command with "<val>".
|
||||
|
||||
const bool isCommand = pCommandBase->IsCommand();
|
||||
const char* pValueString = request.requestval().c_str();
|
||||
|
||||
if (!isCommand)
|
||||
{
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), request.requestmsg().c_str(), cmd_source_t::kCommandSrcCode);
|
||||
ConVar* pConVar = reinterpret_cast<ConVar*>(pCommandBase);
|
||||
pConVar->SetValue(pValueString);
|
||||
}
|
||||
else // Invoke command callback directly.
|
||||
{
|
||||
CCommand cmd;
|
||||
cmd.Tokenize(pValueString, cmd_source_t::kCommandSrcCode);
|
||||
|
||||
v_Cmd_Dispatch(ECommandTarget_t::CBUF_SERVER, pCommandBase, &cmd, false);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks for amount of failed attempts and bans netconsole accordingly
|
||||
// Input : *pData -
|
||||
// Input : &data -
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConServer::CheckForBan(CConnectedNetConsoleData* pData)
|
||||
bool CRConServer::CheckForBan(CConnectedNetConsoleData& data)
|
||||
{
|
||||
if (pData->m_bValidated)
|
||||
if (data.m_bValidated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -503,7 +509,7 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData* pData)
|
||||
}
|
||||
}
|
||||
|
||||
pData->m_bValidated = true;
|
||||
data.m_bValidated = true;
|
||||
|
||||
// Check if IP is in the banned list.
|
||||
if (m_BannedList.find(szNetAdr) != m_BannedList.end())
|
||||
@ -512,14 +518,14 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData* pData)
|
||||
}
|
||||
|
||||
// Check if netconsole has reached maximum number of attempts > add to banned list.
|
||||
if (pData->m_nFailedAttempts >= sv_rcon_maxfailures->GetInt()
|
||||
|| pData->m_nIgnoredMessage >= sv_rcon_maxignores->GetInt())
|
||||
if (data.m_nFailedAttempts >= sv_rcon_maxfailures->GetInt()
|
||||
|| data.m_nIgnoredMessage >= sv_rcon_maxignores->GetInt())
|
||||
{
|
||||
// Don't add white listed address to banned list.
|
||||
if (m_WhiteListAddress.CompareAdr(netAdr))
|
||||
{
|
||||
pData->m_nFailedAttempts = 0;
|
||||
pData->m_nIgnoredMessage = 0;
|
||||
data.m_nFailedAttempts = 0;
|
||||
data.m_nIgnoredMessage = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -545,8 +551,8 @@ void CRConServer::Disconnect(const char* szReason) // NETMGR
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Disconnect(const int nIndex, const char* szReason) // NETMGR
|
||||
{
|
||||
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(nIndex);
|
||||
if (pData->m_bAuthorized || sv_rcon_debug->GetBool())
|
||||
CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(nIndex);
|
||||
if (data.m_bAuthorized || sv_rcon_debug->GetBool())
|
||||
{
|
||||
// Inform server owner when authenticated connection has been closed.
|
||||
netadr_t netAdr = m_Socket.GetAcceptedSocketAddress(nIndex);
|
||||
@ -570,9 +576,9 @@ void CRConServer::CloseNonAuthConnection(void)
|
||||
int nCount = m_Socket.GetAcceptedSocketCount();
|
||||
for (int i = nCount - 1; i >= 0; i--)
|
||||
{
|
||||
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(i);
|
||||
CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(i);
|
||||
|
||||
if (!pData->m_bAuthorized)
|
||||
if (!data.m_bAuthorized)
|
||||
{
|
||||
m_Socket.CloseAcceptedSocket(i);
|
||||
}
|
||||
|
@ -37,13 +37,13 @@ public:
|
||||
bool Serialize(vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal, const sv_rcon::response_t responseType,
|
||||
const int nMessageId = static_cast<int>(eDLL_T::NETCON), const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const;
|
||||
|
||||
void Authenticate(const cl_rcon::request& request, CConnectedNetConsoleData* pData);
|
||||
void Authenticate(const cl_rcon::request& request, CConnectedNetConsoleData& data);
|
||||
bool Comparator(const string& svPassword) const;
|
||||
|
||||
virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override;
|
||||
|
||||
void Execute(const cl_rcon::request& request, const bool bConVar) const;
|
||||
bool CheckForBan(CConnectedNetConsoleData* pData);
|
||||
void Execute(const cl_rcon::request& request) const;
|
||||
bool CheckForBan(CConnectedNetConsoleData& data);
|
||||
|
||||
virtual void Disconnect(const char* szReason = nullptr) override;
|
||||
void Disconnect(const int nIndex, const char* szReason = nullptr);
|
||||
|
@ -8,6 +8,93 @@
|
||||
#include "engine/net.h"
|
||||
#include "shared_rcon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: connect to remote
|
||||
// Input : *pHostName -
|
||||
// nPort -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetConBase::Connect(const char* pHostName, const int nPort)
|
||||
{
|
||||
return CL_NetConConnect(this, pHostName, nPort);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: parses input response buffer using length-prefix framing
|
||||
// Input : &data -
|
||||
// *pRecvBuf -
|
||||
// nRecvLen -
|
||||
// nMaxLen -
|
||||
// Output: true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetConBase::ProcessBuffer(CConnectedNetConsoleData& data,
|
||||
const char* pRecvBuf, int nRecvLen, const int nMaxLen)
|
||||
{
|
||||
bool bSuccess = true;
|
||||
|
||||
while (nRecvLen > 0)
|
||||
{
|
||||
if (data.m_nPayloadLen)
|
||||
{
|
||||
if (data.m_nPayloadRead < data.m_nPayloadLen)
|
||||
{
|
||||
data.m_RecvBuffer[data.m_nPayloadRead++] = *pRecvBuf;
|
||||
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
if (data.m_nPayloadRead == data.m_nPayloadLen)
|
||||
{
|
||||
if (!ProcessMessage(
|
||||
reinterpret_cast<const char*>(data.m_RecvBuffer.data()), data.m_nPayloadLen)
|
||||
&& bSuccess)
|
||||
{
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
data.m_nPayloadLen = 0;
|
||||
data.m_nPayloadRead = 0;
|
||||
}
|
||||
}
|
||||
else if (data.m_nPayloadRead+1 <= sizeof(int)) // Read size field.
|
||||
{
|
||||
data.m_RecvBuffer[data.m_nPayloadRead++] = *pRecvBuf;
|
||||
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
else // Build prefix.
|
||||
{
|
||||
data.m_nPayloadLen = int(ntohl(*reinterpret_cast<u_long*>(&data.m_RecvBuffer[0])));
|
||||
data.m_nPayloadRead = 0;
|
||||
|
||||
if (!data.m_bAuthorized && nMaxLen > -1)
|
||||
{
|
||||
if (data.m_nPayloadLen > nMaxLen)
|
||||
{
|
||||
Disconnect("overflow"); // Sending large messages while not authenticated.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.m_nPayloadLen < 0 ||
|
||||
data.m_nPayloadLen > data.m_RecvBuffer.max_size())
|
||||
{
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "RCON Cmd: sync error (%d)\n", data.m_nPayloadLen);
|
||||
Disconnect("desync"); // Out of sync (irrecoverable).
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.m_RecvBuffer.resize(data.m_nPayloadLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: encode message to buffer
|
||||
// Input : *pMsg -
|
||||
@ -34,17 +121,6 @@ bool CNetConBase::Decode(google::protobuf::MessageLite* pMsg,
|
||||
return pMsg->ParseFromArray(pMsgBuf, int(nMsgLen));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: connect to remote
|
||||
// Input : *pHostName -
|
||||
// nPort -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetConBase::Connect(const char* pHostName, const int nPort)
|
||||
{
|
||||
return CL_NetConConnect(this, pHostName, nPort);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: send message to specific connected socket
|
||||
// Input : hSocket -
|
||||
@ -69,23 +145,16 @@ bool CNetConBase::Send(const SocketHandle_t hSocket, const char* pMsgBuf,
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: receive message
|
||||
// Input : *pData -
|
||||
// Input : &data -
|
||||
// nMaxLen -
|
||||
// Output: true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetConBase::Recv(CConnectedNetConsoleData* pData, const int nMaxLen)
|
||||
void CNetConBase::Recv(CConnectedNetConsoleData& data, const int nMaxLen)
|
||||
{
|
||||
if (!pData)
|
||||
{
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "RCON Cmd: invalid input data\n");
|
||||
Assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
static char szRecvBuf[1024];
|
||||
|
||||
{//////////////////////////////////////////////
|
||||
const int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
|
||||
const int nPendingLen = ::recv(data.m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
|
||||
if (nPendingLen == SOCKET_ERROR && m_Socket.IsSocketBlocking())
|
||||
{
|
||||
return;
|
||||
@ -95,10 +164,15 @@ void CNetConBase::Recv(CConnectedNetConsoleData* pData, const int nMaxLen)
|
||||
Disconnect("remote closed socket");
|
||||
return;
|
||||
}
|
||||
else if (nPendingLen < 0)
|
||||
{
|
||||
Disconnect("socket closed unexpectedly");
|
||||
return;
|
||||
}
|
||||
}//////////////////////////////////////////////
|
||||
|
||||
int nReadLen = 0; // Find out how much we have to read.
|
||||
int iResult = ::ioctlsocket(pData->m_hSocket, FIONREAD, reinterpret_cast<u_long*>(&nReadLen));
|
||||
int iResult = ::ioctlsocket(data.m_hSocket, FIONREAD, reinterpret_cast<u_long*>(&nReadLen));
|
||||
|
||||
if (iResult == SOCKET_ERROR)
|
||||
{
|
||||
@ -108,10 +182,10 @@ void CNetConBase::Recv(CConnectedNetConsoleData* pData, const int nMaxLen)
|
||||
|
||||
while (nReadLen > 0)
|
||||
{
|
||||
const int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
|
||||
const int nRecvLen = ::recv(data.m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
|
||||
if (nRecvLen == 0) // Socket was closed.
|
||||
{
|
||||
Disconnect("socket closed unexpectedly");
|
||||
Disconnect("socket closed");
|
||||
break;
|
||||
}
|
||||
if (nRecvLen < 0 && !m_Socket.IsSocketBlocking())
|
||||
@ -121,83 +195,8 @@ void CNetConBase::Recv(CConnectedNetConsoleData* pData, const int nMaxLen)
|
||||
}
|
||||
|
||||
nReadLen -= nRecvLen; // Process what we've got.
|
||||
ProcessBuffer(pData, szRecvBuf, nRecvLen, nMaxLen);
|
||||
ProcessBuffer(data, szRecvBuf, nRecvLen, nMaxLen);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: parses input response buffer using length-prefix framing
|
||||
// Input : *pRecvBuf -
|
||||
// nRecvLen -
|
||||
// *pData -
|
||||
// Output: true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetConBase::ProcessBuffer(CConnectedNetConsoleData* pData,
|
||||
const char* pRecvBuf, int nRecvLen, const int nMaxLen)
|
||||
{
|
||||
bool bSuccess = true;
|
||||
|
||||
while (nRecvLen > 0)
|
||||
{
|
||||
if (pData->m_nPayloadLen)
|
||||
{
|
||||
if (pData->m_nPayloadRead < pData->m_nPayloadLen)
|
||||
{
|
||||
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
|
||||
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
if (pData->m_nPayloadRead == pData->m_nPayloadLen)
|
||||
{
|
||||
if (!ProcessMessage(
|
||||
reinterpret_cast<const char*>(pData->m_RecvBuffer.data()), pData->m_nPayloadLen)
|
||||
&& bSuccess)
|
||||
{
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
pData->m_nPayloadLen = 0;
|
||||
pData->m_nPayloadRead = 0;
|
||||
}
|
||||
}
|
||||
else if (pData->m_nPayloadRead+1 <= sizeof(int)) // Read size field.
|
||||
{
|
||||
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
|
||||
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
else // Build prefix.
|
||||
{
|
||||
pData->m_nPayloadLen = int(ntohl(*reinterpret_cast<u_long*>(&pData->m_RecvBuffer[0])));
|
||||
pData->m_nPayloadRead = 0;
|
||||
|
||||
if (!pData->m_bAuthorized && nMaxLen > -1)
|
||||
{
|
||||
if (pData->m_nPayloadLen > nMaxLen)
|
||||
{
|
||||
Disconnect("overflow"); // Sending large messages while not authenticated.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (pData->m_nPayloadLen < 0 ||
|
||||
pData->m_nPayloadLen > pData->m_RecvBuffer.max_size())
|
||||
{
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "RCON Cmd: sync error (%d)\n", pData->m_nPayloadLen);
|
||||
Disconnect("desync"); // Out of sync (irrecoverable).
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->m_RecvBuffer.resize(pData->m_nPayloadLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
@ -11,18 +11,18 @@ public:
|
||||
CNetConBase(void)
|
||||
{}
|
||||
|
||||
virtual bool Encode(google::protobuf::MessageLite* pMsg, char* pMsgBuf, const size_t nMsgLen) const;
|
||||
virtual bool Decode(google::protobuf::MessageLite* pMsg, const char* pMsgBuf, const size_t nMsgLen) const;
|
||||
|
||||
virtual bool Connect(const char* pHostAdr, const int nHostPort = SOCKET_ERROR);
|
||||
virtual void Disconnect(const char* szReason = nullptr) { NOTE_UNUSED(szReason); };
|
||||
|
||||
virtual bool Send(const SocketHandle_t hSocket, const char* pMsgBuf, const int nMsgLen) const;
|
||||
virtual void Recv(CConnectedNetConsoleData* pData, const int nMaxLen = SOCKET_ERROR);
|
||||
|
||||
virtual bool ProcessBuffer(CConnectedNetConsoleData* pData, const char* pRecvBuf, int nRecvLen, const int nMaxLen = SOCKET_ERROR);
|
||||
virtual bool ProcessBuffer(CConnectedNetConsoleData& data, const char* pRecvBuf, int nRecvLen, const int nMaxLen = SOCKET_ERROR);
|
||||
virtual bool ProcessMessage(const char* /*pMsgBuf*/, int /*nMsgLen*/) { return true; };
|
||||
|
||||
virtual bool Encode(google::protobuf::MessageLite* pMsg, char* pMsgBuf, const size_t nMsgLen) const;
|
||||
virtual bool Decode(google::protobuf::MessageLite* pMsg, const char* pMsgBuf, const size_t nMsgLen) const;
|
||||
|
||||
virtual bool Send(const SocketHandle_t hSocket, const char* pMsgBuf, const int nMsgLen) const;
|
||||
virtual void Recv(CConnectedNetConsoleData& data, const int nMaxLen = SOCKET_ERROR);
|
||||
|
||||
CSocketCreator* GetSocketCreator(void) { return &m_Socket; }
|
||||
netadr_t* GetNetAddress(void) { return &m_Address; }
|
||||
|
||||
|
@ -91,7 +91,7 @@ bool CL_NetConConnect(CNetConBase* pBase, const char* pHostAdr, const int nHostP
|
||||
//-----------------------------------------------------------------------------
|
||||
CConnectedNetConsoleData* SH_GetNetConData(CNetConBase* pBase, const int iSocket)
|
||||
{
|
||||
const CSocketCreator* pCreator = pBase->GetSocketCreator();
|
||||
CSocketCreator* pCreator = pBase->GetSocketCreator();
|
||||
Assert(iSocket >= 0 && (pCreator->GetAcceptedSocketCount() == 0
|
||||
|| iSocket < pCreator->GetAcceptedSocketCount()));
|
||||
|
||||
@ -100,7 +100,7 @@ CConnectedNetConsoleData* SH_GetNetConData(CNetConBase* pBase, const int iSocket
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return pCreator->GetAcceptedSocketData(iSocket);
|
||||
return &pCreator->GetAcceptedSocketData(iSocket);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -26,6 +26,10 @@ CNetCon::CNetCon(void)
|
||||
, m_bPromptConnect(true)
|
||||
, m_flTickInterval(0.05f)
|
||||
{
|
||||
// Empty character set used for ip addresses if we still need to initiate a
|
||||
// connection, as we don't want to break on ':' characters found in an IPv6
|
||||
// address.
|
||||
CharacterSetBuild(&m_CharacterSet, "");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -39,7 +43,7 @@ CNetCon::~CNetCon(void)
|
||||
// Purpose: WSA and NETCON systems init
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetCon::Init(void)
|
||||
bool CNetCon::Init(const bool bAnsiColor)
|
||||
{
|
||||
g_CoreMsgVCallback = &EngineLoggerSink;
|
||||
|
||||
@ -54,7 +58,7 @@ bool CNetCon::Init(void)
|
||||
|
||||
m_bInitialized = true;
|
||||
|
||||
TermSetup();
|
||||
TermSetup(bAnsiColor);
|
||||
DevMsg(eDLL_T::NONE, "R5 TCP net console [Version %s]\n", NETCON_VERSION);
|
||||
|
||||
static std::thread frame([this]()
|
||||
@ -99,13 +103,10 @@ bool CNetCon::Shutdown(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: terminal setup
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetCon::TermSetup(void)
|
||||
void CNetCon::TermSetup(const bool bAnsiColor)
|
||||
{
|
||||
const char* pszCommandLine = GetCommandLineA();
|
||||
const bool bEnableColor = strstr("-ansicolor", pszCommandLine) != nullptr;
|
||||
|
||||
SpdLog_Init(bEnableColor);
|
||||
Console_Init(bEnableColor);
|
||||
SpdLog_Init(bAnsiColor);
|
||||
Console_Init(bAnsiColor);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -122,38 +123,33 @@ void CNetCon::UserInput(void)
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> l(m_Mutex);
|
||||
|
||||
if (IsConnected())
|
||||
{
|
||||
if (m_Input.compare("disconnect") == 0)
|
||||
CCommand cmd;
|
||||
cmd.Tokenize(m_Input.c_str());
|
||||
|
||||
if (V_strcmp(cmd.Arg(0), "disconnect") == 0)
|
||||
{
|
||||
Disconnect("user closed connection");
|
||||
return;
|
||||
}
|
||||
|
||||
const vector<string> vSubStrings = StringSplit(m_Input, ' ', 2);
|
||||
vector<char> vecMsg;
|
||||
|
||||
const SocketHandle_t hSocket = GetSocket();
|
||||
bool bSend = false;
|
||||
|
||||
if (vSubStrings.size() > 1)
|
||||
if (cmd.ArgC() > 1)
|
||||
{
|
||||
if (vSubStrings[0].compare("PASS") == 0) // Auth with RCON server.
|
||||
if (V_strcmp(cmd.Arg(0), "PASS") == 0) // Auth with RCON server.
|
||||
{
|
||||
bSend = Serialize(vecMsg, vSubStrings[1].c_str(), "",
|
||||
bSend = Serialize(vecMsg, cmd.Arg(1), "",
|
||||
cl_rcon::request_t::SERVERDATA_REQUEST_AUTH);
|
||||
}
|
||||
else if (vSubStrings[0].compare("SET") == 0) // Set value query.
|
||||
{
|
||||
if (vSubStrings.size() > 2)
|
||||
{
|
||||
bSend = Serialize(vecMsg, vSubStrings[1].c_str(), vSubStrings[2].c_str(),
|
||||
cl_rcon::request_t::SERVERDATA_REQUEST_SETVALUE);
|
||||
}
|
||||
}
|
||||
else // Execute command query.
|
||||
{
|
||||
bSend = Serialize(vecMsg, m_Input.c_str(), "",
|
||||
bSend = Serialize(vecMsg, cmd.Arg(0), cmd.GetCommandString(),
|
||||
cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND);
|
||||
}
|
||||
}
|
||||
@ -172,34 +168,30 @@ void CNetCon::UserInput(void)
|
||||
}
|
||||
else // Setup connection from input.
|
||||
{
|
||||
const vector<string> vSubStrings = StringSplit(m_Input, ' ', 2);
|
||||
if (vSubStrings.size() > 1)
|
||||
CCommand cmd;
|
||||
cmd.Tokenize(m_Input.c_str(), cmd_source_t::kCommandSrcCode, &m_CharacterSet);
|
||||
|
||||
if (cmd.ArgC() > 1)
|
||||
{
|
||||
const string::size_type nPos = m_Input.find(' ');
|
||||
if (nPos > 0
|
||||
&& nPos < m_Input.size()
|
||||
&& nPos != m_Input.size())
|
||||
const char* inAddr = cmd.Arg(0);
|
||||
const char* inPort = cmd.Arg(1);
|
||||
|
||||
if (!*inAddr || !*inPort)
|
||||
{
|
||||
string svInPort = m_Input.substr(nPos + 1);
|
||||
string svInAdr = m_Input.erase(m_Input.find(' '));
|
||||
Warning(eDLL_T::CLIENT, "No IP address or port provided\n");
|
||||
m_bPromptConnect = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (svInPort.empty() || svInAdr.empty())
|
||||
{
|
||||
Warning(eDLL_T::CLIENT, "No IP address or port provided\n");
|
||||
m_bPromptConnect = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Connect(svInAdr.c_str(), atoi(svInPort.c_str())))
|
||||
{
|
||||
m_bPromptConnect = true;
|
||||
return;
|
||||
}
|
||||
if (!Connect(inAddr, atoi(inPort)))
|
||||
{
|
||||
m_bPromptConnect = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else // Initialize as [ip]:port.
|
||||
else
|
||||
{
|
||||
if (m_Input.empty() || !Connect(m_Input.c_str()))
|
||||
if (!Connect(cmd.GetCommandString()))
|
||||
{
|
||||
m_bPromptConnect = true;
|
||||
return;
|
||||
@ -226,7 +218,7 @@ void CNetCon::RunFrame(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> l(m_Mutex);
|
||||
|
||||
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(0);
|
||||
CConnectedNetConsoleData& pData = m_Socket.GetAcceptedSocketData(0);
|
||||
Recv(pData);
|
||||
}
|
||||
else if (m_bPromptConnect)
|
||||
@ -291,7 +283,7 @@ bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
if (!response.responseval().empty())
|
||||
{
|
||||
const long i = strtol(response.responseval().c_str(), NULL, NULL);
|
||||
if (!i) // sv_rcon_sendlogs is not set.
|
||||
if (!i) // Means we are marked 'input only' on the rcon server.
|
||||
{
|
||||
vector<char> vecMsg;
|
||||
bool ret = Serialize(vecMsg, "", "1", cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
|
||||
@ -368,7 +360,18 @@ bool CNetCon::IsConnected(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (!NetConsole()->Init())
|
||||
bool bEnableColor = false;
|
||||
|
||||
for (int i = 0; i < argc; i++)
|
||||
{
|
||||
if (V_strcmp(argv[i], "-ansicolor") == NULL)
|
||||
{
|
||||
bEnableColor = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NetConsole()->Init(bEnableColor))
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
//
|
||||
//===========================================================================//
|
||||
#pragma once
|
||||
#include "tier1/cmd.h"
|
||||
#include "protoc/cl_rcon.pb.h"
|
||||
#include "protoc/sv_rcon.pb.h"
|
||||
#include "engine/shared/base_rcon.h"
|
||||
@ -16,10 +17,10 @@ public:
|
||||
CNetCon(void);
|
||||
~CNetCon(void);
|
||||
|
||||
bool Init(void);
|
||||
bool Init(const bool bAnsiColor);
|
||||
bool Shutdown(void);
|
||||
|
||||
void TermSetup(void);
|
||||
void TermSetup(const bool bAnsiColor);
|
||||
void UserInput(void);
|
||||
void ClearInput(void);
|
||||
|
||||
@ -42,6 +43,8 @@ private:
|
||||
bool m_bPromptConnect;
|
||||
float m_flTickInterval;
|
||||
|
||||
characterset_t m_CharacterSet;
|
||||
|
||||
std::string m_Input;
|
||||
mutable std::mutex m_Mutex;
|
||||
};
|
||||
|
@ -43,41 +43,29 @@ bool request_t_IsValid(int value) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<std::string> request_t_strings[6] = {};
|
||||
static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<std::string> request_t_strings[3] = {};
|
||||
|
||||
static const char request_t_names[] =
|
||||
"SERVERDATA_REQUEST_AUTH"
|
||||
"SERVERDATA_REQUEST_EXECCOMMAND"
|
||||
"SERVERDATA_REQUEST_SEND_CONSOLE_LOG"
|
||||
"SERVERDATA_REQUEST_SEND_REMOTEBUG"
|
||||
"SERVERDATA_REQUEST_SETVALUE"
|
||||
"SERVERDATA_REQUEST_VALUE";
|
||||
"SERVERDATA_REQUEST_SEND_CONSOLE_LOG";
|
||||
|
||||
static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry request_t_entries[] = {
|
||||
{ {request_t_names + 0, 23}, 3 },
|
||||
{ {request_t_names + 23, 30}, 2 },
|
||||
{ {request_t_names + 53, 35}, 4 },
|
||||
{ {request_t_names + 88, 33}, 5 },
|
||||
{ {request_t_names + 121, 27}, 1 },
|
||||
{ {request_t_names + 148, 24}, 0 },
|
||||
{ {request_t_names + 0, 23}, 1 },
|
||||
{ {request_t_names + 23, 30}, 0 },
|
||||
{ {request_t_names + 53, 35}, 2 },
|
||||
};
|
||||
|
||||
static const int request_t_entries_by_number[] = {
|
||||
5, // 0 -> SERVERDATA_REQUEST_VALUE
|
||||
4, // 1 -> SERVERDATA_REQUEST_SETVALUE
|
||||
1, // 2 -> SERVERDATA_REQUEST_EXECCOMMAND
|
||||
0, // 3 -> SERVERDATA_REQUEST_AUTH
|
||||
2, // 4 -> SERVERDATA_REQUEST_SEND_CONSOLE_LOG
|
||||
3, // 5 -> SERVERDATA_REQUEST_SEND_REMOTEBUG
|
||||
1, // 0 -> SERVERDATA_REQUEST_EXECCOMMAND
|
||||
0, // 1 -> SERVERDATA_REQUEST_AUTH
|
||||
2, // 2 -> SERVERDATA_REQUEST_SEND_CONSOLE_LOG
|
||||
};
|
||||
|
||||
const std::string& request_t_Name(
|
||||
@ -86,12 +74,12 @@ const std::string& request_t_Name(
|
||||
::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings(
|
||||
request_t_entries,
|
||||
request_t_entries_by_number,
|
||||
6, request_t_strings);
|
||||
3, request_t_strings);
|
||||
(void) dummy;
|
||||
int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName(
|
||||
request_t_entries,
|
||||
request_t_entries_by_number,
|
||||
6, value);
|
||||
3, value);
|
||||
return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() :
|
||||
request_t_strings[idx].get();
|
||||
}
|
||||
@ -99,7 +87,7 @@ bool request_t_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, request_t* value) {
|
||||
int int_value;
|
||||
bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue(
|
||||
request_t_entries, 6, name, &int_value);
|
||||
request_t_entries, 3, name, &int_value);
|
||||
if (success) {
|
||||
*value = static_cast<request_t>(int_value);
|
||||
}
|
||||
|
@ -53,18 +53,15 @@ PROTOBUF_NAMESPACE_CLOSE
|
||||
namespace cl_rcon {
|
||||
|
||||
enum request_t : int {
|
||||
SERVERDATA_REQUEST_VALUE = 0,
|
||||
SERVERDATA_REQUEST_SETVALUE = 1,
|
||||
SERVERDATA_REQUEST_EXECCOMMAND = 2,
|
||||
SERVERDATA_REQUEST_AUTH = 3,
|
||||
SERVERDATA_REQUEST_SEND_CONSOLE_LOG = 4,
|
||||
SERVERDATA_REQUEST_SEND_REMOTEBUG = 5,
|
||||
SERVERDATA_REQUEST_EXECCOMMAND = 0,
|
||||
SERVERDATA_REQUEST_AUTH = 1,
|
||||
SERVERDATA_REQUEST_SEND_CONSOLE_LOG = 2,
|
||||
request_t_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(),
|
||||
request_t_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max()
|
||||
};
|
||||
bool request_t_IsValid(int value);
|
||||
constexpr request_t request_t_MIN = SERVERDATA_REQUEST_VALUE;
|
||||
constexpr request_t request_t_MAX = SERVERDATA_REQUEST_SEND_REMOTEBUG;
|
||||
constexpr request_t request_t_MIN = SERVERDATA_REQUEST_EXECCOMMAND;
|
||||
constexpr request_t request_t_MAX = SERVERDATA_REQUEST_SEND_CONSOLE_LOG;
|
||||
constexpr int request_t_ARRAYSIZE = request_t_MAX + 1;
|
||||
|
||||
const std::string& request_t_Name(request_t value);
|
||||
|
@ -42,42 +42,26 @@ bool response_t_IsValid(int value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<std::string> response_t_strings[6] = {};
|
||||
static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<std::string> response_t_strings[2] = {};
|
||||
|
||||
static const char response_t_names[] =
|
||||
"SERVERDATA_RESPONSE_AUTH"
|
||||
"SERVERDATA_RESPONSE_CONSOLE_LOG"
|
||||
"SERVERDATA_RESPONSE_REMOTEBUG"
|
||||
"SERVERDATA_RESPONSE_STRING"
|
||||
"SERVERDATA_RESPONSE_UPDATE"
|
||||
"SERVERDATA_RESPONSE_VALUE";
|
||||
"SERVERDATA_RESPONSE_CONSOLE_LOG";
|
||||
|
||||
static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry response_t_entries[] = {
|
||||
{ {response_t_names + 0, 24}, 2 },
|
||||
{ {response_t_names + 24, 31}, 3 },
|
||||
{ {response_t_names + 55, 29}, 5 },
|
||||
{ {response_t_names + 84, 26}, 4 },
|
||||
{ {response_t_names + 110, 26}, 1 },
|
||||
{ {response_t_names + 136, 25}, 0 },
|
||||
{ {response_t_names + 0, 24}, 0 },
|
||||
{ {response_t_names + 24, 31}, 1 },
|
||||
};
|
||||
|
||||
static const int response_t_entries_by_number[] = {
|
||||
5, // 0 -> SERVERDATA_RESPONSE_VALUE
|
||||
4, // 1 -> SERVERDATA_RESPONSE_UPDATE
|
||||
0, // 2 -> SERVERDATA_RESPONSE_AUTH
|
||||
1, // 3 -> SERVERDATA_RESPONSE_CONSOLE_LOG
|
||||
3, // 4 -> SERVERDATA_RESPONSE_STRING
|
||||
2, // 5 -> SERVERDATA_RESPONSE_REMOTEBUG
|
||||
0, // 0 -> SERVERDATA_RESPONSE_AUTH
|
||||
1, // 1 -> SERVERDATA_RESPONSE_CONSOLE_LOG
|
||||
};
|
||||
|
||||
const std::string& response_t_Name(
|
||||
@ -86,12 +70,12 @@ const std::string& response_t_Name(
|
||||
::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings(
|
||||
response_t_entries,
|
||||
response_t_entries_by_number,
|
||||
6, response_t_strings);
|
||||
2, response_t_strings);
|
||||
(void) dummy;
|
||||
int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName(
|
||||
response_t_entries,
|
||||
response_t_entries_by_number,
|
||||
6, value);
|
||||
2, value);
|
||||
return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() :
|
||||
response_t_strings[idx].get();
|
||||
}
|
||||
@ -99,7 +83,7 @@ bool response_t_Parse(
|
||||
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, response_t* value) {
|
||||
int int_value;
|
||||
bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue(
|
||||
response_t_entries, 6, name, &int_value);
|
||||
response_t_entries, 2, name, &int_value);
|
||||
if (success) {
|
||||
*value = static_cast<response_t>(int_value);
|
||||
}
|
||||
|
@ -53,18 +53,14 @@ PROTOBUF_NAMESPACE_CLOSE
|
||||
namespace sv_rcon {
|
||||
|
||||
enum response_t : int {
|
||||
SERVERDATA_RESPONSE_VALUE = 0,
|
||||
SERVERDATA_RESPONSE_UPDATE = 1,
|
||||
SERVERDATA_RESPONSE_AUTH = 2,
|
||||
SERVERDATA_RESPONSE_CONSOLE_LOG = 3,
|
||||
SERVERDATA_RESPONSE_STRING = 4,
|
||||
SERVERDATA_RESPONSE_REMOTEBUG = 5,
|
||||
SERVERDATA_RESPONSE_AUTH = 0,
|
||||
SERVERDATA_RESPONSE_CONSOLE_LOG = 1,
|
||||
response_t_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(),
|
||||
response_t_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max()
|
||||
};
|
||||
bool response_t_IsValid(int value);
|
||||
constexpr response_t response_t_MIN = SERVERDATA_RESPONSE_VALUE;
|
||||
constexpr response_t response_t_MAX = SERVERDATA_RESPONSE_REMOTEBUG;
|
||||
constexpr response_t response_t_MIN = SERVERDATA_RESPONSE_AUTH;
|
||||
constexpr response_t response_t_MAX = SERVERDATA_RESPONSE_CONSOLE_LOG;
|
||||
constexpr int response_t_ARRAYSIZE = response_t_MAX + 1;
|
||||
|
||||
const std::string& response_t_Name(response_t value);
|
||||
|
@ -2,6 +2,24 @@
|
||||
#define ICONCOMMAND_H
|
||||
#include "icvar.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommandBase;
|
||||
class CCommand;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Any executable that wants to use ConVars need to implement one of
|
||||
// these to hook up access to console variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IConCommandBaseAccessor
|
||||
{
|
||||
public:
|
||||
// Flags is a combination of FCVAR flags in cvar.h.
|
||||
// hOut is filled in with a handle to the variable.
|
||||
virtual bool RegisterConCommandBase(ConCommandBase* pVar) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Abstract interface for ConVars
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef ICVAR_H
|
||||
#define ICVAR_H
|
||||
#include "tier0/annotations.h"
|
||||
#include "iconvar.h"
|
||||
#include "appframework/IAppSystem.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -12,29 +12,7 @@
|
||||
#ifndef TIER1_CMD_H
|
||||
#define TIER1_CMD_H
|
||||
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlstring.h"
|
||||
#include "tier1/characterset.h"
|
||||
#include "public/iconvar.h"
|
||||
#include "public/iconcommand.h"
|
||||
#include "mathlib/color.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommandBase;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Any executable that wants to use ConVars need to implement one of
|
||||
// these to hook up access to console variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
class IConCommandBaseAccessor
|
||||
{
|
||||
public:
|
||||
// Flags is a combination of FCVAR flags in cvar.h.
|
||||
// hOut is filled in with a handle to the variable.
|
||||
virtual bool RegisterConCommandBase(ConCommandBase* pVar) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Command buffer context
|
||||
@ -77,7 +55,7 @@ private:
|
||||
public:
|
||||
CCommand();
|
||||
CCommand(int nArgC, const char** ppArgV, cmd_source_t source);
|
||||
bool Tokenize(const char* pCommand, cmd_source_t source, characterset_t* pBreakSet = nullptr);
|
||||
bool Tokenize(const char* pCommand, cmd_source_t source = cmd_source_t::kCommandSrcCode, characterset_t* pBreakSet = nullptr);
|
||||
|
||||
int64_t ArgC(void) const;
|
||||
const char** ArgV(void) const;
|
||||
@ -99,135 +77,4 @@ private:
|
||||
const char* m_ppArgv[COMMAND_MAX_ARGC];
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The base console invoked command/cvar interface
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommandBase
|
||||
{
|
||||
public:
|
||||
virtual ~ConCommandBase(void) { };
|
||||
|
||||
virtual bool IsCommand(void) const = 0;
|
||||
virtual bool IsFlagSet(int nFlags) const = 0;
|
||||
|
||||
virtual void AddFlags(int nFlags) = 0;
|
||||
virtual void RemoveFlags(int nFlags) = 0;
|
||||
|
||||
virtual int GetFlags(void) const = 0;
|
||||
virtual const char* GetName(void) const = 0;
|
||||
virtual const char* GetHelpText(void) const = 0;
|
||||
virtual const char* GetUsageText(void) const = 0;
|
||||
|
||||
virtual void SetAccessor(IConCommandBaseAccessor* pAccessor) = 0;
|
||||
virtual bool IsRegistered(void) const = 0;
|
||||
|
||||
virtual int GetDLLIdentifier() const = 0;
|
||||
virtual ConCommandBase* Create (const char* szName, const char* szHelpString,
|
||||
int nFlags, const char* pszUsageString) = 0;
|
||||
|
||||
virtual void Init() = 0;
|
||||
|
||||
bool HasFlags(int nFlags) const;
|
||||
|
||||
ConCommandBase* GetNext(void) const;
|
||||
char* CopyString(const char* szFrom) const;
|
||||
|
||||
ConCommandBase* m_pNext; //0x0008
|
||||
bool m_bRegistered; //0x0010
|
||||
const char* m_pszName; //0x0018
|
||||
const char* m_pszHelpString; //0x0020
|
||||
const char* m_pszUsageString; //0x0028
|
||||
IConCommandBaseAccessor* s_pAccessor; //0x0030 <-- unused since executable is monolithic.
|
||||
int m_nFlags; //0x0038
|
||||
}; //Size: 0x0040
|
||||
static_assert(sizeof(ConCommandBase) == 0x40);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The console invoked command
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommand : public ConCommandBase
|
||||
{
|
||||
friend class CCvar;
|
||||
public:
|
||||
ConCommand(void);
|
||||
|
||||
static ConCommand* StaticCreate(const char* szName, const char* szHelpString, const char* pszUsageString,
|
||||
int nFlags, FnCommandCallback_t pCallback, FnCommandCompletionCallback pCommandCompletionCallback);
|
||||
|
||||
virtual int AutoCompleteSuggest(const char* partial, CUtlVector< CUtlString >& commands) = 0;
|
||||
virtual bool CanAutoComplete(void) const = 0;
|
||||
|
||||
void* m_nNullCallBack; //0x0040
|
||||
void* m_pSubCallback; //0x0048
|
||||
// Call this function when executing the command
|
||||
union
|
||||
{
|
||||
FnCommandCallbackV1_t m_fnCommandCallbackV1;
|
||||
FnCommandCallback_t m_fnCommandCallback;
|
||||
ICommandCallback* m_pCommandCallback;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
FnCommandCompletionCallback m_fnCompletionCallback;
|
||||
ICommandCompletionCallback* m_pCommandCompletionCallback;
|
||||
};
|
||||
|
||||
bool m_bHasCompletionCallback : 1;
|
||||
bool m_bUsingNewCommandCallback : 1;
|
||||
bool m_bUsingCommandCallbackInterface : 1;
|
||||
};
|
||||
|
||||
/* ==== CONCOMMAND ====================================================================================================================================================== */
|
||||
inline CMemory p_ConCommand_AutoCompleteSuggest;
|
||||
inline bool(*ConCommand_AutoCompleteSuggest)(ConCommand* pCommand, const char* partial, CUtlVector< CUtlString >& commands);
|
||||
|
||||
inline CMemory p_ConCommandBase_IsFlagSet;
|
||||
inline bool(*ConCommandBase_IsFlagSet)(ConCommandBase* pCommand, int nFlag);
|
||||
|
||||
inline CMemory p_NullSub;
|
||||
inline void(*NullSub)(void);
|
||||
|
||||
inline CMemory p_CallbackStub;
|
||||
inline FnCommandCompletionCallback CallbackStub;
|
||||
|
||||
inline ConCommandBase* g_pConCommandVFTable;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ECommandTarget_t Cbuf_GetCurrentPlayer(void);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VConCommand : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("ConCommandBase::IsFlagSet", p_ConCommandBase_IsFlagSet.GetPtr());
|
||||
LogFunAdr("ConCommand::AutoCompleteSuggest", p_ConCommand_AutoCompleteSuggest.GetPtr());
|
||||
LogFunAdr("CallbackStub", p_CallbackStub.GetPtr());
|
||||
LogFunAdr("NullSub", p_NullSub.GetPtr());
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_ConCommand_AutoCompleteSuggest = g_GameDll.FindPatternSIMD("40 ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 F6 41 60 04");
|
||||
p_ConCommandBase_IsFlagSet = g_GameDll.FindPatternSIMD("85 51 38 0F 95 C0 C3");
|
||||
|
||||
p_NullSub = g_GameDll.FindPatternSIMD("C2 ?? ?? CC CC CC CC CC CC CC CC CC CC CC CC CC 40 53 48 83 EC 20 48 8D 05 ?? ?? ?? ??");
|
||||
p_CallbackStub = g_GameDll.FindPatternSIMD("33 C0 C3 CC CC CC CC CC CC CC CC CC CC CC CC CC 80 49 68 08");
|
||||
|
||||
ConCommandBase_IsFlagSet = p_ConCommandBase_IsFlagSet.RCast<bool (*)(ConCommandBase*, int)>(); /*85 51 38 0F 95 C0 C3*/
|
||||
ConCommand_AutoCompleteSuggest = p_ConCommand_AutoCompleteSuggest.RCast<bool (*)(ConCommand*, const char*, CUtlVector< CUtlString >&)>();
|
||||
|
||||
NullSub = p_NullSub.RCast<void(*)(void)>(); /*C2 00 00 CC CC CC CC CC CC CC CC CC CC CC CC CC 40 53 48 83 EC 20 48 8D 05 ?? ?? ?? ??*/
|
||||
CallbackStub = p_CallbackStub.RCast<FnCommandCompletionCallback>(); /*33 C0 C3 CC CC CC CC CC CC CC CC CC CC CC CC CC 80 49 68 08*/ /*UserMathErrorFunction*/
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const
|
||||
{
|
||||
g_pConCommandVFTable = g_GameDll.GetVirtualMethodTable(".?AVConCommand@@").RCast<ConCommandBase*>();
|
||||
}
|
||||
virtual void Attach(void) const { };
|
||||
virtual void Detach(void) const { };
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // TIER1_CMD_H
|
||||
|
302
r5dev/public/tier1/convar.h
Normal file
302
r5dev/public/tier1/convar.h
Normal file
@ -0,0 +1,302 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef CONVAR_H
|
||||
#define CONVAR_H
|
||||
|
||||
#include "mathlib/color.h"
|
||||
#include "public/iconvar.h"
|
||||
#include "public/iconcommand.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlstring.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The base console invoked command/cvar interface
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommandBase
|
||||
{
|
||||
public:
|
||||
virtual ~ConCommandBase(void) { };
|
||||
|
||||
virtual bool IsCommand(void) const = 0;
|
||||
virtual bool IsFlagSet(int nFlags) const = 0;
|
||||
|
||||
virtual void AddFlags(int nFlags) = 0;
|
||||
virtual void RemoveFlags(int nFlags) = 0;
|
||||
|
||||
virtual int GetFlags(void) const = 0;
|
||||
virtual const char* GetName(void) const = 0;
|
||||
virtual const char* GetHelpText(void) const = 0;
|
||||
virtual const char* GetUsageText(void) const = 0;
|
||||
|
||||
virtual void SetAccessor(IConCommandBaseAccessor* pAccessor) = 0;
|
||||
virtual bool IsRegistered(void) const = 0;
|
||||
|
||||
virtual int GetDLLIdentifier() const = 0;
|
||||
virtual ConCommandBase* Create(const char* szName, const char* szHelpString,
|
||||
int nFlags, const char* pszUsageString) = 0;
|
||||
|
||||
virtual void Init() = 0;
|
||||
|
||||
bool HasFlags(int nFlags) const;
|
||||
|
||||
ConCommandBase* GetNext(void) const;
|
||||
char* CopyString(const char* szFrom) const;
|
||||
|
||||
ConCommandBase* m_pNext; //0x0008
|
||||
bool m_bRegistered; //0x0010
|
||||
const char* m_pszName; //0x0018
|
||||
const char* m_pszHelpString; //0x0020
|
||||
const char* m_pszUsageString; //0x0028
|
||||
IConCommandBaseAccessor* s_pAccessor; //0x0030 <-- unused since executable is monolithic.
|
||||
int m_nFlags; //0x0038
|
||||
};
|
||||
static_assert(sizeof(ConCommandBase) == 0x40);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The console invoked command
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommand : public ConCommandBase
|
||||
{
|
||||
friend class CCvar;
|
||||
public:
|
||||
ConCommand(void);
|
||||
|
||||
static ConCommand* StaticCreate(const char* szName, const char* szHelpString, const char* pszUsageString,
|
||||
int nFlags, FnCommandCallback_t pCallback, FnCommandCompletionCallback pCommandCompletionCallback);
|
||||
|
||||
virtual int AutoCompleteSuggest(const char* partial, CUtlVector< CUtlString >& commands) = 0;
|
||||
virtual bool CanAutoComplete(void) const = 0;
|
||||
|
||||
void* m_nNullCallBack; //0x0040
|
||||
void* m_pSubCallback; //0x0048
|
||||
// Call this function when executing the command
|
||||
union
|
||||
{
|
||||
FnCommandCallbackV1_t m_fnCommandCallbackV1;
|
||||
FnCommandCallback_t m_fnCommandCallback;
|
||||
ICommandCallback* m_pCommandCallback;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
FnCommandCompletionCallback m_fnCompletionCallback;
|
||||
ICommandCompletionCallback* m_pCommandCompletionCallback;
|
||||
};
|
||||
|
||||
bool m_bHasCompletionCallback : 1;
|
||||
bool m_bUsingNewCommandCallback : 1;
|
||||
bool m_bUsingCommandCallbackInterface : 1;
|
||||
};
|
||||
static_assert(sizeof(ConCommand) == 0x68);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A console variable
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConVar : public ConCommandBase, public IConVar
|
||||
{
|
||||
friend class CCvar;
|
||||
friend class ConVarRef;
|
||||
|
||||
public:
|
||||
static ConVar* StaticCreate(const char* pszName, const char* pszDefaultValue, int nFlags, const char* pszHelpString,
|
||||
bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t pCallback, const char* pszUsageString);
|
||||
void Destroy(void);
|
||||
|
||||
ConVar(void);
|
||||
virtual ~ConVar(void) { };
|
||||
|
||||
FORCEINLINE bool GetBool(void) const;
|
||||
FORCEINLINE float GetFloat(void) const;
|
||||
FORCEINLINE double GetDouble(void) const;
|
||||
FORCEINLINE int GetInt(void) const;
|
||||
FORCEINLINE Color GetColor(void) const;
|
||||
FORCEINLINE const char* GetString(void) const;
|
||||
|
||||
void SetMax(float flMaxValue);
|
||||
void SetMin(float flMinValue);
|
||||
bool GetMin(float& flMinValue) const;
|
||||
bool GetMax(float& flMaxValue) const;
|
||||
float GetMinValue(void) const;
|
||||
float GetMaxValue(void) const;
|
||||
bool HasMin(void) const;
|
||||
bool HasMax(void) const;
|
||||
|
||||
void SetValue(int nValue);
|
||||
void SetValue(float flValue);
|
||||
void SetValue(const char* pszValue);
|
||||
void SetValue(Color clValue);
|
||||
|
||||
virtual void InternalSetValue(const char* pszValue) = 0;
|
||||
virtual void InternalSetFloatValue(float flValue) = 0;
|
||||
virtual void InternalSetIntValue(int nValue) = 0;
|
||||
void InternalSetColorValue(Color value);
|
||||
|
||||
virtual __int64 Unknown0(unsigned int a2) = 0;
|
||||
virtual __int64 Unknown1(const char* a2) = 0;
|
||||
|
||||
void Revert(void);
|
||||
virtual bool ClampValue(float& flValue) = 0;
|
||||
|
||||
const char* GetDefault(void) const;
|
||||
void SetDefault(const char* pszDefault);
|
||||
bool SetColorFromString(const char* pszValue);
|
||||
|
||||
virtual void ChangeStringValue(const char* pszTempValue) = 0;
|
||||
virtual void CreateInternal(const char* pszName, const char* pszDefaultValue, int nFlags, const char* pszHelpString,
|
||||
bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t pCallback, const char* pszUsageString) = 0;
|
||||
|
||||
void InstallChangeCallback(FnChangeCallback_t callback, bool bInvoke);
|
||||
void RemoveChangeCallback(FnChangeCallback_t callback);
|
||||
|
||||
struct CVValue_t
|
||||
{
|
||||
char* m_pszString;
|
||||
size_t m_iStringLength;
|
||||
float m_fValue;
|
||||
int m_nValue;
|
||||
};
|
||||
|
||||
ConVar* m_pParent; //0x0048
|
||||
const char* m_pszDefaultValue; //0x0050
|
||||
CVValue_t m_Value; //0c0058
|
||||
bool m_bHasMin; //0x0070
|
||||
float m_fMinVal; //0x0074
|
||||
bool m_bHasMax; //0x0078
|
||||
float m_fMaxVal; //0x007C
|
||||
CUtlVector<FnChangeCallback_t> m_fnChangeCallbacks; //0x0080
|
||||
};
|
||||
static_assert(sizeof(ConVar) == 0xA0);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a boolean.
|
||||
// Output : bool
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE bool ConVar::GetBool(void) const
|
||||
{
|
||||
return !!GetInt();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a float.
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE float ConVar::GetFloat(void) const
|
||||
{
|
||||
return m_pParent->m_Value.m_fValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a double.
|
||||
// Output : double
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE double ConVar::GetDouble(void) const
|
||||
{
|
||||
return static_cast<double>(m_pParent->m_Value.m_fValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as an integer.
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE int ConVar::GetInt(void) const
|
||||
{
|
||||
return m_pParent->m_Value.m_nValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a color.
|
||||
// Output : Color
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE Color ConVar::GetColor(void) const
|
||||
{
|
||||
unsigned char* pColorElement = (reinterpret_cast<unsigned char*>(&m_pParent->m_Value.m_nValue));
|
||||
return Color(pColorElement[0], pColorElement[1], pColorElement[2], pColorElement[3]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a string.
|
||||
// Output : const char *
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE const char* ConVar::GetString(void) const
|
||||
{
|
||||
if (m_nFlags & FCVAR_NEVER_AS_STRING)
|
||||
{
|
||||
return "FCVAR_NEVER_AS_STRING";
|
||||
}
|
||||
|
||||
char const* str = m_pParent->m_Value.m_pszString;
|
||||
return str ? str : "";
|
||||
}
|
||||
|
||||
/* ==== CONVAR ========================================================================================================================================================== */
|
||||
inline CMemory p_ConVar_Register;
|
||||
inline void*(*v_ConVar_Register)(ConVar* thisptr, const char* szName, const char* szDefaultValue, int nFlags, const char* szHelpString, bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t pCallback, const char* pszUsageString);
|
||||
|
||||
inline CMemory p_ConVar_Unregister;
|
||||
inline void(*v_ConVar_Unregister)(ConVar* thisptr);
|
||||
|
||||
inline CMemory p_ConVar_IsFlagSet;
|
||||
inline bool(*v_ConVar_IsFlagSet)(ConVar* pConVar, int nFlag);
|
||||
|
||||
inline ConCommandBase* g_pConCommandBaseVFTable;
|
||||
inline ConCommand* g_pConCommandVFTable;
|
||||
inline ConVar* g_pConVarVBTable;
|
||||
inline IConVar* g_pConVarVFTable;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VConVar : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogConAdr("ConCommandBase::`vftable'", reinterpret_cast<uintptr_t>(g_pConCommandBaseVFTable));
|
||||
LogConAdr("ConCommand::`vftable'", reinterpret_cast<uintptr_t>(g_pConCommandVFTable));
|
||||
LogConAdr("ConVar::`vbtable'", reinterpret_cast<uintptr_t>(g_pConVarVBTable));
|
||||
LogConAdr("ConVar::`vftable'", reinterpret_cast<uintptr_t>(g_pConVarVFTable));
|
||||
LogFunAdr("ConVar::Register", p_ConVar_Register.GetPtr());
|
||||
LogFunAdr("ConVar::Unregister", p_ConVar_Unregister.GetPtr());
|
||||
LogFunAdr("ConVar::IsFlagSet", p_ConVar_IsFlagSet.GetPtr());
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_ConVar_Register = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 F3 0F 10 44 24 ??");
|
||||
p_ConVar_Unregister = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B 59 58 48 8D 05 ?? ?? ?? ??");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_ConVar_Register = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 40 F3 0F 10 84 24 ?? ?? ?? ??");
|
||||
p_ConVar_Unregister = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B 79 58");
|
||||
#endif
|
||||
p_ConVar_IsFlagSet = g_GameDll.FindPatternSIMD("48 8B 41 48 85 50 38");
|
||||
|
||||
v_ConVar_IsFlagSet = p_ConVar_IsFlagSet.RCast<bool (*)(ConVar*, int)>();
|
||||
v_ConVar_Register = p_ConVar_Register.RCast<void* (*)(ConVar*, const char*, const char*, int, const char*, bool, float, bool, float, FnChangeCallback_t, const char*)>();
|
||||
v_ConVar_Unregister = p_ConVar_Unregister.RCast<void (*)(ConVar*)>();
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const
|
||||
{
|
||||
g_pConCommandBaseVFTable = g_GameDll.GetVirtualMethodTable(".?AVConCommandBase@@").RCast<ConCommandBase*>();
|
||||
g_pConCommandVFTable = g_GameDll.GetVirtualMethodTable(".?AVConCommand@@").RCast<ConCommand*>();
|
||||
g_pConVarVBTable = g_GameDll.GetVirtualMethodTable(".?AVConVar@@", 0).RCast<ConVar*>();
|
||||
g_pConVarVFTable = g_GameDll.GetVirtualMethodTable(".?AVConVar@@", 1).RCast<IConVar*>();
|
||||
}
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // CONVAR_H
|
@ -13,11 +13,80 @@
|
||||
#define CVAR_H
|
||||
|
||||
#include "vstdlib/concommandhash.h"
|
||||
#include "public/icvar.h"
|
||||
#include "public/iconvar.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlstring.h"
|
||||
|
||||
/* ==== CCVAR =========================================================================================================================================================== */
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommandBase;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Interface to ConVars/ConCommands
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCvar : public CBaseAppSystem< ICvar >
|
||||
{ // Implementation in engine.
|
||||
protected:
|
||||
enum ConVarSetType_t
|
||||
{
|
||||
CONVAR_SET_STRING = 0,
|
||||
CONVAR_SET_INT,
|
||||
CONVAR_SET_FLOAT,
|
||||
};
|
||||
|
||||
struct QueuedConVarSet_t
|
||||
{
|
||||
ConVar* m_pConVar;
|
||||
ConVarSetType_t m_nType;
|
||||
int m_nInt;
|
||||
float m_flFloat;
|
||||
CUtlString m_String;
|
||||
};
|
||||
|
||||
class CCVarIteratorInternal : public ICVarIteratorInternal
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void SetFirst(void) = 0;
|
||||
virtual void Next(void) = 0;
|
||||
virtual bool IsValid(void) = 0;
|
||||
virtual ConCommandBase* Get(void) = 0;
|
||||
|
||||
virtual ~CCVarIteratorInternal() { }
|
||||
|
||||
CCvar* const m_pOuter = nullptr;
|
||||
CConCommandHash* const m_pHash = nullptr;
|
||||
CConCommandHash::CCommandHashIterator_t m_hashIter;
|
||||
};
|
||||
|
||||
virtual CCVarIteratorInternal* FactoryInternalIterator(void) = 0;
|
||||
|
||||
friend class CCVarIteratorInternal;
|
||||
friend class CCvarUtilities;
|
||||
|
||||
private:
|
||||
CUtlVector< FnChangeCallback_t > m_GlobalChangeCallbacks;
|
||||
char pad0[30]; //!TODO:
|
||||
int m_nNextDLLIdentifier;
|
||||
ConCommandBase* m_pConCommandList;
|
||||
CConCommandHash m_CommandHash;
|
||||
CUtlVector<void*> m_Unknown;
|
||||
char pad2[32];
|
||||
void* m_pCallbackStub;
|
||||
void* m_pAllocFunc;
|
||||
char pad3[16];
|
||||
CUtlVector< QueuedConVarSet_t > m_QueuedConVarSets;
|
||||
bool m_bMaterialSystemThreadSetAllowed;
|
||||
};
|
||||
|
||||
extern CCvar* g_pCVar;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: ConVar tools
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCvarUtilities
|
||||
{
|
||||
@ -63,204 +132,7 @@ private:
|
||||
};
|
||||
|
||||
extern CCvarUtilities* cv;
|
||||
|
||||
class CCvar : public CBaseAppSystem< ICvar >
|
||||
{ // Implementation in engine.
|
||||
protected:
|
||||
enum ConVarSetType_t
|
||||
{
|
||||
CONVAR_SET_STRING = 0,
|
||||
CONVAR_SET_INT,
|
||||
CONVAR_SET_FLOAT,
|
||||
};
|
||||
|
||||
struct QueuedConVarSet_t
|
||||
{
|
||||
ConVar* m_pConVar;
|
||||
ConVarSetType_t m_nType;
|
||||
int m_nInt;
|
||||
float m_flFloat;
|
||||
CUtlString m_String;
|
||||
};
|
||||
|
||||
class CCVarIteratorInternal : public ICVarIteratorInternal
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void SetFirst(void) = 0;
|
||||
virtual void Next(void) = 0;
|
||||
virtual bool IsValid(void) = 0;
|
||||
virtual ConCommandBase* Get(void) = 0;
|
||||
|
||||
virtual ~CCVarIteratorInternal() { }
|
||||
|
||||
CCvar* const m_pOuter = nullptr;
|
||||
CConCommandHash* const m_pHash = nullptr;
|
||||
CConCommandHash::CCommandHashIterator_t m_hashIter;
|
||||
};
|
||||
|
||||
virtual CCVarIteratorInternal* FactoryInternalIterator(void) = 0;
|
||||
|
||||
friend class CCVarIteratorInternal;
|
||||
friend class CCvarUtilities;
|
||||
|
||||
private:
|
||||
CUtlVector< FnChangeCallback_t > m_GlobalChangeCallbacks;
|
||||
char pad0[30]; //!TODO:
|
||||
int m_nNextDLLIdentifier;
|
||||
ConCommandBase* m_pConCommandList;
|
||||
CConCommandHash m_CommandHash;
|
||||
CUtlVector<void*> m_Unknown;
|
||||
char pad2[32];
|
||||
void* m_pCallbackStub;
|
||||
void* m_pAllocFunc;
|
||||
char pad3[16];
|
||||
CUtlVector< QueuedConVarSet_t > m_QueuedConVarSets;
|
||||
bool m_bMaterialSystemThreadSetAllowed;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
extern CCvar* g_pCVar;
|
||||
|
||||
/* ==== CONVAR ========================================================================================================================================================== */
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A console variable
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConVar : public ConCommandBase, public IConVar
|
||||
{
|
||||
friend class CCvar;
|
||||
friend class ConVarRef;
|
||||
|
||||
public:
|
||||
static ConVar* StaticCreate(const char* pszName, const char* pszDefaultValue, int nFlags, const char* pszHelpString,
|
||||
bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t pCallback, const char* pszUsageString);
|
||||
void Destroy(void);
|
||||
|
||||
ConVar(void);
|
||||
virtual ~ConVar(void) { };
|
||||
|
||||
FORCEINLINE bool GetBool(void) const;
|
||||
FORCEINLINE float GetFloat(void) const;
|
||||
FORCEINLINE double GetDouble(void) const;
|
||||
FORCEINLINE int GetInt(void) const;
|
||||
FORCEINLINE Color GetColor(void) const;
|
||||
FORCEINLINE const char* GetString(void) const;
|
||||
|
||||
void SetMax(float flMaxValue);
|
||||
void SetMin(float flMinValue);
|
||||
bool GetMin(float& flMinValue) const;
|
||||
bool GetMax(float& flMaxValue) const;
|
||||
float GetMinValue(void) const;
|
||||
float GetMaxValue(void) const;
|
||||
bool HasMin(void) const;
|
||||
bool HasMax(void) const;
|
||||
|
||||
void SetValue(int nValue);
|
||||
void SetValue(float flValue);
|
||||
void SetValue(const char* pszValue);
|
||||
void SetValue(Color clValue);
|
||||
|
||||
virtual void InternalSetValue(const char* pszValue) = 0;
|
||||
virtual void InternalSetFloatValue(float flValue) = 0;
|
||||
virtual void InternalSetIntValue(int nValue) = 0;
|
||||
void InternalSetColorValue(Color value);
|
||||
|
||||
virtual __int64 Unknown0(unsigned int a2) = 0;
|
||||
virtual __int64 Unknown1(const char* a2) = 0;
|
||||
|
||||
void Revert(void);
|
||||
virtual bool ClampValue(float& flValue) = 0;
|
||||
|
||||
const char* GetDefault(void) const;
|
||||
void SetDefault(const char* pszDefault);
|
||||
bool SetColorFromString(const char* pszValue);
|
||||
|
||||
virtual void ChangeStringValue(const char* pszTempValue) = 0;
|
||||
virtual void CreateInternal(const char* pszName, const char* pszDefaultValue, int nFlags, const char* pszHelpString,
|
||||
bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t pCallback, const char* pszUsageString) = 0;
|
||||
|
||||
void InstallChangeCallback(FnChangeCallback_t callback, bool bInvoke);
|
||||
void RemoveChangeCallback(FnChangeCallback_t callback);
|
||||
|
||||
struct CVValue_t
|
||||
{
|
||||
char* m_pszString;
|
||||
size_t m_iStringLength;
|
||||
float m_fValue;
|
||||
int m_nValue;
|
||||
};
|
||||
|
||||
ConVar* m_pParent; //0x0048
|
||||
const char* m_pszDefaultValue; //0x0050
|
||||
CVValue_t m_Value; //0c0058
|
||||
bool m_bHasMin; //0x0070
|
||||
float m_fMinVal; //0x0074
|
||||
bool m_bHasMax; //0x0078
|
||||
float m_fMaxVal; //0x007C
|
||||
CUtlVector<FnChangeCallback_t> m_fnChangeCallbacks; //0x0080
|
||||
}; //Size: 0x00A0
|
||||
static_assert(sizeof(ConVar) == 0xA0);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a boolean.
|
||||
// Output : bool
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE bool ConVar::GetBool(void) const
|
||||
{
|
||||
return !!GetInt();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a float.
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE float ConVar::GetFloat(void) const
|
||||
{
|
||||
return m_pParent->m_Value.m_fValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a double.
|
||||
// Output : double
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE double ConVar::GetDouble(void) const
|
||||
{
|
||||
return static_cast<double>(m_pParent->m_Value.m_fValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as an integer.
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE int ConVar::GetInt(void) const
|
||||
{
|
||||
return m_pParent->m_Value.m_nValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a color.
|
||||
// Output : Color
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE Color ConVar::GetColor(void) const
|
||||
{
|
||||
unsigned char* pColorElement = (reinterpret_cast<unsigned char*>(&m_pParent->m_Value.m_nValue));
|
||||
return Color(pColorElement[0], pColorElement[1], pColorElement[2], pColorElement[3]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a string.
|
||||
// Output : const char *
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE const char* ConVar::GetString(void) const
|
||||
{
|
||||
if (m_nFlags & FCVAR_NEVER_AS_STRING)
|
||||
{
|
||||
return "FCVAR_NEVER_AS_STRING";
|
||||
}
|
||||
|
||||
char const* str = m_pParent->m_Value.m_pszString;
|
||||
return str ? str : "";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Console variable flags container for tools
|
||||
@ -289,52 +161,21 @@ extern ConVarFlags g_ConVarFlags;
|
||||
bool ConVar_ParseFlagString(const char* pszFlags, int& nFlags, const char* pszConVarName = "<<unspecified>>");
|
||||
void ConVar_PrintDescription(ConCommandBase* pVar);
|
||||
|
||||
/* ==== CONVAR ========================================================================================================================================================== */
|
||||
inline CMemory p_ConVar_Register;
|
||||
inline void*(*v_ConVar_Register)(ConVar* thisptr, const char* szName, const char* szDefaultValue, int nFlags, const char* szHelpString, bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t pCallback, const char* pszUsageString);
|
||||
|
||||
inline CMemory p_ConVar_Unregister;
|
||||
inline void(*v_ConVar_Unregister)(ConVar* thisptr);
|
||||
|
||||
inline CMemory p_ConVar_IsFlagSet;
|
||||
inline bool(*v_ConVar_IsFlagSet)(ConVar* pConVar, int nFlag);
|
||||
|
||||
inline CMemory p_ConVar_PrintDescription;
|
||||
inline void*(*v_ConVar_PrintDescription)(ConCommandBase* pVar);
|
||||
|
||||
inline ConVar* g_pConVarVBTable;
|
||||
inline IConVar* g_pConVarVFTable;
|
||||
inline void* (*v_ConVar_PrintDescription)(ConCommandBase* pVar);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VCVar : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogConAdr("ConCommand::`vftable'", reinterpret_cast<uintptr_t>(g_pConCommandVFTable));
|
||||
LogConAdr("ConVar::`vbtable'", reinterpret_cast<uintptr_t>(g_pConVarVBTable));
|
||||
LogConAdr("ConVar::`vftable'", reinterpret_cast<uintptr_t>(g_pConVarVFTable));
|
||||
LogFunAdr("ConVar::Register", p_ConVar_Register.GetPtr());
|
||||
LogFunAdr("ConVar::Unregister", p_ConVar_Unregister.GetPtr());
|
||||
LogFunAdr("ConVar::IsFlagSet", p_ConVar_IsFlagSet.GetPtr());
|
||||
LogFunAdr("ConVar_PrintDescription", p_ConVar_PrintDescription.GetPtr());
|
||||
LogVarAdr("g_pCVar", reinterpret_cast<uintptr_t>(g_pCVar));
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_ConVar_Register = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 F3 0F 10 44 24 ??");
|
||||
p_ConVar_Unregister = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B 59 58 48 8D 05 ?? ?? ?? ??");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_ConVar_Register = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 40 F3 0F 10 84 24 ?? ?? ?? ??");
|
||||
p_ConVar_Unregister = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B 79 58");
|
||||
#endif
|
||||
p_ConVar_IsFlagSet = g_GameDll.FindPatternSIMD("48 8B 41 48 85 50 38");
|
||||
p_ConVar_PrintDescription = g_GameDll.FindPatternSIMD("B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B 01 48 89 9C 24 ?? ?? ?? ??");
|
||||
|
||||
v_ConVar_IsFlagSet = p_ConVar_IsFlagSet.RCast<bool (*)(ConVar*, int)>();
|
||||
v_ConVar_Register = p_ConVar_Register.RCast<void* (*)(ConVar*, const char*, const char*, int, const char*, bool, float, bool, float, FnChangeCallback_t, const char*)>();
|
||||
v_ConVar_Unregister = p_ConVar_Unregister.RCast<void (*)(ConVar*)>();
|
||||
v_ConVar_PrintDescription = p_ConVar_PrintDescription.RCast<void* (*)(ConCommandBase*)>();
|
||||
p_ConVar_PrintDescription = g_GameDll.FindPatternSIMD("B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B 01 48 89 9C 24 ?? ?? ?? ??");
|
||||
v_ConVar_PrintDescription = p_ConVar_PrintDescription.RCast<void* (*)(ConCommandBase*)>();
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
@ -344,11 +185,7 @@ class VCVar : public IDetour
|
||||
//g_pCVar = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 83 3D ?? ?? ?? ?? ?? 48 8B D9 74 09") // Actual CCvar, above is the vtable ptr.
|
||||
//.FindPatternSelf("48 83 3D", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x8).RCast<CCvar*>();
|
||||
}
|
||||
virtual void GetCon(void) const
|
||||
{
|
||||
g_pConVarVBTable = g_GameDll.GetVirtualMethodTable(".?AVConVar@@", 0).RCast<ConVar*>();
|
||||
g_pConVarVFTable = g_GameDll.GetVirtualMethodTable(".?AVConVar@@", 1).RCast<IConVar*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
};
|
||||
|
@ -35,26 +35,26 @@ public:
|
||||
|
||||
SocketHandle_t GetAcceptedSocketHandle(int nIndex) const;
|
||||
const netadr_t& GetAcceptedSocketAddress(int nIndex) const;
|
||||
CConnectedNetConsoleData* GetAcceptedSocketData(int nIndex) const;
|
||||
CConnectedNetConsoleData& GetAcceptedSocketData(int nIndex);
|
||||
const CConnectedNetConsoleData& GetAcceptedSocketData(int nIndex) const;
|
||||
|
||||
public:
|
||||
struct AcceptedSocket_t
|
||||
{
|
||||
AcceptedSocket_t(void)
|
||||
{
|
||||
m_hSocket = NULL;
|
||||
m_pData = nullptr;
|
||||
}
|
||||
AcceptedSocket_t(SocketHandle_t hSocket)
|
||||
: m_hSocket(hSocket)
|
||||
, m_Data(hSocket)
|
||||
{}
|
||||
|
||||
SocketHandle_t m_hSocket;
|
||||
netadr_t m_Address;
|
||||
CConnectedNetConsoleData* m_pData;
|
||||
CConnectedNetConsoleData m_Data;
|
||||
};
|
||||
|
||||
std::vector<AcceptedSocket_t> m_hAcceptedSockets;
|
||||
private:
|
||||
CUtlVector<AcceptedSocket_t> m_AcceptedSockets;
|
||||
SocketHandle_t m_hListenSocket; // Used to accept connections.
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
SOCKET_TCP_MAX_ACCEPTS = 2
|
||||
|
@ -4,12 +4,9 @@ option optimize_for = LITE_RUNTIME;
|
||||
|
||||
enum request_t
|
||||
{
|
||||
SERVERDATA_REQUEST_VALUE = 0;
|
||||
SERVERDATA_REQUEST_SETVALUE = 1;
|
||||
SERVERDATA_REQUEST_EXECCOMMAND = 2;
|
||||
SERVERDATA_REQUEST_AUTH = 3;
|
||||
SERVERDATA_REQUEST_SEND_CONSOLE_LOG = 4;
|
||||
SERVERDATA_REQUEST_SEND_REMOTEBUG = 5;
|
||||
SERVERDATA_REQUEST_EXECCOMMAND = 0;
|
||||
SERVERDATA_REQUEST_AUTH = 1;
|
||||
SERVERDATA_REQUEST_SEND_CONSOLE_LOG = 2;
|
||||
}
|
||||
|
||||
message request
|
||||
|
@ -4,12 +4,8 @@ option optimize_for = LITE_RUNTIME;
|
||||
|
||||
enum response_t
|
||||
{
|
||||
SERVERDATA_RESPONSE_VALUE = 0;
|
||||
SERVERDATA_RESPONSE_UPDATE = 1;
|
||||
SERVERDATA_RESPONSE_AUTH = 2;
|
||||
SERVERDATA_RESPONSE_CONSOLE_LOG = 3;
|
||||
SERVERDATA_RESPONSE_STRING = 4;
|
||||
SERVERDATA_RESPONSE_REMOTEBUG = 5;
|
||||
SERVERDATA_RESPONSE_AUTH = 0;
|
||||
SERVERDATA_RESPONSE_CONSOLE_LOG = 1;
|
||||
}
|
||||
|
||||
message response
|
||||
|
@ -22,6 +22,7 @@ add_sources( SOURCE_GROUP "Utility"
|
||||
|
||||
add_sources( SOURCE_GROUP "Private"
|
||||
"cmd.cpp"
|
||||
"convar.cpp"
|
||||
"cvar.cpp"
|
||||
)
|
||||
|
||||
|
@ -274,90 +274,3 @@ void CCommand::Reset()
|
||||
m_pArgSBuffer[0] = 0;
|
||||
m_nQueuedVal = cmd_source_t::kCommandSrcInvalid;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: create
|
||||
//-----------------------------------------------------------------------------
|
||||
ConCommand* ConCommand::StaticCreate(const char* pszName, const char* pszHelpString, const char* pszUsageString,
|
||||
int nFlags, FnCommandCallback_t pCallback, FnCommandCompletionCallback pCompletionFunc)
|
||||
{
|
||||
ConCommand* pCommand = (ConCommand*)malloc(sizeof(ConCommand));
|
||||
*(ConCommandBase**)pCommand = g_pConCommandVFTable;
|
||||
|
||||
pCommand->m_pNext = nullptr;
|
||||
pCommand->m_bRegistered = false;
|
||||
|
||||
pCommand->m_pszName = pszName;
|
||||
pCommand->m_pszHelpString = pszHelpString;
|
||||
pCommand->m_pszUsageString = pszUsageString;
|
||||
pCommand->s_pAccessor = nullptr;
|
||||
pCommand->m_nFlags = nFlags;
|
||||
|
||||
pCommand->m_nNullCallBack = NullSub;
|
||||
pCommand->m_pSubCallback = nullptr;
|
||||
pCommand->m_fnCommandCallback = pCallback;
|
||||
pCommand->m_bHasCompletionCallback = pCompletionFunc != nullptr ? true : false;
|
||||
pCommand->m_bUsingNewCommandCallback = true;
|
||||
pCommand->m_bUsingCommandCallbackInterface = false;
|
||||
pCommand->m_fnCompletionCallback = pCompletionFunc ? pCompletionFunc : CallbackStub;
|
||||
|
||||
g_pCVar->RegisterConCommand(pCommand);
|
||||
return pCommand;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: construct/allocate
|
||||
//-----------------------------------------------------------------------------
|
||||
ConCommand::ConCommand()
|
||||
: m_nNullCallBack(nullptr)
|
||||
, m_pSubCallback(nullptr)
|
||||
, m_fnCommandCallbackV1(nullptr)
|
||||
, m_fnCompletionCallback(nullptr)
|
||||
, m_bHasCompletionCallback(false)
|
||||
, m_bUsingNewCommandCallback(false)
|
||||
, m_bUsingCommandCallbackInterface(false)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Checks if ConCommand has requested flags.
|
||||
// Input : nFlags -
|
||||
// Output : True if ConCommand has nFlags.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConCommandBase::HasFlags(int nFlags) const
|
||||
{
|
||||
return m_nFlags & nFlags;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : const ConCommandBase
|
||||
//-----------------------------------------------------------------------------
|
||||
ConCommandBase* ConCommandBase::GetNext(void) const
|
||||
{
|
||||
return m_pNext;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Copies string using local new/delete operators
|
||||
// Input : *szFrom -
|
||||
// Output : char
|
||||
//-----------------------------------------------------------------------------
|
||||
char* ConCommandBase::CopyString(const char* szFrom) const
|
||||
{
|
||||
size_t nLen;
|
||||
char* szTo;
|
||||
|
||||
nLen = strlen(szFrom);
|
||||
if (nLen <= 0)
|
||||
{
|
||||
szTo = new char[1];
|
||||
szTo[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
szTo = new char[nLen + 1];
|
||||
memmove(szTo, szFrom, nLen + 1);
|
||||
}
|
||||
return szTo;
|
||||
}
|
||||
|
497
r5dev/tier1/convar.cpp
Normal file
497
r5dev/tier1/convar.cpp
Normal file
@ -0,0 +1,497 @@
|
||||
//=============================================================================//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "tier0/tslist.h"
|
||||
#include "tier1/convar.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Checks if ConCommand has requested flags.
|
||||
// Input : nFlags -
|
||||
// Output : True if ConCommand has nFlags.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConCommandBase::HasFlags(int nFlags) const
|
||||
{
|
||||
return m_nFlags & nFlags;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : const ConCommandBase
|
||||
//-----------------------------------------------------------------------------
|
||||
ConCommandBase* ConCommandBase::GetNext(void) const
|
||||
{
|
||||
return m_pNext;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Copies string using local new/delete operators
|
||||
// Input : *szFrom -
|
||||
// Output : char
|
||||
//-----------------------------------------------------------------------------
|
||||
char* ConCommandBase::CopyString(const char* szFrom) const
|
||||
{
|
||||
size_t nLen;
|
||||
char* szTo;
|
||||
|
||||
nLen = strlen(szFrom);
|
||||
if (nLen <= 0)
|
||||
{
|
||||
szTo = new char[1];
|
||||
szTo[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
szTo = new char[nLen + 1];
|
||||
memmove(szTo, szFrom, nLen + 1);
|
||||
}
|
||||
return szTo;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Default do nothing function
|
||||
//-----------------------------------------------------------------------------
|
||||
void DefaultNullSub()
|
||||
{
|
||||
; /*DO NOTHING*/
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Default console command autocompletion function
|
||||
//-----------------------------------------------------------------------------
|
||||
int DefaultCompletionFunc(const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: create
|
||||
//-----------------------------------------------------------------------------
|
||||
ConCommand* ConCommand::StaticCreate(const char* pszName, const char* pszHelpString, const char* pszUsageString,
|
||||
int nFlags, FnCommandCallback_t pCallback, FnCommandCompletionCallback pCompletionFunc)
|
||||
{
|
||||
ConCommand* pCommand = (ConCommand*)malloc(sizeof(ConCommand));
|
||||
*(ConCommand**)pCommand = g_pConCommandVFTable;
|
||||
|
||||
pCommand->m_pNext = nullptr;
|
||||
pCommand->m_bRegistered = false;
|
||||
|
||||
pCommand->m_pszName = pszName;
|
||||
pCommand->m_pszHelpString = pszHelpString;
|
||||
pCommand->m_pszUsageString = pszUsageString;
|
||||
pCommand->s_pAccessor = nullptr;
|
||||
pCommand->m_nFlags = nFlags;
|
||||
|
||||
pCommand->m_nNullCallBack = DefaultNullSub;
|
||||
pCommand->m_pSubCallback = nullptr;
|
||||
pCommand->m_fnCommandCallback = pCallback;
|
||||
pCommand->m_bHasCompletionCallback = pCompletionFunc != nullptr ? true : false;
|
||||
pCommand->m_bUsingNewCommandCallback = true;
|
||||
pCommand->m_bUsingCommandCallbackInterface = false;
|
||||
pCommand->m_fnCompletionCallback = pCompletionFunc ? pCompletionFunc : DefaultCompletionFunc;
|
||||
|
||||
g_pCVar->RegisterConCommand(pCommand);
|
||||
return pCommand;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: construct/allocate
|
||||
//-----------------------------------------------------------------------------
|
||||
ConCommand::ConCommand()
|
||||
: m_nNullCallBack(nullptr)
|
||||
, m_pSubCallback(nullptr)
|
||||
, m_fnCommandCallbackV1(nullptr)
|
||||
, m_fnCompletionCallback(nullptr)
|
||||
, m_bHasCompletionCallback(false)
|
||||
, m_bUsingNewCommandCallback(false)
|
||||
, m_bUsingCommandCallbackInterface(false)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: create
|
||||
//-----------------------------------------------------------------------------
|
||||
ConVar* ConVar::StaticCreate(const char* pszName, const char* pszDefaultValue,
|
||||
int nFlags, const char* pszHelpString, bool bMin, float fMin, bool bMax,
|
||||
float fMax, FnChangeCallback_t pCallback, const char* pszUsageString)
|
||||
{
|
||||
ConVar* pNewConVar = (ConVar*)malloc(sizeof(ConVar));
|
||||
|
||||
pNewConVar->m_bRegistered = false;
|
||||
*(ConVar**)pNewConVar = g_pConVarVBTable;
|
||||
char* pConVarVFTable = (char*)pNewConVar + sizeof(ConCommandBase);
|
||||
*(IConVar**)pConVarVFTable = g_pConVarVFTable;
|
||||
|
||||
pNewConVar->m_pszName = nullptr;
|
||||
pNewConVar->m_pszHelpString = nullptr;
|
||||
pNewConVar->m_pszUsageString = nullptr;
|
||||
pNewConVar->s_pAccessor = nullptr;
|
||||
pNewConVar->m_nFlags = FCVAR_NONE;
|
||||
pNewConVar->m_pNext = nullptr;
|
||||
|
||||
pNewConVar->m_fnChangeCallbacks.Init();
|
||||
|
||||
v_ConVar_Register(pNewConVar, pszName, pszDefaultValue, nFlags,
|
||||
pszHelpString, bMin, fMin, bMax, fMax, pCallback, pszUsageString);
|
||||
return pNewConVar;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: destroy
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::Destroy(void)
|
||||
{
|
||||
v_ConVar_Unregister(this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: construct/allocate
|
||||
//-----------------------------------------------------------------------------
|
||||
ConVar::ConVar(void)
|
||||
: m_pParent(nullptr)
|
||||
, m_pszDefaultValue(nullptr)
|
||||
, m_bHasMin(false)
|
||||
, m_fMinVal(0.f)
|
||||
, m_bHasMax(false)
|
||||
, m_fMaxVal(0.f)
|
||||
{
|
||||
m_Value.m_pszString = nullptr;
|
||||
m_Value.m_iStringLength = 0;
|
||||
m_Value.m_fValue = 0.0f;
|
||||
m_Value.m_nValue = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
//ConVar::~ConVar(void)
|
||||
//{
|
||||
// if (m_Value.m_pszString)
|
||||
// {
|
||||
// delete[] m_Value.m_pszString);
|
||||
// m_Value.m_pszString = NULL;
|
||||
// }
|
||||
//}
|
||||
|
||||
////-----------------------------------------------------------------------------
|
||||
//// Purpose: Returns the base ConVar name.
|
||||
//// Output : const char*
|
||||
////-----------------------------------------------------------------------------
|
||||
//const char* ConVar::GetBaseName(void) const
|
||||
//{
|
||||
// return m_pParent->m_pszName;
|
||||
//}
|
||||
//
|
||||
////-----------------------------------------------------------------------------
|
||||
//// Purpose: Returns the ConVar help text.
|
||||
//// Output : const char*
|
||||
////-----------------------------------------------------------------------------
|
||||
//const char* ConVar::GetHelpText(void) const
|
||||
//{
|
||||
// return m_pParent->m_pszHelpString;
|
||||
//}
|
||||
//
|
||||
////-----------------------------------------------------------------------------
|
||||
//// Purpose: Returns the ConVar usage text.
|
||||
//// Output : const char*
|
||||
////-----------------------------------------------------------------------------
|
||||
//const char* ConVar::GetUsageText(void) const
|
||||
//{
|
||||
// return m_pParent->m_pszUsageString;
|
||||
//}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flMaxVal -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetMax(float flMaxVal)
|
||||
{
|
||||
m_pParent->m_fMaxVal = flMaxVal;
|
||||
m_pParent->m_bHasMax = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flMinVal -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetMin(float flMinVal)
|
||||
{
|
||||
m_pParent->m_fMinVal = flMinVal;
|
||||
m_pParent->m_bHasMin = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flMinVal -
|
||||
// Output : true if there is a min set.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::GetMin(float& flMinVal) const
|
||||
{
|
||||
flMinVal = m_pParent->m_fMinVal;
|
||||
return m_pParent->m_bHasMin;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flMaxVal -
|
||||
// Output : true if there is a max set.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::GetMax(float& flMaxVal) const
|
||||
{
|
||||
flMaxVal = m_pParent->m_fMaxVal;
|
||||
return m_pParent->m_bHasMax;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the min value.
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float ConVar::GetMinValue(void) const
|
||||
{
|
||||
return m_pParent->m_fMinVal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the max value.
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float ConVar::GetMaxValue(void) const
|
||||
{
|
||||
return m_pParent->m_fMaxVal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if ConVar has min value.
|
||||
// Output : bool
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::HasMin(void) const
|
||||
{
|
||||
return m_pParent->m_bHasMin;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if ConVar has max value.
|
||||
// Output : bool
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::HasMax(void) const
|
||||
{
|
||||
return m_pParent->m_bHasMax;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the ConVar int value.
|
||||
// Input : nValue -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetValue(int nValue)
|
||||
{
|
||||
ConVar* pCVar = reinterpret_cast<ConVar*>(m_pParent);
|
||||
pCVar->InternalSetIntValue(nValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the ConVar float value.
|
||||
// Input : flValue -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetValue(float flValue)
|
||||
{
|
||||
ConVar* pCVar = reinterpret_cast<ConVar*>(m_pParent);
|
||||
pCVar->InternalSetFloatValue(flValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the ConVar string value.
|
||||
// Input : *szValue -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetValue(const char* pszValue)
|
||||
{
|
||||
ConVar* pCVar = reinterpret_cast<ConVar*>(m_pParent);
|
||||
pCVar->InternalSetValue(pszValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the ConVar color value.
|
||||
// Input : value -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetValue(Color value)
|
||||
{
|
||||
ConVar* pCVar = reinterpret_cast<ConVar*>(m_pParent);
|
||||
pCVar->InternalSetColorValue(value);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *value -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::InternalSetColorValue(Color value)
|
||||
{
|
||||
// Stuff color values into an int
|
||||
int nValue = 0;
|
||||
|
||||
unsigned char* pColorElement = (reinterpret_cast<unsigned char*>(&nValue));
|
||||
pColorElement[0] = value[0];
|
||||
pColorElement[1] = value[1];
|
||||
pColorElement[2] = value[2];
|
||||
pColorElement[3] = value[3];
|
||||
|
||||
// Call the int internal set
|
||||
InternalSetIntValue(nValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Reset to default value.
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::Revert(void)
|
||||
{
|
||||
SetValue(m_pszDefaultValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the default ConVar value.
|
||||
// Output : const char
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* ConVar::GetDefault(void) const
|
||||
{
|
||||
return m_pParent->m_pszDefaultValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the default ConVar value.
|
||||
// Input : *pszDefault -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetDefault(const char* pszDefault)
|
||||
{
|
||||
static const char* pszEmpty = "";
|
||||
m_pszDefaultValue = pszDefault ? pszDefault : pszEmpty;
|
||||
assert(m_pszDefaultValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the ConVar color value from string.
|
||||
// Input : *pszValue -
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::SetColorFromString(const char* pszValue)
|
||||
{
|
||||
bool bColor = false;
|
||||
|
||||
// Try pulling RGBA color values out of the string.
|
||||
int nRGBA[4];
|
||||
int nParamsRead = sscanf_s(pszValue, "%i %i %i %i",
|
||||
&(nRGBA[0]), &(nRGBA[1]), &(nRGBA[2]), &(nRGBA[3]));
|
||||
|
||||
if (nParamsRead >= 3)
|
||||
{
|
||||
// This is probably a color!
|
||||
if (nParamsRead == 3)
|
||||
{
|
||||
// Assume they wanted full alpha.
|
||||
nRGBA[3] = 255;
|
||||
}
|
||||
|
||||
if (nRGBA[0] >= 0 && nRGBA[0] <= 255 &&
|
||||
nRGBA[1] >= 0 && nRGBA[1] <= 255 &&
|
||||
nRGBA[2] >= 0 && nRGBA[2] <= 255 &&
|
||||
nRGBA[3] >= 0 && nRGBA[3] <= 255)
|
||||
{
|
||||
//printf("*** WOW! Found a color!! ***\n");
|
||||
|
||||
// This is definitely a color!
|
||||
bColor = true;
|
||||
|
||||
// Stuff all the values into each byte of our int.
|
||||
unsigned char* pColorElement =
|
||||
(reinterpret_cast<unsigned char*>(&m_Value.m_nValue));
|
||||
|
||||
pColorElement[0] = (unsigned char)nRGBA[0];
|
||||
pColorElement[1] = (unsigned char)nRGBA[1];
|
||||
pColorElement[2] = (unsigned char)nRGBA[2];
|
||||
pColorElement[3] = (unsigned char)nRGBA[3];
|
||||
|
||||
// Copy that value into our float.
|
||||
m_Value.m_fValue = static_cast<float>(m_Value.m_nValue);
|
||||
}
|
||||
}
|
||||
|
||||
return bColor;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: changes the ConVar string value.
|
||||
// Input : *pszTempVal - flOldValue
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::ChangeStringValue(const char* pszTempVal)
|
||||
{
|
||||
Assert(!(m_nFlags & FCVAR_NEVER_AS_STRING));
|
||||
|
||||
char* pszOldValue = (char*)stackalloc(m_Value.m_iStringLength);
|
||||
memcpy(pszOldValue, m_Value.m_pszString, m_Value.m_iStringLength);
|
||||
|
||||
size_t len = strlen(pszTempVal) + 1;
|
||||
|
||||
if (len > m_Value.m_iStringLength)
|
||||
{
|
||||
if (m_Value.m_pszString)
|
||||
{
|
||||
delete[] m_Value.m_pszString;
|
||||
}
|
||||
|
||||
m_Value.m_pszString = new char[len];
|
||||
m_Value.m_iStringLength = len;
|
||||
}
|
||||
|
||||
memcpy(reinterpret_cast<void*>(m_Value.m_pszString), pszTempVal, len);
|
||||
|
||||
// Invoke any necessary callback function
|
||||
for (int i = 0; i < m_fnChangeCallbacks.Count(); ++i)
|
||||
{
|
||||
m_fnChangeCallbacks[i](this, pszOldValue, NULL);
|
||||
}
|
||||
|
||||
if (g_pCVar)
|
||||
{
|
||||
g_pCVar->CallGlobalChangeCallbacks(this, pszOldValue);
|
||||
}
|
||||
|
||||
stackfree(pszOldValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Install a change callback (there shouldn't already be one....)
|
||||
// Input : callback -
|
||||
// bInvoke -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::InstallChangeCallback(FnChangeCallback_t callback, bool bInvoke /*=true*/)
|
||||
{
|
||||
if (!callback)
|
||||
{
|
||||
Warning(eDLL_T::COMMON, "%s: Called with NULL callback; ignoring!!!\n",
|
||||
__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pParent->m_fnChangeCallbacks.Find(callback)
|
||||
!= m_pParent->m_fnChangeCallbacks.InvalidIndex())
|
||||
{
|
||||
// Same ptr added twice, sigh...
|
||||
Warning(eDLL_T::COMMON, "%s: Ignoring duplicate change callback!!!\n",
|
||||
__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
m_pParent->m_fnChangeCallbacks.AddToTail(callback);
|
||||
|
||||
// Call it immediately to set the initial value...
|
||||
if (bInvoke)
|
||||
{
|
||||
callback(this, m_Value.m_pszString, m_Value.m_fValue);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Install a change callback (there shouldn't already be one....)
|
||||
// Input : callback -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::RemoveChangeCallback(FnChangeCallback_t callback)
|
||||
{
|
||||
m_pParent->m_fnChangeCallbacks.FindAndRemove(callback);
|
||||
}
|
@ -1,398 +1,12 @@
|
||||
#include "tier1/utlrbtree.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include "tier1/NetAdr.h"
|
||||
//=============================================================================//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "mathlib/color.h"
|
||||
#include "tier1/convar.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "public/const.h"
|
||||
#include "engine/sys_dll2.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
#include "vstdlib/concommandhash.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: create
|
||||
//-----------------------------------------------------------------------------
|
||||
ConVar* ConVar::StaticCreate(const char* pszName, const char* pszDefaultValue,
|
||||
int nFlags, const char* pszHelpString, bool bMin, float fMin, bool bMax,
|
||||
float fMax, FnChangeCallback_t pCallback, const char* pszUsageString)
|
||||
{
|
||||
ConVar* pNewConVar = (ConVar*)malloc(sizeof(ConVar));
|
||||
|
||||
pNewConVar->m_bRegistered = false;
|
||||
*(ConVar**)pNewConVar = g_pConVarVBTable;
|
||||
char* pConVarVFTable = (char*)pNewConVar + sizeof(ConCommandBase);
|
||||
*(IConVar**)pConVarVFTable = g_pConVarVFTable;
|
||||
|
||||
pNewConVar->m_pszName = nullptr;
|
||||
pNewConVar->m_pszHelpString = nullptr;
|
||||
pNewConVar->m_pszUsageString = nullptr;
|
||||
pNewConVar->s_pAccessor = nullptr;
|
||||
pNewConVar->m_nFlags = FCVAR_NONE;
|
||||
pNewConVar->m_pNext = nullptr;
|
||||
|
||||
pNewConVar->m_fnChangeCallbacks.Init();
|
||||
|
||||
v_ConVar_Register(pNewConVar, pszName, pszDefaultValue, nFlags,
|
||||
pszHelpString, bMin, fMin, bMax, fMax, pCallback, pszUsageString);
|
||||
return pNewConVar;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: destroy
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::Destroy(void)
|
||||
{
|
||||
v_ConVar_Unregister(this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: construct/allocate
|
||||
//-----------------------------------------------------------------------------
|
||||
ConVar::ConVar(void)
|
||||
: m_pParent(nullptr)
|
||||
, m_pszDefaultValue(nullptr)
|
||||
, m_bHasMin(false)
|
||||
, m_fMinVal(0.f)
|
||||
, m_bHasMax(false)
|
||||
, m_fMaxVal(0.f)
|
||||
{
|
||||
m_Value.m_pszString = nullptr;
|
||||
m_Value.m_iStringLength = 0;
|
||||
m_Value.m_fValue = 0.0f;
|
||||
m_Value.m_nValue = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
//ConVar::~ConVar(void)
|
||||
//{
|
||||
// if (m_Value.m_pszString)
|
||||
// {
|
||||
// delete[] m_Value.m_pszString);
|
||||
// m_Value.m_pszString = NULL;
|
||||
// }
|
||||
//}
|
||||
|
||||
////-----------------------------------------------------------------------------
|
||||
//// Purpose: Returns the base ConVar name.
|
||||
//// Output : const char*
|
||||
////-----------------------------------------------------------------------------
|
||||
//const char* ConVar::GetBaseName(void) const
|
||||
//{
|
||||
// return m_pParent->m_pszName;
|
||||
//}
|
||||
//
|
||||
////-----------------------------------------------------------------------------
|
||||
//// Purpose: Returns the ConVar help text.
|
||||
//// Output : const char*
|
||||
////-----------------------------------------------------------------------------
|
||||
//const char* ConVar::GetHelpText(void) const
|
||||
//{
|
||||
// return m_pParent->m_pszHelpString;
|
||||
//}
|
||||
//
|
||||
////-----------------------------------------------------------------------------
|
||||
//// Purpose: Returns the ConVar usage text.
|
||||
//// Output : const char*
|
||||
////-----------------------------------------------------------------------------
|
||||
//const char* ConVar::GetUsageText(void) const
|
||||
//{
|
||||
// return m_pParent->m_pszUsageString;
|
||||
//}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flMaxVal -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetMax(float flMaxVal)
|
||||
{
|
||||
m_pParent->m_fMaxVal = flMaxVal;
|
||||
m_pParent->m_bHasMax = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flMinVal -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetMin(float flMinVal)
|
||||
{
|
||||
m_pParent->m_fMinVal = flMinVal;
|
||||
m_pParent->m_bHasMin = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flMinVal -
|
||||
// Output : true if there is a min set.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::GetMin(float& flMinVal) const
|
||||
{
|
||||
flMinVal = m_pParent->m_fMinVal;
|
||||
return m_pParent->m_bHasMin;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flMaxVal -
|
||||
// Output : true if there is a max set.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::GetMax(float& flMaxVal) const
|
||||
{
|
||||
flMaxVal = m_pParent->m_fMaxVal;
|
||||
return m_pParent->m_bHasMax;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the min value.
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float ConVar::GetMinValue(void) const
|
||||
{
|
||||
return m_pParent->m_fMinVal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the max value.
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float ConVar::GetMaxValue(void) const
|
||||
{
|
||||
return m_pParent->m_fMaxVal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if ConVar has min value.
|
||||
// Output : bool
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::HasMin(void) const
|
||||
{
|
||||
return m_pParent->m_bHasMin;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if ConVar has max value.
|
||||
// Output : bool
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::HasMax(void) const
|
||||
{
|
||||
return m_pParent->m_bHasMax;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the ConVar int value.
|
||||
// Input : nValue -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetValue(int nValue)
|
||||
{
|
||||
ConVar* pCVar = reinterpret_cast<ConVar*>(m_pParent);
|
||||
pCVar->InternalSetIntValue(nValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the ConVar float value.
|
||||
// Input : flValue -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetValue(float flValue)
|
||||
{
|
||||
ConVar* pCVar = reinterpret_cast<ConVar*>(m_pParent);
|
||||
pCVar->InternalSetFloatValue(flValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the ConVar string value.
|
||||
// Input : *szValue -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetValue(const char* pszValue)
|
||||
{
|
||||
ConVar* pCVar = reinterpret_cast<ConVar*>(m_pParent);
|
||||
pCVar->InternalSetValue(pszValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the ConVar color value.
|
||||
// Input : value -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetValue(Color value)
|
||||
{
|
||||
ConVar* pCVar = reinterpret_cast<ConVar*>(m_pParent);
|
||||
pCVar->InternalSetColorValue(value);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *value -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::InternalSetColorValue(Color value)
|
||||
{
|
||||
// Stuff color values into an int
|
||||
int nValue = 0;
|
||||
|
||||
unsigned char* pColorElement = (reinterpret_cast<unsigned char*>(&nValue));
|
||||
pColorElement[0] = value[0];
|
||||
pColorElement[1] = value[1];
|
||||
pColorElement[2] = value[2];
|
||||
pColorElement[3] = value[3];
|
||||
|
||||
// Call the int internal set
|
||||
InternalSetIntValue(nValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Reset to default value.
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::Revert(void)
|
||||
{
|
||||
SetValue(m_pszDefaultValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the default ConVar value.
|
||||
// Output : const char
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* ConVar::GetDefault(void) const
|
||||
{
|
||||
return m_pParent->m_pszDefaultValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the default ConVar value.
|
||||
// Input : *pszDefault -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::SetDefault(const char* pszDefault)
|
||||
{
|
||||
static const char* pszEmpty = "";
|
||||
m_pszDefaultValue = pszDefault ? pszDefault : pszEmpty;
|
||||
assert(m_pszDefaultValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the ConVar color value from string.
|
||||
// Input : *pszValue -
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::SetColorFromString(const char* pszValue)
|
||||
{
|
||||
bool bColor = false;
|
||||
|
||||
// Try pulling RGBA color values out of the string.
|
||||
int nRGBA[4];
|
||||
int nParamsRead = sscanf_s(pszValue, "%i %i %i %i",
|
||||
&(nRGBA[0]), &(nRGBA[1]), &(nRGBA[2]), &(nRGBA[3]));
|
||||
|
||||
if (nParamsRead >= 3)
|
||||
{
|
||||
// This is probably a color!
|
||||
if (nParamsRead == 3)
|
||||
{
|
||||
// Assume they wanted full alpha.
|
||||
nRGBA[3] = 255;
|
||||
}
|
||||
|
||||
if (nRGBA[0] >= 0 && nRGBA[0] <= 255 &&
|
||||
nRGBA[1] >= 0 && nRGBA[1] <= 255 &&
|
||||
nRGBA[2] >= 0 && nRGBA[2] <= 255 &&
|
||||
nRGBA[3] >= 0 && nRGBA[3] <= 255)
|
||||
{
|
||||
//printf("*** WOW! Found a color!! ***\n");
|
||||
|
||||
// This is definitely a color!
|
||||
bColor = true;
|
||||
|
||||
// Stuff all the values into each byte of our int.
|
||||
unsigned char* pColorElement =
|
||||
(reinterpret_cast<unsigned char*>(&m_Value.m_nValue));
|
||||
|
||||
pColorElement[0] = (unsigned char)nRGBA[0];
|
||||
pColorElement[1] = (unsigned char)nRGBA[1];
|
||||
pColorElement[2] = (unsigned char)nRGBA[2];
|
||||
pColorElement[3] = (unsigned char)nRGBA[3];
|
||||
|
||||
// Copy that value into our float.
|
||||
m_Value.m_fValue = static_cast<float>(m_Value.m_nValue);
|
||||
}
|
||||
}
|
||||
|
||||
return bColor;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: changes the ConVar string value.
|
||||
// Input : *pszTempVal - flOldValue
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::ChangeStringValue(const char* pszTempVal)
|
||||
{
|
||||
Assert(!(m_nFlags & FCVAR_NEVER_AS_STRING));
|
||||
|
||||
char* pszOldValue = (char*)stackalloc(m_Value.m_iStringLength);
|
||||
memcpy(pszOldValue, m_Value.m_pszString, m_Value.m_iStringLength);
|
||||
|
||||
size_t len = strlen(pszTempVal) + 1;
|
||||
|
||||
if (len > m_Value.m_iStringLength)
|
||||
{
|
||||
if (m_Value.m_pszString)
|
||||
{
|
||||
delete[] m_Value.m_pszString;
|
||||
}
|
||||
|
||||
m_Value.m_pszString = new char[len];
|
||||
m_Value.m_iStringLength = len;
|
||||
}
|
||||
|
||||
memcpy(reinterpret_cast<void*>(m_Value.m_pszString), pszTempVal, len);
|
||||
|
||||
// Invoke any necessary callback function
|
||||
for (int i = 0; i < m_fnChangeCallbacks.Count(); ++i)
|
||||
{
|
||||
m_fnChangeCallbacks[i](this, pszOldValue, NULL);
|
||||
}
|
||||
|
||||
if (g_pCVar)
|
||||
{
|
||||
g_pCVar->CallGlobalChangeCallbacks(this, pszOldValue);
|
||||
}
|
||||
|
||||
stackfree(pszOldValue);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Install a change callback (there shouldn't already be one....)
|
||||
// Input : callback -
|
||||
// bInvoke -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::InstallChangeCallback(FnChangeCallback_t callback, bool bInvoke /*=true*/)
|
||||
{
|
||||
if (!callback)
|
||||
{
|
||||
Warning(eDLL_T::COMMON, "%s: Called with NULL callback; ignoring!!!\n",
|
||||
__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pParent->m_fnChangeCallbacks.Find(callback)
|
||||
!= m_pParent->m_fnChangeCallbacks.InvalidIndex())
|
||||
{
|
||||
// Same ptr added twice, sigh...
|
||||
Warning(eDLL_T::COMMON, "%s: Ignoring duplicate change callback!!!\n",
|
||||
__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
m_pParent->m_fnChangeCallbacks.AddToTail(callback);
|
||||
|
||||
// Call it immediately to set the initial value...
|
||||
if (bInvoke)
|
||||
{
|
||||
callback(this, m_Value.m_pszString, m_Value.m_fValue);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Install a change callback (there shouldn't already be one....)
|
||||
// Input : callback -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::RemoveChangeCallback(FnChangeCallback_t callback)
|
||||
{
|
||||
m_pParent->m_fnChangeCallbacks.FindAndRemove(callback);
|
||||
}
|
||||
|
||||
#define SET_CONVARFLAG(x, y) SetFlag(FCVAR_##x, #x, y)
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1064,212 +678,6 @@ int CCvarUtilities::CvarFindFlagsCompletionCallback(const char* partial,
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
CCvar* g_pCVar = nullptr;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Console command hash data structure
|
||||
//-----------------------------------------------------------------------------
|
||||
CConCommandHash::CConCommandHash()
|
||||
{
|
||||
Purge(true);
|
||||
}
|
||||
|
||||
CConCommandHash::~CConCommandHash()
|
||||
{
|
||||
Purge(false);
|
||||
}
|
||||
|
||||
void CConCommandHash::Purge(bool bReinitialize)
|
||||
{
|
||||
m_aBuckets.Purge();
|
||||
m_aDataPool.Purge();
|
||||
if (bReinitialize)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize.
|
||||
void CConCommandHash::Init(void)
|
||||
{
|
||||
// kNUM_BUCKETS must be a power of two.
|
||||
COMPILE_TIME_ASSERT((kNUM_BUCKETS & (kNUM_BUCKETS - 1)) == 0);
|
||||
|
||||
// Set the bucket size.
|
||||
m_aBuckets.SetSize(kNUM_BUCKETS);
|
||||
for (int iBucket = 0; iBucket < kNUM_BUCKETS; ++iBucket)
|
||||
{
|
||||
m_aBuckets[iBucket] = m_aDataPool.InvalidIndex();
|
||||
}
|
||||
|
||||
// Calculate the grow size.
|
||||
int nGrowSize = 4 * kNUM_BUCKETS;
|
||||
m_aDataPool.SetGrowSize(nGrowSize);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Insert data into the hash table given its key (unsigned int),
|
||||
// WITH a check to see if the element already exists within the hash.
|
||||
//-----------------------------------------------------------------------------
|
||||
CConCommandHash::CCommandHashHandle_t CConCommandHash::Insert(ConCommandBase* cmd)
|
||||
{
|
||||
// Check to see if that key already exists in the buckets (should be unique).
|
||||
CCommandHashHandle_t hHash = Find(cmd);
|
||||
if (hHash != InvalidHandle())
|
||||
return hHash;
|
||||
|
||||
return FastInsert(cmd);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Insert data into the hash table given its key (unsigned int),
|
||||
// WITHOUT a check to see if the element already exists within the hash.
|
||||
//-----------------------------------------------------------------------------
|
||||
CConCommandHash::CCommandHashHandle_t CConCommandHash::FastInsert(ConCommandBase* cmd)
|
||||
{
|
||||
// Get a new element from the pool.
|
||||
intptr_t iHashData = m_aDataPool.Alloc(true);
|
||||
HashEntry_t* RESTRICT pHashData = &m_aDataPool[iHashData];
|
||||
if (!pHashData)
|
||||
return InvalidHandle();
|
||||
|
||||
HashKey_t key = Hash(cmd);
|
||||
|
||||
// Add data to new element.
|
||||
pHashData->m_uiKey = key;
|
||||
pHashData->m_Data = cmd;
|
||||
|
||||
// Link element.
|
||||
int iBucket = key & kBUCKETMASK; // HashFuncs::Hash( uiKey, m_uiBucketMask );
|
||||
m_aDataPool.LinkBefore(m_aBuckets[iBucket], iHashData);
|
||||
m_aBuckets[iBucket] = iHashData;
|
||||
|
||||
return iHashData;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Remove a given element from the hash.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConCommandHash::Remove(CCommandHashHandle_t hHash) /*RESTRICT*/
|
||||
{
|
||||
HashEntry_t* /*RESTRICT*/ entry = &m_aDataPool[hHash];
|
||||
HashKey_t iBucket = entry->m_uiKey & kBUCKETMASK;
|
||||
if (m_aBuckets[iBucket] == hHash)
|
||||
{
|
||||
// It is a bucket head.
|
||||
m_aBuckets[iBucket] = m_aDataPool.Next(hHash);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a bucket head.
|
||||
m_aDataPool.Unlink(hHash);
|
||||
}
|
||||
|
||||
// Remove the element.
|
||||
m_aDataPool.Remove(hHash);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Remove all elements from the hash
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConCommandHash::RemoveAll(void)
|
||||
{
|
||||
m_aBuckets.RemoveAll();
|
||||
m_aDataPool.RemoveAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Find hash entry corresponding to a string name
|
||||
//-----------------------------------------------------------------------------
|
||||
CConCommandHash::CCommandHashHandle_t CConCommandHash::Find(
|
||||
const char* name, HashKey_t hashkey) const /*RESTRICT*/
|
||||
{
|
||||
// hash the "key" - get the correct hash table "bucket"
|
||||
int iBucket = hashkey & kBUCKETMASK;
|
||||
|
||||
for (datapool_t::IndexLocalType_t iElement = m_aBuckets[iBucket];
|
||||
iElement != m_aDataPool.InvalidIndex(); iElement = m_aDataPool.Next(iElement))
|
||||
{
|
||||
const HashEntry_t& element = m_aDataPool[iElement];
|
||||
if (element.m_uiKey == hashkey && // if hashes of strings match,
|
||||
Q_stricmp(name, element.m_Data->GetName()) == 0) // then test the actual strings
|
||||
{
|
||||
return iElement;
|
||||
}
|
||||
}
|
||||
|
||||
// found nuffink
|
||||
return InvalidHandle();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Find a command in the hash.
|
||||
//-----------------------------------------------------------------------------
|
||||
CConCommandHash::CCommandHashHandle_t CConCommandHash::Find(const ConCommandBase* cmd) const /*RESTRICT*/
|
||||
{
|
||||
// Set this #if to 1 if the assert at bottom starts whining --
|
||||
// that indicates that a console command is being double-registered,
|
||||
// or something similarly non-fatally bad. With this #if 1, we'll search
|
||||
// by name instead of by pointer, which is more robust in the face
|
||||
// of double registered commands, but obviously slower.
|
||||
#if 0
|
||||
return Find(cmd->GetName());
|
||||
#else
|
||||
HashKey_t hashkey = Hash(cmd);
|
||||
int iBucket = hashkey & kBUCKETMASK;
|
||||
|
||||
// hunt through all entries in that bucket
|
||||
for (datapool_t::IndexLocalType_t iElement = m_aBuckets[iBucket];
|
||||
iElement != m_aDataPool.InvalidIndex(); iElement = m_aDataPool.Next(iElement))
|
||||
{
|
||||
const HashEntry_t& element = m_aDataPool[iElement];
|
||||
if (element.m_uiKey == hashkey && // if the hashes match...
|
||||
element.m_Data == cmd) // and the pointers...
|
||||
{
|
||||
// in debug, test to make sure we don't have commands under the same name
|
||||
// or something goofy like that
|
||||
Assert(iElement == Find(cmd->GetName()),
|
||||
"ConCommand %s had two entries in the hash!", cmd->GetName());
|
||||
|
||||
// return this element
|
||||
return iElement;
|
||||
}
|
||||
}
|
||||
|
||||
// found nothing.
|
||||
#ifdef DBGFLAG_ASSERT // double check against search by name
|
||||
CCommandHashHandle_t dbghand = Find(cmd->GetName());
|
||||
|
||||
Assert(InvalidHandle() == dbghand,
|
||||
"ConCommand %s couldn't be found by pointer, but was found by name!", cmd->GetName());
|
||||
#endif
|
||||
return InvalidHandle();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//#ifdef _DEBUG
|
||||
// Dump a report to MSG
|
||||
void CConCommandHash::Report(void)
|
||||
{
|
||||
DevMsg(eDLL_T::COMMON, "Console command hash bucket load:\n");
|
||||
int total = 0;
|
||||
for (int iBucket = 0; iBucket < kNUM_BUCKETS; ++iBucket)
|
||||
{
|
||||
int count = 0;
|
||||
CCommandHashHandle_t iElement = m_aBuckets[iBucket]; // get the head of the bucket
|
||||
while (iElement != m_aDataPool.InvalidIndex())
|
||||
{
|
||||
++count;
|
||||
iElement = m_aDataPool.Next(iElement);
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::COMMON, "%d: %d\n", iBucket, count);
|
||||
total += count;
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::COMMON, "\tAverage: %.1f\n", total / ((float)(kNUM_BUCKETS)));
|
||||
}
|
||||
//#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VCVar::Attach() const
|
||||
{
|
||||
|
@ -266,15 +266,12 @@ bool CSocketCreator::ConfigureSocket(SocketHandle_t hSocket, bool bDualStack /*=
|
||||
//-----------------------------------------------------------------------------
|
||||
int CSocketCreator::OnSocketAccepted(SocketHandle_t hSocket, const netadr_t& netAdr)
|
||||
{
|
||||
AcceptedSocket_t newEntry;
|
||||
|
||||
newEntry.m_hSocket = hSocket;
|
||||
AcceptedSocket_t newEntry(hSocket);
|
||||
newEntry.m_Address = netAdr;
|
||||
newEntry.m_pData = new CConnectedNetConsoleData(hSocket);
|
||||
|
||||
m_hAcceptedSockets.push_back(newEntry);
|
||||
m_AcceptedSockets.AddToTail(newEntry);
|
||||
|
||||
int nIndex = static_cast<int>(m_hAcceptedSockets.size()) - 1;
|
||||
int nIndex = m_AcceptedSockets.Count() - 1;
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
@ -284,17 +281,16 @@ int CSocketCreator::OnSocketAccepted(SocketHandle_t hSocket, const netadr_t& net
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSocketCreator::CloseAcceptedSocket(int nIndex)
|
||||
{
|
||||
if (nIndex >= int(m_hAcceptedSockets.size()))
|
||||
if (nIndex >= m_AcceptedSockets.Count())
|
||||
{
|
||||
Assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
AcceptedSocket_t& connected = m_hAcceptedSockets[nIndex];
|
||||
AcceptedSocket_t& connected = m_AcceptedSockets[nIndex];
|
||||
DisconnectSocket(connected.m_hSocket);
|
||||
delete connected.m_pData;
|
||||
|
||||
m_hAcceptedSockets.erase(m_hAcceptedSockets.begin() + nIndex);
|
||||
m_AcceptedSockets.Remove(nIndex);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -302,14 +298,12 @@ void CSocketCreator::CloseAcceptedSocket(int nIndex)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSocketCreator::CloseAllAcceptedSockets(void)
|
||||
{
|
||||
for (size_t i = 0; i < m_hAcceptedSockets.size(); ++i)
|
||||
for (int i = 0; i < m_AcceptedSockets.Count(); ++i)
|
||||
{
|
||||
AcceptedSocket_t& connected = m_hAcceptedSockets[i];
|
||||
AcceptedSocket_t& connected = m_AcceptedSockets[i];
|
||||
DisconnectSocket(connected.m_hSocket);
|
||||
|
||||
delete connected.m_pData;
|
||||
}
|
||||
m_hAcceptedSockets.clear();
|
||||
m_AcceptedSockets.Purge();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -338,9 +332,9 @@ int CSocketCreator::GetAuthorizedSocketCount(void) const
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
for (size_t i = 0; i < m_hAcceptedSockets.size(); ++i)
|
||||
for (int i = 0; i < m_AcceptedSockets.Count(); ++i)
|
||||
{
|
||||
if (m_hAcceptedSockets[i].m_pData->m_bAuthorized)
|
||||
if (m_AcceptedSockets[i].m_Data.m_bAuthorized)
|
||||
{
|
||||
ret++;
|
||||
}
|
||||
@ -355,7 +349,7 @@ int CSocketCreator::GetAuthorizedSocketCount(void) const
|
||||
//-----------------------------------------------------------------------------
|
||||
int CSocketCreator::GetAcceptedSocketCount(void) const
|
||||
{
|
||||
return static_cast<int>(m_hAcceptedSockets.size());
|
||||
return m_AcceptedSockets.Count();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -365,8 +359,8 @@ int CSocketCreator::GetAcceptedSocketCount(void) const
|
||||
//-----------------------------------------------------------------------------
|
||||
SocketHandle_t CSocketCreator::GetAcceptedSocketHandle(int nIndex) const
|
||||
{
|
||||
Assert(nIndex >= 0 && nIndex < int(m_hAcceptedSockets.size()));
|
||||
return m_hAcceptedSockets[nIndex].m_hSocket;
|
||||
Assert(nIndex >= 0 && nIndex < m_AcceptedSockets.Count());
|
||||
return m_AcceptedSockets[nIndex].m_hSocket;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -376,8 +370,8 @@ SocketHandle_t CSocketCreator::GetAcceptedSocketHandle(int nIndex) const
|
||||
//-----------------------------------------------------------------------------
|
||||
const netadr_t& CSocketCreator::GetAcceptedSocketAddress(int nIndex) const
|
||||
{
|
||||
Assert(nIndex >= 0 && nIndex < int(m_hAcceptedSockets.size()));
|
||||
return m_hAcceptedSockets[nIndex].m_Address;
|
||||
Assert(nIndex >= 0 && nIndex < m_AcceptedSockets.Count());
|
||||
return m_AcceptedSockets[nIndex].m_Address;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -385,8 +379,19 @@ const netadr_t& CSocketCreator::GetAcceptedSocketAddress(int nIndex) const
|
||||
// Input : nIndex -
|
||||
// Output : CConnectedNetConsoleData*
|
||||
//-----------------------------------------------------------------------------
|
||||
CConnectedNetConsoleData* CSocketCreator::GetAcceptedSocketData(int nIndex) const
|
||||
CConnectedNetConsoleData& CSocketCreator::GetAcceptedSocketData(int nIndex)
|
||||
{
|
||||
Assert(nIndex >= 0 && nIndex < int(m_hAcceptedSockets.size()));
|
||||
return m_hAcceptedSockets[nIndex].m_pData;
|
||||
Assert(nIndex >= 0 && nIndex < m_AcceptedSockets.Count());
|
||||
return m_AcceptedSockets[nIndex].m_Data;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns accepted socket data
|
||||
// Input : nIndex -
|
||||
// Output : CConnectedNetConsoleData*
|
||||
//-----------------------------------------------------------------------------
|
||||
const CConnectedNetConsoleData& CSocketCreator::GetAcceptedSocketData(int nIndex) const
|
||||
{
|
||||
Assert(nIndex >= 0 && nIndex < m_AcceptedSockets.Count());
|
||||
return m_AcceptedSockets[nIndex].m_Data;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ start_sources()
|
||||
add_sources( SOURCE_GROUP "Private"
|
||||
"autocompletefilelist.cpp"
|
||||
"autocompletefilelist.h"
|
||||
"concommandhash.cpp"
|
||||
"concommandhash.h"
|
||||
"keyvaluessystem.cpp"
|
||||
"keyvaluessystem.h"
|
||||
|
211
r5dev/vstdlib/concommandhash.cpp
Normal file
211
r5dev/vstdlib/concommandhash.cpp
Normal file
@ -0,0 +1,211 @@
|
||||
//=============================================================================//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "concommandhash.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Console command hash data structure
|
||||
//-----------------------------------------------------------------------------
|
||||
CConCommandHash::CConCommandHash()
|
||||
{
|
||||
Purge(true);
|
||||
}
|
||||
|
||||
CConCommandHash::~CConCommandHash()
|
||||
{
|
||||
Purge(false);
|
||||
}
|
||||
|
||||
void CConCommandHash::Purge(bool bReinitialize)
|
||||
{
|
||||
m_aBuckets.Purge();
|
||||
m_aDataPool.Purge();
|
||||
if (bReinitialize)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize.
|
||||
void CConCommandHash::Init(void)
|
||||
{
|
||||
// kNUM_BUCKETS must be a power of two.
|
||||
COMPILE_TIME_ASSERT((kNUM_BUCKETS & (kNUM_BUCKETS - 1)) == 0);
|
||||
|
||||
// Set the bucket size.
|
||||
m_aBuckets.SetSize(kNUM_BUCKETS);
|
||||
for (int iBucket = 0; iBucket < kNUM_BUCKETS; ++iBucket)
|
||||
{
|
||||
m_aBuckets[iBucket] = m_aDataPool.InvalidIndex();
|
||||
}
|
||||
|
||||
// Calculate the grow size.
|
||||
int nGrowSize = 4 * kNUM_BUCKETS;
|
||||
m_aDataPool.SetGrowSize(nGrowSize);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Insert data into the hash table given its key (unsigned int),
|
||||
// WITH a check to see if the element already exists within the hash.
|
||||
//-----------------------------------------------------------------------------
|
||||
CConCommandHash::CCommandHashHandle_t CConCommandHash::Insert(ConCommandBase* cmd)
|
||||
{
|
||||
// Check to see if that key already exists in the buckets (should be unique).
|
||||
CCommandHashHandle_t hHash = Find(cmd);
|
||||
if (hHash != InvalidHandle())
|
||||
return hHash;
|
||||
|
||||
return FastInsert(cmd);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Insert data into the hash table given its key (unsigned int),
|
||||
// WITHOUT a check to see if the element already exists within the hash.
|
||||
//-----------------------------------------------------------------------------
|
||||
CConCommandHash::CCommandHashHandle_t CConCommandHash::FastInsert(ConCommandBase* cmd)
|
||||
{
|
||||
// Get a new element from the pool.
|
||||
intptr_t iHashData = m_aDataPool.Alloc(true);
|
||||
HashEntry_t* RESTRICT pHashData = &m_aDataPool[iHashData];
|
||||
if (!pHashData)
|
||||
return InvalidHandle();
|
||||
|
||||
HashKey_t key = Hash(cmd);
|
||||
|
||||
// Add data to new element.
|
||||
pHashData->m_uiKey = key;
|
||||
pHashData->m_Data = cmd;
|
||||
|
||||
// Link element.
|
||||
int iBucket = key & kBUCKETMASK; // HashFuncs::Hash( uiKey, m_uiBucketMask );
|
||||
m_aDataPool.LinkBefore(m_aBuckets[iBucket], iHashData);
|
||||
m_aBuckets[iBucket] = iHashData;
|
||||
|
||||
return iHashData;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Remove a given element from the hash.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConCommandHash::Remove(CCommandHashHandle_t hHash) /*RESTRICT*/
|
||||
{
|
||||
HashEntry_t* /*RESTRICT*/ entry = &m_aDataPool[hHash];
|
||||
HashKey_t iBucket = entry->m_uiKey & kBUCKETMASK;
|
||||
if (m_aBuckets[iBucket] == hHash)
|
||||
{
|
||||
// It is a bucket head.
|
||||
m_aBuckets[iBucket] = m_aDataPool.Next(hHash);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a bucket head.
|
||||
m_aDataPool.Unlink(hHash);
|
||||
}
|
||||
|
||||
// Remove the element.
|
||||
m_aDataPool.Remove(hHash);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Remove all elements from the hash
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConCommandHash::RemoveAll(void)
|
||||
{
|
||||
m_aBuckets.RemoveAll();
|
||||
m_aDataPool.RemoveAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Find hash entry corresponding to a string name
|
||||
//-----------------------------------------------------------------------------
|
||||
CConCommandHash::CCommandHashHandle_t CConCommandHash::Find(
|
||||
const char* name, HashKey_t hashkey) const /*RESTRICT*/
|
||||
{
|
||||
// hash the "key" - get the correct hash table "bucket"
|
||||
int iBucket = hashkey & kBUCKETMASK;
|
||||
|
||||
for (datapool_t::IndexLocalType_t iElement = m_aBuckets[iBucket];
|
||||
iElement != m_aDataPool.InvalidIndex(); iElement = m_aDataPool.Next(iElement))
|
||||
{
|
||||
const HashEntry_t& element = m_aDataPool[iElement];
|
||||
if (element.m_uiKey == hashkey && // if hashes of strings match,
|
||||
Q_stricmp(name, element.m_Data->GetName()) == 0) // then test the actual strings
|
||||
{
|
||||
return iElement;
|
||||
}
|
||||
}
|
||||
|
||||
// found nuffink
|
||||
return InvalidHandle();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Find a command in the hash.
|
||||
//-----------------------------------------------------------------------------
|
||||
CConCommandHash::CCommandHashHandle_t CConCommandHash::Find(const ConCommandBase* cmd) const /*RESTRICT*/
|
||||
{
|
||||
// Set this #if to 1 if the assert at bottom starts whining --
|
||||
// that indicates that a console command is being double-registered,
|
||||
// or something similarly non-fatally bad. With this #if 1, we'll search
|
||||
// by name instead of by pointer, which is more robust in the face
|
||||
// of double registered commands, but obviously slower.
|
||||
#if 0
|
||||
return Find(cmd->GetName());
|
||||
#else
|
||||
HashKey_t hashkey = Hash(cmd);
|
||||
int iBucket = hashkey & kBUCKETMASK;
|
||||
|
||||
// hunt through all entries in that bucket
|
||||
for (datapool_t::IndexLocalType_t iElement = m_aBuckets[iBucket];
|
||||
iElement != m_aDataPool.InvalidIndex(); iElement = m_aDataPool.Next(iElement))
|
||||
{
|
||||
const HashEntry_t& element = m_aDataPool[iElement];
|
||||
if (element.m_uiKey == hashkey && // if the hashes match...
|
||||
element.m_Data == cmd) // and the pointers...
|
||||
{
|
||||
// in debug, test to make sure we don't have commands under the same name
|
||||
// or something goofy like that
|
||||
Assert(iElement == Find(cmd->GetName()),
|
||||
"ConCommand %s had two entries in the hash!", cmd->GetName());
|
||||
|
||||
// return this element
|
||||
return iElement;
|
||||
}
|
||||
}
|
||||
|
||||
// found nothing.
|
||||
#ifdef DBGFLAG_ASSERT // double check against search by name
|
||||
CCommandHashHandle_t dbghand = Find(cmd->GetName());
|
||||
|
||||
Assert(InvalidHandle() == dbghand,
|
||||
"ConCommand %s couldn't be found by pointer, but was found by name!", cmd->GetName());
|
||||
#endif
|
||||
return InvalidHandle();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//#ifdef _DEBUG
|
||||
// Dump a report to MSG
|
||||
void CConCommandHash::Report(void)
|
||||
{
|
||||
DevMsg(eDLL_T::COMMON, "Console command hash bucket load:\n");
|
||||
int total = 0;
|
||||
for (int iBucket = 0; iBucket < kNUM_BUCKETS; ++iBucket)
|
||||
{
|
||||
int count = 0;
|
||||
CCommandHashHandle_t iElement = m_aBuckets[iBucket]; // get the head of the bucket
|
||||
while (iElement != m_aDataPool.InvalidIndex())
|
||||
{
|
||||
++count;
|
||||
iElement = m_aDataPool.Next(iElement);
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::COMMON, "%d: %d\n", iBucket, count);
|
||||
total += count;
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::COMMON, "\tAverage: %.1f\n", total / ((float)(kNUM_BUCKETS)));
|
||||
}
|
||||
//#endif
|
@ -12,10 +12,10 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/cmd.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utllinkedlist.h"
|
||||
#include "tier1/generichash.h"
|
||||
#include "tier1/convar.h"
|
||||
|
||||
// This is a hash table class very similar to the CUtlHashFast, but
|
||||
// modified specifically so that we can look up ConCommandBases
|
||||
|
Loading…
x
Reference in New Issue
Block a user