Server: add option to respect game state when performing auto reload

Can be toggled with the new cvar 'host_autoReloadRespectGameState', and used in combination with the new server script func 'SetAutoReloadState( bool state )'. This makes sure that even when the timer reaches 'host_autoReloadRate', it would wait with the reload until the game itself is finished (which is when SetAutoReloadState( true ) is being called from scripts).
This commit is contained in:
Kawe Mazidjatari 2024-04-12 22:06:31 +02:00
parent 9e0c375a7b
commit 5a2dfaf03a
6 changed files with 61 additions and 17 deletions

View File

@ -57,10 +57,10 @@
#include "game/shared/vscript_shared.h"
#ifndef CLIENT_DLL
static ConVar sv_pylonVisibility("sv_pylonVisibility", "0", FCVAR_RELEASE, "Determines the visibility to the Pylon master server.", "0 = Offline, 1 = Hidden, 2 = Public.");
static ConVar sv_pylonRefreshRate("sv_pylonRefreshRate", "5.0", FCVAR_DEVELOPMENTONLY, "Pylon host refresh rate (seconds).");
static ConVar host_statusRefreshRate("host_statusRefreshRate", "0.5", FCVAR_RELEASE, "Host status refresh rate (seconds).", true, 0.f, false, 0.f);
static ConVar sv_autoReloadRate("sv_autoReloadRate", "0", FCVAR_RELEASE, "Time in seconds between each server auto-reload (disabled if null).");
static ConVar host_autoReloadRate("host_autoReloadRate", "0", FCVAR_RELEASE, "Time in seconds between each auto-reload (disabled if null).");
static ConVar host_autoReloadRespectGameState("host_autoReloadRespectGameState", "0", FCVAR_RELEASE, "Check the game state before proceeding to auto-reload (don't reload in the middle of a match).");
#endif // !CLIENT_DLL
#ifdef DEDICATED
@ -136,6 +136,24 @@ static void HostState_KeepAlive()
}
#endif // DEDICATED
#ifndef CLIENT_DLL
void HostState_HandleAutoReload()
{
if (host_autoReloadRate.GetBool())
{
if (g_ServerGlobalVariables->m_flCurTime > host_autoReloadRate.GetFloat())
{
// We should respect the game state, and the game isn't finished yet so
// don't reload the server now.
if (host_autoReloadRespectGameState.GetBool() && !g_hostReloadState)
return;
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "reload\n", cmd_source_t::kCommandSrcCode);
}
}
}
#endif // !CLIENT_DLL
//-----------------------------------------------------------------------------
// Purpose: state machine's main processing loop
//-----------------------------------------------------------------------------
@ -343,14 +361,10 @@ void CHostState::Think(void) const
#endif // DEDICATED
bInitialized = true;
}
if (sv_autoReloadRate.GetBool())
{
if (g_ServerGlobalVariables->m_flCurTime > sv_autoReloadRate.GetFloat())
{
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "reload\n", cmd_source_t::kCommandSrcCode);
}
}
if (statsTimer.GetDurationInProgress().GetSeconds() > sv_statusRefreshRate.GetFloat())
HostState_HandleAutoReload();
if (statsTimer.GetDurationInProgress().GetSeconds() > host_statusRefreshRate.GetFloat())
{
SetConsoleTitleA(Format("%s - %d/%d Players (%s on %s) - %d%% Server CPU (%.3f msec on frame %d)",
hostname->GetString(), g_pServer->GetNumClients(),
@ -547,3 +561,7 @@ void VHostState::Detour(const bool bAttach) const
///////////////////////////////////////////////////////////////////////////////
CHostState* g_pHostState = nullptr;
#ifndef CLIENT_DLL
bool g_hostReloadState = false;
#endif // !CLIENT_DLL

View File

@ -58,6 +58,9 @@ inline void(*v_HostState_ChangeLevelMP)(char const* pNewLevel, char const* pLand
///////////////////////////////////////////////////////////////////////////////
extern CHostState* g_pHostState;
#ifndef CLIENT_DLL
extern bool g_hostReloadState;
#endif // !CLIENT_DLL
///////////////////////////////////////////////////////////////////////////////
class VHostState : public IDetour

View File

@ -25,10 +25,12 @@
// Console variables
//---------------------------------------------------------------------------------
ConVar sv_showconnecting("sv_showconnecting", "1", FCVAR_RELEASE, "Logs information about the connecting client to the console");
ConVar sv_globalBanlist("sv_globalBanlist", "1", FCVAR_RELEASE, "Determines whether or not to use the global banned list.", false, 0.f, false, 0.f, "0 = Disable, 1 = Enable.");
ConVar sv_pylonVisibility("sv_pylonVisibility", "0", FCVAR_RELEASE, "Determines the visibility to the Pylon master server.", "0 = Offline, 1 = Hidden, 2 = Public.");
ConVar sv_pylonRefreshRate("sv_pylonRefreshRate", "5.0", FCVAR_DEVELOPMENTONLY, "Pylon host refresh rate (seconds).");
ConVar sv_globalBanlist("sv_globalBanlist", "1", FCVAR_RELEASE, "Determines whether or not to use the global banned list.", false, 0.f, false, 0.f, "0 = Disable, 1 = Enable.");
ConVar sv_banlistRefreshRate("sv_banlistRefreshRate", "30.0", FCVAR_DEVELOPMENTONLY, "Banned list refresh rate (seconds).", true, 1.f, false, 0.f);
ConVar sv_statusRefreshRate("sv_statusRefreshRate", "0.5", FCVAR_RELEASE, "Server status refresh rate (seconds).", true, 0.f, false, 0.f);
static ConVar sv_validatePersonaName("sv_validatePersonaName", "1", FCVAR_RELEASE, "Validate the client's textual persona name on connect.");
static ConVar sv_minPersonaNameLength("sv_minPersonaNameLength", "4", FCVAR_RELEASE, "The minimum length of the client's textual persona name.", true, 0.f, false, 0.f);

View File

@ -111,13 +111,14 @@ static_assert(sizeof(CServer) == 0x25264C0);
extern CServer* g_pServer;
extern ConVar sv_showconnecting;
extern ConVar sv_pylonVisibility;
extern ConVar sv_pylonRefreshRate;
extern ConVar sv_globalBanlist;
extern ConVar sv_banlistRefreshRate;
extern ConVar sv_statusRefreshRate;
extern ConVar sv_showconnecting;
/* ==== CSERVER ========================================================================================================================================================= */
inline void(*CServer__FrameJob)(double flFrameTime, bool bRunOverlays, bool bUpdateFrame);
inline void(*CServer__RunFrame)(CServer* pServer);

View File

@ -83,6 +83,7 @@ namespace VScriptCode
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
}
//-----------------------------------------------------------------------------
// Purpose: shuts the server down and disconnects all clients
//-----------------------------------------------------------------------------
@ -94,6 +95,21 @@ namespace VScriptCode
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
}
//-----------------------------------------------------------------------------
// Purpose: sets whether the server could auto reload at this time (e.g. if
// server admin has host_autoReloadRate AND host_autoReloadRespectGameState
// set, and its time to auto reload, but the match hasn't finished yet, wait
// until this is set to proceed the reload of the server
//-----------------------------------------------------------------------------
SQRESULT SetAutoReloadState(HSQUIRRELVM v)
{
SQBool state = false;
sq_getbool(v, 2, &state);
g_hostReloadState = state;
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
}
//-----------------------------------------------------------------------------
// Purpose: kicks a player by given name
//-----------------------------------------------------------------------------
@ -282,6 +298,8 @@ void Script_RegisterCoreServerFunctions(CSquirrelVM* s)
DEFINE_SERVER_SCRIPTFUNC_NAMED(s, CreateServer, "Starts server with the specified settings", "void", "string, string, string, string, int");
DEFINE_SERVER_SCRIPTFUNC_NAMED(s, DestroyServer, "Shuts the local server down", "void", "");
DEFINE_SERVER_SCRIPTFUNC_NAMED(s, SetAutoReloadState, "Set whether we can auto-reload the server", "void", "bool");
}
//---------------------------------------------------------------------------------

View File

@ -9,6 +9,8 @@ namespace VScriptCode
SQRESULT CreateServer(HSQUIRRELVM v);
SQRESULT DestroyServer(HSQUIRRELVM v);
SQRESULT SetAutoReloadState(HSQUIRRELVM v);
SQRESULT KickPlayerByName(HSQUIRRELVM v);
SQRESULT KickPlayerById(HSQUIRRELVM v);
SQRESULT BanPlayerByName(HSQUIRRELVM v);