Esempio n. 1
0
/*
==================
SV_CheckTimeouts

If a packet has not been received from a client in timeout.value
seconds, drop the conneciton.

When a client is normally dropped, the client_t goes into a zombie state
for a few seconds to make sure any final reliable message gets resent
if necessary
==================
*/
void SV_CheckTimeouts (void)
{
	int		i;
	client_t	*cl;
	float	droptime;
	int	nclients;
	
	droptime = curtime - sv_timeout.value;
	nclients = 0;

	for (i=0,cl=svs.clients ; i<MAX_CLIENTS ; i++,cl++)
	{
		if (cl->state == cs_connected || cl->state == cs_spawned) {
			if (!cl->spectator)
				nclients++;
			if (cl->netchan.last_received < droptime) {
				SV_BroadcastPrintf (PRINT_HIGH, "%s timed out\n", cl->name);
				SV_DropClient (cl); 
				cl->state = cs_free;	// don't bother with zombie state
			}
		}
		if (cl->state == cs_zombie && 
			svs.realtime - cl->connection_started > sv_zombietime.value)
		{
			cl->state = cs_free;	// can now be reused
		}
	}
	if (((int) sv_paused.value & 1) && !nclients) {
		// nobody left, unpause the server
		SV_TogglePause("Pause released since no players are left.\n");
	}
}
Esempio n. 2
0
/*
==================
SV_CheckTimeouts

If a packet has not been received from a client for timeout->value
seconds, drop the conneciton.  Server frames are used instead of
realtime to avoid dropping the local client while debugging.

When a client is normally dropped, the sv_client_t goes into a zombie state
for a few seconds to make sure any final reliable message gets resent
if necessary
==================
*/
void SV_CheckTimeouts( void )
{
	sv_client_t	*cl;
	float		droppoint;
	float		zombiepoint;
	int		i, numclients = 0;

	droppoint = host.realtime - timeout->value;
	zombiepoint = host.realtime - zombietime->value;

	for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
	{
		if( cl->state >= cs_connected )
		{
			if( cl->edict && !( cl->edict->v.flags & (FL_SPECTATOR|FL_FAKECLIENT)))
				numclients++;
                    }

		// fake clients do not timeout
		if( cl->fakeclient ) cl->lastmessage = host.realtime;

		// message times may be wrong across a changelevel
		if( cl->lastmessage > host.realtime )
			cl->lastmessage = host.realtime;

		if( cl->state == cs_zombie && cl->lastmessage < zombiepoint )
		{
			cl->state = cs_free; // can now be reused
			continue;
		}

		if(( cl->state == cs_connected || cl->state == cs_spawned ) && cl->lastmessage < droppoint )
		{
			SV_BroadcastPrintf( PRINT_HIGH, "%s timed out\n", cl->name );
			SV_DropClient( cl ); 
			cl->state = cs_free; // don't bother with zombie state
		}
	}

	if( sv.paused && !numclients )
	{
		// nobody left, unpause the server
		SV_TogglePause( "Pause released since no players are left." );
	}
}
Esempio n. 3
0
void SV_Pause_f (void)
{
	int i;
	client_t *cl;
	char st[sizeof(host_client->name) + 32];

	if (!pausable.value) {
		SV_ClientPrintf (host_client, PRINT_HIGH, "Pause not allowed.\n");
		return;
	}

	if (host_client->spectator) {
		SV_ClientPrintf (host_client, PRINT_HIGH, "Spectators can not pause.\n");
		return;
	}

	if (sv.paused)
		sprintf (st, "%s paused the game\n", host_client->name);
	else
		sprintf (st, "%s unpaused the game\n", host_client->name);

	SV_TogglePause(st);
}
Esempio n. 4
0
void SV_LoadGame_f (void) {
	extern cvar_t sv_progtype;
	char name[MAX_OSPATH], mapname[MAX_QPATH], str[32 * 1024], *start;
	FILE *f;
	float time, tfloat, spawn_parms[NUM_SPAWN_PARMS];
	edict_t *ent;
	int entnum, version, r;
	unsigned int i;

	if (Cmd_Argc() != 2) {
		Com_Printf ("Usage: %s <savename> : load a game\n", Cmd_Argv(0));
		return;
	}

	snprintf (name, sizeof (name), "%s/save/%s", com_gamedir, Cmd_Argv(1));
	COM_DefaultExtension (name, ".sav");

	Com_Printf ("Loading game from %s...\n", name);
	if (!(f = fopen (name, "rb"))) {
		Com_Printf ("ERROR: couldn't open.\n");
		return;
	}

	if (fscanf (f, "%i\n", &version) != 1) {
		fclose (f);
		Com_Printf ("Error reading savegame data\n");
		return;
	}

	if (version != SAVEGAME_VERSION) {
		fclose (f);
		Com_Printf ("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION);
		return;
	}

	if (fscanf (f, "%s\n", str) != 1) {
		fclose (f);
		Com_Printf ("Error reading savegame data\n");
		return;
	}
	for (i = 0; i < NUM_SPAWN_PARMS; i++) {
		if (fscanf (f, "%f\n", &spawn_parms[i]) != 1) {
			fclose (f);
			Com_Printf ("Error reading savegame data\n");
			return;
		}
	}

	// this silliness is so we can load 1.06 save files, which have float skill values
	if (fscanf (f, "%f\n", &tfloat) != 1) {
		fclose (f);
		Com_Printf ("Error reading savegame data\n");
		return;
	}
	current_skill = (int)(tfloat + 0.1);
	Cvar_Set (&skill, va("%i", current_skill));

	Cvar_SetValue (&deathmatch, 0);
	Cvar_SetValue (&coop, 0);
	Cvar_SetValue (&teamplay, 0);
	Cvar_SetValue (&maxclients, 1);

	Cvar_Set (&sv_progsname, "spprogs"); // force progsname
#ifdef USE_PR2
	Cvar_Set (&sv_progtype, "0"); // force .dat
#endif

	if (fscanf (f, "%s\n", mapname) != 1) {
		fclose (f);
		Com_Printf ("Error reading savegame data\n");
		return;
	}
	if (fscanf (f, "%f\n", &time) != 1) {
		fclose (f);
		Com_Printf ("Error reading savegame data\n");
		return;
	}

	Host_EndGame();

	CL_BeginLocalConnection ();

	SV_SpawnServer (mapname, false);

	if (sv.state != ss_active) {
		Com_Printf ("Couldn't load map\n");
		fclose (f);
		return;
	}

	// load the light styles
	for (i = 0; i < MAX_LIGHTSTYLES; i++) {
		if (fscanf (f, "%s\n", str) != 1) {
			Com_Printf("Couldn't read lightstyles\n");
			fclose (f);
			return;
		}
		sv.lightstyles[i] = (char *) Hunk_Alloc (strlen(str) + 1);
		strlcpy (sv.lightstyles[i], str, strlen(str) + 1);
	}

	// pause until all clients connect
	if (!(sv.paused & 1))
		SV_TogglePause (NULL, 1);

	sv.loadgame = true;

	// load the edicts out of the savegame file
	entnum = -1;		// -1 is the globals
	while (!feof(f)) {
		for (i = 0; i < sizeof(str) - 1; i++) {
			r = fgetc (f);
			if (r == EOF || !r)
				break;
			str[i] = r;
			if (r == '}') {
				i++;
				break;
			}
		}
		if (i == sizeof(str)-1)
			Host_Error ("Loadgame buffer overflow");
		str[i] = 0;
		start = str;
		start = COM_Parse(str);
		if (!com_token[0])
			break;		// end of file

		if (strcmp(com_token,"{"))
			Host_Error ("First token isn't a brace");

		if (entnum == -1) {	
			// parse the global vars
			ED_ParseGlobals (start);
		} else {	
			// parse an edict
			ent = EDICT_NUM(entnum);
			memset (&ent->v, 0, progs->entityfields * 4);
			ent->e->free = false;
			ED_ParseEdict (start, ent);
	
			// link it into the bsp tree
			if (!ent->e->free)
				SV_LinkEdict (ent, false);
		}
		entnum++;
	}

	sv.num_edicts = entnum;
	sv.time = time;

	fclose (f);

	for (i = 0; i < NUM_SPAWN_PARMS; i++)
		svs.clients->spawn_parms[i] = spawn_parms[i];
}