2022-02-06 16:48:52 +01:00
//=============================================================================//
//
2022-02-14 23:16:24 +01:00
// Purpose: Runs the state machine for the host & server.
2022-02-06 16:48:52 +01:00
//
//=============================================================================//
2023-03-18 17:36:09 +01:00
// host_state.cpp:.
2022-05-20 20:14:39 +02:00
//
/////////////////////////////////////////////////////////////////////////////////
2021-12-25 22:36:38 +01:00
# include "core/stdafx.h"
2022-05-04 02:25:27 +02:00
# include "tier0/jobthread.h"
2022-01-10 02:47:19 +01:00
# include "tier0/commandline.h"
2022-03-25 02:30:36 +01:00
# include "tier0/fasttimer.h"
2024-03-10 01:57:04 +01:00
# include "tier0/frametask.h"
2022-04-09 16:16:40 +02:00
# include "tier1/cvar.h"
2023-01-29 15:12:27 +01:00
# include "tier1/NetAdr.h"
2022-02-06 16:48:52 +01:00
# include "tier2/socketcreator.h"
2022-04-29 05:30:06 +02:00
# include "datacache/mdlcache.h"
2023-01-29 16:07:02 +01:00
# ifndef CLIENT_DLL
2022-05-20 11:52:19 +02:00
# include "engine/server/sv_rcon.h"
2023-07-19 02:19:43 +02:00
# include "engine/server/server.h"
2023-01-29 16:07:02 +01:00
# endif // !CLIENT_DLL
# ifndef DEDICATED
2022-05-20 11:52:19 +02:00
# include "engine/client/cl_rcon.h"
# include "engine/client/cl_main.h"
2022-11-10 11:47:02 +01:00
# include "engine/client/clientstate.h"
2022-02-08 16:32:00 +01:00
# endif // DEDICATED
2023-05-10 00:05:38 +02:00
# include "engine/cmd.h"
2022-04-02 02:48:54 +02:00
# include "engine/net.h"
2022-03-01 02:39:46 +01:00
# include "engine/gl_screen.h"
2022-04-12 02:48:46 +02:00
# include "engine/host.h"
# include "engine/host_cmd.h"
2022-02-19 02:31:16 +01:00
# include "engine/host_state.h"
2022-03-01 02:39:46 +01:00
# include "engine/sys_engine.h"
2022-04-12 02:48:46 +02:00
# include "engine/modelloader.h"
2022-03-01 02:39:46 +01:00
# include "engine/cmodel_bsp.h"
2022-03-27 22:17:30 +02:00
# ifndef CLIENT_DLL
2022-05-20 11:52:19 +02:00
# include "engine/server/server.h"
2024-04-05 18:30:22 +02:00
# include "rtech/liveapi/liveapi.h"
2022-03-27 22:17:30 +02:00
# endif // !CLIENT_DLL
2022-04-12 02:48:46 +02:00
# include "rtech/stryder/stryder.h"
2024-04-05 17:42:05 +02:00
# include "rtech/playlists/playlists.h"
2022-02-19 02:31:16 +01:00
# ifndef DEDICATED
# include "vgui/vgui_baseui_interface.h"
2022-04-02 12:27:35 +02:00
# include "client/vengineclient_impl.h"
2024-04-05 18:17:12 +02:00
# include "gameui/imgui_system.h"
2022-08-17 02:04:01 +02:00
# endif // DEDICATED
2022-02-19 02:31:16 +01:00
# include "networksystem/pylon.h"
2022-09-01 01:32:32 +02:00
# ifndef CLIENT_DLL
2022-08-09 17:34:10 +02:00
# include "networksystem/bansystem.h"
2024-03-10 01:57:04 +01:00
# include "networksystem/hostmanager.h"
2022-09-01 01:32:32 +02:00
# endif // !CLIENT_DLL
2022-08-27 23:45:58 +02:00
# include "networksystem/listmanager.h"
2022-08-09 17:18:07 +02:00
# include "public/edict.h"
2022-03-27 22:17:30 +02:00
# ifndef CLIENT_DLL
2022-02-24 01:51:11 +01:00
# include "game/server/gameinterface.h"
2022-03-27 22:17:30 +02:00
# endif // !CLIENT_DLL
2023-05-06 16:23:56 +02:00
# include "game/shared/vscript_shared.h"
2022-01-09 14:35:43 +01:00
2023-07-19 02:19:43 +02:00
# ifndef CLIENT_DLL
2024-04-12 22:06:31 +02:00
static ConVar host_statusRefreshRate ( " host_statusRefreshRate " , " 0.5 " , FCVAR_RELEASE , " Host status refresh rate (seconds) . " , true, 0.f, false, 0.f) ;
2024-02-24 02:15:09 +01:00
2024-04-12 22:06:31 +02:00
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) . " ) ;
2024-03-10 01:57:04 +01:00
# endif // !CLIENT_DLL
2024-02-24 02:15:09 +01:00
2024-03-10 01:57:04 +01:00
# ifdef DEDICATED
static ConVar hostdesc ( " hostdesc " , " " , FCVAR_RELEASE , " Host game server description. " ) ;
2023-07-19 02:19:43 +02:00
//-----------------------------------------------------------------------------
// Purpose: Send keep alive request to Pylon Master Server.
// Output : Returns true on success, false otherwise.
//-----------------------------------------------------------------------------
2024-03-10 01:57:04 +01:00
static void HostState_KeepAlive ( )
2023-07-19 02:19:43 +02:00
{
2024-02-24 02:15:09 +01:00
if ( ! g_pServer - > IsActive ( ) | | ! sv_pylonVisibility . GetBool ( ) ) // Check for active game.
2023-07-19 02:19:43 +02:00
{
2024-03-10 01:57:04 +01:00
return ;
2023-07-19 02:19:43 +02:00
}
2024-03-10 01:57:04 +01:00
const NetGameServer_t gameServer
2023-07-19 02:19:43 +02:00
{
2024-03-10 01:57:04 +01:00
hostname - > GetString ( ) ,
hostdesc . GetString ( ) ,
sv_pylonVisibility . GetInt ( ) = = ServerVisibility_e : : HIDDEN ,
g_pHostState - > m_levelName ,
v_Playlists_GetCurrent ( ) ,
hostip - > GetString ( ) ,
hostport - > GetInt ( ) ,
g_pNetKey - > GetBase64NetKey ( ) ,
* g_nServerRemoteChecksum ,
SDK_VERSION ,
g_pServer - > GetNumClients ( ) ,
g_ServerGlobalVariables - > m_nMaxClients ,
std : : chrono : : duration_cast < std : : chrono : : milliseconds > (
std : : chrono : : system_clock : : now ( ) . time_since_epoch ( )
) . count ( )
} ;
std : : thread request ( [ & , gameServer ]
2023-07-19 02:19:43 +02:00
{
2024-03-10 01:57:04 +01:00
string errorMsg ;
string hostToken ;
string hostIp ;
const bool result = g_MasterServer . PostServerHost ( errorMsg , hostToken , hostIp , gameServer ) ;
// Apply the data the next frame
g_TaskQueue . Dispatch ( [ result , errorMsg , hostToken , hostIp ]
{
if ( ! result )
{
if ( ! errorMsg . empty ( ) & & g_ServerHostManager . GetCurrentError ( ) . compare ( errorMsg ) ! = NULL )
{
g_ServerHostManager . SetCurrentError ( errorMsg ) ;
Error ( eDLL_T : : SERVER , NO_ERROR , " %s \n " , errorMsg . c_str ( ) ) ;
}
}
else // Attempt to log the token, if there is one.
{
if ( ! hostToken . empty ( ) & & g_ServerHostManager . GetCurrentToken ( ) . compare ( hostToken ) ! = NULL )
{
g_ServerHostManager . SetCurrentToken ( hostToken ) ;
Msg ( eDLL_T : : SERVER , " Published server with token: %s'%s%s%s' \n " ,
g_svReset , g_svGreyB ,
hostToken . c_str ( ) , g_svReset ) ;
}
}
if ( hostIp . length ( ) ! = 0 )
g_ServerHostManager . SetHostIP ( hostIp ) ;
2023-07-19 02:19:43 +02:00
2024-03-10 01:57:04 +01:00
} , 0 ) ;
}
) ;
2023-10-15 10:40:46 +02:00
2024-03-10 01:57:04 +01:00
request . detach ( ) ;
2023-07-19 02:19:43 +02:00
}
2024-03-10 01:57:04 +01:00
# endif // DEDICATED
2023-07-19 02:19:43 +02:00
2024-04-12 22:06:31 +02:00
# 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
2021-12-25 22:36:38 +01:00
//-----------------------------------------------------------------------------
// Purpose: state machine's main processing loop
//-----------------------------------------------------------------------------
2023-03-18 17:36:09 +01:00
void CHostState : : FrameUpdate ( CHostState * pHostState , double flCurrentTime , float flFrameTime )
2021-12-25 22:36:38 +01:00
{
static bool bInitialized = false ;
2022-09-14 21:51:15 +02:00
static bool bResetIdleName = false ;
2021-12-25 22:36:38 +01:00
if ( ! bInitialized )
{
2022-02-19 02:31:16 +01:00
g_pHostState - > Setup ( ) ;
2021-12-25 22:36:38 +01:00
bInitialized = true ;
}
2022-08-27 23:45:58 +02:00
g_pHostState - > Think ( ) ;
2023-01-29 16:07:02 +01:00
# ifndef CLIENT_DLL
2022-07-25 19:35:08 +02:00
RCONServer ( ) - > RunFrame ( ) ;
2023-01-29 16:07:02 +01:00
# endif // !CLIENT_DLL
# ifndef DEDICATED
2022-07-25 19:35:08 +02:00
RCONClient ( ) - > RunFrame ( ) ;
2023-01-29 16:07:02 +01:00
# endif // !DEDICATED
2022-02-06 16:48:52 +01:00
2023-04-03 14:55:16 +02:00
// Disable "warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable"
# pragma warning(push)
# pragma warning(disable : 4611)
2022-04-12 02:48:46 +02:00
if ( setjmp ( * host_abortserver ) )
2021-12-25 22:36:38 +01:00
{
2022-04-12 02:48:46 +02:00
g_pHostState - > Init ( ) ;
2021-12-25 22:36:38 +01:00
return ;
}
2023-04-03 14:55:16 +02:00
# pragma warning(pop)
2021-12-25 22:36:38 +01:00
else
{
2022-03-27 22:17:30 +02:00
# ifndef CLIENT_DLL
2022-04-12 02:48:46 +02:00
* g_bAbortServerSet = true ;
2022-03-27 22:17:30 +02:00
# endif // !CLIENT_DLL
2024-02-06 14:33:40 +01:00
while ( true )
2021-12-25 22:36:38 +01:00
{
2022-02-19 02:31:16 +01:00
Cbuf_Execute ( ) ;
2024-02-06 14:33:40 +01:00
2024-02-27 17:43:18 +01:00
const HostStates_t oldState = g_pHostState - > m_iCurrentState ;
2021-12-25 22:36:38 +01:00
switch ( g_pHostState - > m_iCurrentState )
{
case HostStates_t : : HS_NEW_GAME :
{
2022-02-19 02:31:16 +01:00
g_pHostState - > State_NewGame ( ) ;
2021-12-25 22:36:38 +01:00
break ;
}
case HostStates_t : : HS_CHANGE_LEVEL_SP :
{
2022-02-19 02:31:16 +01:00
g_pHostState - > State_ChangeLevelSP ( ) ;
2021-12-25 22:36:38 +01:00
break ;
}
case HostStates_t : : HS_CHANGE_LEVEL_MP :
{
2022-02-19 02:31:16 +01:00
g_pHostState - > State_ChangeLevelMP ( ) ;
2021-12-25 22:36:38 +01:00
break ;
}
case HostStates_t : : HS_RUN :
{
2022-09-14 21:51:15 +02:00
if ( ! g_pHostState - > m_bActiveGame )
{
if ( bResetIdleName )
{
g_pHostState - > ResetLevelName ( ) ;
bResetIdleName = false ;
}
}
else // Reset idle name the next non-active frame.
{
bResetIdleName = true ;
}
2024-01-02 15:21:36 +01:00
CHostState__State_Run ( & g_pHostState - > m_iCurrentState , flCurrentTime , flFrameTime ) ;
2021-12-25 22:36:38 +01:00
break ;
}
case HostStates_t : : HS_GAME_SHUTDOWN :
{
2023-08-21 19:12:29 +02:00
Msg ( eDLL_T : : ENGINE , " %s: Shutdown host game \n " , __FUNCTION__ ) ;
2024-01-02 15:21:36 +01:00
CHostState__State_GameShutDown ( g_pHostState ) ;
2021-12-25 22:36:38 +01:00
break ;
}
case HostStates_t : : HS_RESTART :
{
2023-08-21 19:12:29 +02:00
Msg ( eDLL_T : : ENGINE , " %s: Restarting state machine \n " , __FUNCTION__ ) ;
2022-02-19 02:31:16 +01:00
# ifndef DEDICATED
2024-01-02 15:21:36 +01:00
v_CL_EndMovie ( ) ;
2022-02-19 02:31:16 +01:00
# endif // !DEDICATED
2024-01-02 15:21:36 +01:00
v_Stryder_SendOfflineRequest ( ) ; // We have hostnames nulled anyway.
2022-08-09 11:53:33 +02:00
g_pEngine - > SetNextState ( IEngine : : DLL_RESTART ) ;
2021-12-25 22:36:38 +01:00
break ;
}
case HostStates_t : : HS_SHUTDOWN :
{
2023-08-21 19:12:29 +02:00
Msg ( eDLL_T : : ENGINE , " %s: Shutdown state machine \n " , __FUNCTION__ ) ;
2022-02-19 02:31:16 +01:00
# ifndef DEDICATED
2024-01-02 15:21:36 +01:00
v_CL_EndMovie ( ) ;
2022-02-19 02:31:16 +01:00
# endif // !DEDICATED
2024-01-02 15:21:36 +01:00
v_Stryder_SendOfflineRequest ( ) ; // We have hostnames nulled anyway.
2022-08-09 11:53:33 +02:00
g_pEngine - > SetNextState ( IEngine : : DLL_CLOSE ) ;
2021-12-25 22:36:38 +01:00
break ;
}
default :
{
break ;
}
}
2024-02-06 14:33:40 +01:00
// only do a single pass at HS_RUN per frame. All other states loop until they reach HS_RUN
if ( oldState = = HostStates_t : : HS_RUN & & ( g_pHostState - > m_iNextState ! = HostStates_t : : HS_LOAD_GAME | | ! single_frame_shutdown_for_reload - > GetBool ( ) ) )
break ;
// shutting down
if ( oldState = = HostStates_t : : HS_SHUTDOWN | |
oldState = = HostStates_t : : HS_RESTART )
break ;
}
2021-12-25 22:36:38 +01:00
}
}
2022-02-19 02:31:16 +01:00
//-----------------------------------------------------------------------------
2022-04-12 02:48:46 +02:00
// Purpose: state machine initialization
//-----------------------------------------------------------------------------
2023-03-18 17:36:09 +01:00
void CHostState : : Init ( void )
2022-04-12 02:48:46 +02:00
{
if ( m_iNextState ! = HostStates_t : : HS_SHUTDOWN )
{
if ( m_iNextState = = HostStates_t : : HS_GAME_SHUTDOWN )
{
2024-01-02 15:21:36 +01:00
CHostState__State_GameShutDown ( this ) ;
2022-04-12 02:48:46 +02:00
}
else
{
m_iCurrentState = HostStates_t : : HS_RUN ;
if ( m_iNextState ! = HostStates_t : : HS_SHUTDOWN | | ! single_frame_shutdown_for_reload - > GetInt ( ) )
m_iNextState = HostStates_t : : HS_RUN ;
}
}
2022-08-27 23:45:58 +02:00
m_flShortFrameTime = 1.0f ;
2023-02-18 19:18:00 +01:00
m_bActiveGame = false ;
m_bRememberLocation = false ;
m_bBackgroundLevel = false ;
m_bWaitingForConnection = false ;
2022-04-12 02:48:46 +02:00
m_levelName [ 0 ] = 0 ;
m_landMarkName [ 0 ] = 0 ;
m_mapGroupName [ 0 ] = 0 ;
2023-02-18 19:18:00 +01:00
m_bSplitScreenConnect = false ;
m_bGameHasShutDownAndFlushedMemory = true ;
2022-04-12 02:48:46 +02:00
m_vecLocation . Init ( ) ;
m_angLocation . Init ( ) ;
2023-02-18 19:18:00 +01:00
m_iServerState = HostStates_t : : HS_NEW_GAME ;
2022-04-12 02:48:46 +02:00
}
//-----------------------------------------------------------------------------
// Purpose: state machine setup
2022-02-19 02:31:16 +01:00
//-----------------------------------------------------------------------------
2023-03-18 17:36:09 +01:00
void CHostState : : Setup ( void )
2022-02-19 02:31:16 +01:00
{
g_pHostState - > LoadConfig ( ) ;
2022-09-01 01:32:32 +02:00
# ifndef CLIENT_DLL
2024-01-21 21:29:23 +01:00
g_BanSystem . LoadList ( ) ;
2022-09-01 01:32:32 +02:00
# endif // !CLIENT_DLL
2023-05-10 00:05:38 +02:00
ConVar_PurgeHostNames ( ) ;
2022-02-19 02:31:16 +01:00
2024-04-05 18:30:22 +02:00
# ifndef CLIENT_DLL
2024-03-31 15:15:30 +02:00
LiveAPISystem ( ) - > Init ( ) ;
2024-04-05 18:30:22 +02:00
# endif // !CLIENT_DLL
2024-02-24 02:15:09 +01:00
if ( net_useRandomKey . GetBool ( ) )
2022-02-19 02:31:16 +01:00
{
2022-04-02 02:48:54 +02:00
NET_GenerateKey ( ) ;
2022-02-19 02:31:16 +01:00
}
2023-04-16 11:57:45 +02:00
# if !defined (DEDICATED) && !defined (CLIENT_DLL)
// Parallel processing of 'C_BaseAnimating::SetupBones()' is currently
// not supported on listen servers running the local client due to an
// engine bug specific to S3 that still needs to be addressed. Remove
// this once the issue has been solved:
if ( cl_threaded_bone_setup - > GetBool ( ) )
{
cl_threaded_bone_setup - > SetValue ( false ) ;
}
# endif // !DEDICATED && !CLIENT_DLL
2022-05-04 02:25:27 +02:00
ResetLevelName ( ) ;
2022-02-19 02:31:16 +01:00
}
2022-02-27 19:47:29 +01:00
//-----------------------------------------------------------------------------
// Purpose: think
//-----------------------------------------------------------------------------
2023-03-18 17:36:09 +01:00
void CHostState : : Think ( void ) const
2022-02-27 19:47:29 +01:00
{
2023-04-10 23:11:52 +02:00
# ifndef CLIENT_DLL
2022-03-26 01:19:02 +01:00
static bool bInitialized = false ;
2023-04-10 23:11:52 +02:00
static CFastTimer statsTimer ;
2022-03-25 02:30:36 +01:00
static CFastTimer banListTimer ;
2023-04-10 23:11:52 +02:00
# ifdef DEDICATED
2022-03-25 02:30:36 +01:00
static CFastTimer pylonTimer ;
2023-04-10 23:11:52 +02:00
# endif // DEDICATED
2022-03-25 02:30:36 +01:00
2022-08-27 23:45:58 +02:00
if ( ! bInitialized ) // Initialize clocks.
2022-03-26 00:24:13 +01:00
{
2023-04-10 23:11:52 +02:00
statsTimer . Start ( ) ;
2022-08-27 23:45:58 +02:00
banListTimer . Start ( ) ;
2022-03-26 18:06:54 +01:00
# ifdef DEDICATED
2022-08-27 23:45:58 +02:00
pylonTimer . Start ( ) ;
2022-03-26 18:06:54 +01:00
# endif // DEDICATED
2022-08-27 23:45:58 +02:00
bInitialized = true ;
}
2024-04-12 22:06:31 +02:00
HostState_HandleAutoReload ( ) ;
if ( statsTimer . GetDurationInProgress ( ) . GetSeconds ( ) > host_statusRefreshRate . GetFloat ( ) )
2023-04-10 23:11:52 +02:00
{
2023-08-08 12:55:17 +02:00
SetConsoleTitleA ( Format ( " %s - %d/%d Players (%s on %s) - %d%% Server CPU (%.3f msec on frame %d) " ,
2023-04-10 23:11:52 +02:00
hostname - > GetString ( ) , g_pServer - > GetNumClients ( ) ,
2024-04-05 17:42:05 +02:00
g_ServerGlobalVariables - > m_nMaxClients , v_Playlists_GetCurrent ( ) , m_levelName ,
2023-08-08 12:55:17 +02:00
static_cast < int > ( g_pServer - > GetCPUUsage ( ) * 100.0f ) , ( g_pEngine - > GetFrameTime ( ) * 1000.0f ) ,
g_pServer - > GetTick ( ) ) . c_str ( ) ) ;
2023-04-10 23:11:52 +02:00
statsTimer . Start ( ) ;
}
2024-02-24 02:15:09 +01:00
if ( sv_globalBanlist . GetBool ( ) & &
banListTimer . GetDurationInProgress ( ) . GetSeconds ( ) > sv_banlistRefreshRate . GetFloat ( ) )
2022-08-27 23:45:58 +02:00
{
2024-03-10 01:57:04 +01:00
SV_CheckClientsForBan ( ) ;
2022-08-27 23:45:58 +02:00
banListTimer . Start ( ) ;
}
2022-03-26 18:06:54 +01:00
# ifdef DEDICATED
2024-02-24 02:15:09 +01:00
if ( pylonTimer . GetDurationInProgress ( ) . GetSeconds ( ) > sv_pylonRefreshRate . GetFloat ( ) )
2022-08-27 23:45:58 +02:00
{
2024-03-10 01:57:04 +01:00
HostState_KeepAlive ( ) ;
2022-08-27 23:45:58 +02:00
pylonTimer . Start ( ) ;
}
2022-03-26 18:06:54 +01:00
# endif // DEDICATED
2022-08-27 23:45:58 +02:00
# endif // !CLIENT_DLL
2022-02-27 19:47:29 +01:00
}
2022-02-19 02:31:16 +01:00
//-----------------------------------------------------------------------------
2022-02-19 02:43:20 +01:00
// Purpose: load and execute configuration files
2022-02-19 02:31:16 +01:00
//-----------------------------------------------------------------------------
2023-03-18 17:36:09 +01:00
void CHostState : : LoadConfig ( void ) const
2022-02-19 02:31:16 +01:00
{
2022-05-25 12:07:08 +02:00
if ( CommandLine ( ) - > ParmValue ( " -launcher " , 0 ) < 1 ) // Launcher level 1 indicates everything is handled from the commandline/launcher.
2022-02-19 02:31:16 +01:00
{
2022-05-24 02:23:37 +02:00
if ( ! CommandLine ( ) - > CheckParm ( " -devsdk " ) )
{
2023-07-13 23:15:10 +02:00
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec system/autoexec.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
2022-03-28 12:02:11 +02:00
# ifndef CLIENT_DLL
2023-07-13 23:15:10 +02:00
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec system/autoexec_server.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec tools/rcon_server.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
2022-03-28 12:02:11 +02:00
# endif //!CLIENT_DLL
2022-02-19 02:31:16 +01:00
# ifndef DEDICATED
2023-07-13 23:15:10 +02:00
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec system/autoexec_client.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec tools/rcon_client.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
2022-02-19 02:31:16 +01:00
# endif // !DEDICATED
2022-05-24 02:23:37 +02:00
}
else // Development configs.
{
2023-07-13 23:15:10 +02:00
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec system/autoexec_dev.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
2022-03-28 12:02:11 +02:00
# ifndef CLIENT_DLL
2023-07-13 23:15:10 +02:00
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec system/autoexec_server_dev.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec tools/rcon_server_dev.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
2022-03-28 12:02:11 +02:00
# endif //!CLIENT_DLL
2022-02-19 02:31:16 +01:00
# ifndef DEDICATED
2023-07-13 23:15:10 +02:00
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec system/autoexec_client_dev.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec tools/rcon_client_dev.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
2022-02-19 02:31:16 +01:00
# endif // !DEDICATED
2022-05-24 02:23:37 +02:00
}
2024-04-12 20:53:19 +02:00
# ifndef CLIENT_DLL
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec liveapi.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
# endif //!CLIENT_DLL
2022-11-10 15:42:27 +01:00
# ifndef DEDICATED
2023-07-13 23:15:10 +02:00
Cbuf_AddText ( Cbuf_GetCurrentPlayer ( ) , " exec bind.cfg \n " , cmd_source_t : : kCommandSrcCode ) ;
2022-11-10 15:42:27 +01:00
# endif // !DEDICATED
2022-02-19 02:31:16 +01:00
}
}
2023-10-12 17:07:35 +02:00
//-----------------------------------------------------------------------------
// Purpose: set state machine
// Input : newState -
// clearNext -
//-----------------------------------------------------------------------------
void CHostState : : SetState ( const HostStates_t newState )
{
m_iCurrentState = newState ;
// If our next state isn't a shutdown, or its a forced shutdown then set
// next state to run.
if ( m_iNextState ! = HostStates_t : : HS_SHUTDOWN | |
! host_hasIrreversibleShutdown - > GetBool ( ) )
{
m_iNextState = newState ;
}
}
2022-03-01 02:39:46 +01:00
//-----------------------------------------------------------------------------
// Purpose: shutdown active game
//-----------------------------------------------------------------------------
2023-03-18 17:36:09 +01:00
void CHostState : : GameShutDown ( void )
2022-03-01 02:39:46 +01:00
{
if ( m_bActiveGame )
{
2022-03-27 22:17:30 +02:00
# ifndef CLIENT_DLL
2022-03-01 02:39:46 +01:00
g_pServerGameDLL - > GameShutdown ( ) ;
2022-03-27 22:17:30 +02:00
# endif // !CLIENT_DLL
2022-09-18 13:55:44 +02:00
m_bActiveGame = false ;
2022-09-14 21:59:32 +02:00
ResetLevelName ( ) ;
2022-03-01 02:39:46 +01:00
}
}
2022-02-19 02:31:16 +01:00
//-----------------------------------------------------------------------------
2022-02-19 02:43:20 +01:00
// Purpose: initialize new game
2022-02-19 02:31:16 +01:00
//-----------------------------------------------------------------------------
2023-03-18 17:36:09 +01:00
void CHostState : : State_NewGame ( void )
2022-02-19 02:31:16 +01:00
{
2023-08-21 19:12:29 +02:00
Msg ( eDLL_T : : ENGINE , " %s: Loading level: '%s' \n " , __FUNCTION__ , g_pHostState - > m_levelName ) ;
2022-12-22 00:44:53 +01:00
2022-04-12 02:48:46 +02:00
LARGE_INTEGER time { } ;
2023-07-19 02:19:43 +02:00
# ifndef CLIENT_DLL
2023-10-12 17:07:35 +02:00
const bool bSplitScreenConnect = m_bSplitScreenConnect ;
2024-02-27 17:43:18 +01:00
m_bSplitScreenConnect = false ;
2023-07-19 02:19:43 +02:00
2022-04-12 02:48:46 +02:00
if ( ! g_pServerGameClients ) // Init Game if it ain't valid.
2022-02-19 02:31:16 +01:00
{
2022-04-12 02:48:46 +02:00
SV_InitGameDLL ( ) ;
2022-02-19 02:31:16 +01:00
}
2022-05-12 19:39:55 +02:00
# endif // !CLIENT_DLL
2022-02-19 02:31:16 +01:00
2022-05-12 19:39:55 +02:00
# ifndef CLIENT_DLL
2022-04-12 02:48:46 +02:00
if ( ! CModelLoader__Map_IsValid ( g_pModelLoader , m_levelName ) // Check if map is valid and if we can start a new game.
2023-04-10 19:14:59 +02:00
| | ! v_Host_NewGame ( m_levelName , nullptr , m_bBackgroundLevel , bSplitScreenConnect , time ) | | ! g_pServerGameClients )
2022-02-19 02:31:16 +01:00
{
2023-04-30 11:39:20 +02:00
Error ( eDLL_T : : ENGINE , NO_ERROR , " %s: Level not valid \n " , __FUNCTION__ ) ;
2022-02-19 02:31:16 +01:00
# ifndef DEDICATED
SCR_EndLoadingPlaque ( ) ;
# endif // !DEDICATED
GameShutDown ( ) ;
}
2022-05-12 19:39:55 +02:00
# endif // !CLIENT_DLL
2022-02-19 02:31:16 +01:00
2023-10-12 17:07:35 +02:00
SetState ( HostStates_t : : HS_RUN ) ;
2022-02-19 02:31:16 +01:00
}
//-----------------------------------------------------------------------------
2022-02-19 02:43:20 +01:00
// Purpose: change singleplayer level
2022-02-19 02:31:16 +01:00
//-----------------------------------------------------------------------------
2023-03-18 17:36:09 +01:00
void CHostState : : State_ChangeLevelSP ( void )
2022-02-19 02:31:16 +01:00
{
2023-08-21 19:12:29 +02:00
Msg ( eDLL_T : : ENGINE , " %s: Changing singleplayer level to: '%s' \n " , __FUNCTION__ , m_levelName ) ;
2022-02-19 02:31:16 +01:00
m_flShortFrameTime = 1.5 ; // Set frame time.
2022-04-12 02:48:46 +02:00
if ( CModelLoader__Map_IsValid ( g_pModelLoader , m_levelName ) ) // Check if map is valid and if we can start a new game.
2022-02-19 02:31:16 +01:00
{
2023-04-10 19:14:59 +02:00
v_Host_ChangeLevel ( true , m_levelName , m_mapGroupName ) ; // Call change level as singleplayer level.
2022-02-19 02:31:16 +01:00
}
else
{
2023-04-30 11:39:20 +02:00
Error ( eDLL_T : : ENGINE , NO_ERROR , " %s: Unable to find level: '%s' \n " , __FUNCTION__ , m_levelName ) ;
2022-02-19 02:31:16 +01:00
}
2023-10-12 17:07:35 +02:00
// Set current state to run.
SetState ( HostStates_t : : HS_RUN ) ;
2022-02-19 02:31:16 +01:00
}
//-----------------------------------------------------------------------------
2022-02-19 02:43:20 +01:00
// Purpose: change multiplayer level
2022-02-19 02:31:16 +01:00
//-----------------------------------------------------------------------------
2023-03-18 17:36:09 +01:00
void CHostState : : State_ChangeLevelMP ( void )
2022-02-19 02:31:16 +01:00
{
2023-08-21 19:12:29 +02:00
Msg ( eDLL_T : : ENGINE , " %s: Changing multiplayer level to: '%s' \n " , __FUNCTION__ , m_levelName ) ;
2022-02-19 02:31:16 +01:00
m_flShortFrameTime = 0.5 ; // Set frame time.
2022-03-27 22:17:30 +02:00
# ifndef CLIENT_DLL
2022-02-24 01:51:11 +01:00
g_pServerGameDLL - > LevelShutdown ( ) ;
2022-03-27 22:17:30 +02:00
# endif // !CLIENT_DLL
2022-04-12 02:48:46 +02:00
if ( CModelLoader__Map_IsValid ( g_pModelLoader , m_levelName ) ) // Check if map is valid and if we can start a new game.
2022-02-19 02:31:16 +01:00
{
# ifndef DEDICATED
2022-04-18 03:35:08 +02:00
g_pEngineVGui - > EnabledProgressBarForNextLoad ( ) ;
2022-02-19 02:31:16 +01:00
# endif // !DEDICATED
2023-04-10 19:14:59 +02:00
v_Host_ChangeLevel ( false , m_levelName , m_mapGroupName ) ; // Call change level as multiplayer level.
2022-02-19 02:31:16 +01:00
}
else
{
2023-04-30 11:39:20 +02:00
Error ( eDLL_T : : ENGINE , NO_ERROR , " %s: Unable to find level: '%s' \n " , __FUNCTION__ , m_levelName ) ;
2022-02-19 02:31:16 +01:00
}
2023-10-12 17:07:35 +02:00
// Set current state to run.
SetState ( HostStates_t : : HS_RUN ) ;
2022-05-04 02:25:27 +02:00
}
//-----------------------------------------------------------------------------
// Purpose: resets the level name
//-----------------------------------------------------------------------------
2023-03-18 17:36:09 +01:00
void CHostState : : ResetLevelName ( void )
2022-05-04 02:25:27 +02:00
{
2023-02-26 19:44:16 +01:00
static const char * szNoMap = " no_map " ;
2023-04-08 19:14:00 +02:00
Q_snprintf ( const_cast < char * > ( m_levelName ) , sizeof ( m_levelName ) , " %s " , szNoMap ) ;
2022-05-04 02:25:27 +02:00
}
2023-11-26 13:21:20 +01:00
void VHostState : : Detour ( const bool bAttach ) const
2021-12-25 22:36:38 +01:00
{
2024-01-02 15:21:36 +01:00
DetourSetup ( & CHostState__FrameUpdate , & CHostState : : FrameUpdate , bAttach ) ;
2021-12-25 22:36:38 +01:00
}
2022-02-19 02:31:16 +01:00
///////////////////////////////////////////////////////////////////////////////
2022-04-12 02:48:46 +02:00
CHostState * g_pHostState = nullptr ;
2024-04-12 22:06:31 +02:00
# ifndef CLIENT_DLL
bool g_hostReloadState = false ;
# endif // !CLIENT_DLL