Changeset 3584

Show
Ignore:
Timestamp:
02/21/07 09:42:42 (2 years ago)
Author:
timothy
Message:

Allow plugins to work on incoming and outgoing messages as NSData before they get processed by Colloquy. This allows support for encryption plugins. Patch by hennk. Fixes #1005

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Chat Core/MVChatConnection.h

    r3582 r3584  
    407407 
    408408@interface NSObject (MVChatPluginConnectionSupport) 
     409- (void) processIncomingMessageAsData:(NSMutableData *) message from:(MVChatUser *) sender to:(id) receiver isNotice:(BOOL) notice; 
     410- (void) processOutgoingMessageAsData:(NSMutableData *) message to:(id) receiver; 
     411 
    409412- (BOOL) processSubcodeRequest:(NSString *) command withArguments:(NSData *) arguments fromUser:(MVChatUser *) user; 
    410413- (BOOL) processSubcodeReply:(NSString *) command withArguments:(NSData *) arguments fromUser:(MVChatUser *) user; 
  • trunk/Chat Core/MVICBChatUser.m

    r3582 r3584  
    7171         withEncoding:(NSStringEncoding) encoding 
    7272                 asAction:(BOOL) action { 
    73         [_connection ctsCommandPersonal:_nickname withMessage:[message string]]; 
     73        [(MVICBChatConnection *)_connection ctsCommandPersonal:_nickname withMessage:[message string]]; 
    7474} 
    7575 
  • trunk/Chat Core/MVIRCChatConnection.h

    r3543 r3584  
    4646         
    4747+ (NSData *) _flattenedIRCDataForMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) enc andChatFormat:(MVChatMessageFormat) format; 
    48 - (void) _sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding toTarget:(NSString *) target asAction:(BOOL) action; 
     48- (void) _sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) msgEncoding toTarget:(id) target asAction:(BOOL) action; 
    4949 
    5050- (void) _processErrorCode:(int) errorCode withContext:(char *) context; 
  • trunk/Chat Core/MVIRCChatConnection.m

    r3580 r3584  
    931931} 
    932932 
    933 - (void) _sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) msgEncoding toTarget:(NSString *) target asAction:(BOOL) action { 
    934         NSData *msg = [[self class] _flattenedIRCDataForMessage:message withEncoding:msgEncoding andChatFormat:[self outgoingChatFormat]]; 
     933- (void) _sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) msgEncoding toTarget:(id) target asAction:(BOOL) action { 
     934        NSParameterAssert( [target isKindOfClass:[MVChatUser class]] || [target isKindOfClass:[MVChatRoom class]] ); 
     935 
     936        NSMutableData *msg = [[[self class] _flattenedIRCDataForMessage:message withEncoding:msgEncoding andChatFormat:[self outgoingChatFormat]] mutableCopyWithZone:nil]; 
     937 
     938        NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( id ), nil]; 
     939        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 
     940        [invocation setSelector:@selector( processOutgoingMessageAsData:to: )]; 
     941        [invocation setArgument:&msg atIndex:2]; 
     942        [invocation setArgument:&target atIndex:3]; 
     943 
     944        [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation]; 
     945        if( ! [msg length] ) { 
     946                [msg release]; 
     947                return; 
     948        } 
     949 
     950        NSString *targetName = [target isKindOfClass:[MVChatRoom class]] ? [target name] : [target nickname]; 
     951 
    935952        if( action ) { 
    936                 NSString *prefix = [[NSString allocWithZone:nil] initWithFormat:@"PRIVMSG %@ :\001ACTION ", target]; 
     953                NSString *prefix = [[NSString allocWithZone:nil] initWithFormat:@"PRIVMSG %@ :\001ACTION ", targetName]; 
    937954                [self sendRawMessageWithComponents:prefix, msg, @"\001", nil]; 
    938955                [prefix release]; 
    939956        } else { 
    940                 NSString *prefix = [[NSString allocWithZone:nil] initWithFormat:@"PRIVMSG %@ :", target]; 
     957                NSString *prefix = [[NSString allocWithZone:nil] initWithFormat:@"PRIVMSG %@ :", targetName]; 
    941958                [self sendRawMessageWithComponents:prefix, msg, nil]; 
    942959                [prefix release]; 
    943960        } 
     961 
     962        [msg release]; 
    944963} 
    945964 
     
    14381457#pragma mark Incoming Message Replies 
    14391458 
     1459- (void) _handlePrivmsg:(NSDictionary *) privmsgInfo { 
     1460        MVAssertMainThreadRequired(); 
     1461 
     1462        MVChatRoom *room = [privmsgInfo objectForKey:@"room"]; 
     1463        MVChatUser *sender = [privmsgInfo objectForKey:@"user"]; 
     1464        NSMutableData *message = [privmsgInfo objectForKey:@"message"]; 
     1465        BOOL isNotice = NO; 
     1466 
     1467        NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( MVChatUser * ), @encode( id ), @encode( BOOL ), nil]; 
     1468        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 
     1469        [invocation setSelector:@selector( processIncomingMessageAsData:from:to:isNotice: )]; 
     1470        [invocation setArgument:&message atIndex:2]; 
     1471        [invocation setArgument:&sender atIndex:3]; 
     1472        [invocation setArgument:&room atIndex:4]; 
     1473        [invocation setArgument:&isNotice atIndex:5]; 
     1474 
     1475        [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation]; 
     1476        if( ! [message length] ) return; 
     1477 
     1478        if( room ) { 
     1479                [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomGotMessageNotification object:room userInfo:privmsgInfo]; 
     1480        } else { 
     1481                [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotPrivateMessageNotification object:sender userInfo:privmsgInfo]; 
     1482        } 
     1483} 
     1484 
    14401485- (void) _handlePrivmsgWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { 
    14411486        MVAssertCorrectThreadRequired( _connectionThread ); 
     
    14671512                [self _markUserAsOnline:sender]; 
    14681513 
    1469                 if( [[self chatRoomNamePrefixes] characterIsMember:[targetName characterAtIndex:0]] ) { 
    1470                         MVChatRoom *room = [self joinedChatRoomWithName:targetName]; 
    1471                         if( ctcp ) [self _handleCTCP:msgData asRequest:YES fromSender:sender forRoom:room]; 
    1472                         else [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatRoomGotMessageNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:sender, @"user", msgData, @"message", [NSString locallyUniqueString], @"identifier", nil]]; 
     1514                MVChatRoom *room = nil; 
     1515                if( [[self chatRoomNamePrefixes] characterIsMember:[targetName characterAtIndex:0]] ) 
     1516                        room = [self joinedChatRoomWithName:targetName]; 
     1517 
     1518                if( ctcp ) { 
     1519                        [self _handleCTCP:msgData asRequest:YES fromSender:sender forRoom:room]; 
    14731520                } else { 
    1474                         if( ctcp ) [self _handleCTCP:msgData asRequest:YES fromSender:sender forRoom:nil]; 
    1475                         else [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionGotPrivateMessageNotification object:sender userInfo:[NSDictionary dictionaryWithObjectsAndKeys:msgData, @"message", [NSString locallyUniqueString], @"identifier", nil]]; 
     1521                        NSDictionary *privmsgInfo = [NSDictionary dictionaryWithObjectsAndKeys:msgData, @"message", sender, @"user", [NSString locallyUniqueString], @"identifier", room, @"room", nil]; 
     1522                        [self performSelectorOnMainThread:@selector( _handlePrivmsg: ) withObject:privmsgInfo waitUntilDone:NO]; 
     1523                } 
     1524        } 
     1525
     1526 
     1527- (void) _handleNotice:(NSDictionary *) noticeInfo { 
     1528        MVAssertMainThreadRequired(); 
     1529 
     1530        MVChatRoom *room = [noticeInfo objectForKey:@"room"]; 
     1531        MVChatUser *sender = [noticeInfo objectForKey:@"user"]; 
     1532        NSMutableData *message = [noticeInfo objectForKey:@"message"]; 
     1533        BOOL isNotice = YES; 
     1534 
     1535        NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( MVChatUser * ), @encode( id ), @encode( BOOL ), nil]; 
     1536        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 
     1537        [invocation setSelector:@selector( processIncomingMessageAsData:from:to:isNotice: )]; 
     1538        [invocation setArgument:&message atIndex:2]; 
     1539        [invocation setArgument:&sender atIndex:3]; 
     1540        [invocation setArgument:&room atIndex:4]; 
     1541        [invocation setArgument:&isNotice atIndex:5]; 
     1542 
     1543        [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation]; 
     1544        if( ! [message length] ) return; 
     1545 
     1546        if( room ) { 
     1547                [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomGotMessageNotification object:room userInfo:noticeInfo]; 
     1548        } else { 
     1549                [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotPrivateMessageNotification object:sender userInfo:noticeInfo]; 
     1550 
     1551                if( [[sender nickname] isEqualToString:@"NickServ"] ) { 
     1552                        NSString *msg = [self _newStringWithBytes:[message bytes] length:[message length]]; 
     1553 
     1554                        if( [msg hasCaseInsensitiveSubstring:@"NickServ"] && [msg hasCaseInsensitiveSubstring:@"IDENTIFY"] ) { 
     1555                                if( ! [self nicknamePassword] ) { 
     1556                                        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionNeedNicknamePasswordNotification object:self userInfo:nil]; 
     1557                                } else [self sendRawMessageImmediatelyWithFormat:@"NickServ IDENTIFY %@", [self nicknamePassword]]; 
     1558                        } else if( [msg hasCaseInsensitiveSubstring:@"password accepted"] ) { 
     1559                                [[self localUser] _setIdentified:YES]; 
     1560                        } else if( [msg hasCaseInsensitiveSubstring:@"authentication required"] || [msg hasCaseInsensitiveSubstring:@"nickname is owned"] ) { 
     1561                                [[self localUser] _setIdentified:NO]; 
     1562                        } 
     1563 
     1564                        [msg release]; 
    14761565                } 
    14771566        } 
     
    15041593                BOOL ctcp = ( *bytes == '\001' && [msgData length] > 2 ); 
    15051594 
    1506                 if( [[self chatRoomNamePrefixes] characterIsMember:[targetName characterAtIndex:0]] ) { 
    1507                         MVChatRoom *room = [self joinedChatRoomWithName:targetName]; 
    1508                         if( ctcp ) [self _handleCTCP:msgData asRequest:NO fromSender:sender forRoom:room]; 
    1509                         else [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatRoomGotMessageNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:sender, @"user", msgData, @"message", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"notice", nil]]; 
     1595                MVChatRoom *room = nil; 
     1596                if( [[self chatRoomNamePrefixes] characterIsMember:[targetName characterAtIndex:0]] ) 
     1597                        room = [self joinedChatRoomWithName:targetName]; 
     1598 
     1599                if ( ctcp ) { 
     1600                        [self _handleCTCP:msgData asRequest:NO fromSender:sender forRoom:room]; 
    15101601                } else { 
    1511                         if( ctcp ) [self _handleCTCP:msgData asRequest:NO fromSender:sender forRoom:nil]; 
    1512                         else { 
    1513                                 [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionGotPrivateMessageNotification object:sender userInfo:[NSDictionary dictionaryWithObjectsAndKeys:msgData, @"message", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"notice", nil]]; 
    1514                                 if( [[sender nickname] isEqualToString:@"NickServ"] ) { 
    1515                                         NSString *msg = [self _newStringWithBytes:[msgData bytes] length:[msgData length]]; 
    1516  
    1517                                         if( [msg hasCaseInsensitiveSubstring:@"NickServ"] && [msg hasCaseInsensitiveSubstring:@"IDENTIFY"] ) { 
    1518                                                 if( ! [self nicknamePassword] ) { 
    1519                                                         [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionNeedNicknamePasswordNotification object:self userInfo:nil]; 
    1520                                                 } else [self sendRawMessageImmediatelyWithFormat:@"NickServ IDENTIFY %@", [self nicknamePassword]]; 
    1521                                         } else if( [msg hasCaseInsensitiveSubstring:@"password accepted"] ) { 
    1522                                                 [[self localUser] _setIdentified:YES]; 
    1523                                         } else if( [msg hasCaseInsensitiveSubstring:@"authentication required"] || [msg hasCaseInsensitiveSubstring:@"nickname is owned"] ) { 
    1524                                                 [[self localUser] _setIdentified:NO]; 
    1525                                         } 
    1526  
    1527                                         [msg release]; 
    1528                                 } 
    1529                         } 
     1602                        NSDictionary *noticeInfo = [NSDictionary dictionaryWithObjectsAndKeys:msgData, @"message", sender, @"user", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"notice", room, @"room", nil]; 
     1603                        [self performSelectorOnMainThread:@selector( _handleNotice: ) withObject:noticeInfo waitUntilDone:NO]; 
    15301604                } 
    15311605        } 
     
    15551629        if( [command isCaseInsensitiveEqualToString:@"ACTION"] && arguments ) { 
    15561630                // special case ACTION and send it out like a message with the action flag 
    1557                 if( room ) [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatRoomGotMessageNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:sender, @"user", arguments, @"message", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"action", nil]]; 
    1558                 else [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionGotPrivateMessageNotification object:sender userInfo:[NSDictionary dictionaryWithObjectsAndKeys:arguments, @"message", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"action", nil]]; 
     1631                NSDictionary *msgInfo = [NSDictionary dictionaryWithObjectsAndKeys:[arguments mutableCopyWithZone:nil], @"message", sender, @"user", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"action", room, @"room", nil]; 
     1632                [self _handlePrivmsg:msgInfo]; // No need to explicitly call this on main thread, as we are already in it. 
     1633 
    15591634                [command release]; 
    15601635                [arguments release]; 
  • trunk/Chat Core/MVIRCChatRoom.m

    r3581 r3584  
    5656- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) msgEncoding asAction:(BOOL) action { 
    5757        NSParameterAssert( message != nil ); 
    58         [[self connection] _sendMessage:message withEncoding:msgEncoding toTarget:[self name] asAction:action]; 
     58        [[self connection] _sendMessage:message withEncoding:msgEncoding toTarget:self asAction:action]; 
    5959} 
    6060 
  • trunk/Chat Core/MVIRCChatUser.m

    r3541 r3584  
    4444- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action { 
    4545        NSParameterAssert( message != nil ); 
    46         [[self connection] _sendMessage:message withEncoding:encoding toTarget:[self nickname] asAction:action]; 
     46        [[self connection] _sendMessage:message withEncoding:encoding toTarget:self asAction:action]; 
    4747} 
    4848