mirror of
https://github.com/YGGverse/xash3d-fwgs.git
synced 2025-01-17 18:40:02 +00:00
host.c port
This commit is contained in:
parent
d564a062ce
commit
b940a62f02
@ -148,6 +148,12 @@ typedef enum
|
||||
HOST_DEDICATED,
|
||||
} instance_t;
|
||||
|
||||
#ifdef XASH_DEDICATED
|
||||
#define Host_IsDedicated() ( true )
|
||||
#else
|
||||
#define Host_IsDedicated() ( host.type == HOST_DEDICATED )
|
||||
#endif
|
||||
|
||||
#include "system.h"
|
||||
#include "com_model.h"
|
||||
#include "com_strings.h"
|
||||
@ -446,6 +452,9 @@ typedef struct host_parm_s
|
||||
qboolean config_executed; // a bit who indicated was config.cfg already executed e.g. from valve.rc
|
||||
int sv_cvars_restored; // count of restored server cvars
|
||||
qboolean crashed; // set to true if crashed
|
||||
qboolean daemonized;
|
||||
qboolean enabledll;
|
||||
qboolean textmode;
|
||||
|
||||
// some settings were changed and needs to global update
|
||||
qboolean userinfo_changed;
|
||||
|
@ -13,6 +13,22 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifdef XASH_SDL
|
||||
#include <SDL.h>
|
||||
#endif // XASH_SDL
|
||||
#include <stdarg.h> // va_args
|
||||
#include <errno.h> // errno
|
||||
#include <string.h> // strerror
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h> // fork
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
#include "netchan.h"
|
||||
#include "protocol.h"
|
||||
@ -22,11 +38,11 @@ GNU General Public License for more details.
|
||||
#include "enginefeatures.h"
|
||||
#include "render_api.h" // decallist_t
|
||||
|
||||
|
||||
typedef void (*pfnChangeGame)( const char *progname );
|
||||
|
||||
pfnChangeGame pChangeGame = NULL;
|
||||
HINSTANCE hCurrent; // hinstance of current .dll
|
||||
host_parm_t host; // host parms
|
||||
host_parm_t host; // host parms
|
||||
sysinfo_t SI;
|
||||
|
||||
CVAR_DEFINE( host_developer, "developer", "0", 0, "engine is in development-mode" );
|
||||
@ -275,7 +291,9 @@ void Host_MemStats_f( void )
|
||||
|
||||
void Host_Minimize_f( void )
|
||||
{
|
||||
if( host.hWnd ) ShowWindow( host.hWnd, SW_MINIMIZE );
|
||||
#ifdef XASH_SDL
|
||||
if( host.hWnd ) SDL_MinimizeWindow( host.hWnd );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -495,7 +513,9 @@ void Host_Error( const char *error, ... )
|
||||
if( host.mouse_visible && !CL_IsInMenu( ))
|
||||
{
|
||||
// hide VGUI mouse
|
||||
while( ShowCursor( false ) >= 0 );
|
||||
#ifdef XASH_SDL
|
||||
SDL_ShowCursor( 0 );
|
||||
#endif
|
||||
host.mouse_visible = false;
|
||||
}
|
||||
|
||||
@ -588,61 +608,107 @@ static void Host_Crash_f( void )
|
||||
Host_InitCommon
|
||||
=================
|
||||
*/
|
||||
void Host_InitCommon( const char *hostname, qboolean bChangeGame )
|
||||
void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bChangeGame )
|
||||
{
|
||||
MEMORYSTATUS lpBuffer;
|
||||
char dev_level[4];
|
||||
char progname[128];
|
||||
char cmdline[128];
|
||||
qboolean parse_cmdline = false;
|
||||
char szTemp[MAX_SYSPATH];
|
||||
int developer = 0;
|
||||
string szRootPath;
|
||||
char *in, *out;
|
||||
const char *baseDir;
|
||||
|
||||
lpBuffer.dwLength = sizeof( MEMORYSTATUS );
|
||||
GlobalMemoryStatus( &lpBuffer );
|
||||
// some commands may turn engine into infinite loop,
|
||||
// e.g. xash.exe +game xash -game xash
|
||||
// so we clear all cmd_args, but leave dbg states as well
|
||||
Sys_ParseCommandLine( argc, argv );
|
||||
|
||||
if( !GetCurrentDirectory( sizeof( host.rootdir ), host.rootdir ))
|
||||
Sys_Error( "couldn't determine current directory\n" );
|
||||
if( !Sys_CheckParm( "-noch" ) )
|
||||
Sys_SetupCrashHandler();
|
||||
|
||||
// to be accessed later
|
||||
if( ( host.daemonized = Sys_CheckParm( "-daemonize" ) ) )
|
||||
{
|
||||
#if defined(_POSIX_VERSION) && !defined(XASH_MOBILE_PLATFORM)
|
||||
pid_t daemon;
|
||||
|
||||
daemon = fork();
|
||||
|
||||
if( daemon < 0 )
|
||||
{
|
||||
Host_Error( "fork() failed: %s\n", strerror( errno ) );
|
||||
}
|
||||
|
||||
if( daemon > 0 )
|
||||
{
|
||||
// parent
|
||||
MsgDev( D_INFO, "Child pid: %i\n", daemon );
|
||||
exit( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't be closed by parent
|
||||
if( setsid() < 0 )
|
||||
{
|
||||
Host_Error( "setsid() failed: %s\n", strerror( errno ) );
|
||||
}
|
||||
|
||||
// set permissions
|
||||
umask( 0 );
|
||||
|
||||
// engine will still use stdin/stdout,
|
||||
// so just redirect them to /dev/null
|
||||
close( STDIN_FILENO );
|
||||
close( STDOUT_FILENO );
|
||||
close( STDERR_FILENO );
|
||||
open("/dev/null", O_RDONLY); // becomes stdin
|
||||
open("/dev/null", O_RDWR); // stdout
|
||||
open("/dev/null", O_RDWR); // stderr
|
||||
|
||||
// fallthrough
|
||||
}
|
||||
#elif defined(XASH_MOBILE_PLATFORM)
|
||||
Sys_Error( "Can't run in background on mobile platforms!" );
|
||||
#else
|
||||
Sys_Error( "Daemonize not supported on this platform!" );
|
||||
#endif
|
||||
}
|
||||
|
||||
if( ( baseDir = getenv( "XASH3D_BASEDIR" ) ) )
|
||||
{
|
||||
Q_strncpy( host.rootdir, baseDir, sizeof(host.rootdir) );
|
||||
}
|
||||
else
|
||||
{
|
||||
#if TARGET_OS_IOS
|
||||
const char *IOS_GetDocsDir();
|
||||
Q_strncpy( host.rootdir, IOS_GetDocsDir(), sizeof(host.rootdir) );
|
||||
#elif defined(XASH_SDL)
|
||||
if( !( baseDir = SDL_GetBasePath() ) )
|
||||
Sys_Error( "couldn't determine current directory: %s", SDL_GetError() );
|
||||
Q_strncpy( host.rootdir, baseDir, sizeof( host.rootdir ) );
|
||||
SDL_free( baseDir );
|
||||
#else
|
||||
if( !getcwd( host.rootdir, sizeof(host.rootdir) ) )
|
||||
{
|
||||
Sys_Error( "couldn't determine current directory: %s", strerror( errno ) );
|
||||
host.rootdir[0] = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if( host.rootdir[Q_strlen( host.rootdir ) - 1] == '/' )
|
||||
host.rootdir[Q_strlen( host.rootdir ) - 1] = 0;
|
||||
|
||||
host.oldFilter = SetUnhandledExceptionFilter( Sys_Crash );
|
||||
host.hInst = GetModuleHandle( NULL );
|
||||
host.enabledll = !Sys_CheckParm( "-nodll" );
|
||||
|
||||
#ifdef DLL_LOADER
|
||||
if( host.enabledll )
|
||||
Setup_LDT_Keeper( ); // Must call before creating any thread
|
||||
#endif
|
||||
|
||||
host.change_game = bChangeGame;
|
||||
host.config_executed = false;
|
||||
host.status = HOST_INIT; // initialzation started
|
||||
|
||||
Memory_Init(); // init memory subsystem
|
||||
|
||||
progname[0] = cmdline[0] = '\0';
|
||||
in = (char *)hostname;
|
||||
out = progname;
|
||||
|
||||
while( *in != '\0' )
|
||||
{
|
||||
if( parse_cmdline )
|
||||
{
|
||||
*out++ = *in++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( *in == ' ' )
|
||||
{
|
||||
parse_cmdline = true;
|
||||
*out++ = '\0';
|
||||
out = cmdline;
|
||||
}
|
||||
else *out++ = *in++;
|
||||
}
|
||||
}
|
||||
*out = '\0'; // write terminator
|
||||
|
||||
Sys_ParseCommandLine( GetCommandLine( ), false );
|
||||
SetErrorMode( SEM_FAILCRITICALERRORS ); // no abort/retry/fail errors
|
||||
|
||||
host.mempool = Mem_AllocPool( "Zone Engine" );
|
||||
|
||||
if( Sys_CheckParm( "-console" ))
|
||||
@ -663,46 +729,51 @@ void Host_InitCommon( const char *hostname, qboolean bChangeGame )
|
||||
host.type = HOST_NORMAL; // predict state
|
||||
host.con_showalways = true;
|
||||
|
||||
// we can specified custom name, from Sys_NewInstance
|
||||
if( GetModuleFileName( NULL, szTemp, sizeof( szTemp )) && !host.change_game )
|
||||
COM_FileBase( szTemp, SI.exeName );
|
||||
|
||||
COM_ExtractFilePath( szTemp, szRootPath );
|
||||
if( Q_stricmp( host.rootdir, szRootPath ))
|
||||
#ifdef XASH_DEDICATED
|
||||
host.type = HOST_DEDICATED; // predict state
|
||||
#else
|
||||
if( Sys_CheckParm("-dedicated") || progname[0] == '#' )
|
||||
{
|
||||
Q_strncpy( host.rootdir, szRootPath, sizeof( host.rootdir ));
|
||||
SetCurrentDirectory( host.rootdir );
|
||||
host.type = HOST_DEDICATED;
|
||||
}
|
||||
else
|
||||
{
|
||||
host.type = HOST_NORMAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( SI.exeName[0] == '#' ) host.type = HOST_DEDICATED;
|
||||
#ifdef XASH_SDL
|
||||
// should work even if it failed
|
||||
SDL_Init( SDL_INIT_TIMER );
|
||||
|
||||
// determine host type
|
||||
if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS ) )
|
||||
{
|
||||
Sys_Warn( "SDL_Init failed: %s", SDL_GetError() );
|
||||
host.type = HOST_DEDICATED;
|
||||
}
|
||||
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");
|
||||
#if defined XASH_GLES && !defined __EMSCRIPTEN__ && !TARGET_OS_IOS
|
||||
SDL_SetHint( SDL_HINT_OPENGL_ES_DRIVER, "1" );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ( !host.rootdir[0] || SetCurrentDirectory( host.rootdir ) != 0)
|
||||
MsgDev( D_INFO, "%s is working directory now\n", host.rootdir );
|
||||
else
|
||||
Sys_Error( "Changing working directory to %s failed.\n", host.rootdir );
|
||||
|
||||
Sys_InitLog();
|
||||
|
||||
// set default gamedir
|
||||
if( progname[0] == '#' )
|
||||
progname++;
|
||||
|
||||
Q_strncpy( SI.exeName, progname, sizeof( SI.exeName ));
|
||||
|
||||
if( Host_IsDedicated() )
|
||||
{
|
||||
Q_strncpy( SI.basedirName, progname + 1, sizeof( SI.basedirName ));
|
||||
host.type = HOST_DEDICATED;
|
||||
}
|
||||
else Q_strncpy( SI.basedirName, progname, sizeof( SI.basedirName ));
|
||||
Sys_MergeCommandLine( );
|
||||
|
||||
if( Sys_CheckParm( "-dedicated" ))
|
||||
host.type = HOST_DEDICATED;
|
||||
|
||||
if( host.type == HOST_DEDICATED )
|
||||
{
|
||||
// check for duplicate dedicated server
|
||||
host.hMutex = CreateMutex( NULL, 0, "Xash Dedicated Server" );
|
||||
|
||||
if( !host.hMutex )
|
||||
{
|
||||
MSGBOX( "Dedicated server already running" );
|
||||
Sys_Quit();
|
||||
return;
|
||||
}
|
||||
|
||||
Sys_MergeCommandLine( cmdline );
|
||||
|
||||
CloseHandle( host.hMutex );
|
||||
host.hMutex = CreateSemaphore( NULL, 0, 1, "Xash Dedicated Server" );
|
||||
host.allow_console = true;
|
||||
}
|
||||
else
|
||||
@ -773,13 +844,13 @@ void Host_FreeCommon( void )
|
||||
Host_Main
|
||||
=================
|
||||
*/
|
||||
int EXPORT Host_Main( const char *progname, int bChangeGame, pfnChangeGame func )
|
||||
int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGame, pfnChangeGame func )
|
||||
{
|
||||
static double oldtime, newtime;
|
||||
|
||||
pChangeGame = func; // may be NULL
|
||||
|
||||
Host_InitCommon( progname, bChangeGame );
|
||||
Host_InitCommon( argc, argv, progname, bChangeGame );
|
||||
|
||||
// init commands and vars
|
||||
if( host_developer.value >= DEV_EXTENDED )
|
||||
@ -897,13 +968,6 @@ void EXPORT Host_Shutdown( void )
|
||||
// must be last, console uses this
|
||||
Mem_FreePool( &host.mempool );
|
||||
|
||||
// restore filter
|
||||
if( host.oldFilter ) SetUnhandledExceptionFilter( host.oldFilter );
|
||||
// restore filter
|
||||
Sys_RestoreCrashHandler();
|
||||
}
|
||||
|
||||
// main DLL entry point
|
||||
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
|
||||
{
|
||||
hCurrent = hinstDLL;
|
||||
return TRUE;
|
||||
}
|
@ -307,8 +307,6 @@ void Con_CreateConsole( void )
|
||||
fontsize = 14;
|
||||
}
|
||||
|
||||
Sys_InitLog();
|
||||
|
||||
if( !RegisterClass( &wc ))
|
||||
{
|
||||
// print into log
|
||||
@ -532,4 +530,4 @@ void Sys_PrintLog( const char *pMsg )
|
||||
if( !s_wcd.logfile ) return;
|
||||
fprintf( s_wcd.logfile, pMsg );
|
||||
fflush( s_wcd.logfile );
|
||||
}
|
||||
}
|
||||
|
@ -192,64 +192,28 @@ Sys_ParseCommandLine
|
||||
|
||||
==================
|
||||
*/
|
||||
void Sys_ParseCommandLine( LPSTR lpCmdLine, qboolean uncensored )
|
||||
void Sys_ParseCommandLine( int argc, const char** argv )
|
||||
{
|
||||
const char *blank = "censored";
|
||||
static char commandline[MAX_SYSPATH];
|
||||
int i;
|
||||
|
||||
host.argc = 1;
|
||||
host.argv[0] = "exe";
|
||||
host.argc = argc;
|
||||
host.argv = argv;
|
||||
|
||||
Q_strncpy( commandline, lpCmdLine, Q_strlen( lpCmdLine ) + 1 );
|
||||
lpCmdLine = commandline; // to prevent modify original commandline
|
||||
|
||||
while( *lpCmdLine && ( host.argc < MAX_NUM_ARGVS ))
|
||||
{
|
||||
while( *lpCmdLine && *lpCmdLine <= ' ' )
|
||||
lpCmdLine++;
|
||||
if( !*lpCmdLine ) break;
|
||||
|
||||
if( *lpCmdLine == '\"' )
|
||||
{
|
||||
// quoted string
|
||||
lpCmdLine++;
|
||||
host.argv[host.argc] = lpCmdLine;
|
||||
host.argc++;
|
||||
while( *lpCmdLine && ( *lpCmdLine != '\"' ))
|
||||
lpCmdLine++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// unquoted word
|
||||
host.argv[host.argc] = lpCmdLine;
|
||||
host.argc++;
|
||||
while( *lpCmdLine && *lpCmdLine > ' ')
|
||||
lpCmdLine++;
|
||||
}
|
||||
|
||||
if( *lpCmdLine )
|
||||
{
|
||||
*lpCmdLine = 0;
|
||||
lpCmdLine++;
|
||||
}
|
||||
}
|
||||
|
||||
if( uncensored || !host.change_game )
|
||||
return;
|
||||
if( !host.change_game ) return;
|
||||
|
||||
for( i = 0; i < host.argc; i++ )
|
||||
{
|
||||
// we wan't return to first game
|
||||
if( !Q_stricmp( "-game", host.argv[i] )) host.argv[i] = (char *)blank;
|
||||
// we don't want to return to first game
|
||||
if( !Q_stricmp( "-game", host.argv[i] )) host.argv[i] = (char *)blank;
|
||||
// probably it's timewaster, because engine rejected second change
|
||||
if( !Q_stricmp( "+game", host.argv[i] )) host.argv[i] = (char *)blank;
|
||||
// you sure what is map exists in new game?
|
||||
if( !Q_stricmp( "+map", host.argv[i] )) host.argv[i] = (char *)blank;
|
||||
else if( !Q_stricmp( "+game", host.argv[i] )) host.argv[i] = (char *)blank;
|
||||
// you sure that map exists in new game?
|
||||
else if( !Q_stricmp( "+map", host.argv[i] )) host.argv[i] = (char *)blank;
|
||||
// just stupid action
|
||||
if( !Q_stricmp( "+load", host.argv[i] )) host.argv[i] = (char *)blank;
|
||||
else if( !Q_stricmp( "+load", host.argv[i] )) host.argv[i] = (char *)blank;
|
||||
// changelevel beetwen games? wow it's great idea!
|
||||
if( !Q_stricmp( "+changelevel", host.argv[i] )) host.argv[i] = (char *)blank;
|
||||
else if( !Q_stricmp( "+changelevel", host.argv[i] )) host.argv[i] = (char *)blank;
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,44 +223,18 @@ Sys_MergeCommandLine
|
||||
|
||||
==================
|
||||
*/
|
||||
void Sys_MergeCommandLine( LPSTR lpCmdLine )
|
||||
void Sys_MergeCommandLine( )
|
||||
{
|
||||
static char commandline[MAX_SYSPATH];
|
||||
const char *blank = "censored";
|
||||
int i;
|
||||
|
||||
if( !host.change_game ) return;
|
||||
|
||||
Q_strncpy( commandline, lpCmdLine, Q_strlen( lpCmdLine ) + 1 );
|
||||
lpCmdLine = commandline; // to prevent modify original commandline
|
||||
|
||||
while( *lpCmdLine && ( host.argc < MAX_NUM_ARGVS ))
|
||||
for( i = 0; i < host.argc; i++ )
|
||||
{
|
||||
while( *lpCmdLine && *lpCmdLine <= ' ' )
|
||||
lpCmdLine++;
|
||||
if( !*lpCmdLine ) break;
|
||||
|
||||
if( *lpCmdLine == '\"' )
|
||||
{
|
||||
// quoted string
|
||||
lpCmdLine++;
|
||||
host.argv[host.argc] = lpCmdLine;
|
||||
host.argc++;
|
||||
while( *lpCmdLine && ( *lpCmdLine != '\"' ))
|
||||
lpCmdLine++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// unquoted word
|
||||
host.argv[host.argc] = lpCmdLine;
|
||||
host.argc++;
|
||||
while( *lpCmdLine && *lpCmdLine > ' ')
|
||||
lpCmdLine++;
|
||||
}
|
||||
|
||||
if( *lpCmdLine )
|
||||
{
|
||||
*lpCmdLine = 0;
|
||||
lpCmdLine++;
|
||||
}
|
||||
// second call
|
||||
if( Host_IsDedicated() && !Q_strnicmp( "+menu_", host.argv[i], 6 ))
|
||||
host.argv[i] = (char *)blank;
|
||||
}
|
||||
}
|
||||
|
||||
@ -656,4 +594,4 @@ void MsgDev( int type, const char *pMsg, ... )
|
||||
Sys_Print( text );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,8 +85,10 @@ void Sys_Error( const char *error, ... );
|
||||
qboolean Sys_LoadLibrary( dll_info_t *dll );
|
||||
void* Sys_GetProcAddress( dll_info_t *dll, const char* name );
|
||||
qboolean Sys_FreeLibrary( dll_info_t *dll );
|
||||
void Sys_ParseCommandLine( LPSTR lpCmdLine, qboolean uncensored );
|
||||
void Sys_MergeCommandLine( LPSTR lpCmdLine );
|
||||
void Sys_ParseCommandLine( int argc, char **argv );
|
||||
void Sys_MergeCommandLine( void );
|
||||
void Sys_SetupCrashHandler( void );
|
||||
void Sys_RestoreCrashHandler( void );
|
||||
void Sys_SetClipboardData( const byte *buffer, size_t size );
|
||||
#define Sys_GetParmFromCmdLine( parm, out ) _Sys_GetParmFromCmdLine( parm, out, sizeof( out ))
|
||||
qboolean _Sys_GetParmFromCmdLine( char *parm, char *out, size_t size );
|
||||
|
Loading…
x
Reference in New Issue
Block a user