Exemple #1
0
/*
 * @brief Entry point for spawning a new server or changing maps / demos. Brings any
 * connected clients along for the ride by broadcasting a reconnect before
 * clearing state. Special effort is made to ensure that a locally connected
 * client sees the reconnect message immediately.
 */
void Sv_InitServer(const char *server, sv_state_t state) {
#ifdef BUILD_CLIENT
	extern void Cl_Disconnect(void);
#endif
	char path[MAX_QPATH];

	Com_Debug("Sv_InitServer: %s (%d)\n", server, state);

	Cbuf_CopyToDefer();

	// ensure that the requested map or demo exists
	if (state == SV_ACTIVE_DEMO)
		g_snprintf(path, sizeof(path), "demos/%s.dem", server);
	else
		g_snprintf(path, sizeof(path), "maps/%s.bsp", server);

	if (!Fs_Exists(path)) {
		Com_Print("Couldn't open %s\n", path);
		return;
	}

	// inform any connected clients to reconnect to us
	Sv_ShutdownMessage("Server restarting...\n", true);

#ifdef BUILD_CLIENT
	// disconnect any local client, they'll immediately reconnect
	Cl_Disconnect();
#endif

	// clear the sv_server_t structure
	Sv_ClearState();

	Com_Print("Server initialization...\n");

	// initialize the clients, loading the game module if we need it
	Sv_InitClients();

	// load the map or demo and related media
	Sv_LoadMedia(server, state);
	sv.state = state;

	Sb_Init(&sv.multicast, sv.multicast_buffer, sizeof(sv.multicast_buffer));

	Com_Print("Server initialized\n");
	Com_InitSubsystem(Q2W_SERVER);

	svs.initialized = true;
}
Exemple #2
0
void SV_Map(qboolean attractloop, char *levelstring, qboolean loadgame)
{
  char spawnpoint[1];
  spawnpoint[0] = 0;
  sv.loadgame = loadgame;
  sv.attractloop = attractloop;

  if ((sv.state == ss_dead) && !sv.loadgame) {
    SV_InitGame(); /* the game is just starting */
  }

  Cvar_Set("nextserver", "");

#ifndef DEDICATED_ONLY
  SCR_BeginLoadingPlaque(); /* for local system */
#endif
  SV_BroadcastCommand("changing\n");
  SV_SendClientMessages();
  SV_SpawnServer(levelstring, spawnpoint, ss_game, attractloop, loadgame);
  Cbuf_CopyToDefer();

  SV_BroadcastCommand("reconnect\n");
}
Exemple #3
0
/**
 * @brief Change the server to a new map, taking all connected clients along with it.
 * @note the full syntax is: @code map [day|night] [+]<map> [<assembly>] @endcode
 * @sa SV_AssembleMap
 * @sa CM_LoadMap
 * @sa Com_SetServerState
 */
void SV_Map (qboolean day, const char *levelstring, const char *assembly)
{
	int i;
	unsigned checksum = 0;
	char * map = SV_GetConfigString(CS_TILES);
	char * pos = SV_GetConfigString(CS_POSITIONS);
	mapInfo_t *randomMap = NULL;
	client_t *cl;

	/* any partially connected client will be restarted */
	Com_SetServerState(ss_restart);

	/* the game is just starting */
	SV_InitGame();

	if (!svs.initialized) {
		Com_Printf("Could not spawn the server\n");
		return;
	}

	assert(levelstring[0] != '\0');

	Com_DPrintf(DEBUG_SERVER, "SpawnServer: %s\n", levelstring);

	/* save name for levels that don't set message */
	SV_SetConfigString(CS_NAME, levelstring);
	SV_SetConfigString(CS_LIGHTMAP, day);

	Q_strncpyz(sv->name, levelstring, sizeof(sv->name));

	/* set serverinfo variable */
	sv_mapname = Cvar_FullSet("sv_mapname", sv->name, CVAR_SERVERINFO | CVAR_NOSET);

	/* notify the client in case of a listening server */
	SCR_BeginLoadingPlaque();

	if (assembly)
		Q_strncpyz(sv->assembly, assembly, sizeof(sv->assembly));
	else
		sv->assembly[0] = '\0';

	/* leave slots at start for clients only */
	cl = NULL;
	while ((cl = SV_GetNextClient(cl)) != NULL) {
		/* needs to reconnect */
		if (cl->state >= cs_spawning)
			SV_SetClientState(cl, cs_connected);
	}

	/* assemble and load the map */
	if (levelstring[0] == '+') {
		randomMap = SV_AssembleMap(levelstring + 1, assembly, map, pos, 0);
		if (!randomMap) {
			Com_Printf("Could not load assembly for map '%s'\n", levelstring);
			return;
		}
	} else {
		SV_SetConfigString(CS_TILES, levelstring);
		SV_SetConfigString(CS_POSITIONS, assembly ? assembly : "");
	}

	CM_LoadMap(map, day, pos, &sv->mapData, &sv->mapTiles);

	Com_Printf("checksum for the map '%s': %u\n", levelstring, sv->mapData.mapChecksum);
	SV_SetConfigString(CS_MAPCHECKSUM, sv->mapData.mapChecksum);

	checksum = Com_GetScriptChecksum();

	Com_Printf("ufo script checksum %u\n", checksum);
	SV_SetConfigString(CS_UFOCHECKSUM, checksum);
	SV_SetConfigString(CS_OBJECTAMOUNT, csi.numODs);
	SV_SetConfigString(CS_VERSION, UFO_VERSION);
	SV_SetConfigString(CS_MAPTITLE, SV_GetMapTitle(randomMap, levelstring));
	if (Q_strstart(SV_GetConfigString(CS_MAPTITLE), "b/")) {
		/* For base attack, CS_MAPTITLE contains too many chars */
		SV_SetConfigString(CS_MAPTITLE, "Base attack");
		SV_SetConfigString(CS_NAME, ".baseattack");
	}

	/* clear random-map assembly data */
	Mem_Free(randomMap);
	randomMap = NULL;

	/* clear physics interaction links */
	SV_ClearWorld();

	/* fix this! */
	for (i = 1; i <= sv->mapData.numInline; i++)
		sv->models[i] = CM_InlineModel(&sv->mapTiles, va("*%i", i));

	/* precache and static commands can be issued during map initialization */
	Com_SetServerState(ss_loading);

	TH_MutexLock(svs.serverMutex);
	/* load and spawn all other entities */
	svs.ge->SpawnEntities(sv->name, SV_GetConfigStringInteger(CS_LIGHTMAP), sv->mapData.mapEntityString);
	TH_MutexUnlock(svs.serverMutex);

	/* all precaches are complete */
	Com_SetServerState(ss_game);

	Com_Printf("-------------------------------------\n");

	Cbuf_CopyToDefer();
}
Exemple #4
0
/*
======================
SV_Map

  the full syntax is:

  map [*]<map>$<startspot>+<nextserver>

command from the console or progs.
Map can also be a.cin, .pcx, or .dm2 file
Nextserver is used to allow a cinematic to play, then proceed to
another level:

	map tram.cin+jail_e3
======================
*/
void SV_Map (qboolean attractloop, char *levelstring, qboolean loadgame)
{
	char	level[MAX_QPATH];
	char	*ch;
	int		l;
	char	spawnpoint[MAX_QPATH];

	sv.loadgame = loadgame;
	sv.attractloop = attractloop;

	if (sv.state == ss_dead && !sv.loadgame)
		SV_InitGame ();	// the game is just starting

	strcpy (level, levelstring);

	// if there is a + in the map, set nextserver to the remainder
	ch = strstr(level, "+");
	if (ch)
	{
		*ch = 0;
			Cvar_Set ("nextserver", va("gamemap \"%s\"", ch+1));
	}
	else
		Cvar_Set ("nextserver", "");

	//ZOID special hack for end game screen in coop mode
	if (Cvar_VariableValue ("coop") && !Q_stricmp(level, "victory.pcx"))
		Cvar_Set ("nextserver", "gamemap \"*base1\"");

	// if there is a $, use the remainder as a spawnpoint
	ch = strstr(level, "$");
	if (ch)
	{
		*ch = 0;
		strcpy (spawnpoint, ch+1);
	}
	else
		spawnpoint[0] = 0;

	// skip the end-of-unit flag if necessary
	if (level[0] == '*')
		strcpy (level, level+1);

	l = strlen(level);
	if (l > 4 && !strcmp (level+l-4, ".cin") )
	{
		SCR_BeginLoadingPlaque ();			// for local system
		SV_BroadcastCommand ("changing\n");
		SV_SpawnServer (level, spawnpoint, ss_cinematic, attractloop, loadgame);
	}
	else if (l > 4 && !strcmp (level+l-4, ".dm2") )
	{
		SCR_BeginLoadingPlaque ();			// for local system
		SV_BroadcastCommand ("changing\n");
		SV_SpawnServer (level, spawnpoint, ss_demo, attractloop, loadgame);
	}
	else if (l > 4 && !strcmp (level+l-4, ".pcx") )
	{
		SCR_BeginLoadingPlaque ();			// for local system
		SV_BroadcastCommand ("changing\n");
		SV_SpawnServer (level, spawnpoint, ss_pic, attractloop, loadgame);
	}
	else
	{
		SCR_BeginLoadingPlaque ();			// for local system
		SV_BroadcastCommand ("changing\n");
		SV_SendClientMessages ();
		SV_SpawnServer (level, spawnpoint, ss_game, attractloop, loadgame);
		Cbuf_CopyToDefer ();
	}

	SV_BroadcastCommand ("reconnect\n");
}
Exemple #5
0
/*
 * ======================
 * SV_Map
 *
 * the full syntax is:
 *
 * map [*]<map>$<startspot>+<nextserver>
 *
 * command from the console or progs.
 * Map can also be a.cin, .pcx, or .dm2 file
 * Nextserver is used to allow a cinematic to play, then proceed to
 * another level:
 *
 *      map tram.cin+jail_e3
 * ======================
 */
void SV_Map(qboolean attractloop, char *levelstring, qboolean loadgame)
{
    char level[MAX_QPATH];
    char *ch;
    int  l;
    char spawnpoint[MAX_QPATH];

    sv.loadgame    = loadgame;
    sv.attractloop = attractloop;

    if ((sv.state == ss_dead) && !sv.loadgame)
    {
        SV_InitGame();          // the game is just starting
    }
    // r1ch fix: buffer overflow
//	strcpy (level, levelstring);
    strncpy(level, levelstring, sizeof(level) - 1);

    // if there is a + in the map, set nextserver to the remainder
    ch = strstr(level, "+");
    if (ch)
    {
        *ch = 0;
        Cvar_Set("nextserver", va("gamemap \"%s\"", ch + 1));
    }
    else
    {
        Cvar_Set("nextserver", "");
    }

    //ZOID special hack for end game screen in coop mode
    if (Cvar_VariableValue("coop") && !Q_strcasecmp(level, "victory.pcx"))
    {
        Cvar_Set("nextserver", "gamemap \"*base1\"");
    }

    // if there is a $, use the remainder as a spawnpoint
    ch = strstr(level, "$");
    if (ch)
    {
        *ch = 0;
        strcpy(spawnpoint, ch + 1);
    }
    else
    {
        spawnpoint[0] = 0;
    }

    // skip the end-of-unit flag if necessary
    if (level[0] == '*')
    {
        strcpy(level, level + 1);
    }

    l = strlen(level);
#ifdef  ROQ_SUPPORT
    if ((l > 4) && (!strcmp(level + l - 4, ".cin") || !strcmp(level + l - 4, ".roq")))
#else
    if ((l > 4) && !strcmp(level + l - 4, ".cin"))
#endif // ROQ_SUPPORT
    {
        if (!dedicated->value)
        {
#ifndef DEDICATED_ONLY                 
            SCR_BeginLoadingPlaque();                                   // for local system
#endif            
        }
        SV_BroadcastCommand("changing\n");
        SV_SpawnServer(level, spawnpoint, ss_cinematic, attractloop, loadgame);
    }
    else if ((l > 4) && !strcmp(level + l - 4, ".dm2"))
    {
        if (!dedicated->value)
        {
#ifndef DEDICATED_ONLY                 
            SCR_BeginLoadingPlaque();                                   // for local system
#endif            
        }
        SV_BroadcastCommand("changing\n");
        SV_SpawnServer(level, spawnpoint, ss_demo, attractloop, loadgame);
    }
    else if ((l > 4) && !strcmp(level + l - 4, ".pcx"))
    {
        if (!dedicated->value)
        {
#ifndef DEDICATED_ONLY                 
            SCR_BeginLoadingPlaque();                                   // for local system
#endif            
        }
        SV_BroadcastCommand("changing\n");
        SV_SpawnServer(level, spawnpoint, ss_pic, attractloop, loadgame);
    }
    else
    {
        if (!dedicated->value)
        {
#ifndef DEDICATED_ONLY                 
            SCR_BeginLoadingPlaque();                                   // for local system
#endif            
        }
        SV_BroadcastCommand("changing\n");
        SV_SendClientMessages();
        SV_SpawnServer(level, spawnpoint, ss_game, attractloop, loadgame);
        Cbuf_CopyToDefer();
    }

    SV_BroadcastCommand("reconnect\n");
}
Exemple #6
0
/*
======================
SV_Map

  the full syntax is:

  map [*]<map>$<startspot>+<nextserver>

command from the console or progs.
Map can also be a.cin, .pcx, or .dm2 file
Nextserver is used to allow a cinematic to play, then proceed to
another level:

	map tram.cin+jail_e3
======================
*/
void SV_Map (qboolean attractloop, const char *levelstring, qboolean loadgame)
{
	char	level[MAX_QPATH];
	char	*ch;
	int		l;
	char	spawnpoint[MAX_QPATH];

	strcpy(level, levelstring); // jit - copy level string before it gets modified by other commands (since it's a command argument)
	sv.loadgame = loadgame;
	sv.attractloop = attractloop;

	if (sv.state == ss_dead && !sv.loadgame)
		SV_InitGame();	// the game is just starting

	// if there is a + in the map, set nextserver to the remainder
	ch = strstr(level, "+");

	if (ch)
	{
		*ch = 0;
		Cvar_Set("nextserver", va("gamemap \"%s\"", ch + 1));
	}
	else
	{
		Cvar_Set("nextserver", "");
	}

	//ZOID special hack for end game screen in coop mode
	if (Cvar_VariableValue("coop") && Q_strcaseeq(level, "victory.pcx"))
		Cvar_Set("nextserver", "gamemap \"*base1\"");

	// if there is a $, use the remainder as a spawnpoint
	ch = strstr(level, "$");

	if (ch)
	{
		*ch = 0;
		strcpy(spawnpoint, ch + 1);
	}
	else
	{
		spawnpoint[0] = 0;
	}

	// skip the end-of-unit flag if necessary
	if (level[0] == '*')
		strcpy (level, level+1);

	l = strlen(level);

	if (l > 4 && Q_streq(level + l - 4, ".cin"))
	{
		SCR_BeginLoadingPlaque(NULL);			// for local system
		SV_BroadcastCommand("changing\n");
		SV_SpawnServer(level, spawnpoint, ss_cinematic, attractloop, loadgame);
	}
	else if (l > 4 && Q_streq(level + l - 4, ".dm2"))
	{
		SCR_BeginLoadingPlaque(NULL);			// for local system
		SV_BroadcastCommand("changing\n");
		SV_SpawnServer(level, spawnpoint, ss_demo, attractloop, loadgame);
	}
	else if (l > 4 && Q_streq(level + l - 4, ".pcx"))
	{
		SCR_BeginLoadingPlaque(NULL);			// for local system
		SV_BroadcastCommand("changing\n");
		SV_SpawnServer(level, spawnpoint, ss_pic, attractloop, loadgame);
	}
	else
	{
		char changing_cmd[1024];

		if (!dedicated->value)
			SCR_BeginLoadingPlaque(level);			// for local system

		Com_sprintf(changing_cmd, sizeof(changing_cmd), "changing \"%s\"\n", level);
		SV_BroadcastCommand(changing_cmd);
		SV_SendClientMessages();
		SV_SpawnServer(level, spawnpoint, ss_game, attractloop, loadgame);
		Cbuf_CopyToDefer();
	}

	SV_BroadcastCommand("reconnect\n");
}