Browse Source

host.c port

pull/2/head
Alibek Omarov 6 years ago
parent
commit
b940a62f02
  1. 9
      engine/common/common.h
  2. 222
      engine/common/host.c
  3. 4
      engine/common/sys_con.c
  4. 100
      engine/common/sys_win.c
  5. 6
      engine/common/system.h

9
engine/common/common.h

@ -148,6 +148,12 @@ typedef enum
HOST_DEDICATED, HOST_DEDICATED,
} instance_t; } instance_t;
#ifdef XASH_DEDICATED
#define Host_IsDedicated() ( true )
#else
#define Host_IsDedicated() ( host.type == HOST_DEDICATED )
#endif
#include "system.h" #include "system.h"
#include "com_model.h" #include "com_model.h"
#include "com_strings.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 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 int sv_cvars_restored; // count of restored server cvars
qboolean crashed; // set to true if crashed qboolean crashed; // set to true if crashed
qboolean daemonized;
qboolean enabledll;
qboolean textmode;
// some settings were changed and needs to global update // some settings were changed and needs to global update
qboolean userinfo_changed; qboolean userinfo_changed;

222
engine/common/host.c

@ -13,6 +13,22 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. 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 "common.h"
#include "netchan.h" #include "netchan.h"
#include "protocol.h" #include "protocol.h"
@ -22,11 +38,11 @@ GNU General Public License for more details.
#include "enginefeatures.h" #include "enginefeatures.h"
#include "render_api.h" // decallist_t #include "render_api.h" // decallist_t
typedef void (*pfnChangeGame)( const char *progname ); typedef void (*pfnChangeGame)( const char *progname );
pfnChangeGame pChangeGame = NULL; pfnChangeGame pChangeGame = NULL;
HINSTANCE hCurrent; // hinstance of current .dll host_parm_t host; // host parms
host_parm_t host; // host parms
sysinfo_t SI; sysinfo_t SI;
CVAR_DEFINE( host_developer, "developer", "0", 0, "engine is in development-mode" ); 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 ) 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( )) if( host.mouse_visible && !CL_IsInMenu( ))
{ {
// hide VGUI mouse // hide VGUI mouse
while( ShowCursor( false ) >= 0 ); #ifdef XASH_SDL
SDL_ShowCursor( 0 );
#endif
host.mouse_visible = false; host.mouse_visible = false;
} }
@ -588,60 +608,106 @@ static void Host_Crash_f( void )
Host_InitCommon 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 dev_level[4];
char progname[128];
char cmdline[128];
qboolean parse_cmdline = false;
char szTemp[MAX_SYSPATH];
int developer = 0; int developer = 0;
string szRootPath; const char *baseDir;
char *in, *out;
lpBuffer.dwLength = sizeof( MEMORYSTATUS );
GlobalMemoryStatus( &lpBuffer );
if( !GetCurrentDirectory( sizeof( host.rootdir ), host.rootdir )) // some commands may turn engine into infinite loop,
Sys_Error( "couldn't determine current directory\n" ); // 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( host.rootdir[Q_strlen( host.rootdir ) - 1] == '/' ) if( !Sys_CheckParm( "-noch" ) )
host.rootdir[Q_strlen( host.rootdir ) - 1] = 0; Sys_SetupCrashHandler();
host.oldFilter = SetUnhandledExceptionFilter( Sys_Crash ); // to be accessed later
host.hInst = GetModuleHandle( NULL ); if( ( host.daemonized = Sys_CheckParm( "-daemonize" ) ) )
host.change_game = bChangeGame; {
host.config_executed = false; #if defined(_POSIX_VERSION) && !defined(XASH_MOBILE_PLATFORM)
host.status = HOST_INIT; // initialzation started pid_t daemon;
Memory_Init(); // init memory subsystem daemon = fork();
progname[0] = cmdline[0] = '\0'; if( daemon < 0 )
in = (char *)hostname; {
out = progname; Host_Error( "fork() failed: %s\n", strerror( errno ) );
}
while( *in != '\0' ) if( daemon > 0 )
{
if( parse_cmdline )
{ {
*out++ = *in++; // parent
MsgDev( D_INFO, "Child pid: %i\n", daemon );
exit( 0 );
} }
else else
{ {
if( *in == ' ' ) // don't be closed by parent
if( setsid() < 0 )
{ {
parse_cmdline = true; Host_Error( "setsid() failed: %s\n", strerror( errno ) );
*out++ = '\0';
out = cmdline;
} }
else *out++ = *in++;
// 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
} }
*out = '\0'; // write terminator
Sys_ParseCommandLine( GetCommandLine( ), false ); if( ( baseDir = getenv( "XASH3D_BASEDIR" ) ) )
SetErrorMode( SEM_FAILCRITICALERRORS ); // no abort/retry/fail errors {
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.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
host.mempool = Mem_AllocPool( "Zone Engine" ); host.mempool = Mem_AllocPool( "Zone Engine" );
@ -663,46 +729,51 @@ void Host_InitCommon( const char *hostname, qboolean bChangeGame )
host.type = HOST_NORMAL; // predict state host.type = HOST_NORMAL; // predict state
host.con_showalways = true; host.con_showalways = true;
// we can specified custom name, from Sys_NewInstance #ifdef XASH_DEDICATED
if( GetModuleFileName( NULL, szTemp, sizeof( szTemp )) && !host.change_game ) host.type = HOST_DEDICATED; // predict state
COM_FileBase( szTemp, SI.exeName ); #else
if( Sys_CheckParm("-dedicated") || progname[0] == '#' )
COM_ExtractFilePath( szTemp, szRootPath ); {
if( Q_stricmp( host.rootdir, szRootPath )) host.type = HOST_DEDICATED;
}
else
{ {
Q_strncpy( host.rootdir, szRootPath, sizeof( host.rootdir )); host.type = HOST_NORMAL;
SetCurrentDirectory( host.rootdir );
} }
#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 ) )
if( progname[0] == '#' )
{ {
Q_strncpy( SI.basedirName, progname + 1, sizeof( SI.basedirName )); Sys_Warn( "SDL_Init failed: %s", SDL_GetError() );
host.type = HOST_DEDICATED; host.type = HOST_DEDICATED;
} }
else Q_strncpy( SI.basedirName, progname, sizeof( SI.basedirName )); 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( Sys_CheckParm( "-dedicated" )) if ( !host.rootdir[0] || SetCurrentDirectory( host.rootdir ) != 0)
host.type = HOST_DEDICATED; MsgDev( D_INFO, "%s is working directory now\n", host.rootdir );
else
Sys_Error( "Changing working directory to %s failed.\n", host.rootdir );
if( host.type == HOST_DEDICATED ) Sys_InitLog();
{
// check for duplicate dedicated server
host.hMutex = CreateMutex( NULL, 0, "Xash Dedicated Server" );
if( !host.hMutex ) // set default gamedir
{ if( progname[0] == '#' )
MSGBOX( "Dedicated server already running" ); progname++;
Sys_Quit();
return; Q_strncpy( SI.exeName, progname, sizeof( SI.exeName ));
}
Sys_MergeCommandLine( cmdline ); if( Host_IsDedicated() )
{
Sys_MergeCommandLine( );
CloseHandle( host.hMutex );
host.hMutex = CreateSemaphore( NULL, 0, 1, "Xash Dedicated Server" );
host.allow_console = true; host.allow_console = true;
} }
else else
@ -773,13 +844,13 @@ void Host_FreeCommon( void )
Host_Main 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; static double oldtime, newtime;
pChangeGame = func; // may be NULL pChangeGame = func; // may be NULL
Host_InitCommon( progname, bChangeGame ); Host_InitCommon( argc, argv, progname, bChangeGame );
// init commands and vars // init commands and vars
if( host_developer.value >= DEV_EXTENDED ) if( host_developer.value >= DEV_EXTENDED )
@ -897,13 +968,6 @@ void EXPORT Host_Shutdown( void )
// must be last, console uses this // must be last, console uses this
Mem_FreePool( &host.mempool ); Mem_FreePool( &host.mempool );
// restore filter // restore filter
if( host.oldFilter ) SetUnhandledExceptionFilter( host.oldFilter ); Sys_RestoreCrashHandler();
} }
// main DLL entry point
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
hCurrent = hinstDLL;
return TRUE;
}

4
engine/common/sys_con.c

@ -307,8 +307,6 @@ void Con_CreateConsole( void )
fontsize = 14; fontsize = 14;
} }
Sys_InitLog();
if( !RegisterClass( &wc )) if( !RegisterClass( &wc ))
{ {
// print into log // print into log
@ -532,4 +530,4 @@ void Sys_PrintLog( const char *pMsg )
if( !s_wcd.logfile ) return; if( !s_wcd.logfile ) return;
fprintf( s_wcd.logfile, pMsg ); fprintf( s_wcd.logfile, pMsg );
fflush( s_wcd.logfile ); fflush( s_wcd.logfile );
} }

100
engine/common/sys_win.c

@ -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"; const char *blank = "censored";
static char commandline[MAX_SYSPATH];
int i; int i;
host.argc = 1; host.argc = argc;
host.argv[0] = "exe"; host.argv = argv;
Q_strncpy( commandline, lpCmdLine, Q_strlen( lpCmdLine ) + 1 ); if( !host.change_game ) return;
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;
for( i = 0; i < host.argc; i++ ) for( i = 0; i < host.argc; i++ )
{ {
// we wan't return to first game // we don't want to return to first game
if( !Q_stricmp( "-game", host.argv[i] )) host.argv[i] = (char *)blank; if( !Q_stricmp( "-game", host.argv[i] )) host.argv[i] = (char *)blank;
// probably it's timewaster, because engine rejected second change // probably it's timewaster, because engine rejected second change
if( !Q_stricmp( "+game", host.argv[i] )) host.argv[i] = (char *)blank; else if( !Q_stricmp( "+game", host.argv[i] )) host.argv[i] = (char *)blank;
// you sure what is map exists in new game? // you sure that map exists in new game?
if( !Q_stricmp( "+map", host.argv[i] )) host.argv[i] = (char *)blank; else if( !Q_stricmp( "+map", host.argv[i] )) host.argv[i] = (char *)blank;
// just stupid action // 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! // 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; if( !host.change_game ) return;
Q_strncpy( commandline, lpCmdLine, Q_strlen( lpCmdLine ) + 1 ); for( i = 0; i < host.argc; i++ )
lpCmdLine = commandline; // to prevent modify original commandline
while( *lpCmdLine && ( host.argc < MAX_NUM_ARGVS ))
{ {
while( *lpCmdLine && *lpCmdLine <= ' ' ) // second call
lpCmdLine++; if( Host_IsDedicated() && !Q_strnicmp( "+menu_", host.argv[i], 6 ))
if( !*lpCmdLine ) break; host.argv[i] = (char *)blank;
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++;
}
} }
} }
@ -656,4 +594,4 @@ void MsgDev( int type, const char *pMsg, ... )
Sys_Print( text ); Sys_Print( text );
break; break;
} }
} }

6
engine/common/system.h

@ -85,8 +85,10 @@ void Sys_Error( const char *error, ... );
qboolean Sys_LoadLibrary( dll_info_t *dll ); qboolean Sys_LoadLibrary( dll_info_t *dll );
void* Sys_GetProcAddress( dll_info_t *dll, const char* name ); void* Sys_GetProcAddress( dll_info_t *dll, const char* name );
qboolean Sys_FreeLibrary( dll_info_t *dll ); qboolean Sys_FreeLibrary( dll_info_t *dll );
void Sys_ParseCommandLine( LPSTR lpCmdLine, qboolean uncensored ); void Sys_ParseCommandLine( int argc, char **argv );
void Sys_MergeCommandLine( LPSTR lpCmdLine ); void Sys_MergeCommandLine( void );
void Sys_SetupCrashHandler( void );
void Sys_RestoreCrashHandler( void );
void Sys_SetClipboardData( const byte *buffer, size_t size ); void Sys_SetClipboardData( const byte *buffer, size_t size );
#define Sys_GetParmFromCmdLine( parm, out ) _Sys_GetParmFromCmdLine( parm, out, sizeof( out )) #define Sys_GetParmFromCmdLine( parm, out ) _Sys_GetParmFromCmdLine( parm, out, sizeof( out ))
qboolean _Sys_GetParmFromCmdLine( char *parm, char *out, size_t size ); qboolean _Sys_GetParmFromCmdLine( char *parm, char *out, size_t size );

Loading…
Cancel
Save