/* ================== Host_Restart_f Restarts the current server for a dead player ================== */ static void Host_Restart_f (void) { char mapname[MAX_QPATH]; char startspot[MAX_QPATH]; if (cls.demoplayback || !sv.active) return; if (cmd_source != src_command) return; q_strlcpy (mapname, sv.name, sizeof(mapname)); // mapname gets cleared in spawnserver q_strlcpy (startspot, sv.startspot, sizeof(startspot)); if (Cmd_Argc() == 2 && q_strcasecmp(Cmd_Argv(1),"restore") == 0) { if (LoadGamestate(mapname, startspot, 3) != 0) { SV_SpawnServer (mapname, startspot); if (!sv.active) Host_Error ("%s: cannot restart map %s", __thisfunc__, mapname); RestoreClients (0); } } else { SV_SpawnServer (mapname, startspot); if (!sv.active) Host_Error ("%s: cannot restart map %s", __thisfunc__, mapname); } }
/* ================== Host_Restart_f Restarts the current server for a dead player ================== */ void Host_Restart_f (void) { char mapname[MAX_QPATH]; #if 666 char startspot[MAX_QPATH]; #endif if (cls.demoplayback || !sv.active) return; if (cmd_source != src_command) return; strcpy (mapname, sv.name); // must copy out, because it gets cleared // in sv_spawnserver #if 666 strcpy(startspot, sv.startspot); // try to restore the new level if (LoadGamestate (mapname, startspot)) SV_SpawnServer (mapname, startspot); else SV_SpawnServer (mapname, NULL); #else SV_SpawnServer (mapname); #endif }
/* ====================== Host_Map_f handle a map <servername> command from the console. Active clients are kicked off. ====================== */ void Host_Map_f (void) { int i; char name[MAX_QPATH]; extern void Host_InitVideo(); if (cmd_source != src_command) return; cls.demonum = -1; // stop demo loop in case this fails CL_Disconnect (); Host_ShutdownServer(false); key_dest = key_game; // remove console or menu SCR_BeginLoadingPlaque (); cls.mapstring[0] = 0; for (i=0 ; i<Cmd_Argc() ; i++) { strcat (cls.mapstring, Cmd_Argv(i)); strcat (cls.mapstring, " "); } strcat (cls.mapstring, "\n"); svs.serverflags = 0; // haven't completed an episode yet allowcheats = sv_cheats.value != 0; strcpy (name, Cmd_Argv(1)); // if the video isn't initialized already, it needs to be Host_InitVideo(); #ifdef QUAKE2 SV_SpawnServer (name, NULL); #else SV_SpawnServer (name); #endif if (!sv.active) return; if (cls.state != ca_dedicated) { strcpy (cls.spawnparms, ""); for (i=2 ; i<Cmd_Argc() ; i++) { strcat (cls.spawnparms, Cmd_Argv(i)); strcat (cls.spawnparms, " "); } Cmd_ExecuteString ("connect local", src_command); } }
/* ================== Host_Changelevel_f Goes to a new map, taking all clients along ================== */ void Host_Changelevel_f (void) { #ifdef QUAKE2 char level[MAX_QPATH]; char _startspot[MAX_QPATH]; char *startspot; if (Cmd_Argc() < 2) { Con_Printf ("changelevel <levelname> : continue game on a new level\n"); return; } if (!sv.active || cls.demoplayback) { Con_Printf ("Only the server may changelevel\n"); return; } strcpy (level, Cmd_Argv(1)); if (Cmd_Argc() == 2) startspot = NULL; else { strcpy (_startspot, Cmd_Argv(2)); startspot = _startspot; } SV_SaveSpawnparms (); SV_SpawnServer (level, startspot); #else char level[MAX_QPATH]; if (Cmd_Argc() != 2) { Con_Printf ("changelevel <levelname> : continue game on a new level\n"); return; } if (!sv.active || cls.demoplayback) { Con_Printf ("Only the server may changelevel\n"); return; } SV_SaveSpawnparms (); allowcheats = sv_cheats.value != 0; // sv_cheats strcpy (level, Cmd_Argv(1)); // if the video isn't initialized already, it needs to be Host_InitVideo(); SV_SpawnServer (level); #endif }
/** * @brief Restart the server on a different map */ static void SV_Map_f(void) { char *cmd; char *map; char mapname[MAX_QPATH]; qboolean cheat; char expanded[MAX_QPATH]; map = Cmd_Argv(1); if (!map || !map[0]) { Com_Printf("Usage: \n map <map name>\n devmap <map name>\n"); return; } // make sure the level exists before trying to change, so that // a typo at the server console won't end the game Com_sprintf(expanded, sizeof(expanded), "maps/%s.bsp", map); if (FS_ReadFile(expanded, NULL) == -1) { Com_Printf("Can't find map %s\n", expanded); return; } Cvar_Set("gamestate", va("%i", GS_INITIALIZE)); // reset gamestate on map/devmap Cvar_Set("g_currentRound", "0"); // reset the current round Cvar_Set("g_nextTimeLimit", "0"); // reset the next time limit cmd = Cmd_Argv(0); if (!Q_stricmp(cmd, "devmap")) { cheat = qtrue; } else { cheat = qfalse; } // save the map name here cause on a map restart we reload the etconfig.cfg // and thus nuke the arguments of the map command Q_strncpyz(mapname, map, sizeof(mapname)); // start up the map SV_SpawnServer(mapname); // set the cheat value // if the level was started with "map <mapname>", then // cheats will not be allowed. // If started with "devmap <mapname>" // then cheats will be allowed if (cheat) { Cvar_Set("sv_cheats", "1"); } else { Cvar_Set("sv_cheats", "0"); } }
qboolean SV_NewGame( const char *mapName, qboolean loadGame ) { if( !loadGame ) { if( !SV_MapIsValid( mapName, GI->sp_entity, NULL )) { return false; } SV_ClearSaveDir (); SV_Shutdown( true ); } else { S_StopAllSounds (); SV_DeactivateServer (); } sv.loadgame = loadGame; sv.background = false; sv.changelevel = false; if( !SV_SpawnServer( mapName, NULL )) return false; SV_LevelInit( mapName, NULL, NULL, loadGame ); sv.loadgame = loadGame; SV_ActivateServer(); if( sv.state != ss_active ) return false; return true; }
// changing levels within a unit void Host_Changelevel2_f (void) { char level[MAX_QPATH]; char _startspot[MAX_QPATH]; char *startspot; if (Cmd_Argc() < 2) { Con_Printf ("changelevel2 <levelname> : continue game on a new level in the unit\n"); return; } if (!sv.active || cls.demoplayback) { Con_Printf ("Only the server may changelevel\n"); return; } strcpy (level, Cmd_Argv(1)); if (Cmd_Argc() == 2) startspot = NULL; else { strcpy (_startspot, Cmd_Argv(2)); startspot = _startspot; } SV_SaveSpawnparms (); // save the current level's state SaveGamestate (); // try to restore the new level if (LoadGamestate (level, startspot)) SV_SpawnServer (level, startspot); }
/* ====================== Host_Map_f handle a map <servername> command from the console. Active clients are kicked off. ====================== */ void Host_Map_f (void) { int i; char name[MAX_QPATH], *p; if (Cmd_Argc() < 2) //no map name given { if (cls.state == ca_dedicated) { if (sv.active) Con_Printf ("Current map: %s\n", sv.name); else Con_Printf ("Server not active\n"); } else if (cls.state == ca_connected) { Con_Printf ("Current map: %s ( %s )\n", cl.levelname, cl.mapname); } else { Con_Printf ("map <levelname>: start a new server\n"); } return; } if (cmd_source != src_command) return; cls.demonum = -1; // stop demo loop in case this fails CL_Disconnect (); Host_ShutdownServer(false); if (cls.state != ca_dedicated) IN_Activate(); key_dest = key_game; // remove console or menu SCR_BeginLoadingPlaque (); svs.serverflags = 0; // haven't completed an episode yet q_strlcpy (name, Cmd_Argv(1), sizeof(name)); // remove (any) trailing ".bsp" from mapname -- S.A. p = strstr(name, ".bsp"); if (p && p[4] == '\0') *p = '\0'; SV_SpawnServer (name); if (!sv.active) return; if (cls.state != ca_dedicated) { memset (cls.spawnparms, 0, MAX_MAPSTRING); for (i = 2; i < Cmd_Argc(); i++) { q_strlcat (cls.spawnparms, Cmd_Argv(i), MAX_MAPSTRING); q_strlcat (cls.spawnparms, " ", MAX_MAPSTRING); } Cmd_ExecuteString ("connect local", src_command); } }
/* ================== Host_Changelevel_f Goes to a new map, taking all clients along ================== */ static void Host_Changelevel_f (void) { char level[MAX_QPATH]; char _startspot[MAX_QPATH]; char *startspot; if (Cmd_Argc() < 2) { Con_Printf ("changelevel <levelname> : continue game on a new level\n"); return; } if (!sv.active || cls.demoplayback) { Con_Printf ("Only the server may changelevel\n"); return; } q_snprintf (level, sizeof(level), "maps/%s.bsp", Cmd_Argv(1)); if (!FS_FileExists(level, NULL)) Host_Error ("%s: cannot find map %s", __thisfunc__, level); q_strlcpy (level, Cmd_Argv(1), sizeof(level)); if (Cmd_Argc() == 2) startspot = NULL; else { q_strlcpy (_startspot, Cmd_Argv(2), sizeof(_startspot)); startspot = _startspot; } SV_SaveSpawnparms (); SV_SpawnServer (level, startspot); if (!sv.active) Host_Error ("%s: cannot run map %s", __thisfunc__, level); }
static void SV_ChangeMap( qbool cheats ) { const char* map = Cmd_Argv(1); if ( !map ) { return; } // make sure the level exists before trying to change // so that a typo at the server console won't end the game const char* mapfile = va( "maps/%s.bsp", map ); if ( FS_ReadFile( mapfile, NULL ) == -1 ) { Com_Printf( "Can't find map %s\n", mapfile ); return; } // force latched values to get set Cvar_Get( "g_gametype", "0", CVAR_SERVERINFO | CVAR_LATCH ); // save the map name here cause on a map restart we reload the q3config.cfg // and thus nuke the arguments of the map command char mapname[MAX_QPATH]; Q_strncpyz( mapname, map, sizeof(mapname) ); // start up the map SV_SpawnServer( mapname ); Cvar_Set( "sv_cheats", cheats ? "1" : "0" ); }
/* ================== Host_Changelevel_f Goes to a new map, taking all clients along ================== */ void Host_Changelevel_f (void) { char level[MAX_QPATH]; if (Cmd_Argc() != 2) { Con_Printf ("changelevel <levelname> : continue game on a new level\n"); return; } if (!sv.active || cls.demoplayback) { Con_Printf ("Only the server may changelevel\n"); return; } //johnfitz -- check for client having map before anything else q_snprintf (level, sizeof(level), "maps/%s.bsp", Cmd_Argv(1)); if (!COM_FileExists(level, NULL)) Host_Error ("cannot find map %s", level); //johnfitz if (cls.state != ca_dedicated) IN_Activate(); // -- S.A. key_dest = key_game; // remove console or menu SV_SaveSpawnparms (); q_strlcpy (level, Cmd_Argv(1), sizeof(level)); SV_SpawnServer (level); // also issue an error if spawn failed -- O.S. if (!sv.active) Host_Error ("cannot run map %s", level); }
//========================================================= // don't call this directly, it should only be called from SV_Map_f() or SV_MapTransition_f() // static void SV_Map_( ForceReload_e eForceReload ) { char *map; char expanded[MAX_QPATH]; map = Cmd_Argv(1); if ( !*map ) { return; } // make sure the level exists before trying to change, so that // a typo at the server console won't end the game if (strchr (map, '\\') ) { Com_Printf ("Can't have mapnames with a \\\n"); return; } Com_sprintf (expanded, sizeof(expanded), "maps/%s.bsp", map); if ( FS_ReadFile (expanded, NULL) == -1 ) { Com_Printf ("Can't find map %s\n", expanded); return; } if (map[0]!='_') { SG_WipeSavegame("auto"); } SP_Unload(SP_REGISTER_CLIENT); //clear the previous map srings SV_SpawnServer( map, eForceReload, qtrue ); // start up the map }
/* ====================== SV_Map_f handle a map <mapname> command from the console or progs. ====================== */ void SV_Map_f (void) { char expanded[MAX_QPATH]; qfile_t *f; if (Cmd_Argc() != 2) { Com_Printf ("map <mapname> : continue game on a new map\n"); return; } // check to make sure the level exists Q_snprintf (expanded, sizeof(expanded), "maps/%s.bsp", Cmd_Argv(1)); f = FS_Open (expanded, "rb", false, true); if (!f) return; FS_Close (f); if (sv.mvdrecording) SV_MVDStop_f(); NET_ServerConfig (true); if (!dedicated) CL_BeginLocalConnection (); SV_BroadcastCommand ("changing\n"); SV_SendMessagesToAll (); SV_SpawnServer (Cmd_Argv(1), !Q_stricmp(Cmd_Argv(0), "devmap")); SV_BroadcastCommand ("reconnect\n"); }
/* ================== Host_Changelevel_f Goes to a new map, taking all clients along ================== */ void Host_Changelevel_f (void) { #ifdef QUAKE2 char level[MAX_QPATH]; char _startspot[MAX_QPATH]; char *startspot; if (Cmd_Argc() < 2) { Con_Printf ("changelevel <levelname> : continue game on a new level\n"); return; } if (!sv.active || cls.demoplayback) { Con_Printf ("Only the server may changelevel\n"); return; } strcpy (level, Cmd_Argv(1)); if (Cmd_Argc() == 2) startspot = NULL; else { strcpy (_startspot, Cmd_Argv(2)); startspot = _startspot; } SV_SaveSpawnparms (); SV_SpawnServer (level, startspot); #else char level[MAX_QPATH]; if (Cmd_Argc() != 2) { Con_Printf ("changelevel <levelname> : continue game on a new level\n"); return; } if (!sv.active || cls.demoplayback) { Con_Printf ("Only the server may changelevel\n"); return; } SV_SaveSpawnparms (); strcpy (level, Cmd_Argv(1)); SV_SpawnServer (level); #endif }
/* ================== SV_Map_f Goes directly to a given map without any savegame archiving. For development work ================== */ void SV_Map_f( void ) { char *spawn_entity; string mapname; int flags; if( Cmd_Argc() != 2 ) { Msg( "Usage: map <mapname>\n" ); return; } // hold mapname to other place Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname )); // determine spawn entity classname if( sv_maxclients->integer == 1 ) spawn_entity = GI->sp_entity; else spawn_entity = GI->mp_entity; flags = SV_MapIsValid( mapname, spawn_entity, NULL ); if( flags & MAP_INVALID_VERSION ) { Msg( "SV_NewMap: map %s is invalid or not supported\n", mapname ); return; } if(!( flags & MAP_IS_EXIST )) { Msg( "SV_NewMap: map %s doesn't exist\n", mapname ); return; } if(!( flags & MAP_HAS_SPAWNPOINT )) { Msg( "SV_NewMap: map %s doesn't have a valid spawnpoint\n", mapname ); return; } // init network stuff NET_Config(( sv_maxclients->integer > 1 )); // changing singleplayer to multiplayer or back. refresh the player count if(( sv_maxclients->modified ) || ( deathmatch->modified ) || ( coop->modified ) || ( teamplay->modified )) Host_ShutdownServer(); SCR_BeginLoadingPlaque( false ); sv.changelevel = false; sv.background = false; sv.loadgame = false; // set right state SV_ClearSaveDir (); // delete all temporary *.hl files SV_DeactivateServer(); SV_SpawnServer( mapname, NULL ); SV_LevelInit( mapname, NULL, NULL, false ); SV_ActivateServer (); }
/* * SV_Map * command from the console or progs. */ void SV_Map( const char *level, qboolean devmap ) { client_t *cl; int i; if( svs.demo.file ) SV_Demo_Stop_f(); // skip the end-of-unit flag if necessary if( level[0] == '*' ) level++; if( sv.state == ss_dead ) SV_InitGame(); // the game is just starting // remove all bots before changing map for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ ) { if( cl->state && cl->edict && ( cl->edict->r.svflags & SVF_FAKECLIENT ) ) { SV_DropClient( cl, DROP_TYPE_GENERAL, NULL ); } } // wsw : Medar : this used to be at SV_SpawnServer, but we need to do it before sending changing // so we don't send frames after sending changing command // leave slots at start for clients only for( i = 0; i < sv_maxclients->integer; i++ ) { // needs to reconnect if( svs.clients[i].state > CS_CONNECTING ) { svs.clients[i].state = CS_CONNECTING; } // limit number of connected multiview clients if( svs.clients[i].mv ) { if( sv.num_mv_clients < sv_maxmvclients->integer ) sv.num_mv_clients++; else svs.clients[i].mv = qfalse; } svs.clients[i].lastframe = -1; memset( svs.clients[i].gameCommands, 0, sizeof( svs.clients[i].gameCommands ) ); } SV_MOTD_Update(); SCR_BeginLoadingPlaque(); // for local system SV_BroadcastCommand( "changing\n" ); SV_SendClientMessages(); SV_SpawnServer( level, devmap ); SV_BroadcastCommand( "reconnect\n" ); }
/* ================== Host_Restart_f Restarts the current server for a dead player ================== */ void Host_Restart_f (void) { char mapname[MAX_QPATH]; #ifdef QUAKE2 char startspot[MAX_QPATH]; #endif if (cls.demoplayback || !sv.active) return; if (cmd_source != src_command) return; strcpy (mapname, sv.name); // must copy out, because it gets cleared // in sv_spawnserver #ifdef QUAKE2 strcpy(startspot, sv.startspot); SV_SpawnServer (mapname, startspot); #else SV_SpawnServer (mapname); #endif }
/* ================== SV_Map_f Goes directly to a given map without any savegame archiving. For development work ================== */ void SV_Map_f( void ) { char *spawn_entity; string mapname; int flags; if( Cmd_Argc() != 2 ) { Msg( "Usage: map <mapname>\n" ); return; } // hold mapname to other place Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname )); // determine spawn entity classname if( sv_maxclients->integer == 1 ) spawn_entity = GI->sp_entity; else spawn_entity = GI->mp_entity; flags = SV_MapIsValid( mapname, spawn_entity, NULL ); if( flags & MAP_INVALID_VERSION ) { Msg( "SV_NewMap: map %s is invalid or not supported\n", mapname ); return; } if(!( flags & MAP_IS_EXIST )) { Msg( "SV_NewMap: map %s doesn't exist\n", mapname ); return; } if(!( flags & MAP_HAS_SPAWNPOINT )) { Msg( "SV_NewMap: map %s doesn't have a valid spawnpoint\n", mapname ); return; } #ifndef _DEDICATED SCR_BeginLoadingPlaque( false ); #endif sv.background = false; sv.loadgame = false; // set right state SV_ClearSaveDir (); // delete all temporary *.hl files SV_DeactivateServer(); SV_SpawnServer( mapname, NULL ); SV_LevelInit( mapname, NULL, NULL, false ); SV_ActivateServer (); }
/* ================== Host_Restart_f Restarts the current server for a dead player ================== */ void Host_Restart_f (void) { char mapname[MAX_QPATH]; if (cls.demoplayback || !sv.active) return; if (cmd_source != src_command) return; strcpy (mapname, sv.name); // must copy out, because it gets cleared in sv_spawnserver SV_SpawnServer (mapname); }
/* ================== SV_MapBackground_f Set background map (enable physics in menu) ================== */ void SV_MapBackground_f( void ) { string mapname; int flags; if( Cmd_Argc() != 2 ) { Msg( "Usage: map_background <mapname>\n" ); return; } if( sv.state == ss_active && !sv.background ) { Msg( "SV_NewMap: can't set background map while game is active\n" ); return; } // hold mapname to other place Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname )); flags = SV_MapIsValid( mapname, GI->sp_entity, NULL ); if(!( flags & MAP_IS_EXIST )) { Msg( "SV_NewMap: map %s doesn't exist\n", mapname ); return; } // background maps allow without spawnpoints (just throw warning) if(!( flags & MAP_HAS_SPAWNPOINT )) MsgDev( D_WARN, "SV_NewMap: map %s doesn't have a valid spawnpoint\n", mapname ); Q_strncpy( host.finalmsg, "", MAX_STRING ); SV_Shutdown( true ); NET_Config ( false ); // close network sockets sv.background = true; sv.loadgame = false; // set right state // reset all multiplayer cvars Cvar_FullSet( "coop", "0", CVAR_LATCH ); Cvar_FullSet( "teamplay", "0", CVAR_LATCH ); Cvar_FullSet( "deathmatch", "0", CVAR_LATCH ); Cvar_FullSet( "maxplayers", "1", CVAR_LATCH ); #ifndef _DEDICATED SCR_BeginLoadingPlaque( true ); #endif SV_SpawnServer( mapname, NULL ); SV_LevelInit( mapname, NULL, NULL, false ); SV_ActivateServer (); }
/* ================== SV_Map_f Restart the server on a different map ================== */ static void SV_Map_f( void ) { char *cmd; char *map; qboolean killBots, cheat; char expanded[MAX_QPATH]; char mapname[MAX_QPATH]; int i; map = Cmd_Argv(1); if ( !map ) { return; } // make sure the level exists before trying to change, so that // a typo at the server console won't end the game Com_sprintf (expanded, sizeof(expanded), "maps/%s.bsp", map); if ( FS_ReadFile (expanded, NULL) == -1 ) { Com_Printf ("Can't find map %s\n", expanded); return; } cmd = Cmd_Argv(0); if ( !Q_stricmp( cmd, "devmap" ) ) { cheat = qtrue; killBots = qtrue; } else { cheat = qfalse; killBots = qfalse; } // save the map name here cause on a map restart we reload the autogen.cfg // and thus nuke the arguments of the map command Q_strncpyz(mapname, map, sizeof(mapname)); // start up the map SV_SpawnServer( mapname, killBots ); // set the cheat value // if the level was started with "map <levelname>", then // cheats will not be allowed. If started with "devmap <levelname>" // then cheats will be allowed if ( cheat ) { Cvar_Set( "sv_cheats", "1" ); } else { Cvar_Set( "sv_cheats", "0" ); } // This forces the local master server IP address cache // to be updated on sending the next heartbeat for( i = 0; i < MAX_MASTER_SERVERS; i++ ) sv_master[ i ]->modified = qtrue; }
/* ================== SV_Map_f Restart the server on a different map ================== */ static void SV_Map_f( void ) { char *cmd; char *map; const char *layouts; char mapname[ MAX_QPATH ]; qboolean cheat; char expanded[ MAX_QPATH ]; char layout[ MAX_CVAR_VALUE_STRING ]; map = Cmd_Argv( 1 ); if ( !map ) { return; } // make sure the level exists before trying to change, so that // a typo at the server console won't end the game Com_sprintf( expanded, sizeof( expanded ), "maps/%s.bsp", map ); if ( FS_ReadFile( expanded, NULL ) == -1 ) { Com_Printf(_( "Can't find map %s\n"), expanded ); return; } // layout(s) - note that ArgsFrom adds quoting which we don't want here // Also, if empty, don't override layouts = Cmd_UnquoteString( Cmd_ArgsFrom( 2 ) ); if ( *layouts ) { Cvar_Set( "g_layouts", layouts ); } cheat = !Q_stricmp( Cmd_Argv( 0 ), "devmap" ); // save the map name here cause on a map restart we reload the q3config.cfg // and thus nuke the arguments of the map command Q_strncpyz( mapname, map, sizeof( mapname ) ); // start up the map SV_SpawnServer( mapname ); // set the cheat value // if the level was started with "map <levelname>", then // cheats will not be allowed. If started with "devmap <levelname>" // then cheats will be allowed Cvar_Set( "sv_cheats", cheat ? "1" : "0" ); }
/* ================== Host_Restart_f Restarts the current server for a dead player ================== */ void Host_Restart_f (void) { char mapname[MAX_QPATH]; if (cls.demoplayback || !sv.active) return; if (cmd_source != src_command) return; q_strlcpy (mapname, sv.name, sizeof(mapname)); // mapname gets cleared in spawnserver SV_SpawnServer (mapname); if (!sv.active) Host_Error ("cannot restart map %s", mapname); }
/* ====================== SV_Map_f handle a map <mapname> command from the console or progs. ====================== */ void SV_Map_f (void) { char level[MAX_QPATH]; char expanded[MAX_QPATH]; FILE *f; char _startspot[MAX_QPATH]; char *startspot; if (Cmd_Argc() < 2) { Con_Printf ("map <levelname> : continue game on a new level\n"); return; } strcpy (level, Cmd_Argv(1)); if (Cmd_Argc() == 2) { startspot = NULL; } else { strcpy (_startspot, Cmd_Argv(2)); startspot = _startspot; } #if 0 if (!strcmp (level, "e1m8")) { // QuakeWorld can't go to e1m8 SV_BroadcastPrintf (PRINT_HIGH, "can't go to low grav level in HexenWorld...\n"); strcpy (level, "e1m5"); } #endif // check to make sure the level exists sprintf (expanded, "maps/%s.bsp", level); COM_FOpenFile (expanded, &f, false); if (!f) { Con_Printf ("Can't find %s\n", expanded); return; } fclose (f); SV_BroadcastCommand ("changing\n"); SV_SendMessagesToAll (); SV_SpawnServer (level, startspot); SV_BroadcastCommand ("reconnect\n"); }
/* ====================== Host_Map_f handle a map <servername> command from the console. Active clients are kicked off. ====================== */ static void Host_Map_f(void) { int i; char name[MAX_QPATH]; if (cmd_source != src_command) return; if (Cmd_Argc() < 2) { // no map name given Con_Printf ("map <levelname>: start a new server\n"); if (cls.state == ca_dedicated) { if (sv.active) Con_Printf ("Currently on: %s\n", sv.name); else Con_Printf ("Server not active\n"); } else if (cls.state >= ca_connected) { Con_Printf ("Currently on: %s ( %s )\n", cl.levelname, cl.mapname); } return; } cls.demonum = -1; // stop demo loop in case this fails CL_Disconnect(); Host_ShutdownServer(false); key_dest = key_game; // remove console or menu SCR_BeginLoadingPlaque(); svs.serverflags = 0; // haven't completed an episode yet strcpy(name, Cmd_Argv(1)); SV_SpawnServer(name); if (!sv.active) return; if (cls.state != ca_dedicated) { strcpy(cls.spawnparms, ""); for (i = 2; i < Cmd_Argc(); i++) { strcat(cls.spawnparms, Cmd_Argv(i)); strcat(cls.spawnparms, " "); } Cmd_ExecuteString("connect local", src_command); } }
/* Host_Map_f handle a map <servername> command from the console. Active clients are kicked off. */ static void Host_Map_f (void) { char name[MAX_QPATH]; const char *expanded; QFile *f; if (cmd_source != src_command) return; if (Cmd_Argc () > 2) { Sys_Printf ("map <levelname> : continue game on a new level\n"); return; } if (Cmd_Argc () == 1) { Sys_Printf ("map is %s \"%s\" (%s)\n", sv.name, PR_GetString (&sv_pr_state, SVstring (sv.edicts, message)), nice_time (sv.time)); return; } // check to make sure the level exists expanded = va ("maps/%s.bsp", Cmd_Argv (1)); QFS_FOpenFile (expanded, &f); if (!f) { Sys_Printf ("Can't find %s\n", expanded); return; } Qclose (f); cls.demonum = -1; // stop demo loop in case this fails CL_Disconnect (); Host_ShutdownServer (false); cl.loading = true; CL_UpdateScreen (cl.time); svs.serverflags = 0; // haven't completed an episode yet strcpy (name, Cmd_Argv (1)); SV_SpawnServer (name); if (!sv.active) return; if (cls.state != ca_dedicated) { Cmd_ExecuteString ("connect local", src_command); } }
//========================================================= // don't call this directly, it should only be called from SV_Map_f() or SV_MapTransition_f() // static bool SV_Map_( ForceReload_e eForceReload ) { char *map; char expanded[MAX_QPATH]; map = Cmd_Argv(1); if ( !*map ) { Com_Printf ("no map specified\n"); return false; } // make sure the level exists before trying to change, so that // a typo at the server console won't end the game if (strchr (map, '\\') ) { Com_Printf ("Can't have mapnames with a \\\n"); return false; } #ifndef _XBOX // Could check for maps/%s/brushes.mle or something... Com_sprintf (expanded, sizeof(expanded), "maps/%s.bsp", map); #ifndef _DEBUG Com_Printf("SV_Map_ CHECK HERE: %s\n", expanded); #endif if ( FS_ReadFile (expanded, NULL) == -1 ) { Com_Printf ("Can't find map %s\n", expanded); extern cvar_t *com_buildScript; if (com_buildScript && com_buildScript->integer) {//yes, it's happened, someone deleted a map during my build... Com_Error( ERR_FATAL, "Can't find map %s\n", expanded ); } return false; } #endif if (map[0]!='_') { SG_WipeSavegame("auto"); } #ifndef _DEBUG Com_Printf("SV_SpawnServer call: %s\n", map); #endif SV_SpawnServer( map, eForceReload, qtrue ); // start up the map return true; }
/* SV_Map_f handle a map <mapname> command from the console or progs. */ static void SV_Map_f (void) { const char *level; char *expanded; QFile *f; if (!curlevel) curlevel = dstring_newstr (); if (Cmd_Argc () > 2) { SV_Printf ("map <levelname> : continue game on a new level\n"); return; } if (Cmd_Argc () == 1) { SV_Printf ("map is %s \"%s\" (%s)\n", curlevel->str, PR_GetString (&sv_pr_state, SVstring (sv.edicts, message)), nice_time (sv.time)); return; } level = Cmd_Argv (1); // check to make sure the level exists expanded = nva ("maps/%s.bsp", level); f = QFS_FOpenFile (expanded); if (!f) { SV_Printf ("Can't find %s\n", expanded); free (expanded); return; } Qclose (f); free (expanded); if (sv.recording_demo) SV_Stop (0); SV_qtvChanging (); SV_BroadcastCommand ("changing\n"); SV_SendMessagesToAll (); dstring_copystr (curlevel, level); SV_SpawnServer (level); SV_qtvReconnect (); SV_BroadcastCommand ("reconnect\n"); }
/* ================== SV_Map_f Restart the server on a different map ================== */ static void SV_Map_f( void ) { char *cmd; char *map; qboolean killBots, cheat; char expanded[MAX_QPATH]; char mapname[MAX_QPATH]; map = Cmd_Argv(1); if ( !map ) { return; } // make sure the level exists before trying to change, so that // a typo at the server console won't end the game Com_sprintf (expanded, sizeof(expanded), "maps/%s.bsp", map); if ( FS_ReadFile (expanded, NULL) == -1 ) { Com_Printf ("Can't find map %s\n", expanded); return; } cmd = Cmd_Argv(0); if ( !Q_stricmp( cmd, "devmap" ) ) { cheat = qtrue; killBots = qtrue; } else { cheat = qfalse; killBots = Com_GameIsSinglePlayer(); } // save the map name here cause on a map restart we reload the q3config.cfg // and thus nuke the arguments of the map command Q_strncpyz(mapname, map, sizeof(mapname)); // start up the map SV_SpawnServer( mapname, killBots ); // set the cheat value // if the level was started with "map <levelname>", then // cheats will not be allowed. If started with "devmap <levelname>" // then cheats will be allowed if ( cheat ) { Cvar_Set( "sv_cheats", "1" ); } else { Cvar_Set( "sv_cheats", "0" ); } }
/* ================== Host_Changelevel2_f changing levels within a unit ================== */ static void Host_Changelevel2_f (void) { char level[MAX_QPATH]; char _startspot[MAX_QPATH]; char *startspot; if (Cmd_Argc() < 2) { Con_Printf ("changelevel2 <levelname> : continue game on a new level in the unit\n"); return; } if (!sv.active || cls.demoplayback) { Con_Printf ("Only the server may changelevel\n"); return; } q_snprintf (level, sizeof(level), "maps/%s.bsp", Cmd_Argv(1)); if (!FS_FileExists(level, NULL)) Host_Error ("%s: cannot find map %s", __thisfunc__, level); q_strlcpy (level, Cmd_Argv(1), sizeof(level)); if (Cmd_Argc() == 2) startspot = NULL; else { q_strlcpy (_startspot, Cmd_Argv(2), sizeof(_startspot)); startspot = _startspot; } SV_SaveSpawnparms (); // save the current level's state old_svtime = sv.time; if (SaveGamestate(false) != 0) return; // try to restore the new level if (LoadGamestate(level, startspot, 0) != 0) { SV_SpawnServer (level, startspot); if (!sv.active) Host_Error ("%s: cannot run map %s", __thisfunc__, level); RestoreClients (0); } }