Esempio n. 1
0
void SVCL_Record_f( void ) {
	char		*s;
	client_t	*cl;

	s = 0;
	// make sure server is running
	if ( !com_sv_running->integer ) {
		Com_Printf( "Server is not running.\n" );
		return;
	}

	if ( Cmd_Argc() < 2 || Cmd_Argc() > 3) {
		Com_Printf ("record <clientnumber> [<demoname>]\n");
		return;
	}

	cl = SV_GetPlayerByNum();
	if ( !cl ) {
		// error message was printed by SV_GetPlayerByNum
		return;
	}

	if ( Cmd_Argc() == 3 ) {
		s = Cmd_Argv(2);
//		Com_sprintf (name, sizeof(name), "demos/%s.dm_%d", s, PROTOCOL_VERSION );
		CL_Record(cl,s);
	} else {
		CL_Record(cl,0);
	}
}
Esempio n. 2
0
void CL_Record_f(void)
{
	char name[MAX_OSPATH];
	char *s;

	if (Cmd_Argc() > 2)
	{
		Com_FuncPrinf("record <demoname>\n");
		return;
	}

	if (clc.demorecording)
	{
		Com_FuncPrinf("Already recording.\n");
		return;
	}

	if (cls.state != CA_ACTIVE)
	{
		Com_FuncPrinf("You must be in a level to record.\n");
		return;
	}

	if (Cmd_Argc() == 2)
	{
		s = Cmd_Argv(1);
		Q_strncpyz(demoName, s, sizeof(demoName));
		Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, PROTOCOL_VERSION);
	}
	else
	{
		int number, len;

		// scan for a free demo name
		for (number = 0; number <= 9999; number++)
		{
			CL_DemoFilename(number, demoName);
			Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, PROTOCOL_VERSION);

			len = FS_ReadFile(name, NULL);
			if (len <= 0)
			{
				break;  // file doesn't exist
			}
		}
	}

	CL_Record(name);
}
Esempio n. 3
0
/*
====================
CL_Record_f

record <demoname>
====================
*/
void CL_Record_f (void)
{
	int		c;
	char	name[MAX_OSPATH];

	c = Cmd_Argc();
	if (c != 2)
	{
		Com_Printf ("record <demoname>\n");
		return;
	}

	if (cls.state != ca_active && cls.state != ca_disconnected) {
		Com_Printf ("Cannot record while connecting.\n");
		return;
	}

	if (cls.demorecording)
		CL_Stop_f();
  
	Q_snprintfz (name, sizeof(name), "%s/%s", cls.gamedir, Cmd_Argv(1));

//
// open the demo file
//
	COM_ForceExtension (name, ".qwd");

	cls.demofile = fopen (name, "wb");
	if (!cls.demofile)
	{
		Com_Printf ("ERROR: couldn't open.\n");
		return;
	}

	Com_Printf ("recording to %s.\n", name);

	if (cls.state == ca_active)
		CL_Record ();
	else
		cls.demorecording = true;
}
Esempio n. 4
0
/*
================
CL_ParseSnapshot

If the snapshot is parsed properly, it will be copied to
cl.snap and saved in cl.snapshots[].  If the snapshot is invalid
for any reason, no changes to the state will be made at all.
================
*/
void CL_ParseSnapshot( msg_t *msg )
{
	int          len;
	clSnapshot_t *old;
	clSnapshot_t newSnap;
	int          deltaNum;
	int          oldMessageNum;
	int          i, packetNum;

	// get the reliable sequence acknowledge number
	// NOTE: now sent with all server to client messages
	//clc.reliableAcknowledge = MSG_ReadLong( msg );

	// read in the new snapshot to a temporary buffer
	// we will only copy to cl.snap if it is valid
	Com_Memset( &newSnap, 0, sizeof( newSnap ) );

	// we will have read any new server commands in this
	// message before we got to svc_snapshot
	newSnap.serverCommandNum = clc.serverCommandSequence;

	newSnap.serverTime = MSG_ReadLong( msg );

	// if we were just unpaused, we can only *now* really let the
	// change come into effect or the client hangs.
	cl_paused->modified = 0;

	newSnap.messageNum = clc.serverMessageSequence;

	deltaNum = MSG_ReadByte( msg );

	if ( !deltaNum )
	{
		newSnap.deltaNum = -1;
	}
	else
	{
		newSnap.deltaNum = newSnap.messageNum - deltaNum;
	}

	newSnap.snapFlags = MSG_ReadByte( msg );

	// If the frame is delta compressed from data that we
	// no longer have available, we must suck up the rest of
	// the frame, but not use it, then ask for a non-compressed
	// message
	if ( newSnap.deltaNum <= 0 )
	{
		newSnap.valid = qtrue; // uncompressed frame
		old = NULL;

		if ( clc.demorecording )
		{
			clc.demowaiting = qfalse; // we can start recording now
//          if(cl_autorecord->integer) {
//              Cvar_Set( "g_synchronousClients", "0" );
//          }
		}
		else
		{
			if ( cl_autorecord->integer /*&& Cvar_VariableValue( "g_synchronousClients") */ )
			{
				char    name[ 256 ];
				char    mapname[ MAX_QPATH ];
				char    *period;
				qtime_t time;

				Com_RealTime( &time );

				Q_strncpyz( mapname, cl.mapname, MAX_QPATH );

				for ( period = mapname; *period; period++ )
				{
					if ( *period == '.' )
					{
						*period = '\0';
						break;
					}
				}

				for ( period = mapname; *period; period++ )
				{
					if ( *period == '/' )
					{
						break;
					}
				}

				if ( *period )
				{
					period++;
				}

				Com_sprintf( name, sizeof( name ), "demos/%s_%04i-%02i-%02i_%02i%02i%02i.dm_%d", period,
				             1900 + time.tm_year, time.tm_mon + 1, time.tm_mday,
				             time.tm_hour, time.tm_min, time.tm_sec,
				             PROTOCOL_VERSION );

				CL_Record( name );
			}
		}
	}
	else
	{
		old = &cl.snapshots[ newSnap.deltaNum & PACKET_MASK ];

		if ( !old->valid )
		{
			// should never happen
			Com_Printf( "Delta from invalid frame (not supposed to happen!).\n" );
		}
		else if ( old->messageNum != newSnap.deltaNum )
		{
			// The frame that the server did the delta from
			// is too old, so we can't reconstruct it properly.
			Com_DPrintf( "Delta frame too old.\n" );
		}
		else if ( cl.parseEntitiesNum - old->parseEntitiesNum > MAX_PARSE_ENTITIES - 128 )
		{
			Com_DPrintf( "Delta parseEntitiesNum too old.\n" );
		}
		else
		{
			newSnap.valid = qtrue; // valid delta parse
		}
	}

	// read areamask
	len = MSG_ReadByte( msg );

	if ( len > sizeof( newSnap.areamask ) )
	{
		Com_Error( ERR_DROP, "CL_ParseSnapshot: Invalid size %d for areamask.", len );
	}

	MSG_ReadData( msg, &newSnap.areamask, len );

	// read playerinfo
	SHOWNET( msg, "playerstate" );

	if ( old )
	{
		MSG_ReadDeltaPlayerstate( msg, &old->ps, &newSnap.ps );
	}
	else
	{
		MSG_ReadDeltaPlayerstate( msg, NULL, &newSnap.ps );
	}

	// read packet entities
	SHOWNET( msg, "packet entities" );
	CL_ParsePacketEntities( msg, old, &newSnap );

	// if not valid, dump the entire thing now that it has
	// been properly read
	if ( !newSnap.valid )
	{
		return;
	}

	// clear the valid flags of any snapshots between the last
	// received and this one, so if there was a dropped packet
	// it won't look like something valid to delta from next
	// time we wrap around in the buffer
	oldMessageNum = cl.snap.messageNum + 1;

	if ( newSnap.messageNum - oldMessageNum >= PACKET_BACKUP )
	{
		oldMessageNum = newSnap.messageNum - ( PACKET_BACKUP - 1 );
	}

	for ( ; oldMessageNum < newSnap.messageNum; oldMessageNum++ )
	{
		cl.snapshots[ oldMessageNum & PACKET_MASK ].valid = qfalse;
	}

	// copy to the current good spot
	cl.snap = newSnap;
	cl.snap.ping = 999;

	// calculate ping time
	for ( i = 0; i < PACKET_BACKUP; i++ )
	{
		packetNum = ( clc.netchan.outgoingSequence - 1 - i ) & PACKET_MASK;

		if ( cl.snap.ps.commandTime >= cl.outPackets[ packetNum ].p_serverTime )
		{
			cl.snap.ping = cls.realtime - cl.outPackets[ packetNum ].p_realtime;
			break;
		}
	}

	// save the frame off in the backup array for later delta comparisons
	cl.snapshots[ cl.snap.messageNum & PACKET_MASK ] = cl.snap;

	if ( cl_shownet->integer == 3 )
	{
		Com_Printf( "   snapshot:%i  delta:%i  ping:%i\n", cl.snap.messageNum, cl.snap.deltaNum, cl.snap.ping );
	}

	cl.newSnapshots = qtrue;
}
Esempio n. 5
0
/*
====================
CL_EasyRecord_f

easyrecord [demoname]
====================
*/
void CL_EasyRecord_f (void)
{
	int		c;
	char	name[1024];
	char	name2[MAX_OSPATH*2];
	int		i;
	char	*p;
	FILE	*f;

	c = Cmd_Argc();
	if (c > 2)
	{
		Com_Printf ("easyrecord <demoname>\n");
		return;
	}

	if (cls.state != ca_active) {
		Com_Printf ("You must be connected to record.\n");
		return;
	}

	if (cls.demorecording)
		CL_Stop_f();

/// FIXME: check buffer sizes!!!

	if (c == 2)
		Q_snprintfz (name, sizeof(name), "%s", Cmd_Argv(1));
	else if (cl.spectator) {
		// FIXME: if tracking a player, use his name
		Q_snprintfz (name, sizeof(name), "spec_%s_%s",
			TP_PlayerName(),
			TP_MapName());
	} else {
		// guess game type and write demo name
		i = TP_CountPlayers();
		if (cl.teamplay && i >= 3)
		{
			// Teamplay
			Q_snprintfz (name, sizeof(name), "%s_%s_vs_%s_%s",
				TP_PlayerName(),
				TP_PlayerTeam(),
				TP_EnemyTeam(),
				TP_MapName());
		} else {
			if (i == 2) {
				// Duel
				Q_snprintfz (name, sizeof(name), "%s_vs_%s_%s",
					TP_PlayerName(),
					TP_EnemyName(),
					TP_MapName());
			}
			else if (i > 2) {
				// FFA
				Q_snprintfz (name, sizeof(name), "%s_ffa_%s",
					TP_PlayerName(), 
					TP_MapName());
			}
			else {
				// one player
				Q_snprintfz (name, sizeof(name), "%s_%s",
					TP_PlayerName(),
					TP_MapName());
			}
		}
	}

// Make sure the filename doesn't contain illegal characters
	for (p = name; *p; p++)	{
		char c;
		*p &= 0x7F;		// strip high bit
		c = *p;
		if (c <= ' ' || c == '?' || c == '*' || c == '\\' || c == '/' || c == ':'
			|| c == '<' || c == '>' || c == '"')
			*p = '_';
	}

	strlcpy (name, va("%s/%s", cls.gamedir, name), MAX_OSPATH);

// find a filename that doesn't exist yet
	strcpy (name2, name);
	COM_ForceExtension (name2, ".qwd");
	f = fopen (name2, "rb");
	if (f) {
		i = 0;
		do {
			fclose (f);
			strcpy (name2, va("%s_%02i", name, i));
			COM_ForceExtension (name2, ".qwd");
			f = fopen (name2, "rb");
			i++;
		} while (f);
	}

//
// open the demo file
//
	cls.demofile = fopen (name2, "wb");
	if (!cls.demofile)
	{
		Com_Printf ("ERROR: couldn't open.\n");
		return;
	}

	Com_Printf ("recording to %s.\n", name2);
	CL_Record ();
}