Ejemplo n.º 1
0
/*
=====================
CL_NextDemo

Called to play the next demo in the demo loop
=====================
*/
void
CL_NextDemo(void)
{
    char str[1024];

    if (cls.demonum == -1)
	return;			// don't play demos

    SCR_BeginLoadingPlaque();

    if (!cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS) {
	cls.demonum = 0;
	if (!cls.demos[cls.demonum][0]) {
	    Con_Printf("No demos listed with startdemos\n");
	    cls.demonum = -1;
	    return;
	}
    }

    sprintf(str, "playdemo %s\n", cls.demos[cls.demonum]);
    Cbuf_InsertText(str);
    cls.demonum++;
}
Ejemplo n.º 2
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");
}
Ejemplo n.º 3
0
/*
==============
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));
	}
}
Ejemplo n.º 4
0
/*
==================
Host_Reconnect_f

This command causes the client to wait for the signon messages again.
This is sent just before a server changes levels
==================
*/
void Host_Reconnect_f (void)
{
	SCR_BeginLoadingPlaque ();
	cls.signon = 0;		// need new connection messages
}
Ejemplo n.º 5
0
/*
* 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 );
}
Ejemplo n.º 6
0
/*
====================
Host_Init
====================
*/
static void Host_Init (void)
{
	int i;
	const char* os;
	char vabuf[1024];

	if (COM_CheckParm("-profilegameonly"))
		Sys_AllowProfiling(false);

	// LordHavoc: quake never seeded the random number generator before... heh
	if (COM_CheckParm("-benchmark"))
		srand(0); // predictable random sequence for -benchmark
	else
		srand((unsigned int)time(NULL));

	// FIXME: this is evil, but possibly temporary
	// LordHavoc: doesn't seem very temporary...
	// LordHavoc: made this a saved cvar
// COMMANDLINEOPTION: Console: -developer enables warnings and other notices (RECOMMENDED for mod developers)
	if (COM_CheckParm("-developer"))
	{
		developer.value = developer.integer = 1;
		developer.string = "1";
	}

	if (COM_CheckParm("-developer2") || COM_CheckParm("-developer3"))
	{
		developer.value = developer.integer = 1;
		developer.string = "1";
		developer_extra.value = developer_extra.integer = 1;
		developer_extra.string = "1";
		developer_insane.value = developer_insane.integer = 1;
		developer_insane.string = "1";
		developer_memory.value = developer_memory.integer = 1;
		developer_memory.string = "1";
		developer_memorydebug.value = developer_memorydebug.integer = 1;
		developer_memorydebug.string = "1";
	}

	if (COM_CheckParm("-developer3"))
	{
		gl_paranoid.integer = 1;gl_paranoid.string = "1";
		gl_printcheckerror.integer = 1;gl_printcheckerror.string = "1";
	}

// COMMANDLINEOPTION: Console: -nostdout disables text output to the terminal the game was launched from
	if (COM_CheckParm("-nostdout"))
		sys_nostdout = 1;

	// used by everything
	Memory_Init();

	// initialize console command/cvar/alias/command execution systems
	Cmd_Init();

	// initialize memory subsystem cvars/commands
	Memory_Init_Commands();

	// initialize console and logging and its cvars/commands
	Con_Init();

	// initialize various cvars that could not be initialized earlier
	u8_Init();
	Curl_Init_Commands();
	Cmd_Init_Commands();
	Sys_Init_Commands();
	COM_Init_Commands();
	FS_Init_Commands();

	// initialize console window (only used by sys_win.c)
	Sys_InitConsole();

	// initialize the self-pack (must be before COM_InitGameType as it may add command line options)
	FS_Init_SelfPack();

	// detect gamemode from commandline options or executable name
	COM_InitGameType();

	// construct a version string for the corner of the console
	os = DP_OS_NAME;
	dpsnprintf (engineversion, sizeof (engineversion), "%s %s %s", gamename, os, buildstring);
	Con_Printf("%s\n", engineversion);

	// initialize process nice level
	Sys_InitProcessNice();

	// initialize ixtable
	Mathlib_Init();

	// initialize filesystem (including fs_basedir, fs_gamedir, -game, scr_screenshot_name)
	FS_Init();

	// register the cvars for session locking
	Host_InitSession();

	// must be after FS_Init
	Crypto_Init();
	Crypto_Init_Commands();

	NetConn_Init();
	Curl_Init();
	//PR_Init();
	//PR_Cmd_Init();
	PRVM_Init();
	Mod_Init();
	World_Init();
	SV_Init();
	V_Init(); // some cvars needed by server player physics (cl_rollangle etc)
	Host_InitCommands();
	Host_InitLocal();
	Host_ServerOptions();

	Thread_Init();

	if (cls.state == ca_dedicated)
		Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server (or disconnect all clients if running a server)");
	else
	{
		Con_DPrintf("Initializing client\n");

		R_Modules_Init();
		Palette_Init();
#ifdef CONFIG_MENU
		MR_Init_Commands();
#endif
		VID_Shared_Init();
		VID_Init();
		Render_Init();
		S_Init();
		CDAudio_Init();
		Key_Init();
		CL_Init();
	}

	// save off current state of aliases, commands and cvars for later restore if FS_GameDir_f is called
	// NOTE: menu commands are freed by Cmd_RestoreInitState
	Cmd_SaveInitState();

	// FIXME: put this into some neat design, but the menu should be allowed to crash
	// without crashing the whole game, so this should just be a short-time solution

	// here comes the not so critical stuff
	if (setjmp(host_abortframe)) {
		return;
	}

	Host_AddConfigText();
	Cbuf_Execute();

	// if stuffcmds wasn't run, then quake.rc is probably missing, use default
	if (!host_stuffcmdsrun)
	{
		Cbuf_AddText("exec default.cfg\nexec " CONFIGFILENAME "\nexec autoexec.cfg\nstuffcmds\n");
		Cbuf_Execute();
	}

	// put up the loading image so the user doesn't stare at a black screen...
	SCR_BeginLoadingPlaque(true);

#ifdef CONFIG_MENU
	if (cls.state != ca_dedicated)
	{
		MR_Init();
	}
#endif

	// check for special benchmark mode
// COMMANDLINEOPTION: Client: -benchmark <demoname> runs a timedemo and quits, results of any timedemo can be found in gamedir/benchmark.log (for example id1/benchmark.log)
	i = COM_CheckParm("-benchmark");
	if (i && i + 1 < com_argc)
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText(va(vabuf, sizeof(vabuf), "timedemo %s\n", com_argv[i + 1]));
		Cbuf_Execute();
	}

	// check for special demo mode
// COMMANDLINEOPTION: Client: -demo <demoname> runs a playdemo and quits
	i = COM_CheckParm("-demo");
	if (i && i + 1 < com_argc)
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\n", com_argv[i + 1]));
		Cbuf_Execute();
	}

// COMMANDLINEOPTION: Client: -capturedemo <demoname> captures a playdemo and quits
	i = COM_CheckParm("-capturedemo");
	if (i && i + 1 < com_argc)
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\ncl_capturevideo 1\n", com_argv[i + 1]));
		Cbuf_Execute();
	}

	if (cls.state == ca_dedicated || COM_CheckParm("-listen"))
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText("startmap_dm\n");
		Cbuf_Execute();
	}

	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
#ifdef CONFIG_MENU
		Cbuf_AddText("togglemenu 1\n");
#endif
		Cbuf_Execute();
	}

	Con_DPrint("========Initialized=========\n");

	//Host_StartVideo();

	if (cls.state != ca_dedicated)
		SV_StartThread();
}
Ejemplo n.º 7
0
void SV_ChangeLevel2_f( void )
{
	char	*spawn_entity, *mapname;
	int	flags, c = Cmd_Argc();

	if( c < 2 )
	{
		Msg( "Usage: changelevel2 <map> [landmark]\n" );
		return;
	}

	if( host_xashds_hacks->value )
	{
		Cbuf_InsertText(va("rcon changelevel2 %s %s\n",Cmd_Argv( 1 ), Cmd_Argv( 2 )));
		return;
	}

	mapname = Cmd_Argv( 1 );

	// 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, Cmd_Argv( 2 ));

	if( flags & MAP_INVALID_VERSION )
	{
		Msg( "SV_ChangeLevel: Map %s is invalid or not supported.\n", mapname );
		return;
	}
	
	if(!( flags & MAP_IS_EXIST ))
	{
		Msg( "SV_ChangeLevel: Map %s doesn't exist.\n", mapname );
		return;
	}

	if( c >= 3 && !Q_stricmp( sv.name, Cmd_Argv( 1 )))
	{
		MsgDev( D_INFO, "SV_ChangeLevel: Can't changelevel with same map. Ignored.\n" );
		return;	
	}

	// bad changelevel position invoke enables in one-way transtion
	if( sv.net_framenum < 30 )
	{
		if( sv_validate_changelevel->integer )
		{
			MsgDev( D_INFO, "SV_ChangeLevel: An infinite changelevel detected.\n" );
			MsgDev( D_INFO, "Changelevel will be disabled until the next save\\restore.\n" );
			return; // lock with svs.spawncount here
		}
	}

	/*if( sv.state != ss_active )
	{
		MsgDev( D_INFO, "Only the server may changelevel\n" );
		return;
	}*/

	SCR_BeginLoadingPlaque( false );

	SV_ChangeLevel( true, Cmd_Argv( 1 ), Cmd_Argv( 2 ));
}
Ejemplo n.º 8
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");
}
Ejemplo n.º 9
0
/*
==================
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;
	}

	if( host_xashds_hacks->value )
	{
		CL_Disconnect();
		Cbuf_InsertText(va("wait;rcon map %s\n",Cmd_Argv( 1 )));
		Cbuf_AddText("wait;connect 127.0.0.1\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 ();
}
Ejemplo n.º 10
0
/*
=====================
CL_ParseServerMessage
=====================
*/
void CL_ParseServerMessage( sizebuf_t *msg )
{
	char	*s;
	int	i, j, cmd;
	int	param1, param2;
	int	bufStart;

	cls_message_debug.parsing = true;		// begin parsing
	starting_count = BF_GetNumBytesRead( msg );	// updates each frame
	
	// parse the message
	while( 1 )
	{
		if( BF_CheckOverflow( msg ))
		{
			Host_Error( "CL_ParseServerMessage: overflow!\n" );
			return;
		}

		// mark start position
		bufStart = BF_GetNumBytesRead( msg );

		// end of message
		if( BF_GetNumBitsLeft( msg ) < 8 )
			break;		

		cmd = BF_ReadByte( msg );

		// record command for debugging spew on parse problem
		CL_Parse_RecordCommand( cmd, bufStart );

		// other commands
		switch( cmd )
		{
		case svc_bad:
			Host_Error( "svc_bad\n" );
			break;
		case svc_nop:
			// this does nothing
			break;
		case svc_disconnect:
			MsgDev( D_INFO, "Disconnected from server\n" );
			CL_Drop ();
			Host_AbortCurrentFrame ();
			break;
		case svc_changing:
			if( BF_ReadOneBit( msg ))
			{
				cls.changelevel = true;
				S_StopAllSounds();

				if( cls.demoplayback )
				{
					SCR_BeginLoadingPlaque( cl.background );
					cls.changedemo = true;
				}
			}
			else MsgDev( D_INFO, "Server disconnected, reconnecting\n" );

			CL_ClearState ();
			CL_InitEdicts (); // re-arrange edicts

			if( cls.demoplayback )
			{
				cl.background = (cls.demonum != -1) ? true : false;
				cls.state = ca_connected;
			}
			else cls.state = ca_connecting;
			cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately
			break;
		case svc_setview:
			cl.refdef.viewentity = BF_ReadWord( msg );
			break;
		case svc_sound:
			CL_ParseSoundPacket( msg, false );
			break;
		case svc_time:
			// shuffle timestamps
			cl.mtime[1] = cl.mtime[0];
			cl.mtime[0] = BF_ReadFloat( msg );			
			break;
		case svc_print:
			i = BF_ReadByte( msg );
			MsgDev( D_INFO, "^6%s", BF_ReadString( msg ));
			if( i == PRINT_CHAT ) S_StartLocalSound( "common/menu2.wav", VOL_NORM, false );
			break;
		case svc_stufftext:
			CL_ParseStuffText( msg );
			break;
		case svc_lightstyle:
			CL_ParseLightStyle( msg );
			break;
		case svc_setangle:
			CL_ParseSetAngle( msg );
			break;
		case svc_serverdata:
			Cbuf_Execute(); // make sure any stuffed commands are done
			CL_ParseServerData( msg );
			break;
		case svc_addangle:
			CL_ParseAddAngle( msg );
			break;
		case svc_clientdata:
			CL_ParseClientData( msg );
			break;
		case svc_packetentities:
			CL_ParsePacketEntities( msg, false );
			break;
		case svc_deltapacketentities:
			CL_ParsePacketEntities( msg, true );
			break;
		case svc_updatepings:
			CL_UpdateUserPings( msg );
			break;
		case svc_usermessage:
			CL_RegisterUserMessage( msg );
			break;
		case svc_particle:
			CL_ParseParticles( msg );
			break;
		case svc_restoresound:
			CL_ParseRestoreSoundPacket( msg );
			break;
		case svc_spawnstatic:
			CL_ParseStaticEntity( msg );
			break;
		case svc_ambientsound:
			CL_ParseSoundPacket( msg, true );
			break;
		case svc_crosshairangle:
			CL_ParseCrosshairAngle( msg );
			break;
		case svc_spawnbaseline:
			CL_ParseBaseline( msg );
			break;
		case svc_temp_entity:
			CL_ParseTempEntity( msg );
			break;
		case svc_setpause:
			cl.refdef.paused = ( BF_ReadOneBit( msg ) != 0 );
			break;
		case svc_deltamovevars:
			CL_ParseMovevars( msg );
			break;
		case svc_customization:
			CL_ParseCustomization( msg );
			break;
		case svc_centerprint:
			CL_CenterPrint( BF_ReadString( msg ), 0.25f );
			break;
		case svc_event:
			CL_ParseEvent( msg );
			break;
		case svc_event_reliable:
			CL_ParseReliableEvent( msg );
			break;
		case svc_updateuserinfo:
			CL_UpdateUserinfo( msg );
			break;
		case svc_intermission:
			cl.refdef.intermission = true;
			break;
		case svc_modelindex:
			CL_PrecacheModel( msg );
			break;
		case svc_soundindex:
			CL_PrecacheSound( msg );
			break;
		case svc_soundfade:
			CL_ParseSoundFade( msg );
			break;
		case svc_cdtrack:
			param1 = BF_ReadByte( msg );
			param1 = bound( 1, param1, MAX_CDTRACKS ); // tracknum
			param2 = BF_ReadByte( msg );
			param2 = bound( 1, param2, MAX_CDTRACKS ); // loopnum
			S_StartBackgroundTrack( clgame.cdtracks[param1-1], clgame.cdtracks[param2-1], 0 );
			break;
		case svc_serverinfo:
			CL_ServerInfo( msg );
			break;
		case svc_eventindex:
			CL_PrecacheEvent( msg );
			break;
		case svc_deltatable:
			Delta_ParseTableField( msg );
			break;
		case svc_weaponanim:
			param1 = BF_ReadByte( msg );	// iAnim
			param2 = BF_ReadByte( msg );	// body
			CL_WeaponAnim( param1, param2 );
			break;
		case svc_bspdecal:
			CL_ParseStaticDecal( msg );
			break;
		case svc_roomtype:
			param1 = BF_ReadShort( msg );
			Cvar_SetFloat( "room_type", param1 );
			break;
		case svc_chokecount:
			i = BF_ReadByte( msg );
			j = cls.netchan.incoming_acknowledged - 1;
			for( ; i > 0 && j > cls.netchan.outgoing_sequence - CL_UPDATE_BACKUP; j-- )
			{
				if( cl.frames[j & CL_UPDATE_MASK].receivedtime != -3.0 )
				{
					cl.frames[j & CL_UPDATE_MASK].receivedtime = -2.0;
					i--;
				}
			}
			break;
		case svc_resourcelist:
			CL_ParseResourceList( msg );
			break;
		case svc_director:
			CL_ParseDirector( msg );
			break;
		case svc_studiodecal:
			CL_ParseStudioDecal( msg );
			break;
		case svc_querycvarvalue:
			CL_ParseCvarValue( msg );
			break;
		case svc_querycvarvalue2:
			CL_ParseCvarValue2( msg );
			break;
		default:
			CL_ParseUserMessage( msg, cmd );
			break;
		}
	}

	cls_message_debug.parsing = false;	// done

	// we don't know if it is ok to save a demo message until
	// after we have parsed the frame
	if( !cls.demoplayback )
	{
		if( cls.demorecording && !cls.demowaiting )
		{
			CL_WriteDemoMessage( false, starting_count, msg );
		}
		else if( cls.state != ca_active )
		{
			CL_WriteDemoMessage( true, starting_count, msg );
		}
	}
}
Ejemplo n.º 11
0
/*
======================
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_Argc() < 2)	//no map name given
	{
		Con_Printf ("map <levelname>: start a new server\n");
		if (cls.state == ca_disconnected)
			return;
		if (cls.state == ca_connected)
		{
			Con_Printf ("Current level: %s [ %s ]\n",
					cl.levelname, cl.mapname);
			return;
		}
		// (cls.state == ca_dedicated)
		if (sv.active)
		{
			Con_Printf ("Current level: %s [ %s ]\n",
					SV_GetLevelname(), sv.name);
		}
		return;
	}

	if (cmd_source != src_command)
		return;

	cls.demonum = -1;		// stop demo loop in case this fails

	CL_Disconnect ();
	Host_ShutdownServer(false);

	Key_SetDest (key_game);		// remove console or menu
	SCR_BeginLoadingPlaque ();

	info_mask = 0;
	if (!coop.integer && deathmatch.integer)
		info_mask2 = 0x80000000;
	else
		info_mask2 = 0;

	svs.serverflags = 0;		// haven't completed an episode yet
	q_strlcpy (name, Cmd_Argv(1), sizeof(name));

	SV_SpawnServer (name, NULL);

	if (!sv.active)
		return;

	if (cls.state != ca_dedicated)
	{
		loading_stage = 2;

		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);
	}
}
Ejemplo n.º 12
0
/*
==============
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;
}
Ejemplo n.º 13
0
/*
================
SV_SpawnServer

Change the server to a new map, taking all connected
clients along with it.
================
*/
void SV_SpawnServer( cm_t *cm, const char *server, const char *spawnpoint ) {
    int         i;
    client_t    *client;

#if USE_CLIENT
    SCR_BeginLoadingPlaque();           // for local system
#endif

    Com_Printf( "------- Server Initialization -------\n" );
    Com_Printf( "SpawnServer: %s\n", server );

    // everyone needs to reconnect
    FOR_EACH_CLIENT( client ) {
        SV_ClientReset( client );
    }

    SV_BroadcastCommand( "changing map=%s\n", server );
    SV_SendClientMessages();
    SV_SendAsyncPackets();

    // free current level
    CM_FreeMap( &sv.cm );
    SV_FreeFile( sv.entitystring );
    
    // wipe the entire per-level structure
    memset( &sv, 0, sizeof( sv ) );
    sv.spawncount = ( rand() | ( rand() << 16 ) ) ^ Sys_Milliseconds();
    sv.spawncount &= 0x7FFFFFFF;

    // set legacy spawncounts
    FOR_EACH_CLIENT( client ) {
        client->spawncount = sv.spawncount;
    }

    // reset entity counter
    svs.next_entity = 0;

#if USE_FPS
    // set framerate parameters
    set_frame_time();
#endif

    // save name for levels that don't set message
    Q_strlcpy( sv.configstrings[CS_NAME], server, MAX_QPATH );
    Q_strlcpy( sv.name, server, sizeof( sv.name ) );
    
    if( Cvar_VariableInteger( "deathmatch" ) ) {
        sprintf( sv.configstrings[CS_AIRACCEL],
            "%d", sv_airaccelerate->integer );
    } else {
        strcpy( sv.configstrings[CS_AIRACCEL], "0" );
    }

#if !USE_CLIENT
    resolve_masters();
#endif

    override_entity_string( server );

    sv.cm = *cm;
    sprintf( sv.configstrings[CS_MAPCHECKSUM], "%d", ( int )cm->cache->checksum );

    // set inline model names
    Q_concat( sv.configstrings[CS_MODELS + 1], MAX_QPATH, "maps/", server, ".bsp", NULL );
    for( i = 1; i < cm->cache->nummodels; i++ ) {
        sprintf( sv.configstrings[ CS_MODELS + 1 + i ], "*%d", i );
    }

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

    //
    // spawn the rest of the entities on the map
    //  

    // precache and static commands can be issued during
    // map initialization
    sv.state = ss_loading;

    X86_PUSH_FPCW;
    X86_SINGLE_FPCW;

    // load and spawn all other entities
    ge->SpawnEntities ( sv.name, sv.entitystring ?
        sv.entitystring : cm->cache->entitystring, spawnpoint );

    // run two frames to allow everything to settle
    ge->RunFrame (); sv.framenum++;
    ge->RunFrame (); sv.framenum++;

    X86_POP_FPCW;

    // make sure maxclients string is correct
    sprintf( sv.configstrings[CS_MAXCLIENTS], "%d", sv_maxclients->integer );

    // all precaches are complete
    sv.state = ss_game;

#if USE_MVD_SERVER
    // respawn dummy MVD client, set base states, etc
    SV_MvdMapChanged();
#endif

    // set serverinfo variable
    SV_InfoSet( "mapname", sv.name );
    SV_InfoSet( "port", net_port->string );

    Cvar_SetInteger( sv_running, ss_game, FROM_CODE );
    Cvar_Set( "sv_paused", "0" );
    Cvar_Set( "timedemo", "0" );

    EXEC_TRIGGER( sv_changemapcmd );

#if USE_SYSCON
    SV_SetConsoleTitle();
#endif

    SV_BroadcastCommand( "reconnect\n" );

    Com_Printf ("-------------------------------------\n");
}
Ejemplo n.º 14
0
/*
====================
CL_PlayDemo_f

playdemo <demoname>
====================
*/
void CL_PlayDemo_f( void )
{
	string	filename;
	string	demoname;
	int	i;

	if( Cmd_Argc() != 2 )
	{
		Msg( "Usage: playdemo <demoname>\n" );
		return;
	}

	if( cls.demoplayback )
	{
		CL_StopPlayback();
	}

	if( cls.demorecording )
	{
		Msg( "Can't playback during demo record.\n");
		return;
	}

	Q_strncpy( demoname, Cmd_Argv( 1 ), sizeof( demoname ) - 1 );
	Q_snprintf( filename, sizeof( filename ), "demos/%s.dem", demoname );

	if( !FS_FileExists( filename, true ))
	{
		MsgDev( D_ERROR, "couldn't open %s\n", filename );
		cls.demonum = -1; // stop demo loop
		return;
	}

	cls.demofile = FS_Open( filename, "rb", true );
	Q_strncpy( cls.demoname, demoname, sizeof( cls.demoname ));
	Q_strncpy( menu.globals->demoname, demoname, sizeof( menu.globals->demoname ));

	// read in the m_DemoHeader
	FS_Read( cls.demofile, &demo.header, sizeof( demoheader_t ));

	if( demo.header.id != IDEMOHEADER )
	{
		MsgDev( D_ERROR, "%s is not a demo file\n", filename );
		FS_Close( cls.demofile );
		cls.demofile = NULL;
		cls.demonum = -1; // stop demo loop
		return;
	}

	if( demo.header.net_protocol != PROTOCOL_VERSION || demo.header.dem_protocol != DEMO_PROTOCOL )
	{
		MsgDev( D_ERROR, "demo protocol outdated\n"
			"Demo file protocols Network(%i), Demo(%i)\n"
			"Server protocol is at Network(%i), Demo(%i)\n",
			demo.header.net_protocol, 
			demo.header.dem_protocol,
			PROTOCOL_VERSION,
			DEMO_PROTOCOL
		);

		FS_Close( cls.demofile );
		cls.demofile = NULL;
		cls.demonum = -1; // stop demo loop
		return;
	}

	// now read in the directory structure.
	FS_Seek( cls.demofile, demo.header.directory_offset, SEEK_SET );
	FS_Read( cls.demofile, &demo.directory.numentries, sizeof( int ));

	if( demo.directory.numentries < 1 || demo.directory.numentries > 1024 )
	{
		MsgDev( D_ERROR, "demo had bogus # of directory entries: %i\n", demo.directory.numentries );
		FS_Close( cls.demofile );
		cls.demofile = NULL;
		cls.demonum = -1; // stop demo loop
		cls.changedemo = false;
		return;
	}

	if( cls.changedemo )
	{
		S_StopAllSounds();
		SCR_BeginLoadingPlaque( false );

		CL_ClearState ();
		CL_InitEdicts (); // re-arrange edicts
	}
	else
	{
		// NOTE: at this point demo is still valid
		CL_Disconnect();
		Host_ShutdownServer();

		Con_Close();
		UI_SetActiveMenu( false );
	}

	// allocate demo entries
	demo.directory.entries = Mem_Alloc( cls.mempool, sizeof( demoentry_t ) * demo.directory.numentries );

	for( i = 0; i < demo.directory.numentries; i++ )
	{
		FS_Read( cls.demofile, &demo.directory.entries[i], sizeof( demoentry_t ));
	}

	demo.entryIndex = 0;
	demo.entry = &demo.directory.entries[demo.entryIndex];

	FS_Seek( cls.demofile, demo.entry->offset, SEEK_SET );

	cls.demoplayback = true;
	cls.state = ca_connected;
	cl.background = (cls.demonum != -1) ? true : false;

	demo.starttime = CL_GetDemoPlaybackClock(); // for determining whether to read another message

	Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, net_qport->integer );

	demo.framecount = 0;
	cls.lastoutgoingcommand = -1;
 	cls.nextcmdtime = host.realtime;

	// g-cont. is this need?
	Q_strncpy( cls.servername, demoname, sizeof( cls.servername ));

	// begin a playback demo
}
Ejemplo n.º 15
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();
}
Ejemplo n.º 16
0
/*
==================
SV_ChangeLevel_f

Saves the state of the map just being exited and goes to a new map.
==================
*/
void SV_ChangeLevel_f( void )
{
	char	*spawn_entity, *mapname;
	int	flags, c = Cmd_Argc();

	if( c < 2 )
	{
		Msg( "Usage: changelevel <map> [landmark]\n" );
		return;
	}

	if( host_xashds_hacks->value )
	{
		Cbuf_InsertText(va("rcon changelevel %s %s\n",Cmd_Argv( 1 ), Cmd_Argv( 2 )));
		return;
	}

	mapname = Cmd_Argv( 1 );

	// 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, Cmd_Argv( 2 ));

	if( flags & MAP_INVALID_VERSION )
	{
		Msg( "SV_ChangeLevel: Map %s is invalid or not supported\n", mapname );
		return;
	}
	
	if(!( flags & MAP_IS_EXIST ))
	{
		Msg( "SV_ChangeLevel: Map %s doesn't exist\n", mapname );
		return;
	}

	if( c >= 3 && !( flags & MAP_HAS_LANDMARK ))
	{
		if( sv_validate_changelevel->integer )
		{
			// NOTE: we find valid map but specified landmark it's doesn't exist
			// run simple changelevel like in q1, throw warning
			MsgDev( D_INFO, "SV_ChangeLevel: map %s exists but doesn't contain\n", mapname );
			MsgDev( D_INFO, "landmark with name %s. Run classic Quake changelevel.\n", Cmd_Argv( 2 ));
			c = 2; // reduce args
		}
	}

	if( c >= 3 && !Q_stricmp( sv.name, Cmd_Argv( 1 )))
	{
		MsgDev( D_INFO, "SV_ChangeLevel: Can't changelevel with same map. Ignored.\n" );
		return;	
	}

	if( c == 2 && !( flags & MAP_HAS_SPAWNPOINT ))
	{
		if( sv_validate_changelevel->integer )
		{
			MsgDev( D_INFO, "SV_ChangeLevel: Map %s doesn't have a valid spawnpoint. Ignored.\n", mapname );
			return;	
		}
	}

	// bad changelevel position invoke enables in one-way transtion
	if( sv.net_framenum < 30 )
	{
		if( sv_validate_changelevel->integer && host.type != HOST_DEDICATED )
		{
			MsgDev( D_INFO, "SV_ChangeLevel: An infinite changelevel detected.\n" );
			MsgDev( D_INFO, "Changelevel will be disabled until the next save\\restore.\n" );
			return; // lock with svs.spawncount here
		}
	}

	if( sv.state != ss_active )
	{
		MsgDev( D_INFO, "Only the server may changelevel\n" );
		return;
	}

	SCR_BeginLoadingPlaque( false );

	if( sv.background )
	{
		// just load map
		Cbuf_AddText( va( "map %s\n", mapname ));
		return;
	}

	if( c == 2 ) SV_ChangeLevel( false, Cmd_Argv( 1 ), NULL );
	else SV_ChangeLevel( true, Cmd_Argv( 1 ), Cmd_Argv( 2 ));
}
Ejemplo n.º 17
0
void
SCR_Loading_f(void)
{
	SCR_BeginLoadingPlaque();
}
Ejemplo n.º 18
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");
}