⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clusterfacereceiver.mm

📁 lumaqq
💻 MM
字号:
/* * LumaQQ - Cross platform QQ client, special edition for Mac * * Copyright (C) 2007 luma <stubma@163.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#import "ClusterFaceReceiver.h"#import "QQClientDelegate.h"#import "Connection.h"#import "ByteTool.h"#import "QQClient.h"#import "RequestFaceReplyPacket.h"#import "RequestBeginReplyPacket.h"@implementation ClusterFaceReceiver- (void) dealloc {	[m_client release];	[m_faceLists release];	[m_buffer release];	[m_fragmentCache release];	if(m_imageInfoPacket)		[m_imageInfoPacket release];	[super dealloc];}- (id)initWithClient:(QQClient*)client {	self = [super init];	if(self) {		m_client = [client retain];		m_faceLists = [[NSMutableArray array] retain];		m_buffer = [[NSMutableData data] retain];		m_fragmentCache = [[NSMutableDictionary dictionary] retain];		m_connectionId = -1;		m_receiving = NO;		m_currentFace = -1;		m_expectedConnectionId = -1;	}	return self;}#pragma mark -#pragma mark API- (void)addCustomFaceList:(CustomFaceList*)faceList {	[m_faceLists addObject:faceList];	[self receiveNextFace];}- (void)reset {	m_receiving = NO;	m_currentFace = -1;	m_connectionId = -1;	[m_faceLists removeAllObjects];}#pragma mark -#pragma mark helper- (void)receiveNextFace {	// check flag	if(m_receiving)		return;	m_receiving = YES;		// check next face list array	if([m_faceLists count] == 0) {		m_receiving = NO;		return;	}		// get current face list to first	CustomFaceList* list = [m_faceLists objectAtIndex:0];		// get next face need to be received	id delegate = [m_client delegate];	CustomFace* face = nil;		while(face == nil || [face isReference] || (delegate != nil && ![delegate shouldReceiveCustomFace:face])) {		// get next face		m_currentFace++;		while(m_currentFace >= [list count]) {			m_currentFace = 0;			[m_faceLists removeObjectAtIndex:0];			if([m_faceLists count] == 0) {				m_currentFace = -1;				break;			} else				list = [m_faceLists objectAtIndex:0];		}				// if -1, no more, if not, get face object		if(m_currentFace == -1) 			break;		else			face = [list face:m_currentFace includeReference:YES];	}		// if still -1, return	if(m_currentFace == -1) {		m_receiving = NO;		return;	}		// check connection	if(m_connectionId == -1)		[self createConnection];	else {		// get current connection		Connection* conn = [m_client getConnection:m_connectionId];				// get face agent ip string		NSString* agentIp = [ByteTool ip2String:[face serverIp]];				// compare ip, if not same, release connection		if([agentIp isEqualToString:[conn server]])			[m_client requestFace:m_connectionId sessionId:[face sessionId] owner:[face owner] encryptKey:[face fileAgentKey]];		else			[self releaseConnection];	}}- (void)createConnection {	// check id	if(m_connectionId != -1)		return;		// get face object	CustomFace* face = [self getCurrentFace];	NSAssert(face != nil, @"face should not nil");		// get new connection	Connection* conn = [[m_client mainConnection] copyWithNewAddress:[ByteTool ip2String:[face serverIp]]];	[conn setPort:[NSNumber numberWithInt:[face serverPort]]];	[conn setAdvisorId:[NSNumber numberWithInt:kQQFamilyAgent]];	m_expectedConnectionId = [[conn connectionId] intValue];		// new connection	[m_client newConnection:conn];}- (void)releaseConnection {	// check id	if(m_connectionId == -1)		return;		[m_client releaseConnection:m_connectionId];}- (CustomFace*)getCurrentFace {	if(m_currentFace == -1 || [m_faceLists count] == 0)		return nil;	CustomFaceList* list = [m_faceLists objectAtIndex:0];	CustomFace* face = [list face:m_currentFace includeReference:YES];	return face;}#pragma mark -#pragma mark qq event handler- (BOOL)handleQQEvent:(QQNotification*)event {	BOOL ret = NO;		switch([event eventId]) {		case kQQEventNetworkError:			ret = [self handleNetworkError:event];			break;		case kQQEventNetworkConnectionEstablished:			ret = [self handleConnectionEstablished:event];			break;		case kQQEventNetworkConnectionReleased:			ret = [self handleConnectionReleased:event];			break;		case kQQEventRequestBeginOK:			ret = [self handleRequestBeginOK:event];			break;		case kQQEventRequestFaceOK:			ret = [self handleRequestFaceOK:event];			break;		case kQQEventImageDataReceived:			ret = [self handleReceivedImageData:event];			break;		case kQQEventImageInfoReceived:			ret = [self handleReceivedImageInfo:event];			break;		case kQQEventTimeoutAgent:			ret = [self handleTimeout:event];			break;	}		return ret;}- (BOOL)handleTimeout:(QQNotification*)event {	if(m_connectionId = [event connectionId]) {		// if currently a face is in transfer, then restart		if(m_currentFace != -1) {			// call delegate			if([m_client delegate])				[[m_client delegate] customFaceFailedToReceive:[self getCurrentFace]];						// receive next			m_receiving = NO;			[self receiveNextFace];		}				return YES;	}		return NO;}- (BOOL)handleNetworkError:(QQNotification*)event {	if([event connectionId] == m_connectionId) {		// set id		m_connectionId = -1;				// if currently a face is in transfer, then restart		if(m_currentFace != -1) {			// call delegate			if([m_client delegate])				[[m_client delegate] customFaceFailedToReceive:[self getCurrentFace]];						// receive next			m_receiving = NO;			[self receiveNextFace];		}				return YES;	}	return NO;}- (BOOL)handleRequestFaceOK:(QQNotification*)event {	if([event connectionId] == m_connectionId) {		RequestFaceReplyPacket* packet = (RequestFaceReplyPacket*)[event object];		if([packet unknown] != 0) {			// call delegate			if([m_client delegate])				[[m_client delegate] customFaceFailedToReceive:[self getCurrentFace]];						// receive next			m_receiving = NO;			[self receiveNextFace];		}		return YES;	}		return NO;}- (BOOL)handleConnectionEstablished:(QQNotification*)event {	if(m_expectedConnectionId == [event connectionId]) {		// save connection id		m_connectionId = [event connectionId];		m_expectedConnectionId = -1;				// get current face		CustomFace* face = [self getCurrentFace];		NSAssert(face != nil, @"face should not nil");				// request face		[m_client requestFace:m_connectionId sessionId:[face sessionId] owner:[face owner] encryptKey:[face fileAgentKey]];				return YES;	}		return NO;}- (BOOL)handleConnectionReleased:(QQNotification*)event {	if([event connectionId] == m_connectionId) {		// set id to -1		m_connectionId = -1;				// if has face to send, create connection		if(m_currentFace != -1) {			// call delegate			if([m_client delegate])				[[m_client delegate] customFaceFailedToReceive:[self getCurrentFace]];						m_receiving = NO;			[self receiveNextFace];		}		return YES;	}		return NO;}- (BOOL)handleRequestBeginOK:(QQNotification*)event {	if([event connectionId] == m_connectionId) {		RequestBeginReplyPacket* packet = (RequestBeginReplyPacket*)[event object];		[m_client requestData:m_connectionId sessionId:[packet sessionId]];		return YES;	}	return NO;}- (BOOL)handleReceivedImageInfo:(QQNotification*)event {	if([event connectionId] == m_connectionId) {		CustomFace* face = [self getCurrentFace];		NSAssert(face != nil, @"Face shouldn't be nil");				// save packet		m_imageInfoPacket = [[event object] retain];		m_imageSize = [m_imageInfoPacket imageSize];		m_receivedPacket = 0;				// initialize		[m_buffer setLength:0];		[m_fragmentCache removeAllObjects];		m_nextFragmentIndex = 1;				// request begin		[m_client requestReceiveBegin:m_connectionId							sessionId:[m_imageInfoPacket sessionId]						 transferType:kQQAgentReceive						   encryptKey:[face fileAgentKey]];		return YES;	}	return NO;}- (BOOL)handleReceivedImageData:(QQNotification*)event {	if([event connectionId] == m_connectionId) {		// get packet		ServerTransferPacket* packet = (ServerTransferPacket*)[[event object] retain];		UInt32 sessionId = [packet sessionId];		m_receivedPacket++;				if([packet sequence] % 10 == 0)			[m_client replyTransferData:m_connectionId sessionId:sessionId];				// check fragment index		if([packet sequence] != m_nextFragmentIndex) {			[m_fragmentCache setObject:packet forKey:[NSNumber numberWithInt:[packet sequence]]];			[packet release];						return YES;		} else {			// append data			do {				[packet release];				NSData* data = [packet imageData];				[m_buffer appendData:data];				m_imageSize -= [data length];								m_nextFragmentIndex++;				NSNumber* key = [NSNumber numberWithInt:m_nextFragmentIndex];				packet = [m_fragmentCache objectForKey:key];				if(packet) {					[packet retain];					[m_fragmentCache removeObjectForKey:key];				}								} while(packet);						// if already received all image data, notify delegate			if(m_imageSize <= 0) {				// last reply				[m_client replyTransferData:m_connectionId sessionId:sessionId];				m_receivedPacket = 0;								// get face object				CustomFace* face = [self getCurrentFace];				NSAssert(face != nil, @"Face shouldn't be nil");									// delegate				if([m_client delegate])					[[m_client delegate] customFaceDidReceived:face data:m_buffer];								// receive next face				m_receiving = NO;				[self receiveNextFace];			}		}				return YES;	}	return NO;}@end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -