| 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 | |
|---|
| | 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 | |
|---|
| 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]; |
|---|
| 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]; |
|---|
| 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]; |
|---|
| 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]; |
|---|
| 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 | |
|---|