Changeset 3543
- Timestamp:
- 01/07/07 17:09:41 (2 years ago)
- Files:
-
- trunk/Chat Core/MVDirectChatConnection.h (modified) (1 diff)
- trunk/Chat Core/MVDirectChatConnection.m (modified) (7 diffs)
- trunk/Chat Core/MVDirectChatConnectionPrivate.h (modified) (2 diffs)
- trunk/Chat Core/MVIRCChatConnection.h (modified) (2 diffs)
- trunk/Chat Core/MVIRCChatConnection.m (modified) (15 diffs)
- trunk/Chat Core/MVIRCFileTransfer.m (modified) (8 diffs)
- trunk/Panels/MVChatUserAdditions.m (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Chat Core/MVDirectChatConnection.h
r3539 r3543 30 30 NSHost *_host; 31 31 BOOL _passive; 32 BOOL _localRequest; 32 33 unsigned short _port; 34 unsigned int _passiveId; 33 35 MVChatUser *_user; 34 36 MVDirectChatConnectionStatus _status; 35 37 NSError *_lastError; 36 38 unsigned int _hash; 39 BOOL _releasing; 37 40 } 38 - (id) initWithUser:(MVChatUser *) user;41 + (id) directChatConnectionWithUser:(MVChatUser *) user passively:(BOOL) passive; 39 42 40 43 - (BOOL) isPassive; trunk/Chat Core/MVDirectChatConnection.m
r3542 r3543 4 4 #import "InterThreadMessaging.h" 5 5 #import "MVDirectClientConnection.h" 6 #import "MVIRCChatConnection.h" 6 7 #import "MVFileTransfer.h" 7 8 #import "MVChatUser.h" … … 23 24 24 25 @implementation MVDirectChatConnection 25 - (id) initWithUser:(MVChatUser *) chatUser { 26 if( ( self = [super init] ) ) { 27 _status = MVDirectChatConnectionHoldingStatus; 28 _encoding = NSUTF8StringEncoding; 29 _outgoingChatFormat = MVChatConnectionDefaultMessageFormat; 30 _user = [chatUser retain]; 31 _host = [[NSHost currentHost] retain]; 32 _passive = YES; 33 } 34 35 return self; 26 + (id) directChatConnectionWithUser:(MVChatUser *) user passively:(BOOL) passive { 27 static unsigned passiveId = 0; 28 29 MVDirectChatConnection *ret = [(MVDirectChatConnection *)[MVDirectChatConnection allocWithZone:nil] initWithUser:user]; 30 [ret _setLocalRequest:YES]; 31 [ret _setPassive:passive]; 32 33 if( passive ) { 34 if( ++passiveId > 999 ) passiveId = 1; 35 [ret _setPassiveIdentifier:passiveId]; 36 37 // register with the main connection so the passive reply can find the original 38 [(MVIRCChatConnection *)[user connection] _addDirectClientConnection:ret]; 39 40 [user sendSubcodeRequest:@"DCC" withArguments:[NSString stringWithFormat:@"CHAT chat 16843009 0 %lu", passiveId]]; 41 } else { 42 [ret initiate]; 43 } 44 45 return [ret autorelease]; 46 } 47 48 - (void) release { 49 if( ! _releasing && ( [self retainCount] - 1 ) == 1 ) { 50 _releasing = YES; 51 [(MVIRCChatConnection *)[[self user] connection] _removeDirectClientConnection:self]; 52 } 53 54 [super release]; 36 55 } 37 56 … … 91 110 [_directClientConnection setDelegate:self]; 92 111 93 if( [self isPassive] ) [_directClientConnection acceptConnectionOnFirstPortInRange:[MVFileTransfer fileTransferPortRange]]; 94 else [_directClientConnection connectToHost:[[self host] address] onPort:[self port]]; 112 if( _localRequest ) { 113 if( ! [self isPassive] ) [_directClientConnection acceptConnectionOnFirstPortInRange:[MVFileTransfer fileTransferPortRange]]; 114 else [_directClientConnection connectToHost:[[self host] address] onPort:[self port]]; 115 } else { 116 if( [self isPassive] ) [_directClientConnection acceptConnectionOnFirstPortInRange:[MVFileTransfer fileTransferPortRange]]; 117 else [_directClientConnection connectToHost:[[self host] address] onPort:[self port]]; 118 } 95 119 } 96 120 … … 176 200 177 201 [self _readNextMessage]; 202 203 // now that we are connected deregister with the connection 204 // do this last incase the connection is the last thing retaining us 205 [(MVIRCChatConnection *)[[self user] connection] _removeDirectClientConnection:self]; 178 206 } 179 207 … … 182 210 [self _setPort:port]; 183 211 184 [[self user] sendSubcodeRequest:@"DCC" withArguments:[NSString stringWithFormat:@"CHAT chat %@ %hu", address, [self port]]]; 212 if( [self isPassive] ) [[self user] sendSubcodeRequest:@"DCC" withArguments:[NSString stringWithFormat:@"CHAT chat %@ %hu %lu", address, [self port], [self _passiveIdentifier]]]; 213 else [[self user] sendSubcodeRequest:@"DCC" withArguments:[NSString stringWithFormat:@"CHAT chat %@ %hu", address, [self port]]]; 185 214 } 186 215 … … 241 270 242 271 @implementation MVDirectChatConnection (MVDirectChatConnectionPrivate) 272 - (id) initWithUser:(MVChatUser *) chatUser { 273 if( ( self = [super init] ) ) { 274 _status = MVDirectChatConnectionHoldingStatus; 275 _encoding = NSUTF8StringEncoding; 276 _outgoingChatFormat = MVChatConnectionDefaultMessageFormat; 277 _user = [chatUser retain]; 278 _host = [[NSHost currentHost] retain]; 279 } 280 281 return self; 282 } 283 243 284 - (void) _writeMessage:(NSData *) message { 244 285 MVAssertCorrectThreadRequired( [_directClientConnection connectionThread] ); … … 275 316 } 276 317 318 - (void) _setLocalRequest:(BOOL) localRequest { 319 _localRequest = localRequest; 320 } 321 322 - (void) _setPassiveIdentifier:(unsigned int) identifier { 323 _passiveId = identifier; 324 } 325 326 - (unsigned int) _passiveIdentifier { 327 return _passiveId; 328 } 329 277 330 - (void) _postError:(NSError *) error { 278 331 [self _setStatus:MVDirectChatConnectionErrorStatus]; trunk/Chat Core/MVDirectChatConnectionPrivate.h
r3539 r3543 2 2 3 3 @interface MVDirectChatConnection (MVDirectChatConnectionPrivate) 4 - (id) initWithUser:(MVChatUser *) user; 5 4 6 - (void) _writeMessage:(NSData *) message; 5 7 - (void) _readNextMessage; 8 6 9 - (void) _setStatus:(MVDirectChatConnectionStatus) status; 7 10 - (void) _setStartDate:(NSDate *) startDate; … … 9 12 - (void) _setPort:(unsigned short) port; 10 13 - (void) _setPassive:(BOOL) passive; 14 - (void) _setLocalRequest:(BOOL) localRequest; 15 - (void) _setPassiveIdentifier:(unsigned int) identifier; 16 - (unsigned int) _passiveIdentifier; 11 17 - (void) _postError:(NSError *) error; 12 18 @end trunk/Chat Core/MVIRCChatConnection.h
r3526 r3543 17 17 NSMutableDictionary *_knownUsers; 18 18 NSMutableSet *_pendingWhoisUsers; 19 NSMutableSet *_ fileTransfers;19 NSMutableSet *_directClientConnections; 20 20 NSMutableSet *_supportedFeatures; 21 21 NSMutableDictionary *_serverInformation; … … 52 52 - (void) _updateKnownUser:(MVChatUser *) user withNewNickname:(NSString *) nickname; 53 53 54 - (void) _add FileTransfer:(MVFileTransfer *) transfer;55 - (void) _remove FileTransfer:(MVFileTransfer *) transfer;54 - (void) _addDirectClientConnection:(id) connection; 55 - (void) _removeDirectClientConnection:(id) connection; 56 56 57 57 - (void) _setCurrentNickname:(NSString *) nickname; trunk/Chat Core/MVIRCChatConnection.m
r3539 r3543 131 131 [_chatConnection release]; 132 132 [_knownUsers release]; 133 [_ fileTransfers release];133 [_directClientConnections release]; 134 134 [_server release]; 135 135 [_currentNickname release]; … … 154 154 _connectionThread = nil; 155 155 _knownUsers = nil; 156 _ fileTransfers = nil;156 _directClientConnections = nil; 157 157 _server = nil; 158 158 _currentNickname = nil; … … 725 725 const char *end = line + len - 2; // minus the line endings 726 726 727 if( * ( line + len - 2 )!= '\x0D' )727 if( *end != '\x0D' ) 728 728 end = line + len - 1; // this server only uses \x0A for the message line ending, lets work with it 729 729 … … 1082 1082 #pragma mark - 1083 1083 1084 - (void) _add FileTransfer:(MVFileTransfer *) transfer{1085 if( ! _ fileTransfers )1086 _ fileTransfers = [[NSMutableSet allocWithZone:nil] initWithCapacity:5];1087 @synchronized( _ fileTransfers ) {1088 if( transfer ) [_fileTransfers addObject:transfer];1089 } 1090 } 1091 1092 - (void) _remove FileTransfer:(MVFileTransfer *) transfer{1093 @synchronized( _ fileTransfers ) {1094 if( transfer ) [_fileTransfers removeObject:transfer];1084 - (void) _addDirectClientConnection:(id) connection { 1085 if( ! _directClientConnections ) 1086 _directClientConnections = [[NSMutableSet allocWithZone:nil] initWithCapacity:5]; 1087 @synchronized( _directClientConnections ) { 1088 if( connection ) [_directClientConnections addObject:connection]; 1089 } 1090 } 1091 1092 - (void) _removeDirectClientConnection:(id) connection { 1093 @synchronized( _directClientConnections ) { 1094 if( connection ) [_directClientConnections removeObject:connection]; 1095 1095 } 1096 1096 } … … 1616 1616 1617 1617 if( [subCommand isCaseInsensitiveEqualToString:@"SEND"] ) { 1618 BOOL passive = NO; 1618 1619 NSString *address = nil; 1619 1620 int port = 0; … … 1624 1625 [scanner scanInt:&port]; 1625 1626 [scanner scanLongLong:&size]; 1627 1628 if( [scanner scanLongLong:&passiveId] ) 1629 passive = YES; 1626 1630 1627 1631 if( [address rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@".:"]].location == NSNotFound ) { … … 1631 1635 } 1632 1636 1633 NSHost *host = [NSHost hostWithAddress:address]; 1634 1635 if( [scanner scanLongLong:&passiveId] && port > 0 ) { 1637 if( passive && port > 0 ) { 1636 1638 // this is a passive reply, look up the original transfer 1637 1639 MVIRCUploadFileTransfer *transfer = nil; 1638 1640 1639 @synchronized( _ fileTransfers ) {1640 NSEnumerator *enumerator = [_ fileTransfers objectEnumerator];1641 @synchronized( _directClientConnections ) { 1642 NSEnumerator *enumerator = [_directClientConnections objectEnumerator]; 1641 1643 while( ( transfer = [enumerator nextObject] ) ) { 1642 1644 if( ! [transfer isUpload] ) … … 1652 1654 1653 1655 if( transfer ) { 1654 [transfer _setHost: host];1656 [transfer _setHost:[NSHost hostWithAddress:address]]; 1655 1657 [transfer _setPort:port]; 1656 1658 [transfer _setupAndStart]; … … 1659 1661 MVIRCDownloadFileTransfer *transfer = [(MVIRCDownloadFileTransfer *)[MVIRCDownloadFileTransfer allocWithZone:nil] initWithUser:sender]; 1660 1662 1661 if( port == 0 ) {1663 if( port == 0 && passive ) { 1662 1664 [transfer _setPassiveIdentifier:passiveId]; 1663 1665 [transfer _setPassive:YES]; 1666 } else { 1667 [transfer _setHost:[NSHost hostWithAddress:address]]; 1668 [transfer _setPort:port]; 1664 1669 } 1665 1670 … … 1668 1673 [transfer _setFileNameQuoted:quotedFileName]; 1669 1674 [transfer _setFinalSize:(unsigned long long)size]; 1670 [transfer _setHost:host];1671 [transfer _setPort:port];1672 1675 1673 1676 [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVDownloadFileTransferOfferNotification object:transfer]; 1674 1677 1675 [self _add FileTransfer:transfer];1678 [self _addDirectClientConnection:transfer]; 1676 1679 [transfer release]; 1677 1680 } … … 1688 1691 passive = YES; 1689 1692 1690 @synchronized( _ fileTransfers ) {1691 NSEnumerator *enumerator = [_ fileTransfers objectEnumerator];1693 @synchronized( _directClientConnections ) { 1694 NSEnumerator *enumerator = [_directClientConnections objectEnumerator]; 1692 1695 MVIRCDownloadFileTransfer *transfer = nil; 1693 1696 while( ( transfer = [enumerator nextObject] ) ) { … … 1722 1725 passive = YES; 1723 1726 1724 @synchronized( _ fileTransfers ) {1725 NSEnumerator *enumerator = [_ fileTransfers objectEnumerator];1727 @synchronized( _directClientConnections ) { 1728 NSEnumerator *enumerator = [_directClientConnections objectEnumerator]; 1726 1729 MVIRCUploadFileTransfer *transfer = nil; 1727 1730 while( ( transfer = [enumerator nextObject] ) ) { … … 1745 1748 } 1746 1749 } else if( [subCommand isCaseInsensitiveEqualToString:@"CHAT"] ) { 1750 BOOL passive = NO; 1747 1751 NSString *address = nil; 1748 1752 int port = 0; 1753 long long passiveId = 0; 1749 1754 1750 1755 [scanner scanUpToCharactersFromSet:whitespace intoString:&address]; 1751 1756 [scanner scanInt:&port]; 1757 1758 if( [scanner scanLongLong:&passiveId] ) 1759 passive = YES; 1752 1760 1753 1761 if( [address rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@".:"]].location == NSNotFound ) { … … 1757 1765 } 1758 1766 1759 NSHost *host = [NSHost hostWithAddress:address];1760 1761 1767 if( [fileName isCaseInsensitiveEqualToString:@"CHAT"] || [fileName isCaseInsensitiveEqualToString:@"C H A T"] ) { 1762 MVDirectChatConnection *directChatConnection = [(MVDirectChatConnection *)[MVDirectChatConnection allocWithZone:nil] initWithUser:sender]; 1763 [directChatConnection _setPassive:NO]; 1764 [directChatConnection _setHost:host]; 1765 [directChatConnection _setPort:port]; 1766 1767 [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVDirectChatConnectionOfferNotification object:directChatConnection userInfo:[NSDictionary dictionaryWithObjectsAndKeys:sender, @"user", nil]]; 1768 1769 [directChatConnection release]; 1768 if( passive && port > 0 ) { 1769 // this is a passive reply, look up the original chat request 1770 MVDirectChatConnection *directChat = nil; 1771 1772 @synchronized( _directClientConnections ) { 1773 NSEnumerator *enumerator = [_directClientConnections objectEnumerator]; 1774 while( ( directChat = [enumerator nextObject] ) ) { 1775 if( ! [directChat isPassive] ) 1776 continue; 1777 if( ! [[directChat user] isEqualToChatUser:sender] ) 1778 continue; 1779 if( [directChat _passiveIdentifier] == passiveId ) 1780 break; 1781 } 1782 } 1783 1784 if( directChat ) { 1785 [directChat _setHost:[NSHost hostWithAddress:address]]; 1786 [directChat _setPort:port]; 1787 [directChat initiate]; 1788 } 1789 } else { 1790 MVDirectChatConnection *directChatConnection = [(MVDirectChatConnection *)[MVDirectChatConnection allocWithZone:nil] initWithUser:sender]; 1791 1792 if( port == 0 && passive ) { 1793 [directChatConnection _setPassiveIdentifier:passiveId]; 1794 [directChatConnection _setPassive:YES]; 1795 } else { 1796 [directChatConnection _setHost:[NSHost hostWithAddress:address]]; 1797 [directChatConnection _setPort:port]; 1798 } 1799 1800 [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVDirectChatConnectionOfferNotification object:directChatConnection userInfo:[NSDictionary dictionaryWithObjectsAndKeys:sender, @"user", nil]]; 1801 1802 [self _addDirectClientConnection:directChatConnection]; 1803 [directChatConnection release]; 1804 } 1770 1805 } 1771 1806 } … … 1811 1846 passive = YES; 1812 1847 1813 @synchronized( _ fileTransfers ) {1814 NSEnumerator *enumerator = [[[_ fileTransfers copy] autorelease] objectEnumerator];1848 @synchronized( _directClientConnections ) { 1849 NSEnumerator *enumerator = [[[_directClientConnections copy] autorelease] objectEnumerator]; 1815 1850 MVIRCUploadFileTransfer *transfer = nil; 1816 1851 while( ( transfer = [enumerator nextObject] ) ) { trunk/Chat Core/MVIRCFileTransfer.m
r3539 r3543 28 28 [ret _setFileNameQuoted:( [fileName rangeOfString:@" "].location != NSNotFound )]; 29 29 30 [(MVIRCChatConnection *)[user connection] _add FileTransfer:ret];30 [(MVIRCChatConnection *)[user connection] _addDirectClientConnection:ret]; 31 31 32 32 if( passive ) { … … 48 48 if( ! _releasing && ( [self retainCount] - 1 ) == 1 ) { 49 49 _releasing = YES; 50 [(MVIRCChatConnection *)[[self user] connection] _remove FileTransfer:self];50 [(MVIRCChatConnection *)[[self user] connection] _removeDirectClientConnection:self]; 51 51 } 52 52 … … 77 77 78 78 - (void) cancel { 79 [(MVIRCChatConnection *)[[self user] connection] _removeFileTransfer:self];80 81 79 [self _setStatus:MVFileTransferStoppedStatus]; 82 80 … … 87 85 [old closeFile]; 88 86 [old release]; 87 88 // do this last incase the connection is the last thing retaining us 89 [(MVIRCChatConnection *)[[self user] connection] _removeDirectClientConnection:self]; 89 90 } 90 91 … … 104 105 // now that we are connected deregister with the connection 105 106 // do this last incase the connection is the last thing retaining us 106 [(MVIRCChatConnection *)[[self user] connection] _remove FileTransfer:self];107 [(MVIRCChatConnection *)[[self user] connection] _removeDirectClientConnection:self]; 107 108 } 108 109 … … 227 228 if( ! _releasing && ( [self retainCount] - 1 ) == 1 ) { 228 229 _releasing = YES; 229 [(MVIRCChatConnection *)[[self user] connection] _remove FileTransfer:self];230 [(MVIRCChatConnection *)[[self user] connection] _removeDirectClientConnection:self]; 230 231 } 231 232 … … 283 284 [old release]; 284 285 285 [(MVIRCChatConnection *)[[self user] connection] _removeFileTransfer:self]; 286 // do this last incase the connection is the last thing retaining us 287 [(MVIRCChatConnection *)[[self user] connection] _removeDirectClientConnection:self]; 286 288 } 287 289 … … 319 321 // now that we are connected deregister with the connection 320 322 // do this last incase the connection is the last thing retaining us 321 [(MVIRCChatConnection *)[[self user] connection] _remove FileTransfer:self];323 [(MVIRCChatConnection *)[[self user] connection] _removeDirectClientConnection:self]; 322 324 } 323 325 trunk/Panels/MVChatUserAdditions.m
r3539 r3543 116 116 - (IBAction) startDirectChat:(id) sender { 117 117 if( [self isLocalUser] ) return; 118 MVDirectChatConnection *connection = [(MVDirectChatConnection *)[MVDirectChatConnection alloc] initWithUser:self]; 118 119 BOOL passive = [[NSUserDefaults standardUserDefaults] boolForKey:@"JVSendFilesPassively"]; 120 MVDirectChatConnection *connection = [MVDirectChatConnection directChatConnectionWithUser:self passively:passive]; 119 121 [[JVChatController defaultController] chatViewControllerForDirectChatConnection:connection ifExists:NO]; 120 [connection initiate];121 [connection release];122 122 } 123 123
