Пример #1
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;
}
Пример #2
0
/*
* TV_Downstream_ClientConnect
*/
static bool TV_Downstream_ClientConnect( const socket_t *socket, const netadr_t *address, client_t *client,
											char *userinfo, int game_port, int challenge, bool tv_client )
{
	assert( socket );
	assert( address );
	assert( client );
	assert( userinfo );

	// it may actually happen that we reuse a client slot (same IP, same port),
	// which is "attached" to an active relay, so we need to notify the relay that client
	// isn't active anymore, otherwise it'll get confused after we set the client's state 
	// to CS_CONNECTING down below
	if( client->relay )
		TV_Relay_ClientDisconnect( client->relay, client );

	if( !TV_Lobby_CanConnect( client, userinfo ) )
		return false;

	TV_Lobby_ClientConnect( client );

	// the upstream is accepted, set up the client slot
	client->challenge = challenge; // save challenge for checksumming
	client->tv = (tv_client ? true : false);

	switch( socket->type )
	{
#ifdef TCP_ALLOW_TVCONNECT
	case SOCKET_TCP:
		client->reliable = true;
		client->individual_socket = true;
		client->socket = *socket;
		break;
#endif

	case SOCKET_UDP:
	case SOCKET_LOOPBACK:
		client->reliable = false;
		client->individual_socket = false;
		client->socket.open = false;
		break;

	default:
		assert( false );
	}

	TV_Downstream_ClientResetCommandBuffers( client, true );

	// reset timeouts
	client->lastPacketReceivedTime = tvs.realtime;
	client->lastconnect = tvs.realtime;

	// init the upstream
	client->state = CS_CONNECTING;

	if( client->individual_socket )
		Netchan_Setup( &client->netchan, &client->socket, address, game_port );
	else
		Netchan_Setup( &client->netchan, socket, address, game_port );

	// parse some info from the info strings
	Q_strncpyz( client->userinfo, userinfo, sizeof( client->userinfo ) );
	TV_Downstream_UserinfoChanged( client );

	Com_Printf( "%s" S_COLOR_WHITE " connected\n", client->name );

	return true;
}
Пример #3
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;
}