Пример #1
0
/*
* TV_Downstream_Begin_f
*/
static void TV_Downstream_Begin_f( client_t *client )
{
	if( client->state != CS_CONNECTED )
		return;

	// relay is not ready yet
	if( client->relay && client->relay->state < CA_ACTIVE )
		return;

	// handle the case of a level changing while a client was connecting
	if( atoi( Cmd_Argv( 1 ) ) != ( client->relay ? client->relay->servercount : tvs.lobby.spawncount ) )
	{
		TV_Downstream_SendServerCommand( client, "changing" );
		TV_Downstream_SendServerCommand( client, "reconnect" );
		return;
	}

	client->state = CS_SPAWNED;

	if( client->relay )
		TV_Relay_ClientBegin( client->relay, client );
	else
		TV_Lobby_ClientBegin( client );

	//TV_Downstream_SendChannelList( client );
}
Пример #2
0
/*
* TV_Relay_ReconnectClients
*/
void TV_Relay_ReconnectClients( relay_t *relay ) {
	int i;
	client_t *client;

	if( relay->state < CA_CONNECTED ) {
		return;
	}

	relay->state = CA_HANDSHAKE;

	// send a message to each connected client
	for( i = 0, client = tvs.clients; i < tv_maxclients->integer; i++, client++ ) {
		if( client->relay != relay ) {
			continue;
		}

		// needs to reconnect
		if( client->state > CS_CONNECTING ) {
			client->state = CS_CONNECTING;
		}

		client->lastframe = -1;
		memset( client->gameCommands, 0, sizeof( client->gameCommands ) );

		TV_Downstream_SendServerCommand( client, "changing" );
	}

	TV_Relay_SendClientMessages( relay );

	// send a message to each connected client
	for( i = 0, client = tvs.clients; i < tv_maxclients->integer; i++, client++ ) {
		if( client->relay != relay ) {
			continue;
		}
		if( client->state < CS_CONNECTING ) {
			continue;
		}

		TV_Downstream_SendServerCommand( client, "reconnect" );
	}
}
Пример #3
0
/*
* TV_Module_ConfigString
*/
static void TV_Module_ConfigString( relay_t *relay, int index, const char *val )
{
	size_t len;

	if( !relay )
	{
		Com_Printf( "Error: TV_Module_ConfigString: Relay not set\n" );
		return;
	}

	if( !val )
		TV_Relay_Error( relay, "TV_Module_ConfigString: No value" );

	if( index < 0 || index >= MAX_CONFIGSTRINGS )
		TV_Relay_Error( relay, "TV_Module_ConfigString: Bad index" );

	len = strlen( val );
	if( len >= sizeof( relay->configstrings[0] ) )
	{
		Com_Printf( "WARNING: 'TV_Module_ConfigString', configstring %i overflowed (%i)\n", index, len );
		len = sizeof( relay->configstrings[0] ) - 1;
	}

	if( !COM_ValidateConfigstring( val ) )
	{
		Com_Printf( "WARNING: 'TV_Module_ConfigString' invalid configstring %i: %s\n", index, val );
		return;
	}

	// ignore if no changes
	if( !strncmp( relay->configstrings[index], val, len ) && relay->configstrings[index][len] == '\0' )
		return;

	// change the string in sv
	Q_strncpyz( relay->configstrings[index], val, sizeof( relay->configstrings[index] ) );

	{
		// We have to manually broadcast this one.
		client_t *client;
		int i;
		for( i = 0, client = tvs.clients; i < tv_maxclients->integer; i++, client++ )
		{
			if( client->state < CS_CONNECTED )
				continue;
			if( client->relay != relay )
				continue;
			TV_Downstream_SendServerCommand( client, "cs %i \"%s\"", index, val );
		}
	}
}
Пример #4
0
/*
* TV_Downstream_ChangeStream
*/
qboolean TV_Downstream_ChangeStream( client_t *client, relay_t *relay )
{
	relay_t *oldrelay;

	assert( client );

	oldrelay = client->relay;

	if( relay )
	{
		if( !TV_Relay_CanConnect( relay, client, client->userinfo ) )
			return qfalse;
	}
	else
	{
		if( !TV_Lobby_CanConnect( client, client->userinfo ) )
			return qfalse;
	}

	if( oldrelay )
		TV_Relay_ClientDisconnect( oldrelay, client );
	else
		TV_Lobby_ClientDisconnect( client );

	TV_Downstream_ClientResetCommandBuffers( client, qfalse );

	if( relay )
		TV_Relay_ClientConnect( relay, client );
	else
		TV_Lobby_ClientConnect( client );

	TV_Downstream_SendServerCommand( client, "changing" );
	TV_Downstream_SendServerCommand( client, "reconnect" );
	client->state = CS_CONNECTED;

	return qtrue;
}
Пример #5
0
/*
* TV_Downstream_DenyDownload
* Helper function for generating initdownload packets for denying download
*/
static void TV_Downstream_DenyDownload( client_t *client, const char *reason )
{
	msg_t message;
	uint8_t messageData[MAX_MSGLEN];

	assert( client );
	assert( reason && reason[0] );

	// size -1 is used to signal that it's refused
	// URL field is used for deny reason
	TV_Downstream_InitClientMessage( client, &message, messageData, sizeof( messageData ) );
	TV_Downstream_SendServerCommand( client, "initdownload \"%s\" %i %u %i \"%s\"", "", -1, 0, false, reason );
	TV_Downstream_AddReliableCommandsToMessage( client, &message );
	TV_Downstream_SendMessageToClient( client, &message );
}
Пример #6
0
/*
* TV_Downstream_DropClient
*/
void TV_Downstream_DropClient( client_t *drop, int type, const char *format, ... )
{
	va_list	argptr;
	char string[1024];
	msg_t Message;
	qbyte MessageData[MAX_MSGLEN];

	va_start( argptr, format );
	Q_vsnprintfz( string, sizeof( string ), format, argptr );
	va_end( argptr );

	Com_Printf( "%s" S_COLOR_WHITE " dropped: %s\n", drop->name, string );

	TV_Downstream_InitClientMessage( drop, &Message, MessageData, sizeof( MessageData ) );

	TV_Downstream_SendServerCommand( drop, "disconnect %i \"%s\"", type, string );
	TV_Downstream_AddReliableCommandsToMessage( drop, &Message );

	TV_Downstream_SendMessageToClient( drop, &Message );
	Netchan_PushAllFragments( &drop->netchan );

	if( drop->relay && /*drop->relay->state == CA_ACTIVE && */drop->state >= CS_CONNECTING )
		TV_Relay_ClientDisconnect( drop->relay, drop );

	// make sure everything is clean
	TV_Downstream_ClientResetCommandBuffers( drop, qtrue );

	SNAP_FreeClientFrames( drop );

	if( drop->download.name )
	{
		if( drop->download.data )
		{
			FS_FreeBaseFile( drop->download.data );
			drop->download.data = NULL;
		}

		Mem_ZoneFree( drop->download.name );
		drop->download.name = NULL;

		drop->download.size = 0;
		drop->download.timeout = 0;
	}

	if( drop->individual_socket )
		NET_CloseSocket( &drop->socket );

	if( drop->mv )
	{
		tvs.nummvclients--;
		drop->mv = qfalse;
	}

	memset( &drop->flood, 0, sizeof( drop->flood ) );

	drop->edict = NULL;
	drop->relay = NULL;
	drop->tv = qfalse;
	drop->state = CS_ZOMBIE;    // become free in a few seconds
	drop->name[0] = 0;
}
Пример #7
0
/*
* TV_Downstream_Baselines_f
*/
static void TV_Downstream_Baselines_f( client_t *client )
{
	int start;
	entity_state_t nullstate;
	msg_t message;
	uint8_t messageData[MAX_MSGLEN];

	if( client->state != CS_CONNECTED )
		return;

	// relay is not ready yet
	if( client->relay && client->relay->state < CA_ACTIVE )
	{
		TV_Downstream_SendServerCommand( client, "reconnect" );
		return;
	}

	// handle the case of a level changing while a client was connecting
	if( atoi( Cmd_Argv( 1 ) ) != ( client->relay ? client->relay->servercount : tvs.lobby.spawncount ) )
	{
		TV_Downstream_New_f( client );
		return;
	}

	if( !client->relay )
	{
		TV_Downstream_SendServerCommand( client, "precache %i", tvs.lobby.spawncount );
		return;
	}

	start = atoi( Cmd_Argv( 2 ) );
	if( start < 0 )
		start = 0;

	memset( &nullstate, 0, sizeof( nullstate ) );

	// write a packet full of data
	TV_Downstream_InitClientMessage( client, &message, messageData, sizeof( messageData ) );

	while( message.cursize < FRAGMENT_SIZE * 3 && start < MAX_EDICTS )
	{
		if( client->relay->baselines[start].number )
		{
			MSG_WriteByte( &message, svc_spawnbaseline );
			MSG_WriteDeltaEntity( &nullstate, &client->relay->baselines[start], &message, true, true );
		}
		start++;
	}

	// send next command
	if( start == MAX_EDICTS )
	{
		TV_Downstream_SendServerCommand( client, "precache %i", client->relay->servercount );
	}
	else
	{
		TV_Downstream_SendServerCommand( client, "cmd baselines %i %i", client->relay->servercount, start );
	}

	TV_Downstream_AddReliableCommandsToMessage( client, &message );
	TV_Downstream_SendMessageToClient( client, &message );
}
Пример #8
0
/*
* TV_Downstream_Configstrings_f
*/
static void TV_Downstream_Configstrings_f( client_t *client )
{
	int start;

	// relay is not ready yet
	if( client->relay && client->relay->state < CA_ACTIVE )
	{
		TV_Downstream_SendServerCommand( client, "reconnect" );
		return;
	}

	if( client->state == CS_CONNECTING )
	{
		Com_DPrintf( "Start Configstrings() from %s\n", client->name );
		client->state = CS_CONNECTED;
	}
	else
	{
		Com_DPrintf( "Configstrings() from %s\n", client->name );
	}

	if( client->state != CS_CONNECTED )
	{
		Com_DPrintf( "configstrings not valid -- already spawned\n" );
		return;
	}

	// handle the case of a level changing while a client was connecting
	if( atoi( Cmd_Argv( 1 ) ) != ( client->relay ? client->relay->servercount : tvs.lobby.spawncount ) )
	{
		TV_Downstream_SendServerCommand( client, "reconnect" );
		return;
	}

	if( !client->relay )
	{
		TV_Downstream_SendServerCommand( client, "cs %i \"%s\"", CS_TVSERVER, "1" );
		TV_Downstream_SendServerCommand( client, "cs %i \"%s\"", CS_AUDIOTRACK, tv_lobbymusic->string );
		TV_Downstream_SendServerCommand( client, "cmd baselines %i 0", tvs.lobby.spawncount );
		return;
	}

	start = atoi( Cmd_Argv( 2 ) );
	if( start < 0 )
	{
		start = 0;
	}

	// write a packet full of data
	while( start < MAX_CONFIGSTRINGS &&
		client->reliableSequence - client->reliableAcknowledge < MAX_RELIABLE_COMMANDS - 8 )
	{
		//		if( start == CS_HOSTNAME )
		//			Com_Printf( "cs %s\n", client->relay->configstrings[start] );

		if( client->relay->configstrings[start][0] )
		{
			TV_Downstream_SendServerCommand( client, "cs %i \"%s\"", start, client->relay->configstrings[start] );
		}
		start++;
	}

	// send next command
	if( start == MAX_CONFIGSTRINGS )
	{
		TV_Downstream_SendServerCommand( client, "cmd baselines %i 0", client->relay->servercount );
	}
	else
	{
		TV_Downstream_SendServerCommand( client, "cmd configstrings %i %i", client->relay->servercount, start );
	}
}