/* ============== SV_InitGame A brand new game has been started ============== */ void SV_InitGame (void) { int i; edict_t *ent; char idmaster[32]; if (svs.initialized) { // cause any connected clients to reconnect SV_Shutdown ("Server restarted\n", true); } else { // make sure the client is down CL_Drop (); SCR_BeginLoadingPlaque (); } // get any latched variable changes (maxclients, etc) Cvar_GetLatchedVars (); svs.initialized = true; if (Cvar_VariableValue ("coop") && Cvar_VariableValue ("deathmatch")) { Com_Printf("Deathmatch and Coop both set, disabling Coop\n"); Cvar_FullSet ("coop", "0", CVAR_SERVERINFO | CVAR_LATCH); } // dedicated servers are can't be single player and are usually DM // so unless they explicity set coop, force it to deathmatch if (dedicated->value) { if (!Cvar_VariableValue ("coop")) Cvar_FullSet ("deathmatch", "1", CVAR_SERVERINFO | CVAR_LATCH); } // init clients if (Cvar_VariableValue ("deathmatch")) { if (maxclients->value <= 1) Cvar_FullSet ("maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH); else if (maxclients->value > MAX_CLIENTS) Cvar_FullSet ("maxclients", va("%i", MAX_CLIENTS), CVAR_SERVERINFO | CVAR_LATCH); } else if (Cvar_VariableValue ("coop")) { if (maxclients->value <= 1 || maxclients->value > 4) Cvar_FullSet ("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH); #ifdef COPYPROTECT if (!sv.attractloop && !dedicated->value) Sys_CopyProtect (); #endif } else // non-deathmatch, non-coop is one player { Cvar_FullSet ("maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH); #ifdef COPYPROTECT if (!sv.attractloop) Sys_CopyProtect (); #endif } svs.spawncount = rand(); svs.clients = Z_Malloc (sizeof(client_t)*maxclients->value); svs.num_client_entities = maxclients->value*UPDATE_BACKUP*64; svs.client_entities = Z_Malloc (sizeof(entity_state_t)*svs.num_client_entities); // init network stuff NET_Config ( (maxclients->value > 1) ); // heartbeats will always be sent to the id master svs.last_heartbeat = -99999; // send immediately Com_sprintf(idmaster, sizeof(idmaster), "192.246.40.37:%i", PORT_MASTER); NET_StringToAdr (idmaster, &master_adr[0]); // init game SV_InitGameProgs (); for (i=0 ; i<maxclients->value ; i++) { ent = EDICT_NUM(i+1); ent->s.number = i+1; svs.clients[i].edict = ent; memset (&svs.clients[i].lastcmd, 0, sizeof(svs.clients[i].lastcmd)); } }
/* * SV_ShutdownGame * * Called when each game quits */ void SV_ShutdownGame( const char *finalmsg, qboolean reconnect ) { if( !svs.initialized ) return; if( svs.demo.file ) SV_Demo_Stop_f(); if( svs.clients ) SV_FinalMessage( finalmsg, reconnect ); SV_ShutdownGameProgs(); // SV_MM_Shutdown(); NET_CloseSocket( &svs.socket_loopback ); NET_CloseSocket( &svs.socket_udp ); NET_CloseSocket( &svs.socket_udp6 ); #ifdef TCP_ALLOW_CONNECT if( sv_tcp->integer ) NET_CloseSocket( &svs.socket_tcp ); #endif // get any latched variable changes (sv_maxclients, etc) Cvar_GetLatchedVars( CVAR_LATCH ); if( svs.clients ) { Mem_Free( svs.clients ); svs.clients = NULL; } if( svs.client_entities.entities ) { Mem_Free( svs.client_entities.entities ); memset( &svs.client_entities, 0, sizeof( svs.client_entities ) ); } if( svs.cms ) { CM_Free( svs.cms ); svs.cms = NULL; } memset( &sv, 0, sizeof( sv ) ); Com_SetServerState( sv.state ); Com_FreePureList( &svs.purelist ); if( svs.motd ) { Mem_Free( svs.motd ); svs.motd = NULL; } if( sv_mempool ) Mem_EmptyPool( sv_mempool ); memset( &svs, 0, sizeof( svs ) ); svs.initialized = qfalse; }
/* * SV_InitGame * A brand new game has been started */ void SV_InitGame( void ) { int i; edict_t *ent; netadr_t address, ipv6_address; // make sure the client is down CL_Disconnect( NULL ); SCR_BeginLoadingPlaque(); if( svs.initialized ) { // cause any connected clients to reconnect SV_ShutdownGame( "Server restarted", qtrue ); // SV_ShutdownGame will also call Cvar_GetLatchedVars } else { // get any latched variable changes (sv_maxclients, etc) Cvar_GetLatchedVars( CVAR_LATCH ); } svs.initialized = qtrue; if( sv_skilllevel->integer > 2 ) Cvar_ForceSet( "sv_skilllevel", "2" ); if( sv_skilllevel->integer < 0 ) Cvar_ForceSet( "sv_skilllevel", "0" ); // init clients if( sv_maxclients->integer < 1 ) Cvar_FullSet( "sv_maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH, qtrue ); else if( sv_maxclients->integer > MAX_CLIENTS ) Cvar_FullSet( "sv_maxclients", va( "%i", MAX_CLIENTS ), CVAR_SERVERINFO | CVAR_LATCH, qtrue ); svs.spawncount = rand(); svs.clients = Mem_Alloc( sv_mempool, sizeof( client_t )*sv_maxclients->integer ); svs.client_entities.num_entities = sv_maxclients->integer * UPDATE_BACKUP * MAX_SNAP_ENTITIES; svs.client_entities.entities = Mem_Alloc( sv_mempool, sizeof( entity_state_t ) * svs.client_entities.num_entities ); // init network stuff address.type = NA_NOTRANSMIT; ipv6_address.type = NA_NOTRANSMIT; if( !dedicated->integer ) { NET_InitAddress( &address, NA_LOOPBACK ); if( !NET_OpenSocket( &svs.socket_loopback, SOCKET_LOOPBACK, &address, qtrue ) ) Com_Error( ERR_FATAL, "Couldn't open loopback socket: %s\n", NET_ErrorString() ); } if( dedicated->integer || sv_maxclients->integer > 1 ) { qboolean socket_opened = qfalse; // IPv4 NET_StringToAddress( sv_ip->string, &address ); NET_SetAddressPort( &address, sv_port->integer ); if( !NET_OpenSocket( &svs.socket_udp, SOCKET_UDP, &address, qtrue ) ) Com_Printf( "Error: Couldn't open UDP socket: %s\n", NET_ErrorString() ); else socket_opened = qtrue; // IPv6 NET_StringToAddress( sv_ip6->string, &ipv6_address ); if( ipv6_address.type == NA_IP6 ) { NET_SetAddressPort( &ipv6_address, sv_port6->integer ); if( !NET_OpenSocket( &svs.socket_udp6, SOCKET_UDP, &ipv6_address, qtrue ) ) Com_Printf( "Error: Couldn't open UDP6 socket: %s\n", NET_ErrorString() ); else socket_opened = qtrue; } else Com_Printf( "Error: invalid IPv6 address: %s\n", sv_ip6->string ); if( dedicated->integer && !socket_opened ) Com_Error( ERR_FATAL, "Couldn't open any socket\n" ); } #ifdef TCP_ALLOW_CONNECT if( sv_tcp->integer && ( dedicated->integer || sv_maxclients->integer > 1 ) ) { if( !NET_OpenSocket( &svs.socket_tcp, SOCKET_TCP, &address, qtrue ) ) { Com_Printf( "Error: Couldn't open TCP socket: %s", NET_ErrorString() ); Cvar_ForceSet( "sv_tcp", "0" ); } else { if( !NET_Listen( &svs.socket_tcp ) ) { Com_Printf( "Error: Couldn't listen to TCP socket: %s", NET_ErrorString() ); NET_CloseSocket( &svs.socket_tcp ); Cvar_ForceSet( "sv_tcp", "0" ); } } } #endif // init mm // SV_MM_Init(); // init game SV_InitGameProgs(); for( i = 0; i < sv_maxclients->integer; i++ ) { ent = EDICT_NUM( i+1 ); ent->s.number = i+1; svs.clients[i].edict = ent; } // load the map assert( !svs.cms ); svs.cms = CM_New( NULL ); }
/* * CL_SoundModule_Init */ void CL_SoundModule_Init( qboolean verbose ) { static const char *sound_modules[] = { "qf", "openal" }; static const int num_sound_modules = sizeof( sound_modules )/sizeof( sound_modules[0] ); sound_import_t import; if( !s_module ) s_module = Cvar_Get( "s_module", "1", CVAR_ARCHIVE|CVAR_LATCH_SOUND ); if( !s_module_fallback ) s_module_fallback = Cvar_Get( "s_module_fallback", "2", CVAR_LATCH_SOUND ); // unload anything we have now CL_SoundModule_Shutdown( verbose ); if( verbose ) Com_Printf( "------- sound initialization -------\n" ); Cvar_GetLatchedVars( CVAR_LATCH_SOUND ); if( s_module->integer < 0 || s_module->integer > num_sound_modules ) { Com_Printf( "Invalid value for s_module (%i), reseting to default\n", s_module->integer ); Cvar_ForceSet( "s_module", s_module->dvalue ); } if( s_module_fallback->integer < 0 || s_module_fallback->integer > num_sound_modules ) { Com_Printf( "Invalid value for s_module_fallback (%i), reseting to default\n", s_module_fallback->integer ); Cvar_ForceSet( "s_module_fallback", s_module_fallback->dvalue ); } if( !s_module->integer ) { if( verbose ) { Com_Printf( "Not loading a sound module\n" ); Com_Printf( "------------------------------------\n" ); } return; } cl_soundmodulepool = Mem_AllocPool( NULL, "Client Sound Module" ); import.Error = CL_SoundModule_Error; import.Print = CL_SoundModule_Print; import.Cvar_Get = Cvar_Get; import.Cvar_Set = Cvar_Set; import.Cvar_SetValue = Cvar_SetValue; import.Cvar_ForceSet = Cvar_ForceSet; import.Cvar_String = Cvar_String; import.Cvar_Value = Cvar_Value; import.Cmd_Argc = Cmd_Argc; import.Cmd_Argv = Cmd_Argv; import.Cmd_Args = Cmd_Args; import.Cmd_AddCommand = Cmd_AddCommand; import.Cmd_RemoveCommand = Cmd_RemoveCommand; import.Cmd_ExecuteText = Cbuf_ExecuteText; import.Cmd_Execute = Cbuf_Execute; import.Cmd_SetCompletionFunc = Cmd_SetCompletionFunc; import.FS_FOpenFile = FS_FOpenFile; import.FS_Read = FS_Read; import.FS_Write = FS_Write; import.FS_Print = FS_Print; import.FS_Tell = FS_Tell; import.FS_Seek = FS_Seek; import.FS_Eof = FS_Eof; import.FS_Flush = FS_Flush; import.FS_FCloseFile = FS_FCloseFile; import.FS_RemoveFile = FS_RemoveFile; import.FS_GetFileList = FS_GetFileList; import.FS_IsUrl = FS_IsUrl; import.Milliseconds = Sys_Milliseconds; import.PageInMemory = Com_PageInMemory; import.Mem_Alloc = CL_SoundModule_MemAlloc; import.Mem_Free = CL_SoundModule_MemFree; import.Mem_AllocPool = CL_SoundModule_MemAllocPool; import.Mem_FreePool = CL_SoundModule_MemFreePool; import.Mem_EmptyPool = CL_SoundModule_MemEmptyPool; import.GetEntitySpatilization = CL_GameModule_GetEntitySpatilization; import.LoadLibrary = Com_LoadLibrary; import.UnloadLibrary = Com_UnloadLibrary; if( !CL_SoundModule_Load( sound_modules[s_module->integer-1], &import, verbose ) ) { if( s_module->integer == s_module_fallback->integer || !CL_SoundModule_Load( sound_modules[s_module_fallback->integer-1], &import, verbose ) ) { if( verbose ) { Com_Printf( "Couldn't load a sound module\n" ); Com_Printf( "------------------------------------\n" ); } Mem_FreePool( &cl_soundmodulepool ); se = NULL; return; } Cvar_ForceSet( "s_module", va( "%i", s_module_fallback->integer ) ); } CL_SoundModule_SetAttenuationModel(); // check memory integrity Mem_CheckSentinelsGlobal(); if( verbose ) Com_Printf( "------------------------------------\n" ); }
/* ============== SV_InitGame A brand new game has been started. If mvd_spawn is non-zero, load the built-in MVD game module. ============== */ void SV_InitGame( unsigned mvd_spawn ) { int i, entnum; edict_t *ent; client_t *client; if( svs.initialized ) { // cause any connected clients to reconnect SV_Shutdown( "Server restarted\n", ERR_RECONNECT | mvd_spawn ); } else { #if USE_CLIENT // make sure the client is down CL_Disconnect( ERR_RECONNECT ); SCR_BeginLoadingPlaque(); #endif CM_FreeMap( &sv.cm ); SV_FreeFile( sv.entitystring ); memset( &sv, 0, sizeof( sv ) ); #if USE_FPS // set up default frametime for main loop sv.frametime = BASE_FRAMETIME; #endif } // get any latched variable changes (maxclients, etc) Cvar_GetLatchedVars (); #if !USE_CLIENT Cvar_Reset( sv_recycle ); #endif if( mvd_spawn ) { Cvar_Set( "deathmatch", "1" ); Cvar_Set( "coop", "0" ); } else { if( Cvar_VariableInteger( "coop" ) && Cvar_VariableInteger( "deathmatch" ) ) { Com_Printf( "Deathmatch and Coop both set, disabling Coop\n" ); Cvar_Set( "coop", "0" ); } // dedicated servers can't be single player and are usually DM // so unless they explicity set coop, force it to deathmatch if( Com_IsDedicated() ) { if( !Cvar_VariableInteger( "coop" ) ) Cvar_Set( "deathmatch", "1" ); } } // init clients if( Cvar_VariableInteger( "deathmatch" ) ) { if( sv_maxclients->integer <= 1 ) { Cvar_SetInteger( sv_maxclients, 8, FROM_CODE ); } else if( sv_maxclients->integer > CLIENTNUM_RESERVED ) { Cvar_SetInteger( sv_maxclients, CLIENTNUM_RESERVED, FROM_CODE ); } } else if( Cvar_VariableInteger( "coop" ) ) { if( sv_maxclients->integer <= 1 || sv_maxclients->integer > 4 ) Cvar_Set( "maxclients", "4" ); } else { // non-deathmatch, non-coop is one player Cvar_FullSet( "maxclients", "1", CVAR_SERVERINFO|CVAR_LATCH, FROM_CODE ); } // enable networking if( sv_maxclients->integer > 1 ) { NET_Config( NET_SERVER ); } svs.client_pool = SV_Mallocz( sizeof( client_t ) * sv_maxclients->integer ); svs.num_entities = sv_maxclients->integer * UPDATE_BACKUP * MAX_PACKET_ENTITIES; svs.entities = SV_Mallocz( sizeof( entity_state_t ) * svs.num_entities ); #if USE_MVD_SERVER // initialize MVD server if( !mvd_spawn ) { SV_MvdInit(); } #endif Cvar_ClampInteger( sv_reserved_slots, 0, sv_maxclients->integer - 1 ); #if USE_ZLIB svs.z.zalloc = SV_Zalloc; svs.z.zfree = SV_Zfree; if( deflateInit2( &svs.z, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 9, Z_DEFAULT_STRATEGY ) != Z_OK ) { Com_Error( ERR_FATAL, "%s: deflateInit2() failed", __func__ ); } #endif // init game #if USE_MVD_CLIENT if( mvd_spawn ) { if( ge ) { SV_ShutdownGameProgs(); } ge = &mvd_ge; ge->Init(); } else #endif SV_InitGameProgs(); // send heartbeat very soon svs.last_heartbeat = -(HEARTBEAT_SECONDS-5)*1000; for( i = 0; i < sv_maxclients->integer; i++ ) { client = svs.client_pool + i; entnum = i + 1; ent = EDICT_NUM( entnum ); ent->s.number = entnum; client->edict = ent; client->number = i; } #if USE_AC_SERVER AC_Connect( mvd_spawn ); #endif svs.initialized = qtrue; }
/* * SV_ShutdownGame * * Called when each game quits */ void SV_ShutdownGame( const char *finalmsg, bool reconnect ) { if( !svs.initialized ) { return; } if( svs.demo.file ) { SV_Demo_Stop_f(); } if( svs.clients ) { SV_FinalMessage( finalmsg, reconnect ); } SV_ShutdownGameProgs(); // SV_MM_Shutdown(); SV_MasterSendQuit(); NET_CloseSocket( &svs.socket_loopback ); NET_CloseSocket( &svs.socket_udp ); NET_CloseSocket( &svs.socket_udp6 ); #ifdef TCP_ALLOW_CONNECT if( sv_tcp->integer ) { NET_CloseSocket( &svs.socket_tcp ); NET_CloseSocket( &svs.socket_tcp6 ); } #endif // get any latched variable changes (sv_maxclients, etc) Cvar_GetLatchedVars( CVAR_LATCH ); if( svs.clients ) { Mem_Free( svs.clients ); svs.clients = NULL; } if( svs.client_entities.entities ) { Mem_Free( svs.client_entities.entities ); memset( &svs.client_entities, 0, sizeof( svs.client_entities ) ); } if( svs.cms ) { // CM_ReleaseReference will take care of freeing up the memory // if there are no other modules referencing the collision model CM_ReleaseReference( svs.cms ); svs.cms = NULL; } Com_SetServerCM( NULL, 0 ); memset( &sv, 0, sizeof( sv ) ); Com_SetServerState( sv.state ); Com_FreePureList( &svs.purelist ); if( svs.motd ) { Mem_Free( svs.motd ); svs.motd = NULL; } if( sv_mempool ) { Mem_EmptyPool( sv_mempool ); } if( svs.wakelock ) { Sys_ReleaseWakeLock( svs.wakelock ); svs.wakelock = NULL; } memset( &svs, 0, sizeof( svs ) ); svs.initialized = false; }