mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Cmd: add rate limit logic for 'Cmd_ForwardToServer'
If the client happens to exceed the quota by accident, the client will not be disconnected. This is a quality of life change. Client could still increase cl_quota_stringCmdsPerSecond to allow more submissions per second, or disabling the throttle entirely by setting cl_quota_stringCmdsPerSecond to 0.
This commit is contained in:
parent
484f3251d1
commit
23eba316df
@ -123,6 +123,7 @@ void ConVar::Init(void) const
|
||||
// CLIENT |
|
||||
#ifndef DEDICATED
|
||||
cl_rcon_request_sendlogs = ConVar::Create("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_quota_stringCmdsPerSecond = ConVar::Create("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_showhoststats = ConVar::Create("cl_showhoststats" , "0", FCVAR_DEVELOPMENTONLY, "Host speeds debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_hoststats_invert_x = ConVar::Create("cl_hoststats_invert_x", "0", FCVAR_DEVELOPMENTONLY, "Inverts the X offset for host speeds debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
@ -660,13 +660,65 @@ ECommandTarget_t Cbuf_GetCurrentPlayer(void)
|
||||
return ECommandTarget_t::CBUF_FIRST_PLAYER;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sends the entire command line over to the server
|
||||
// Input : *args -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Cmd_ForwardToServer(const CCommand* args)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
// Client -> Server command throttling.
|
||||
static double flForwardedCommandQuotaStartTime = -1;
|
||||
static int nForwardedCommandQuotaCount = 0;
|
||||
|
||||
// No command to forward.
|
||||
if (args->ArgC() == 0)
|
||||
return false;
|
||||
|
||||
double flStartTime = Plat_FloatTime();
|
||||
int nCmdQuotaLimit = cl_quota_stringCmdsPerSecond->GetInt();
|
||||
const char* pszCmdString = nullptr;
|
||||
|
||||
// Special case: "cmd whatever args..." is forwarded as "whatever args...";
|
||||
// in this case we strip "cmd" from the input.
|
||||
if (Q_strcasecmp(args->Arg(0), "cmd") == 0)
|
||||
pszCmdString = args->ArgS();
|
||||
else
|
||||
pszCmdString = args->GetCommandString();
|
||||
|
||||
if (nCmdQuotaLimit)
|
||||
{
|
||||
if (flStartTime - flForwardedCommandQuotaStartTime >= 1.0)
|
||||
{
|
||||
flForwardedCommandQuotaStartTime = flStartTime;
|
||||
nForwardedCommandQuotaCount = 0;
|
||||
}
|
||||
++nForwardedCommandQuotaCount;
|
||||
|
||||
if (nForwardedCommandQuotaCount > nCmdQuotaLimit)
|
||||
{
|
||||
// If we are over quota commands per second, dump this on the floor.
|
||||
// If we spam the server with too many commands, it will kick us.
|
||||
Warning(eDLL_T::CLIENT, "Command '%s' ignored (submission quota of '%d' per second exceeded!)\n", args->ArgS(), nCmdQuotaLimit);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return v_Cmd_ForwardToServer(args);
|
||||
#else // !DEDICATED
|
||||
return false; // Client only.
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void ConCommand_Attach()
|
||||
{
|
||||
DetourAttach((LPVOID*)&ConCommandBase_IsFlagSet, &ConCommandBase::IsFlagSetInternal);
|
||||
DetourAttach((LPVOID*)&v_Cmd_ForwardToServer, &Cmd_ForwardToServer);
|
||||
}
|
||||
void ConCommand_Detach()
|
||||
{
|
||||
DetourDetach((LPVOID*)&ConCommandBase_IsFlagSet, &ConCommandBase::IsFlagSetInternal);
|
||||
DetourDetach((LPVOID*)&v_Cmd_ForwardToServer, &Cmd_ForwardToServer);
|
||||
}
|
||||
ConCommand* g_pConCommand = new ConCommand();
|
||||
|
@ -164,6 +164,9 @@ inline auto Cbuf_AddText = p_Cbuf_AddText.RCast<void (*)(ECommandTarget_t eTarge
|
||||
inline CMemory p_Cbuf_Execute;
|
||||
inline auto Cbuf_Execute = p_Cbuf_Execute.RCast<void (*)(void)>();
|
||||
|
||||
inline CMemory p_Cmd_ForwardToServer;
|
||||
inline auto v_Cmd_ForwardToServer = p_Cmd_ForwardToServer.RCast<bool (*)(const CCommand* args)>();
|
||||
|
||||
/* ==== CONCOMMAND ====================================================================================================================================================== */
|
||||
inline CMemory p_ConCommandBase_IsFlagSet;
|
||||
inline auto ConCommandBase_IsFlagSet = p_ConCommandBase_IsFlagSet.RCast<bool (*)(ConCommandBase* pCommand, int nFlag)>();
|
||||
@ -191,6 +194,7 @@ class VConCommand : public IDetour
|
||||
{
|
||||
spdlog::debug("| FUN: Cbuf_AddText : {:#18x} |\n", p_Cbuf_AddText.GetPtr());
|
||||
spdlog::debug("| FUN: Cbuf_Execute : {:#18x} |\n", p_Cbuf_Execute.GetPtr());
|
||||
spdlog::debug("| FUN: Cmd_ForwardToServer : {:#18x} |\n", p_Cmd_ForwardToServer.GetPtr());
|
||||
spdlog::debug("+----------------------------------------------------------------+\n");
|
||||
spdlog::debug("| FUN: ConCommandBase::IsFlagSet : {:#18x} |\n", p_ConCommandBase_IsFlagSet.GetPtr());
|
||||
spdlog::debug("+----------------------------------------------------------------+\n");
|
||||
@ -204,12 +208,14 @@ class VConCommand : public IDetour
|
||||
{
|
||||
p_Cbuf_AddText = g_GameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\x48\x63\xD9\x41\x8B\xF8\x48\x8D\x0D\x00\x00\x00\x00\x48\x8B\xF2\xFF\x15\x00\x00\x00\x00\x48\x8D\x05\x00\x00\x00\x00\x41\xB9\x00\x00\x00\x00"), "xxxx?xxxx?xxxxxxxxxxxxxx????xxxxx????xxx????xx????");
|
||||
p_Cbuf_Execute = g_GameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\xFF\x15\x00\x00\x00\x00"), "xxxx?xxxx?xxxx?xxxxxxx????");
|
||||
p_Cmd_ForwardToServer = g_GameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x81\xEC\x00\x00\x00\x00\x44\x8B\x59\x04"), "xxxx?xxxx?xxxx?xxxx????xxxx");
|
||||
p_ConCommandBase_IsFlagSet = g_GameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x85\x51\x38\x0F\x95\xC0\xC3"), "xxxxxxx");
|
||||
p_NullSub = g_GameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\xC2\x00\x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x40\x53\x48\x83\xEC\x20\x48\x8D\x05\x00\x00\x00\x00"), "xxxxxxxxxxxxxxxxxxxxxxxxx????");
|
||||
p_CallbackStub = g_GameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x33\xC0\xC3\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x80\x49\x68\x08"), "xxxxxxxxxxxxxxxxxxxx");
|
||||
|
||||
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_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*/
|
||||
ConCommandBase_IsFlagSet = p_ConCommandBase_IsFlagSet.RCast<bool (*)(ConCommandBase*, int)>(); /*85 51 38 0F 95 C0 C3*/
|
||||
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*/
|
||||
|
@ -93,6 +93,7 @@ ConVar* bhit_abs_origin = nullptr;
|
||||
// CLIENT |
|
||||
#ifndef DEDICATED
|
||||
ConVar* cl_rcon_request_sendlogs = nullptr;
|
||||
ConVar* cl_quota_stringCmdsPerSecond = nullptr;
|
||||
|
||||
ConVar* cl_showhoststats = nullptr;
|
||||
ConVar* cl_hoststats_invert_x = nullptr;
|
||||
|
@ -88,6 +88,7 @@ extern ConVar* bhit_abs_origin;
|
||||
// CLIENT |
|
||||
#ifndef DEDICATED
|
||||
extern ConVar* cl_rcon_request_sendlogs;
|
||||
extern ConVar* cl_quota_stringCmdsPerSecond;
|
||||
|
||||
extern ConVar* cl_showhoststats;
|
||||
extern ConVar* cl_hoststats_invert_x;
|
||||
|
Loading…
x
Reference in New Issue
Block a user