コード例 #1
0
ファイル: host.c プロジェクト: Rinnegatamante/vitaQuake
void Host_ServerFrame (void)
{

	static double port_time = 0;

	if (port_time > sv.time + 1 || port_time < sv.time - 60)
	{
		port_time = sv.time;
		Cmd_ExecuteString(va("port %d\n", net_hostport), src_command);
	}

// run the world state
	pr_global_struct->frametime = host_frametime;

// set the time and clear the general datagram
	SV_ClearDatagram ();

// check for new clients
	SV_CheckForNewClients ();

// read client messages
	SV_RunClients ();

// move things around and think
// always pause in single player if in console or menus
	if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) )
		SV_Physics ();

// send all messages to the clients
	SV_SendClientMessages ();
}
コード例 #2
0
ファイル: host.c プロジェクト: odnarb/manquake
/*
==================
Host_ServerFrame

==================
*/
void Host_ServerFrame (void)
{
// JPG 3.00 - stuff the port number into the server console once every minute
	static double port_time = 0;

	if (port_time > sv.time + 1 || port_time < sv.time - 60)
	{
		port_time = sv.time;
		Cmd_ExecuteString(va("port %d\n", net_hostport), src_command);
	}

// run the world state
	pr_global_struct->frametime = host_frametime;

// set the time and clear the general datagram
	SV_ClearDatagram ();

// check for new clients
	SV_CheckForNewClients ();

// read client messages
	SV_RunClients ();

// move things around and think
	if (!sv.paused)
		SV_Physics ();

// send all messages to the clients
	SV_SendClientMessages ();
}
コード例 #3
0
ファイル: host.c プロジェクト: jjjaaajjj/ws-pro-android-games
void Host_ServerFrame (void)
{
// run the world state
    pr_global_struct->frametime = host_frametime;

// set the time and clear the general datagram
    SV_ClearDatagram ();

// check for new clients
    SV_CheckForNewClients ();

// read client messages
    SV_RunClients ();

// move things around and think
// always pause in single player if in console or menus
    if (!SV_IsPaused ())
    {
        SV_Physics ();
        // Vladimir CondSleep (0);
    }

// send all messages to the clients
    SV_SendClientMessages ();
}
コード例 #4
0
ファイル: host.c プロジェクト: libretro/tyrquake
void
Host_ServerFrame(void)
{
    float save_host_frametime;
    float temp_host_frametime;

// run the world state
    pr_global_struct->frametime = host_frametime;

// set the time and clear the general datagram
    SV_ClearDatagram();

// check for new clients
    SV_CheckForNewClients();

    temp_host_frametime = save_host_frametime = host_frametime;
    while (temp_host_frametime > (1.0 / 72.0)) {
	if (temp_host_frametime > 0.05)
	    host_frametime = 0.05;
	else
	    host_frametime = temp_host_frametime;
	temp_host_frametime -= host_frametime;
	_Host_ServerFrame();
    }
    host_frametime = save_host_frametime;

// send all messages to the clients
    SV_SendClientMessages();
}
コード例 #5
0
ファイル: host.c プロジェクト: libretro/tyrquake
void
Host_ServerFrame(void)
{
    /* run the world state */
    pr_global_struct->frametime = host_frametime;

    /* set the time and clear the general datagram */
    SV_ClearDatagram();

    /* check for new clients */
    SV_CheckForNewClients();

    /* read client messages */
    SV_RunClients();

    /*
     * Move things around and think. Always pause in single player if in
     * console or menus
     */
    if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game))
	SV_Physics();

    /* send all messages to the clients */
    SV_SendClientMessages();
}
コード例 #6
0
/*
 * ==================
 * SV_Frame
 *
 * ==================
 */
void SV_Frame(int msec)
{
    time_before_game = time_after_game = 0;

    // if server is not active, do nothing
    if (!svs.initialized)
    {
        return;
    }

    svs.realtime += msec;

    // keep the random time dependent
    rand();

    // check timeouts
    SV_CheckTimeouts();

    // get packets from clients
    SV_ReadPackets();

    // move autonomous things around if enough time has passed
    if (!sv_timedemo->value && (svs.realtime < sv.time))
    {
        // never let the time get too far off
        if (sv.time - svs.realtime > 100)
        {
            if (sv_showclamp->value)
            {
                Com_Printf("sv lowclamp\n");
            }
            svs.realtime = sv.time - 100;
        }
        NET_Sleep(sv.time - svs.realtime);
        return;
    }

    // update ping based on the last known frame from all clients
    SV_CalcPings();

    // give the clients some timeslices
    SV_GiveMsec();

    // let everything in the world think and move
    SV_RunGameFrame();

    // send messages back to the clients that had packets read this frame
    SV_SendClientMessages();

    // save the entire world state if recording a serverdemo
    SV_RecordDemoMessage();

    // send a heartbeat to the master if needed
    Master_Heartbeat();

    // clear teleport flags, etc for next frame
    SV_PrepWorldFrame();
}
コード例 #7
0
/*
* 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" );
}
コード例 #8
0
/*
==================
SV_Frame

==================
*/
void SV_Frame (float time)
{
	static double	start, end;

	start = Sys_DoubleTime ();
	svs.stats.idle += start - end;

// keep the random time dependent
	rand ();

// decide the simulation time
	realtime += time;
	sv.time += time;

// check timeouts
	SV_CheckTimeouts ();

// toggle the log buffer if full
	SV_CheckLog ();

// move autonomous things around if enough time has passed
	SV_Physics ();

// get packets
	SV_ReadPackets ();

// check for commands typed to the host
	SV_GetConsoleCommands ();

// process console commands
	Cbuf_Execute ();

	SV_CheckVars ();

// send messages back to the clients that had packets read this frame
	SV_SendClientMessages ();

// send a heartbeat to the master if needed
	Master_Heartbeat ();

// collect timing statistics
	end = Sys_DoubleTime ();
	svs.stats.active += end-start;
	if (++svs.stats.count == STATFRAMES)
	{
		svs.stats.latched_active = svs.stats.active;
		svs.stats.latched_idle = svs.stats.idle;
		svs.stats.latched_packets = svs.stats.packets;
		svs.stats.active = 0;
		svs.stats.idle = 0;
		svs.stats.packets = 0;
		svs.stats.count = 0;
	}
}
コード例 #9
0
ファイル: sv_main.c プロジェクト: hettoo/racesow
/*
* SV_Frame
*/
void SV_Frame( int realmsec, int gamemsec )
{
	const unsigned int wrappingPoint = 0x70000000;

	time_before_game = time_after_game = 0;

	// if server is not active, do nothing
	if( !svs.initialized )
	{
		SV_CheckDefaultMap();
		return;
	}

	svs.realtime += realmsec;
	svs.gametime += gamemsec;

	// advance to next map if the server is running for too long (numbers taken from q3 src)
	if( svs.realtime > wrappingPoint || svs.gametime > wrappingPoint || sv.framenum >= wrappingPoint )
	{
		Cbuf_AddText( "wait; vstr nextmap\n" );
		SV_ShutdownGame( "Restarting server due to time wrapping", qtrue );
		return;
	}

	// check timeouts
	SV_CheckTimeouts();

	// get packets from clients
	SV_ReadPackets();

	// let everything in the world think and move
	if( SV_RunGameFrame( gamemsec ) )
	{
		// send messages back to the clients that had packets read this frame
		SV_SendClientMessages();

		// write snap to server demo file
		SV_Demo_WriteSnap();

		// run matchmaker stuff
		SV_CheckMatchUUID();

		SV_MM_Frame();

		// send a heartbeat to the master if needed
		SV_MasterHeartbeat();

		// clear teleport flags, etc for next frame
		ge->ClearSnap();
	}

	SV_CheckAutoUpdate();
}
コード例 #10
0
ファイル: sv_frame.c プロジェクト: a1batross/Xash3D_ancient
/*
=======================
SV_SendMessagesToAll

e.g. before changing level
=======================
*/
void SV_SendMessagesToAll( void )
{
	int		i;
	sv_client_t	*cl;

	for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
	{
		if( cl->state >= cs_connected )
			cl->send_message = true;
	}	
	SV_SendClientMessages();
}
コード例 #11
0
ファイル: host.c プロジェクト: sakridge/quakespasm-ml
/*
==================
Host_ServerFrame
==================
*/
void Host_ServerFrame (void)
{
	int		i, active; //johnfitz
	edict_t	*ent; //johnfitz

// run the world state
	pr_global_struct->frametime = host_frametime;

// set the time and clear the general datagram
	SV_ClearDatagram ();

// check for new clients
	SV_CheckForNewClients ();

// read client messages
	SV_RunClients ();

// move things around and think
// always pause in single player if in console or menus
	if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) )
		SV_Physics ();

//johnfitz -- devstats
	if (cls.signon == SIGNONS)
	{
		for (i=0, active=0; i<sv.num_edicts; i++)
		{
			ent = EDICT_NUM(i);
			if (!ent->free)
				active++;
		}
		if (active > 600 && dev_peakstats.edicts <= 600)
			Con_DWarning ("%i edicts exceeds standard limit of 600.\n", active);
		dev_stats.edicts = active;
		dev_peakstats.edicts = q_max(active, dev_peakstats.edicts);
	}
//johnfitz

// send all messages to the clients
	SV_SendClientMessages ();
}
コード例 #12
0
ファイル: sv_init.c プロジェクト: greck2908/qengine
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");
}
コード例 #13
0
ファイル: sv_main.c プロジェクト: n00ner/xash3d
/*
==================
Host_ServerFrame

==================
*/
void Host_ServerFrame( void )
{
	// if server is not active, do nothing
	if( !svs.initialized ) return;

	svgame.globals->frametime = host.frametime;

	// check timeouts
	SV_CheckTimeouts ();

	// check clients timewindow
	SV_CheckCmdTimes ();

	// read packets from clients
	SV_ReadPackets ();

	// update ping based on the last known frame from all clients
	SV_CalcPings ();

	// refresh serverinfo on the client side
	SV_UpdateServerInfo ();

	// refresh physic movevars on the client side
	SV_UpdateMovevars ( false );

	// let everything in the world think and move
	SV_RunGameFrame ();
		
	// send messages back to the clients that had packets read this frame
	SV_SendClientMessages ();

	// clear edict flags for next frame
	SV_PrepWorldFrame ();

	// send a heartbeat to the master if needed
	Master_Heartbeat ();
}
コード例 #14
0
/*
==================
SV_Frame

Player movement occurs as a result of packet events, which
happen before SV_Frame is called
==================
*/
void SV_Frame( int msec ) {
	int		frameMsec;
	int		startTime;

	// the menu kills the server with this cvar
	if ( sv_killserver->integer ) {
		SV_Shutdown ("Server was killed");
		Cvar_Set( "sv_killserver", "0" );
		return;
	}

	if (!com_sv_running->integer)
	{
		if(com_dedicated->integer)
		{
			// Block indefinitely until something interesting happens
			// on STDIN.
			NET_Sleep(-1);
		}
		
		return;
	}

	// allow pause if only the local client is connected
	if ( SV_CheckPaused() ) {
		return;
	}

	// if it isn't time for the next frame, do nothing
	if ( sv_fps->integer < 1 ) {
		Cvar_Set( "sv_fps", "10" );
	}

	frameMsec = 1000 / sv_fps->integer * com_timescale->value;
	// don't let it scale below 1ms
	if(frameMsec < 1)
	{
		Cvar_Set("timescale", va("%f", sv_fps->integer / 1000.0f));
		frameMsec = 1;
	}

	sv.timeResidual += msec;

	if (!com_dedicated->integer) SV_BotFrame (sv.time + sv.timeResidual);

	if ( com_dedicated->integer && sv.timeResidual < frameMsec ) {
		// NET_Sleep will give the OS time slices until either get a packet
		// or time enough for a server frame has gone by
		NET_Sleep(frameMsec - sv.timeResidual);
		return;
	}

	// if time is about to hit the 32nd bit, kick all clients
	// and clear sv.time, rather
	// than checking for negative time wraparound everywhere.
	// 2giga-milliseconds = 23 days, so it won't be too often
	if ( svs.time > 0x70000000 ) {
		SV_Shutdown( "Restarting server due to time wrapping" );
		Cbuf_AddText( va( "map %s\n", Cvar_VariableString( "mapname" ) ) );
		return;
	}
	// this can happen considerably earlier when lots of clients play and the map doesn't change
	if ( svs.nextSnapshotEntities >= 0x7FFFFFFE - svs.numSnapshotEntities ) {
		SV_Shutdown( "Restarting server due to numSnapshotEntities wrapping" );
		Cbuf_AddText( va( "map %s\n", Cvar_VariableString( "mapname" ) ) );
		return;
	}

	if( sv.restartTime && sv.time >= sv.restartTime ) {
		sv.restartTime = 0;
		Cbuf_AddText( "map_restart 0\n" );
		return;
	}

	// update infostrings if anything has been changed
	if ( cvar_modifiedFlags & CVAR_SERVERINFO ) {
		SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) );
		cvar_modifiedFlags &= ~CVAR_SERVERINFO;
	}
	if ( cvar_modifiedFlags & CVAR_SYSTEMINFO ) {
		SV_SetConfigstring( CS_SYSTEMINFO, Cvar_InfoString_Big( CVAR_SYSTEMINFO ) );
		cvar_modifiedFlags &= ~CVAR_SYSTEMINFO;
	}

	if ( com_speeds->integer ) {
		startTime = Sys_Milliseconds ();
	} else {
		startTime = 0;	// quite a compiler warning
	}

	// update ping based on the all received frames
	SV_CalcPings();

	if (com_dedicated->integer) SV_BotFrame (sv.time);

	// run the game simulation in chunks
	while ( sv.timeResidual >= frameMsec ) {
		sv.timeResidual -= frameMsec;
		svs.time += frameMsec;
		sv.time += frameMsec;

		// let everything in the world think and move
		VM_Call (gvm, GAME_RUN_FRAME, sv.time);
	}

	if ( com_speeds->integer ) {
		time_game = Sys_Milliseconds () - startTime;
	}

	// check timeouts
	SV_CheckTimeouts();
	
	// check user info buffer thingy
	SV_CheckClientUserinfoTimer();

	// send messages back to the clients
	SV_SendClientMessages();

	// send a heartbeat to the master if needed
	SV_MasterHeartbeat();
}
コード例 #15
0
ファイル: sv_main.cpp プロジェクト: 3ddy/Jedi-Outcast
void SV_Frame( int msec,float fractionMsec ) {
	int		frameMsec;
	int		startTime=0;

	// the menu kills the server with this cvar
	if ( sv_killserver->integer ) {
		SV_Shutdown ("Server was killed.\n");
		Cvar_Set( "sv_killserver", "0" );
		return;
	}

	if ( !com_sv_running->integer ) {
		return;
	}

 	extern void SE_CheckForLanguageUpdates(void);
	SE_CheckForLanguageUpdates();	// will fast-return else load different language if menu changed it

	// allow pause if only the local client is connected
	if ( SV_CheckPaused() ) {
		return;
	}

	// go ahead and let time slip if the server really hitched badly
	if ( msec > 1000 ) {
		Com_DPrintf( "SV_Frame: Truncating msec of %i to 1000\n", msec );
		msec = 1000;
	}

	// if it isn't time for the next frame, do nothing
	if ( sv_fps->integer < 1 ) {
		Cvar_Set( "sv_fps", "10" );
	}
	frameMsec = 1000 / sv_fps->integer ;

	sv.timeResidual += msec;
	sv.timeResidualFraction+=fractionMsec;
	if (sv.timeResidualFraction>=1.0f)
	{
		sv.timeResidualFraction-=1.0f;
		if (cl_newClock&&cl_newClock->integer)
		{
			sv.timeResidual++;
		}
	}
	if ( sv.timeResidual < frameMsec ) {
		return;
	}

	// if time is about to hit the 32nd bit, restart the
	// level, which will force the time back to zero, rather
	// than checking for negative time wraparound everywhere.
	// 2giga-milliseconds = 23 days, so it won't be too often
	if ( sv.time > 0x70000000 ) {
		SV_Shutdown( "Restarting server due to time wrapping" );
		Com_Printf("You win.  if you can play this long and not die, you deserve to win.\n");
		return;
	}

	// update infostrings if anything has been changed
	if ( cvar_modifiedFlags & CVAR_SERVERINFO ) {
		SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) );
		cvar_modifiedFlags &= ~CVAR_SERVERINFO;
	}
	if ( cvar_modifiedFlags & CVAR_SYSTEMINFO ) {
		SV_SetConfigstring( CS_SYSTEMINFO, Cvar_InfoString( CVAR_SYSTEMINFO ) );
		cvar_modifiedFlags &= ~CVAR_SYSTEMINFO;
	}

	if ( com_speeds->integer ) {
		startTime = Sys_Milliseconds ();
	}

//	SV_BotFrame( sv.time );

	// run the game simulation in chunks
	while ( sv.timeResidual >= frameMsec ) {
		sv.timeResidual -= frameMsec;
		sv.time += frameMsec;
		G2API_SetTime(sv.time,G2T_SV_TIME);

		// let everything in the world think and move
		ge->RunFrame( sv.time );
	}

	if ( com_speeds->integer ) {
		time_game = Sys_Milliseconds () - startTime;
	}

	SG_TestSave();	// returns immediately if not active, used for fake-save-every-cycle to test (mainly) Icarus disk code

	// check timeouts
	SV_CheckTimeouts ();

	// update ping based on the last known frame from all clients
	SV_CalcPings ();

	// send messages back to the clients
	SV_SendClientMessages ();
}
コード例 #16
0
ファイル: sv_init.c プロジェクト: jitspoe/starviewer
/*
======================
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");
}
コード例 #17
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");
}
コード例 #18
0
ファイル: sv_main.cpp プロジェクト: bibendovsky/rtcw
/*
==================
SV_Frame

Player movement occurs as a result of packet events, which
happen before SV_Frame is called
==================
*/
void SV_Frame( int msec ) {
	int frameMsec;
	int startTime;

#if !defined RTCW_SP
	char mapname[MAX_QPATH];
#endif // RTCW_XX

#if defined RTCW_ET
	int frameStartTime = 0, frameEndTime;
#endif // RTCW_XX

	// the menu kills the server with this cvar
	if ( sv_killserver->integer ) {
		SV_Shutdown( "Server was killed.\n" );
		Cvar_Set( "sv_killserver", "0" );
		return;
	}

	if ( !com_sv_running->integer ) {
		return;
	}

	// allow pause if only the local client is connected
	if ( SV_CheckPaused() ) {
		return;
	}

#if defined RTCW_ET
	if ( com_dedicated->integer ) {
		frameStartTime = Sys_Milliseconds();
	}
#endif // RTCW_XX

	// if it isn't time for the next frame, do nothing
	if ( sv_fps->integer < 1 ) {
		Cvar_Set( "sv_fps", "10" );
	}
	frameMsec = 1000 / sv_fps->integer ;

	sv.timeResidual += msec;

	if ( !com_dedicated->integer ) {
		SV_BotFrame( svs.time + sv.timeResidual );
	}

	if ( com_dedicated->integer && sv.timeResidual < frameMsec ) {
		// NET_Sleep will give the OS time slices until either get a packet
		// or time enough for a server frame has gone by
		NET_Sleep( frameMsec - sv.timeResidual );
		return;
	}

	// if time is about to hit the 32nd bit, kick all clients
	// and clear sv.time, rather
	// than checking for negative time wraparound everywhere.
	// 2giga-milliseconds = 23 days, so it won't be too often
	if ( svs.time > 0x70000000 ) {

#if defined RTCW_SP
		SV_Shutdown( "Restarting server due to time wrapping" );
		Cbuf_AddText( "vstr nextmap\n" );
#else
		Q_strncpyz( mapname, sv_mapname->string, MAX_QPATH );
		SV_Shutdown( "Restarting server due to time wrapping" );
		// TTimo
		// show_bug.cgi?id=388
		// there won't be a map_restart if you have shut down the server
		// since it doesn't restart a non-running server
		// instead, re-run the current map
		Cbuf_AddText( va( "map %s\n", mapname ) );
#endif // RTCW_XX

		return;
	}
	// this can happen considerably earlier when lots of clients play and the map doesn't change
	if ( svs.nextSnapshotEntities >= 0x7FFFFFFE - svs.numSnapshotEntities ) {

#if defined RTCW_SP
		SV_Shutdown( "Restarting server due to numSnapshotEntities wrapping" );
		Cbuf_AddText( "vstr nextmap\n" );
#else
		Q_strncpyz( mapname, sv_mapname->string, MAX_QPATH );
		SV_Shutdown( "Restarting server due to numSnapshotEntities wrapping" );
		// TTimo see above
		Cbuf_AddText( va( "map %s\n", mapname ) );
#endif // RTCW_XX

		return;
	}

	if ( sv.restartTime && svs.time >= sv.restartTime ) {
		sv.restartTime = 0;
		Cbuf_AddText( "map_restart 0\n" );
		return;
	}

	// update infostrings if anything has been changed
	if ( cvar_modifiedFlags & CVAR_SERVERINFO ) {

#if !defined RTCW_ET
		SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) );
#else
		SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO | CVAR_SERVERINFO_NOUPDATE ) );
#endif // RTCW_XX

		cvar_modifiedFlags &= ~CVAR_SERVERINFO;
	}

#if defined RTCW_ET
	if ( cvar_modifiedFlags & CVAR_SERVERINFO_NOUPDATE ) {
		SV_SetConfigstringNoUpdate( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO | CVAR_SERVERINFO_NOUPDATE ) );
		cvar_modifiedFlags &= ~CVAR_SERVERINFO_NOUPDATE;
	}
#endif // RTCW_XX

	if ( cvar_modifiedFlags & CVAR_SYSTEMINFO ) {
		SV_SetConfigstring( CS_SYSTEMINFO, Cvar_InfoString_Big( CVAR_SYSTEMINFO ) );
		cvar_modifiedFlags &= ~CVAR_SYSTEMINFO;
	}

#if !defined RTCW_SP
	// NERVE - SMF
	if ( cvar_modifiedFlags & CVAR_WOLFINFO ) {
		SV_SetConfigstring( CS_WOLFINFO, Cvar_InfoString( CVAR_WOLFINFO ) );
		cvar_modifiedFlags &= ~CVAR_WOLFINFO;
	}
#endif // RTCW_XX

	if ( com_speeds->integer ) {
		startTime = Sys_Milliseconds();
	} else {
		startTime = 0;  // quite a compiler warning
	}

	// update ping based on the all received frames
	SV_CalcPings();

	if ( com_dedicated->integer ) {
		SV_BotFrame( svs.time );
	}

	// run the game simulation in chunks
	while ( sv.timeResidual >= frameMsec ) {
		sv.timeResidual -= frameMsec;
		svs.time += frameMsec;

		// let everything in the world think and move

#if !defined RTCW_MP || (defined RTCW_MP && !UPDATE_SERVER)
		VM_Call( gvm, GAME_RUN_FRAME, svs.time );
#endif // RTCW_XX

	}

	if ( com_speeds->integer ) {
		time_game = Sys_Milliseconds() - startTime;
	}

	// check timeouts
	SV_CheckTimeouts();

	// send messages back to the clients
	SV_SendClientMessages();

	// send a heartbeat to the master if needed

#if defined RTCW_SP
	SV_MasterHeartbeat();
#else
	SV_MasterHeartbeat( HEARTBEAT_GAME );
#endif // RTCW_XX

#if defined RTCW_ET
	if ( com_dedicated->integer ) {
		frameEndTime = Sys_Milliseconds();

		svs.totalFrameTime += ( frameEndTime - frameStartTime );
		svs.currentFrameIndex++;

		//if( svs.currentFrameIndex % 50 == 0 )
		//	Com_Printf( "currentFrameIndex: %i\n", svs.currentFrameIndex );

		if ( svs.currentFrameIndex == SERVER_PERFORMANCECOUNTER_FRAMES ) {
			int averageFrameTime;

			averageFrameTime = svs.totalFrameTime / SERVER_PERFORMANCECOUNTER_FRAMES;

			svs.sampleTimes[svs.currentSampleIndex % SERVER_PERFORMANCECOUNTER_SAMPLES] = averageFrameTime;
			svs.currentSampleIndex++;

			if ( svs.currentSampleIndex > SERVER_PERFORMANCECOUNTER_SAMPLES ) {
				int totalTime, i;

				totalTime = 0;
				for ( i = 0; i < SERVER_PERFORMANCECOUNTER_SAMPLES; i++ ) {
					totalTime += svs.sampleTimes[i];
				}

				if ( !totalTime ) {
					totalTime = 1;
				}

				averageFrameTime = totalTime / SERVER_PERFORMANCECOUNTER_SAMPLES;

				svs.serverLoad = ( averageFrameTime / (float)frameMsec ) * 100;
			}

			//Com_Printf( "serverload: %i (%i/%i)\n", svs.serverLoad, averageFrameTime, frameMsec );

			svs.totalFrameTime = 0;
			svs.currentFrameIndex = 0;
		}
	} else
	{
		svs.serverLoad = -1;
	}
#endif // RTCW_XX

}
コード例 #19
0
ファイル: sv_init.c プロジェクト: 1vanK/Urho3DQuake2
/*
======================
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");
}
コード例 #20
0
ファイル: sv_main.cpp プロジェクト: RkShaRkz/Quake2
void SV_Frame(float msec)
{
	guard(SV_Frame);

	time_before_game = time_after_game = 0;

	// if server is not active, do nothing
	if (!svs.initialized)
		return;

//	SV_DrawTextLeft(va("time: %10d rf: %10.5f d: %10.4f ri:%10d", sv.time, svs.realtimef, msec, svs.realtime));//!!
	svs.realtimef += msec;
	svs.realtime = appFloor(svs.realtimef);

	if (!sv.attractloop)
	{
		// check timeouts
		SV_CheckTimeouts();
	}
	// get packets from clients
	SV_ReadPackets();
	if (sv.state == ss_dead) return;	// server was killed from one of packet (e.g. "rcon killserver")

	int frameTime = 100;	// (sv_fps->integer > 10) ? (1000 / sv_fps->integer) : 100;

	// move autonomous things around if enough time has passed
	if (svs.realtime < sv.time)
	{
		// never let the time get too far off
		if (sv.time - svs.realtime > frameTime)
		{
			if (sv_showclamp->integer)
				appPrintf("sv lowclamp s:%d -- r:%d -> %d\n", sv.time, svs.realtime, sv.time - frameTime);
			svs.realtime  = sv.time - frameTime;
			svs.realtimef = svs.realtime;
		}
		return;
	}

	SV_ClearTexts();

	if (!sv.attractloop)
	{
		// update ping based on the last known frame from all clients
		SV_CalcPings();
		// give the clients some timeslices
		SV_GiveMsec();
	}

	// let everything in the world think and move
	/*-------- SV_RunGameFrame() ---------------*/
	// we always need to bump framenum, even if we
	// don't run the world, otherwise the delta
	// compression can get confused when a client
	// has the "current" frame
	sv.framenum++;
	sv.time += frameTime;	//  = sv.framenum*100; ??

	// don't run if paused
	if (!sv_paused->integer || sv_maxclients->integer > 1)
	{
		time_before_game = appCycles();

		guardGame(ge.RunFrame);
		ge->RunFrame();
		unguardGame;


		// never get more than one tic behind
		if (sv.time < svs.realtime)
		{
			if (sv_showclamp->integer)
				appPrintf("sv highclamp s:%d r:%d -> %d\n", sv.time, svs.realtime, sv.time);
			svs.realtime  = sv.time;
			svs.realtimef = sv.time;
		}
		time_after_game = appCycles();
	}

	// if extended protocol used, recalculate footstep sounds, mdx/mdl/md3 frames etc.
	if (sv_extProtocol->integer && !sv.attractloop)
		SV_PostprocessFrame();

	// send messages back to the clients that had packets read this frame
	SV_SendClientMessages();

	// save the entire world state if recording a serverdemo
	SV_RecordDemoMessage();

	// send a heartbeat to the master if needed
	Master_Heartbeat();

	// clear teleport flags, etc for next frame
	SV_PrepWorldFrame();

	unguard;
}
コード例 #21
0
ファイル: host.c プロジェクト: divVerent/darkplaces-travis
void Host_Main(void)
{
	double time1 = 0;
	double time2 = 0;
	double time3 = 0;
	double cl_timer = 0, sv_timer = 0;
	double clframetime, deltacleantime, olddirtytime, dirtytime;
	double wait;
	int pass1, pass2, pass3, i;
	char vabuf[1024];
	qboolean playing;

	Host_Init();

	realtime = 0;
	host_dirtytime = Sys_DirtyTime();
	for (;;)
	{
		if (setjmp(host_abortframe))
		{
			SCR_ClearLoadingScreen(false);
			continue;			// something bad happened, or the server disconnected
		}

		olddirtytime = host_dirtytime;
		dirtytime = Sys_DirtyTime();
		deltacleantime = dirtytime - olddirtytime;
		if (deltacleantime < 0)
		{
			// warn if it's significant
			if (deltacleantime < -0.01)
				Con_Printf("Host_Mingled: time stepped backwards (went from %f to %f, difference %f)\n", olddirtytime, dirtytime, deltacleantime);
			deltacleantime = 0;
		}
		else if (deltacleantime >= 1800)
		{
			Con_Printf("Host_Mingled: time stepped forward (went from %f to %f, difference %f)\n", olddirtytime, dirtytime, deltacleantime);
			deltacleantime = 0;
		}
		realtime += deltacleantime;
		host_dirtytime = dirtytime;

		cl_timer += deltacleantime;
		sv_timer += deltacleantime;

		if (!svs.threaded)
		{
			svs.perf_acc_realtime += deltacleantime;

			// Look for clients who have spawned
			playing = false;
			for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
				if(host_client->begun)
					if(host_client->netconnection)
						playing = true;
			if(sv.time < 10)
			{
				// don't accumulate time for the first 10 seconds of a match
				// so things can settle
				svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
			}
			else if(svs.perf_acc_realtime > 5)
			{
				svs.perf_cpuload = 1 - svs.perf_acc_sleeptime / svs.perf_acc_realtime;
				svs.perf_lost = svs.perf_acc_lost / svs.perf_acc_realtime;
				if(svs.perf_acc_offset_samples > 0)
				{
					svs.perf_offset_max = svs.perf_acc_offset_max;
					svs.perf_offset_avg = svs.perf_acc_offset / svs.perf_acc_offset_samples;
					svs.perf_offset_sdev = sqrt(svs.perf_acc_offset_squared / svs.perf_acc_offset_samples - svs.perf_offset_avg * svs.perf_offset_avg);
				}
				if(svs.perf_lost > 0 && developer_extra.integer)
					if(playing) // only complain if anyone is looking
						Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
				svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
			}
		}

		if (slowmo.value < 0.00001 && slowmo.value != 0)
			Cvar_SetValue("slowmo", 0);
		if (host_framerate.value < 0.00001 && host_framerate.value != 0)
			Cvar_SetValue("host_framerate", 0);

		// keep the random time dependent, but not when playing demos/benchmarking
		if(!*sv_random_seed.string && !cls.demoplayback)
			rand();

		// get new key events
		Key_EventQueue_Unblock();
		SndSys_SendKeyEvents();
		Sys_SendKeyEvents();

		NetConn_UpdateSockets();

		Log_DestBuffer_Flush();

		// receive packets on each main loop iteration, as the main loop may
		// be undersleeping due to select() detecting a new packet
		if (sv.active && !svs.threaded)
			NetConn_ServerFrame();

		Curl_Run();

		// check for commands typed to the host
		Host_GetConsoleCommands();

		// when a server is running we only execute console commands on server frames
		// (this mainly allows frikbot .way config files to work properly by staying in sync with the server qc)
		// otherwise we execute them on client frames
		if (sv.active ? sv_timer > 0 : cl_timer > 0)
		{
			// process console commands
//			R_TimeReport("preconsole");
			CL_VM_PreventInformationLeaks();
			Cbuf_Frame();
//			R_TimeReport("console");
		}

		//Con_Printf("%6.0f %6.0f\n", cl_timer * 1000000.0, sv_timer * 1000000.0);

		// if the accumulators haven't become positive yet, wait a while
		if (cls.state == ca_dedicated)
			wait = sv_timer * -1000000.0;
		else if (!sv.active || svs.threaded)
			wait = cl_timer * -1000000.0;
		else
			wait = max(cl_timer, sv_timer) * -1000000.0;

		if (!cls.timedemo && wait >= 1)
		{
			double time0, delta;

			if(host_maxwait.value <= 0)
				wait = min(wait, 1000000.0);
			else
				wait = min(wait, host_maxwait.value * 1000.0);
			if(wait < 1)
				wait = 1; // because we cast to int

			time0 = Sys_DirtyTime();
			if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded) {
				NetConn_SleepMicroseconds((int)wait);
				if (cls.state != ca_dedicated)
					NetConn_ClientFrame(); // helps server browser get good ping values
				// TODO can we do the same for ServerFrame? Probably not.
			}
			else
				Sys_Sleep((int)wait);
			delta = Sys_DirtyTime() - time0;
			if (delta < 0 || delta >= 1800) delta = 0;
			if (!svs.threaded)
				svs.perf_acc_sleeptime += delta;
//			R_TimeReport("sleep");
			continue;
		}

		// limit the frametime steps to no more than 100ms each
		if (cl_timer > 0.1)
			cl_timer = 0.1;
		if (sv_timer > 0.1)
		{
			if (!svs.threaded)
				svs.perf_acc_lost += (sv_timer - 0.1);
			sv_timer = 0.1;
		}

		R_TimeReport("---");

	//-------------------
	//
	// server operations
	//
	//-------------------

		// limit the frametime steps to no more than 100ms each
		if (sv.active && sv_timer > 0 && !svs.threaded)
		{
			// execute one or more server frames, with an upper limit on how much
			// execution time to spend on server frames to avoid freezing the game if
			// the server is overloaded, this execution time limit means the game will
			// slow down if the server is taking too long.
			int framecount, framelimit = 1;
			double advancetime, aborttime = 0;
			float offset;
			prvm_prog_t *prog = SVVM_prog;

			// run the world state
			// don't allow simulation to run too fast or too slow or logic glitches can occur

			// stop running server frames if the wall time reaches this value
			if (sys_ticrate.value <= 0)
				advancetime = sv_timer;
			else if (cl.islocalgame && !sv_fixedframeratesingleplayer.integer)
			{
				// synchronize to the client frametime, but no less than 10ms and no more than 100ms
				advancetime = bound(0.01, cl_timer, 0.1);
			}
			else
			{
				advancetime = sys_ticrate.value;
				// listen servers can run multiple server frames per client frame
				framelimit = cl_maxphysicsframesperserverframe.integer;
				aborttime = Sys_DirtyTime() + 0.1;
			}
			if(slowmo.value > 0 && slowmo.value < 1)
				advancetime = min(advancetime, 0.1 / slowmo.value);
			else
				advancetime = min(advancetime, 0.1);

			if(advancetime > 0)
			{
				offset = Sys_DirtyTime() - dirtytime;if (offset < 0 || offset >= 1800) offset = 0;
				offset += sv_timer;
				++svs.perf_acc_offset_samples;
				svs.perf_acc_offset += offset;
				svs.perf_acc_offset_squared += offset * offset;
				if(svs.perf_acc_offset_max < offset)
					svs.perf_acc_offset_max = offset;
			}

			// only advance time if not paused
			// the game also pauses in singleplayer when menu or console is used
			sv.frametime = advancetime * slowmo.value;
			if (host_framerate.value)
				sv.frametime = host_framerate.value;
			if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
				sv.frametime = 0;

			for (framecount = 0;framecount < framelimit && sv_timer > 0;framecount++)
			{
				sv_timer -= advancetime;

				// move things around and think unless paused
				if (sv.frametime)
					SV_Physics();

				// if this server frame took too long, break out of the loop
				if (framelimit > 1 && Sys_DirtyTime() >= aborttime)
					break;
			}
			R_TimeReport("serverphysics");

			// send all messages to the clients
			SV_SendClientMessages();

			if (sv.paused == 1 && realtime > sv.pausedstart && sv.pausedstart > 0) {
				prog->globals.fp[OFS_PARM0] = realtime - sv.pausedstart;
				PRVM_serverglobalfloat(time) = sv.time;
				prog->ExecuteProgram(prog, PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing");
			}

			// send an heartbeat if enough time has passed since the last one
			NetConn_Heartbeat(0);
			R_TimeReport("servernetwork");
		}
		else if (!svs.threaded)
		{
			// don't let r_speeds display jump around
			R_TimeReport("serverphysics");
			R_TimeReport("servernetwork");
		}

	//-------------------
	//
	// client operations
	//
	//-------------------

		if (cls.state != ca_dedicated && (cl_timer > 0 || cls.timedemo || ((vid_activewindow ? cl_maxfps : cl_maxidlefps).value < 1)))
		{
			R_TimeReport("---");
			Collision_Cache_NewFrame();
			R_TimeReport("photoncache");
			// decide the simulation time
			if (cls.capturevideo.active)
			{
				//***
				if (cls.capturevideo.realtime)
					clframetime = cl.realframetime = max(cl_timer, 1.0 / cls.capturevideo.framerate);
				else
				{
					clframetime = 1.0 / cls.capturevideo.framerate;
					cl.realframetime = max(cl_timer, clframetime);
				}
			}
			else if (vid_activewindow && cl_maxfps.value >= 1 && !cls.timedemo)
			{
				clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxfps.value);
				// when running slow, we need to sleep to keep input responsive
				wait = bound(0, cl_maxfps_alwayssleep.value * 1000, 100000);
				if (wait > 0)
					Sys_Sleep((int)wait);
			}
			else if (!vid_activewindow && cl_maxidlefps.value >= 1 && !cls.timedemo)
				clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxidlefps.value);
			else
				clframetime = cl.realframetime = cl_timer;

			// apply slowmo scaling
			clframetime *= cl.movevars_timescale;
			// scale playback speed of demos by slowmo cvar
			if (cls.demoplayback)
			{
				clframetime *= slowmo.value;
				// if demo playback is paused, don't advance time at all
				if (cls.demopaused)
					clframetime = 0;
			}
			else
			{
				// host_framerate overrides all else
				if (host_framerate.value)
					clframetime = host_framerate.value;

				if (cl.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
					clframetime = 0;
			}

			if (cls.timedemo)
				clframetime = cl.realframetime = cl_timer;

			// deduct the frame time from the accumulator
			cl_timer -= cl.realframetime;

			cl.oldtime = cl.time;
			cl.time += clframetime;

			// update video
			if (host_speeds.integer)
				time1 = Sys_DirtyTime();
			R_TimeReport("pre-input");

			// Collect input into cmd
			CL_Input();

			R_TimeReport("input");

			// check for new packets
			NetConn_ClientFrame();

			// read a new frame from a demo if needed
			CL_ReadDemoMessage();
			R_TimeReport("clientnetwork");

			// now that packets have been read, send input to server
			CL_SendMove();
			R_TimeReport("sendmove");

			// update client world (interpolate entities, create trails, etc)
			CL_UpdateWorld();
			R_TimeReport("lerpworld");

			CL_Video_Frame();

			R_TimeReport("client");

			CL_UpdateScreen();
			CL_MeshEntities_Reset();
			R_TimeReport("render");

			if (host_speeds.integer)
				time2 = Sys_DirtyTime();

			// update audio
			if(cl.csqc_usecsqclistener)
			{
				S_Update(&cl.csqc_listenermatrix);
				cl.csqc_usecsqclistener = false;
			}
			else
				S_Update(&r_refdef.view.matrix);

			CDAudio_Update();
			R_TimeReport("audio");

			// reset gathering of mouse input
			in_mouse_x = in_mouse_y = 0;

			if (host_speeds.integer)
			{
				pass1 = (int)((time1 - time3)*1000000);
				time3 = Sys_DirtyTime();
				pass2 = (int)((time2 - time1)*1000000);
				pass3 = (int)((time3 - time2)*1000000);
				Con_Printf("%6ius total %6ius server %6ius gfx %6ius snd\n",
							pass1+pass2+pass3, pass1, pass2, pass3);
			}
		}

#if MEMPARANOIA
		Mem_CheckSentinelsGlobal();
#else
		if (developer_memorydebug.integer)
			Mem_CheckSentinelsGlobal();
#endif

		// if there is some time remaining from this frame, reset the timers
		if (cl_timer >= 0)
			cl_timer = 0;
		if (sv_timer >= 0)
		{
			if (!svs.threaded)
				svs.perf_acc_lost += sv_timer;
			sv_timer = 0;
		}

		host_framecount++;
	}
}
コード例 #22
0
ファイル: sv_main.c プロジェクト: chegestar/omni-bot
/*
==================
SV_Frame

Player movement occurs as a result of packet events, which
happen before SV_Frame is called
==================
*/
void SV_Frame( int msec ) {
	int frameMsec;
	int startTime;
	char mapname[MAX_QPATH];

	// the menu kills the server with this cvar
	if ( sv_killserver->integer ) {
		SV_Shutdown( "Server was killed.\n" );
		Cvar_Set( "sv_killserver", "0" );
		return;
	}

	if ( !com_sv_running->integer ) {
		return;
	}

	// allow pause if only the local client is connected
	if ( SV_CheckPaused() ) {
		return;
	}

	// if it isn't time for the next frame, do nothing
	if ( sv_fps->integer < 1 ) {
		Cvar_Set( "sv_fps", "10" );
	}
	frameMsec = 1000 / sv_fps->integer ;

	sv.timeResidual += msec;

	if ( !com_dedicated->integer ) {
		SV_BotFrame( svs.time + sv.timeResidual );
	}

	if ( com_dedicated->integer && sv.timeResidual < frameMsec ) {
		// NET_Sleep will give the OS time slices until either get a packet
		// or time enough for a server frame has gone by
		NET_Sleep( frameMsec - sv.timeResidual );
		return;
	}

	// if time is about to hit the 32nd bit, kick all clients
	// and clear sv.time, rather
	// than checking for negative time wraparound everywhere.
	// 2giga-milliseconds = 23 days, so it won't be too often
	if ( svs.time > 0x70000000 ) {
		Q_strncpyz( mapname, sv_mapname->string, MAX_QPATH );
		SV_Shutdown( "Restarting server due to time wrapping" );
		// TTimo
		// show_bug.cgi?id=388
		// there won't be a map_restart if you have shut down the server
		// since it doesn't restart a non-running server
		// instead, re-run the current map
		Cbuf_AddText( va( "map %s\n", mapname ) );
		return;
	}
	// this can happen considerably earlier when lots of clients play and the map doesn't change
	if ( svs.nextSnapshotEntities >= 0x7FFFFFFE - svs.numSnapshotEntities ) {
		Q_strncpyz( mapname, sv_mapname->string, MAX_QPATH );
		SV_Shutdown( "Restarting server due to numSnapshotEntities wrapping" );
		// TTimo see above
		Cbuf_AddText( va( "map %s\n", mapname ) );
		return;
	}

	if ( sv.restartTime && svs.time >= sv.restartTime ) {
		sv.restartTime = 0;
		Cbuf_AddText( "map_restart 0\n" );
		return;
	}

	// update infostrings if anything has been changed
	if ( cvar_modifiedFlags & CVAR_SERVERINFO ) {
		SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) );
		cvar_modifiedFlags &= ~CVAR_SERVERINFO;
	}
	if ( cvar_modifiedFlags & CVAR_SYSTEMINFO ) {
		SV_SetConfigstring( CS_SYSTEMINFO, Cvar_InfoString_Big( CVAR_SYSTEMINFO ) );
		cvar_modifiedFlags &= ~CVAR_SYSTEMINFO;
	}
	// NERVE - SMF
	if ( cvar_modifiedFlags & CVAR_WOLFINFO ) {
		SV_SetConfigstring( CS_WOLFINFO, Cvar_InfoString( CVAR_WOLFINFO ) );
		cvar_modifiedFlags &= ~CVAR_WOLFINFO;
	}

	if ( com_speeds->integer ) {
		startTime = Sys_Milliseconds();
	} else {
		startTime = 0;  // quite a compiler warning
	}

	// update ping based on the all received frames
	SV_CalcPings();

	if ( com_dedicated->integer ) {
		SV_BotFrame( svs.time );
	}

	// run the game simulation in chunks
	while ( sv.timeResidual >= frameMsec ) {
		sv.timeResidual -= frameMsec;
		svs.time += frameMsec;

		// let everything in the world think and move
#ifndef UPDATE_SERVER
		VM_Call( gvm, GAME_RUN_FRAME, svs.time );
#endif
	}

	if ( com_speeds->integer ) {
		time_game = Sys_Milliseconds() - startTime;
	}

	// check timeouts
	SV_CheckTimeouts();

	// send messages back to the clients
	SV_SendClientMessages();

	// send a heartbeat to the master if needed
	SV_MasterHeartbeat( HEARTBEAT_GAME );
}
コード例 #23
0
ファイル: sv_init.c プロジェクト: Bad-ptr/q2pro
/*
================
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");
}