Пример #1
0
/*
* TV_Upstream_ParseServerData
*/
static void TV_Upstream_ParseServerData( upstream_t *upstream, msg_t *msg )
{
	int i, numpure;

	TV_Upstream_ClearState( upstream );

	upstream->state = CA_CONNECTED;

	// parse protocol version number
	i = MSG_ReadLong( msg );

	if( i != APP_PROTOCOL_VERSION )
		TV_Upstream_Error( upstream, "Server returned version %i, not %i", i, APP_PROTOCOL_VERSION );

	upstream->servercount = MSG_ReadLong( msg );
	upstream->snapFrameTime = (unsigned int) MSG_ReadShort( msg );

	Q_strncpyz( upstream->basegame, MSG_ReadString( msg ), sizeof( upstream->basegame ) );
	Q_strncpyz( upstream->game, MSG_ReadString( msg ), sizeof( upstream->game ) );

	// parse player entity number
	upstream->playernum = MSG_ReadShort( msg );

	// get the full level name
	Q_strncpyz( upstream->levelname, MSG_ReadString( msg ), sizeof( upstream->levelname ) );

	upstream->sv_bitflags = MSG_ReadByte( msg );
	upstream->reliable = ( ( upstream->sv_bitflags & SV_BITFLAGS_RELIABLE ) ? true : false );

	if( ( upstream->sv_bitflags & SV_BITFLAGS_HTTP ) != 0 ) {
		if( ( upstream->sv_bitflags & SV_BITFLAGS_HTTP_BASEURL ) != 0 ) {
			// read base upstream url
			MSG_ReadString( msg );
		}
		else {
			// http port number
			MSG_ReadShort( msg );
		}
	}
	
	// pure list

	// clean old, if necessary
	Com_FreePureList( &upstream->purelist );

	// add new
	numpure = MSG_ReadShort( msg );
	while( numpure > 0 )
	{
		const char *pakname = MSG_ReadString( msg );
		const unsigned checksum = MSG_ReadLong( msg );

		Com_AddPakToPureList( &upstream->purelist, pakname, checksum, upstream->mempool );

		numpure--;
	}

	TV_Upstream_AddReliableCommand( upstream, va( "configstrings %i 0", upstream->servercount ) );
}
Пример #2
0
/*
* TV_Relay_ParseServerData
*/
static void TV_Relay_ParseServerData( relay_t *relay, msg_t *msg )
{
	int i, numpure;

	TV_Relay_ClearState( relay );

	relay->state = CA_CONNECTED;
	relay->map_checksum = 0;

	// parse protocol version number
	i = MSG_ReadLong( msg );

	if( i != APP_PROTOCOL_VERSION )
		TV_Relay_Error( relay, "Server returned version %i, not %i", i, APP_PROTOCOL_VERSION );

	relay->servercount = MSG_ReadLong( msg );
	relay->snapFrameTime = (unsigned int)MSG_ReadShort( msg );

	Q_strncpyz( relay->basegame, MSG_ReadString( msg ), sizeof( relay->basegame ) );
	Q_strncpyz( relay->game, MSG_ReadString( msg ), sizeof( relay->game ) );

	// parse player entity number
	relay->playernum = MSG_ReadShort( msg );

	// get the full level name
	Q_strncpyz( relay->levelname, MSG_ReadString( msg ), sizeof( relay->levelname ) );

	relay->sv_bitflags = MSG_ReadByte( msg );

	// using upstream->reliable won't work for TV_Relay_ParseServerMessage
	// in case of reliable demo following unreliable demo, causing "clack message while reliable" error
	relay->reliable = ( ( relay->sv_bitflags & SV_BITFLAGS_RELIABLE ) ? qtrue : qfalse );

	// pure list

	// clean old, if necessary
	Com_FreePureList( &relay->purelist );

	// add new
	numpure = MSG_ReadShort( msg );
	while( numpure > 0 )
	{
		const char *pakname = MSG_ReadString( msg );
		const unsigned checksum = MSG_ReadLong( msg );

		Com_AddPakToPureList( &relay->purelist, pakname, checksum, relay->upstream->mempool );

		numpure--;
	}
}
Пример #3
0
/*
* SV_AddPurePak
*/
static void SV_AddPurePak( const char *pakname )
{
	if( !Com_FindPakInPureList( svs.purelist, pakname ) )
		Com_AddPakToPureList( &svs.purelist, pakname, FS_ChecksumBaseFile( pakname ), NULL );
}
Пример #4
0
/*
* CL_ParseServerData
*/
static void CL_ParseServerData( msg_t *msg )
{
	const char *str, *gamedir;
	int i, sv_bitflags, numpure;
	int http_portnum;

	Com_DPrintf( "Serverdata packet received.\n" );

	// wipe the client_state_t struct

	CL_ClearState();
	CL_SetClientState( CA_CONNECTED );

	// parse protocol version number
	i = MSG_ReadLong( msg );

	if( i != APP_PROTOCOL_VERSION )
		Com_Error( ERR_DROP, "Server returned version %i, not %i", i, APP_PROTOCOL_VERSION );

	cl.servercount = MSG_ReadLong( msg );
	cl.snapFrameTime = (unsigned int)MSG_ReadShort( msg );

	// set extrapolation time to half snapshot time
	Cvar_ForceSet( "cl_extrapolationTime", va( "%i", (unsigned int)( cl.snapFrameTime * 0.5 ) ) );
	cl_extrapolationTime->modified = qfalse;

	// base game directory
	str = MSG_ReadString( msg );
	if( !str || !str[0] )
		Com_Error( ERR_DROP, "Server sent an empty base game directory" );
	if( !COM_ValidateRelativeFilename( str ) || strchr( str, '/' ) )
		Com_Error( ERR_DROP, "Server sent an invalid base game directory: %s", str );
	if( strcmp( FS_BaseGameDirectory(), str ) )
	{
		Com_Error( ERR_DROP, "Server has different base game directory (%s) than the client (%s)", str,
			FS_BaseGameDirectory() );
	}

	// game directory
	str = MSG_ReadString( msg );
	if( !str || !str[0] )
		Com_Error( ERR_DROP, "Server sent an empty game directory" );
	if( !COM_ValidateRelativeFilename( str ) || strchr( str, '/' ) )
		Com_Error( ERR_DROP, "Server sent an invalid game directory: %s", str );
	gamedir = FS_GameDirectory();
	if( strcmp( str, gamedir ) )
	{
		// shutdown the cgame module first in case it is running for whatever reason
		// (happens on wswtv in lobby), otherwise precaches that are going to follow
		// will probably f**k up (like models trying to load before the world model)
		CL_GameModule_Shutdown();

		if( !FS_SetGameDirectory( str, qtrue ) )
			Com_Error( ERR_DROP, "Failed to load game directory set by server: %s", str );
		ML_Restart( qtrue );
	}

	// parse player entity number
	cl.playernum = MSG_ReadShort( msg );

	// get the full level name
	Q_strncpyz( cl.servermessage, MSG_ReadString( msg ), sizeof( cl.servermessage ) );

	sv_bitflags = MSG_ReadByte( msg );

	if( cls.demo.playing )
	{
		cls.reliable = ( sv_bitflags & SV_BITFLAGS_RELIABLE );
	}
	else
	{
		if( cls.reliable != ( ( sv_bitflags & SV_BITFLAGS_RELIABLE ) != 0 ) )
			Com_Error( ERR_DROP, "Server and client disagree about connection reliability" );
	}

	// builting HTTP server port
	if( cls.httpbaseurl ) {
		Mem_Free( cls.httpbaseurl );
		cls.httpbaseurl = NULL;
	}

	if( ( sv_bitflags & SV_BITFLAGS_HTTP ) != 0 ) {
		if( ( sv_bitflags & SV_BITFLAGS_HTTP_BASEURL ) != 0 ) {
			// read base upstream url
			cls.httpbaseurl = ZoneCopyString( MSG_ReadString( msg ) );
		}
		else {
			http_portnum = MSG_ReadShort( msg ) & 0xffff;
			cls.httpaddress = cls.serveraddress;
			if( cls.httpaddress.type == NA_IP6 ) {
				cls.httpaddress.address.ipv6.port = BigShort( http_portnum );
			} else {
				cls.httpaddress.address.ipv4.port = BigShort( http_portnum );
			}
			if( http_portnum ) {
				if( cls.httpaddress.type == NA_LOOPBACK ) {
					cls.httpbaseurl = ZoneCopyString( va( "http://localhost:%hu/", http_portnum ) );
				}
				else {
					cls.httpbaseurl = ZoneCopyString( va( "http://%s/", NET_AddressToString( &cls.httpaddress ) ) );
				}
			}
		}
	}

	// pure list

	// clean old, if necessary
	Com_FreePureList( &cls.purelist );

	// add new
	numpure = MSG_ReadShort( msg );
	while( numpure > 0 )
	{
		const char *pakname = MSG_ReadString( msg );
		const unsigned checksum = MSG_ReadLong( msg );

		Com_AddPakToPureList( &cls.purelist, pakname, checksum, NULL );

		numpure--;
	}

	//assert( numpure == 0 );

	// get the configstrings request
	CL_AddReliableCommand( va( "configstrings %i 0", cl.servercount ) );

	cls.sv_pure = ( sv_bitflags & SV_BITFLAGS_PURE ) != 0;
	cls.sv_tv = ( sv_bitflags & SV_BITFLAGS_TVSERVER ) != 0;

#ifdef PURE_CHEAT
	cls.sv_pure = qfalse;
#endif

	// separate the printfs so the server message can have a color
	Com_Printf( S_COLOR_WHITE "\n" "=====================================\n" );
	Com_Printf( S_COLOR_WHITE "%s\n\n", cl.servermessage );
}