summaryrefslogtreecommitdiff
path: root/dedicated/sys_ded.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /dedicated/sys_ded.cpp
downloadarchived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz
archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip
Diffstat (limited to 'dedicated/sys_ded.cpp')
-rw-r--r--dedicated/sys_ded.cpp530
1 files changed, 530 insertions, 0 deletions
diff --git a/dedicated/sys_ded.cpp b/dedicated/sys_ded.cpp
new file mode 100644
index 0000000..c7a9be9
--- /dev/null
+++ b/dedicated/sys_ded.cpp
@@ -0,0 +1,530 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//===========================================================================//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "isys.h"
+#include "console/conproc.h"
+#include "dedicated.h"
+#include "engine_hlds_api.h"
+#include "checksum_md5.h"
+#include "mathlib/mathlib.h"
+#include "tier0/vcrmode.h"
+#include "tier0/dbg.h"
+#include "tier1/strtools.h"
+#include "tier0/icommandline.h"
+#include "idedicatedexports.h"
+#include "vgui/vguihelpers.h"
+#include "appframework/AppFramework.h"
+#include "filesystem_init.h"
+#include "tier2/tier2.h"
+#include "dedicated.h"
+#include "vstdlib/cvar.h"
+#include "inputsystem/iinputsystem.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#include <direct.h>
+#include "KeyValues.h"
+#else
+#define _chdir chdir
+#include <unistd.h>
+#endif
+
+void* FileSystemFactory( const char *pName, int *pReturnCode );
+bool InitInstance( );
+int ProcessConsoleInput( void );
+bool NET_Init( void );
+void NET_Shutdown( void );
+const char *UTIL_GetBaseDir( void );
+#ifdef _WIN32
+bool g_bVGui = false;
+#endif
+
+#if defined ( _WIN32 )
+#include "console/TextConsoleWin32.h"
+CTextConsoleWin32 console;
+#else
+#include "console/TextConsoleUnix.h"
+CTextConsoleUnix console;
+#endif
+
+#ifdef _WIN32
+extern char *gpszCvars;
+#endif
+
+IDedicatedServerAPI *engine = NULL;
+
+//-----------------------------------------------------------------------------
+// Implementation of IVCRHelpers.
+//-----------------------------------------------------------------------------
+class CVCRHelpers : public IVCRHelpers
+{
+public:
+ virtual void ErrorMessage( const char *pMsg )
+ {
+ printf( "ERROR: %s\n", pMsg );
+ }
+
+ virtual void* GetMainWindow()
+ {
+ return 0;
+ }
+};
+CVCRHelpers g_VCRHelpers;
+
+SpewRetval_t DedicatedSpewOutputFunc( SpewType_t spewType, char const *pMsg ); // in sys_common.cpp
+
+//-----------------------------------------------------------------------------
+// Run a single VGUI frame. if bFinished is true, run VGUIFinishedConfig() first.
+//-----------------------------------------------------------------------------
+static bool DoRunVGUIFrame( bool bFinished = false )
+{
+#ifdef _WIN32
+ if ( g_bVGui )
+ {
+ if ( bFinished )
+ VGUIFinishedConfig();
+ RunVGUIFrame();
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Handle the VCRHook PeekMessage loop.
+// Return true if WM_QUIT received.
+//-----------------------------------------------------------------------------
+static bool HandleVCRHook()
+{
+#if defined ( _WIN32 )
+ MSG msg;
+
+ bool bDone = false;
+ while( VCRHook_PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
+ {
+ //if (!GetMessage( &msg, NULL, 0, 0))
+ if ( msg.message == WM_QUIT )
+ {
+ bDone = true;
+ break;
+ }
+
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+
+ if ( IsPC() )
+ {
+ // NOTE: Under some implementations of Win9x,
+ // dispatching messages can cause the FPU control word to change
+ SetupFPUControlWord();
+ }
+
+ if ( bDone /*|| gbAppHasBeenTerminated*/ )
+ return true;
+#endif // _WIN32
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+//
+// Server loop
+//
+//-----------------------------------------------------------------------------
+void RunServer( void )
+{
+#ifdef _WIN32
+ if(gpszCvars)
+ {
+ engine->AddConsoleText(gpszCvars);
+ }
+#endif
+
+ // Run 2 engine frames first to get the engine to load its resources.
+ for ( int i = 0; i < 2; i++ )
+ {
+ DoRunVGUIFrame();
+ if ( !engine->RunFrame() )
+ return;
+ }
+
+ // Run final VGUI frame.
+ DoRunVGUIFrame( true );
+
+ int bDone = false;
+ while ( !bDone )
+ {
+ // Check on VCRHook_PeekMessage...
+ if ( HandleVCRHook() )
+ break;
+
+ if ( !DoRunVGUIFrame() )
+ ProcessConsoleInput();
+
+ if ( !engine->RunFrame() )
+ bDone = true;
+
+ sys->UpdateStatus( 0 /* don't force */ );
+ }
+}
+
+//-----------------------------------------------------------------------------
+//
+// initialize the console or wait for vgui to start the server
+//
+//-----------------------------------------------------------------------------
+static bool ConsoleStartup( )
+{
+#ifdef _WIN32
+ if ( g_bVGui )
+ {
+ RunVGUIFrame();
+
+ // Run the config screen
+ while (VGUIIsInConfig() && VGUIIsRunning())
+ RunVGUIFrame();
+
+ if ( VGUIIsStopping() )
+ return false;
+
+ return true;
+ }
+ else
+ {
+ if ( !console.Init() )
+ {
+ return false;
+ }
+ }
+#endif // _WIN32
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Instantiate all main libraries
+//-----------------------------------------------------------------------------
+bool CDedicatedAppSystemGroup::Create( )
+{
+#ifndef _WIN32
+ if ( !console.Init() )
+ return false;
+#endif
+
+ // Hook the debug output stuff (override the spew func in the appframework)
+ SpewOutputFunc( DedicatedSpewOutputFunc );
+
+ // Added the dedicated exports module for the engine to grab
+ AppModule_t dedicatedModule = LoadModule( Sys_GetFactoryThis() );
+ IAppSystem *pSystem = AddSystem( dedicatedModule, VENGINE_DEDICATEDEXPORTS_API_VERSION );
+ if ( !pSystem )
+ return false;
+
+ if ( sys->LoadModules( this ) )
+ {
+ // Find the input system and tell it to skip Steam Controller initialization (we have to set this flag before Init gets called on the
+ // input system). Dedicated server should skip controller initialization to avoid initializing Steam, because we don't want the user to be
+ // flagged as "playing" the game.
+ auto inputsystem = ( IInputSystem* )FindSystem( INPUTSYSTEM_INTERFACE_VERSION );
+ if ( inputsystem )
+ {
+ inputsystem->SetSkipControllerInitialization( true );
+ }
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool CDedicatedAppSystemGroup::PreInit( )
+{
+ // A little hack needed because dedicated links directly to filesystem .cpp files
+ g_pFullFileSystem = NULL;
+
+ if ( !BaseClass::PreInit() )
+ return false;
+
+ CFSSteamSetupInfo steamInfo;
+ steamInfo.m_pDirectoryName = NULL;
+ steamInfo.m_bOnlyUseDirectoryName = false;
+ steamInfo.m_bToolsMode = false;
+ steamInfo.m_bSetSteamDLLPath = false;
+ steamInfo.m_bSteam = g_pFullFileSystem->IsSteam();
+ steamInfo.m_bNoGameInfo = steamInfo.m_bSteam;
+ if ( FileSystem_SetupSteamEnvironment( steamInfo ) != FS_OK )
+ return false;
+
+ CFSMountContentInfo fsInfo;
+ fsInfo.m_pFileSystem = g_pFullFileSystem;
+ fsInfo.m_bToolsMode = false;
+ fsInfo.m_pDirectoryName = steamInfo.m_GameInfoPath;
+
+ if ( FileSystem_MountContent( fsInfo ) != FS_OK )
+ return false;
+
+ if ( !NET_Init() )
+ return false;
+
+#ifdef _WIN32
+ g_bVGui = !CommandLine()->CheckParm( "-console" );
+#endif
+
+ CreateInterfaceFn factory = GetFactory();
+ IInputSystem *inputsystem = (IInputSystem *)factory( INPUTSYSTEM_INTERFACE_VERSION, NULL );
+ if ( inputsystem )
+ {
+ inputsystem->SetConsoleTextMode( true );
+ }
+
+#ifdef _WIN32
+ if ( g_bVGui )
+ {
+ StartVGUI( GetFactory() );
+ }
+ else
+#endif
+ {
+ if ( !sys->CreateConsoleWindow() )
+ return false;
+ }
+
+ return true;
+}
+
+int CDedicatedAppSystemGroup::Main( )
+{
+ if ( !ConsoleStartup() )
+ return -1;
+
+#ifdef _WIN32
+ if ( g_bVGui )
+ RunVGUIFrame();
+#endif
+
+ // Set up mod information
+ ModInfo_t info;
+ info.m_pInstance = GetAppInstance();
+ info.m_pBaseDirectory = UTIL_GetBaseDir();
+ info.m_pInitialMod = CommandLine()->ParmValue( "-game", "hl2" );
+ info.m_pInitialGame = CommandLine()->ParmValue( "-defaultgamedir", "hl2" );
+ info.m_pParentAppSystemGroup = this;
+ info.m_bTextMode = CommandLine()->CheckParm( "-textmode" );
+
+ if ( engine->ModInit( info ) )
+ {
+ engine->ModShutdown();
+ } // if engine->ModInit
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+void CDedicatedAppSystemGroup::PostShutdown()
+{
+#ifdef _WIN32
+ if ( g_bVGui )
+ StopVGUI();
+#endif
+
+ sys->DestroyConsoleWindow();
+ console.ShutDown();
+ NET_Shutdown();
+ BaseClass::PostShutdown();
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+void CDedicatedAppSystemGroup::Destroy()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Gets the executable name
+//-----------------------------------------------------------------------------
+bool GetExecutableName( char *out, int nMaxLen )
+{
+#ifdef _WIN32
+ if ( !::GetModuleFileName( ( HINSTANCE )GetModuleHandle( NULL ), out, nMaxLen ) )
+ return false;
+ return true;
+#elif POSIX
+ Q_strncpy( out, g_szEXEName, nMaxLen );
+ return true;
+#endif
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Return the directory where this .exe is running from
+// Output : char
+//-----------------------------------------------------------------------------
+void UTIL_ComputeBaseDir( char *pBaseDir, int nMaxLen )
+{
+ int j;
+ char *pBuffer = NULL;
+
+ pBaseDir[ 0 ] = 0;
+
+ if ( GetExecutableName( pBaseDir, nMaxLen ) )
+ {
+ pBuffer = strrchr( pBaseDir, CORRECT_PATH_SEPARATOR );
+ if ( pBuffer && *pBuffer )
+ {
+ *(pBuffer+1) = '\0';
+ }
+
+ j = strlen( pBaseDir );
+ if (j > 0)
+ {
+ if ( ( pBaseDir[ j-1 ] == '\\' ) ||
+ ( pBaseDir[ j-1 ] == '/' ) )
+ {
+ pBaseDir[ j-1 ] = 0;
+ }
+ }
+ }
+
+ char const *pOverrideDir = CommandLine()->CheckParm( "-basedir" );
+ if ( pOverrideDir )
+ {
+ strcpy( pBaseDir, pOverrideDir );
+ }
+
+ Q_strlower( pBaseDir );
+ Q_FixSlashes( pBaseDir );
+}
+
+
+//-----------------------------------------------------------------------------
+// This class is a helper class used for steam-based applications.
+// It loads up the file system in preparation for using it to load other
+// required modules from steam.
+//
+// I couldn't use the one in appframework because the dedicated server
+// inlines all the filesystem code.
+//-----------------------------------------------------------------------------
+class CDedicatedSteamApplication : public CSteamApplication
+{
+public:
+ CDedicatedSteamApplication( CSteamAppSystemGroup *pAppSystemGroup );
+ virtual bool Create( );
+};
+
+
+//-----------------------------------------------------------------------------
+// This class is a helper class used for steam-based applications.
+// It loads up the file system in preparation for using it to load other
+// required modules from steam.
+//
+// I couldn't use the one in appframework because the dedicated server
+// inlines all the filesystem code.
+//-----------------------------------------------------------------------------
+CDedicatedSteamApplication::CDedicatedSteamApplication( CSteamAppSystemGroup *pAppSystemGroup ) : CSteamApplication( pAppSystemGroup )
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Implementation of IAppSystemGroup
+//-----------------------------------------------------------------------------
+bool CDedicatedSteamApplication::Create( )
+{
+ // Add in the cvar factory
+ AppModule_t cvarModule = LoadModule( VStdLib_GetICVarFactory() );
+ AddSystem( cvarModule, CVAR_INTERFACE_VERSION );
+
+ AppModule_t fileSystemModule = LoadModule( FileSystemFactory );
+ m_pFileSystem = (IFileSystem*)AddSystem( fileSystemModule, FILESYSTEM_INTERFACE_VERSION );
+
+ if ( !m_pFileSystem )
+ {
+ Warning( "Unable to load the file system!\n" );
+ return false;
+ }
+
+ return true;
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+// Main entry point for dedicated server, shared between win32 and linux
+//
+//-----------------------------------------------------------------------------
+int main(int argc, char **argv)
+{
+#ifndef POSIX
+ _asm
+ {
+ fninit
+ }
+#endif
+
+ SetupFPUControlWord();
+
+#ifdef POSIX
+ Q_strncpy( g_szEXEName, *argv, ARRAYSIZE( g_szEXEName ) );
+ // Store off command line for argument searching
+ BuildCmdLine( argc, argv );
+#endif
+
+ MathLib_Init( 2.2f, 2.2f, 0.0f, 1.0f );
+
+ // Store off command line for argument searching
+ CommandLine()->CreateCmdLine( VCRHook_GetCommandLine() );
+#ifndef _WIN32
+ Plat_SetCommandLine( CommandLine()->GetCmdLine() );
+#endif
+
+ // Start VCR mode?
+ const char *filename;
+ if( CommandLine()->CheckParm( "-vcrrecord", &filename ) )
+ {
+ if ( !VCRStart( filename, true, &g_VCRHelpers ) )
+ {
+ Error( "-vcrrecord: can't open '%s' for writing.\n", filename );
+ return -1;
+ }
+ }
+ else if( CommandLine()->CheckParm( "-vcrplayback", &filename ) )
+ {
+ if ( !VCRStart( filename, false, &g_VCRHelpers ) )
+ {
+ Error( "-vcrplayback: can't open '%s' for reading.\n", filename );
+ return -1;
+ }
+ }
+
+ // Figure out the directory the executable is running from
+ // and make that be the current working directory
+ char pBasedir[ MAX_PATH ];
+ UTIL_ComputeBaseDir( pBasedir, MAX_PATH );
+ _chdir( pBasedir );
+
+ // Rehook the command line through VCR mode.
+ CommandLine()->CreateCmdLine( VCRHook_GetCommandLine() );
+
+ if ( !InitInstance() )
+ return -1;
+
+ CDedicatedAppSystemGroup dedicatedSystems;
+ CDedicatedSteamApplication steamApplication( &dedicatedSystems );
+ return steamApplication.Run( );
+}