Exemplo n.º 1
0
/*
===============
SV_Startup

Called when a host starts a map when it wasn't running
one before.  Successive map or map_restart commands will
NOT cause this to be called, unless the game is exited to
the menu system first.
===============
*/
static void SV_Startup( void ) {
	if ( svs.initialized ) {
		Com_Error( ERR_FATAL, "SV_Startup: svs.initialized" );
	}
	SV_BoundMaxClients( 1 );

	svs.clients = Z_Malloc (sizeof(client_t) * sv_maxclients->integer );
	svs.players = Z_Malloc (sizeof(player_t) * sv_maxclients->integer );
	if ( !Com_GameIsSinglePlayer() ) {
		svs.numSnapshotEntities = sv_maxclients->integer * PACKET_BACKUP * MAX_SNAPSHOT_ENTITIES;
	} else {
		// we don't need nearly as many when playing locally
		svs.numSnapshotEntities = sv_maxclients->integer * 4 * MAX_SNAPSHOT_ENTITIES;
	}
	svs.initialized = qtrue;

	// Don't respect sv_killserver unless a server is actually running
	if ( sv_killserver->integer ) {
		Cvar_Set( "sv_killserver", "0" );
	}

	Cvar_Set( "sv_running", "1" );
	
	// Join the ipv6 multicast group now that a map is running so clients can scan for us on the local network.
	NET_JoinMulticast6();
}
Exemplo n.º 2
0
/*
=======================================================================================================================================
SV_ChangeMaxClients
=======================================================================================================================================
*/
void SV_ChangeMaxClients(void) {
	int oldMaxClients;
	int i;
	client_t *oldClients;
	int count;

	// get the highest client number in use
	count = 0;

	for (i = 0; i < sv_maxclients->integer; i++) {
		if (svs.clients[i].state >= CS_CONNECTED) {
			if (i > count) {
				count = i;
			}
		}
	}

	count++;

	oldMaxClients = sv_maxclients->integer;
	// never go below the highest client number in use
	SV_BoundMaxClients(count);
	// if still the same
	if (sv_maxclients->integer == oldMaxClients) {
		return;
	}

	oldClients = Hunk_AllocateTempMemory(count * sizeof(client_t));
	// copy the clients to hunk memory
	for (i = 0; i < count; i++) {
		if (svs.clients[i].state >= CS_CONNECTED) {
			oldClients[i] = svs.clients[i];
		} else {
			Com_Memset(&oldClients[i], 0, sizeof(client_t));
		}
	}
	// free old clients arrays
	Z_Free(svs.clients);
	// allocate new clients
	svs.clients = Z_Malloc(sv_maxclients->integer * sizeof(client_t));

	Com_Memset(svs.clients, 0, sv_maxclients->integer * sizeof(client_t));
	// copy the clients over
	for (i = 0; i < count; i++) {
		if (oldClients[i].state >= CS_CONNECTED) {
			svs.clients[i] = oldClients[i];
		}
	}
	// free the old clients on the hunk
	Hunk_FreeTempMemory(oldClients);
	// allocate new snapshot entities
	if (!Com_GameIsSinglePlayer()) {
		svs.numSnapshotEntities = sv_maxclients->integer * PACKET_BACKUP * MAX_SNAPSHOT_ENTITIES;
	} else {
		// we don't need nearly as many when playing locally
		svs.numSnapshotEntities = sv_maxclients->integer * 4 * MAX_SNAPSHOT_ENTITIES;
	}
}
Exemplo n.º 3
0
/*
==================
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" );
	}
}
Exemplo n.º 4
0
/*
==================
SV_ChangeMaxClients
==================
*/
void SV_ChangeMaxClients( void ) {
	int		oldMaxClients;
	int		i, j;
	client_t	*oldClients;
	player_t	*oldPlayers;
	int		count;

	// get the highest client or player number in use
	count = 0;
	for ( i = 0 ; i < sv_maxclients->integer ; i++ ) {
		if ( svs.clients[i].state >= CS_CONNECTED || svs.players[i].inUse ) {
			if (i > count)
				count = i;
		}
	}
	count++;

	oldMaxClients = sv_maxclients->integer;
	// never go below the highest client number in use
	SV_BoundMaxClients( count );
	// if still the same
	if ( sv_maxclients->integer == oldMaxClients ) {
		return;
	}

	oldClients = Hunk_AllocateTempMemory( count * sizeof(client_t) );
	oldPlayers = Hunk_AllocateTempMemory( count * sizeof(player_t) );
	// copy the clients and players to hunk memory
	for ( i = 0 ; i < count ; i++ ) {
		if ( svs.players[i].inUse && svs.players[i].client->state >= CS_CONNECTED ) {
			oldPlayers[i] = svs.players[i];
			oldPlayers[i].client = NULL; // client pointer gets restored using localPlayers pointers.
		}
		else {
			Com_Memset(&oldPlayers[i], 0, sizeof(player_t));
		}

		if ( svs.clients[i].state >= CS_CONNECTED ) {
			oldClients[i] = svs.clients[i];

			// save player indexes
			for ( j = 0; j < MAX_SPLITVIEW; j++ ) {
				if (svs.clients[i].localPlayers[j]) {
					oldClients[i].localPlayers[j] = (void*)((svs.clients[i].localPlayers[j] - svs.players) + 1);
				}
			}
		}
		else {
			Com_Memset(&oldClients[i], 0, sizeof(client_t));
		}
	}

	// free old clients and players arrays
	Z_Free( svs.clients );
	Z_Free( svs.players );

	// allocate new clients and players
	svs.clients = Z_Malloc ( sv_maxclients->integer * sizeof(client_t) );
	Com_Memset( svs.clients, 0, sv_maxclients->integer * sizeof(client_t) );

	svs.players = Z_Malloc ( sv_maxclients->integer * sizeof(player_t) );
	Com_Memset( svs.players, 0, sv_maxclients->integer * sizeof(player_t) );

	// copy the clients and players over
	for ( i = 0 ; i < count ; i++ ) {
		if ( oldPlayers[i].inUse ) {
			svs.players[i] = oldPlayers[i];
		}

		if ( oldClients[i].state >= CS_CONNECTED ) {
			svs.clients[i] = oldClients[i];

			// restore pointers
			for ( j = 0; j < MAX_SPLITVIEW; j++ ) {
				if (oldClients[i].localPlayers[j]) {
					svs.clients[i].localPlayers[j] = &svs.players[ (intptr_t)oldClients[i].localPlayers[j] - 1 ];
					svs.clients[i].localPlayers[j]->client = &svs.clients[i];
				}
			}
		}
	}

	// free the old playes and clients on the hunk
	Hunk_FreeTempMemory( oldPlayers );
	Hunk_FreeTempMemory( oldClients );
	
	// allocate new snapshot entities
	if ( !Com_GameIsSinglePlayer() ) {
		svs.numSnapshotEntities = sv_maxclients->integer * PACKET_BACKUP * MAX_SNAPSHOT_ENTITIES;
	} else {
		// we don't need nearly as many when playing locally
		svs.numSnapshotEntities = sv_maxclients->integer * 4 * MAX_SNAPSHOT_ENTITIES;
	}
}