| 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] autorelease]; |
| | 937 | |
| | 938 | |
| | 939 | NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( id ), nil]; |
| | 940 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; |
| | 941 | [invocation setSelector:@selector( processOutgoingMessageAsData:to: )]; |
| | 942 | [invocation setArgument:&msg atIndex:2]; |
| | 943 | [invocation setArgument:&target atIndex:3]; |
| | 944 | |
| | 945 | [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation]; |
| | 946 | if ([msg length] <= 0) |
| | 947 | return; |
| | 948 | |
| | 949 | |
| | 950 | NSString *targetName = [target isKindOfClass:[MVChatRoom class]] ? [target name] : [target nickname]; |
| | 951 | |
| | 1457 | - (void) _handlePrivmsg:(NSDictionary *)privmsgInfo { |
| | 1458 | MVAssertMainThreadRequired(); |
| | 1459 | |
| | 1460 | MVChatRoom *room = [privmsgInfo objectForKey:@"room"]; |
| | 1461 | MVChatUser *sender = [privmsgInfo objectForKey:@"user"]; |
| | 1462 | NSMutableData *message = [privmsgInfo objectForKey:@"message"]; |
| | 1463 | BOOL isNotice = NO; |
| | 1464 | |
| | 1465 | |
| | 1466 | NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( MVChatUser * ), @encode( id ), @encode( BOOL ), nil]; |
| | 1467 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; |
| | 1468 | [invocation setSelector:@selector( processIncomingMessageAsData:from:to:isNotice: )]; |
| | 1469 | [invocation setArgument:&message atIndex:2]; |
| | 1470 | [invocation setArgument:&sender atIndex:3]; |
| | 1471 | [invocation setArgument:&room atIndex:4]; |
| | 1472 | [invocation setArgument:&isNotice atIndex:5]; |
| | 1473 | |
| | 1474 | [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation]; |
| | 1475 | if ([message length] <= 0) |
| | 1476 | return; |
| | 1477 | |
| | 1478 | |
| | 1479 | if ( room ) { |
| | 1480 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomGotMessageNotification |
| | 1481 | object:room |
| | 1482 | userInfo:privmsgInfo]; |
| | 1483 | } else { |
| | 1484 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotPrivateMessageNotification |
| | 1485 | object:sender |
| | 1486 | userInfo:privmsgInfo]; |
| | 1487 | } |
| | 1488 | } |
| | 1489 | |
| 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]]; |
| 1473 | | } 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]]; |
| 1476 | | } |
| | 1521 | room = [self joinedChatRoomWithName:targetName]; |
| | 1522 | } |
| | 1523 | |
| | 1524 | if ( ctcp ) { |
| | 1525 | [self _handleCTCP:msgData asRequest:YES fromSender:sender forRoom:room]; |
| | 1526 | } else { |
| | 1527 | NSDictionary *privmsgInfo = [NSDictionary dictionaryWithObjectsAndKeys: |
| | 1528 | msgData, @"message", |
| | 1529 | sender, @"user", |
| | 1530 | [NSString locallyUniqueString], @"identifier", |
| | 1531 | room, @"room", // room can be nil, if the privmsg wasn't directed at a chat-room. |
| | 1532 | nil]; |
| | 1533 | [self performSelectorOnMainThread:@selector(_handlePrivmsg:) withObject:privmsgInfo waitUntilDone:NO]; |
| | 1534 | } |
| | 1538 | - (void) _handleNotice:(NSDictionary *)noticeInfo { |
| | 1539 | MVAssertMainThreadRequired(); |
| | 1540 | |
| | 1541 | MVChatRoom *room = [noticeInfo objectForKey:@"room"]; |
| | 1542 | MVChatUser *sender = [noticeInfo objectForKey:@"user"]; |
| | 1543 | NSMutableData *message = [noticeInfo objectForKey:@"message"]; |
| | 1544 | BOOL isNotice = YES; |
| | 1545 | |
| | 1546 | |
| | 1547 | NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( MVChatUser * ), @encode( id ), @encode( BOOL ), nil]; |
| | 1548 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; |
| | 1549 | [invocation setSelector:@selector( processIncomingMessageAsData:from:to:isNotice: )]; |
| | 1550 | [invocation setArgument:&message atIndex:2]; |
| | 1551 | [invocation setArgument:&sender atIndex:3]; |
| | 1552 | [invocation setArgument:&room atIndex:4]; |
| | 1553 | [invocation setArgument:&isNotice atIndex:5]; |
| | 1554 | |
| | 1555 | [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation]; |
| | 1556 | if ([message length] <= 0) |
| | 1557 | return; |
| | 1558 | |
| | 1559 | |
| | 1560 | if ( room ) { |
| | 1561 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomGotMessageNotification |
| | 1562 | object:room |
| | 1563 | userInfo:noticeInfo]; |
| | 1564 | } else { |
| | 1565 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotPrivateMessageNotification |
| | 1566 | object:sender |
| | 1567 | userInfo:noticeInfo]; |
| | 1568 | |
| | 1569 | if( [[sender nickname] isEqualToString:@"NickServ"] ) { |
| | 1570 | NSString *msg = [self _newStringWithBytes:[message bytes] length:[message length]]; |
| | 1571 | |
| | 1572 | if( [msg hasCaseInsensitiveSubstring:@"NickServ"] && [msg hasCaseInsensitiveSubstring:@"IDENTIFY"] ) { |
| | 1573 | if( ! [self nicknamePassword] ) { |
| | 1574 | [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionNeedNicknamePasswordNotification object:self userInfo:nil]; |
| | 1575 | } else [self sendRawMessageImmediatelyWithFormat:@"NickServ IDENTIFY %@", [self nicknamePassword]]; |
| | 1576 | } else if( [msg hasCaseInsensitiveSubstring:@"password accepted"] ) { |
| | 1577 | [[self localUser] _setIdentified:YES]; |
| | 1578 | } else if( [msg hasCaseInsensitiveSubstring:@"authentication required"] || [msg hasCaseInsensitiveSubstring:@"nickname is owned"] ) { |
| | 1579 | [[self localUser] _setIdentified:NO]; |
| | 1580 | } |
| | 1581 | |
| | 1582 | [msg release]; |
| | 1583 | } |
| | 1584 | } |
| | 1585 | } |
| | 1586 | |
| 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]]; |
| 1510 | | } 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 | | } |
| 1530 | | } |
| | 1615 | room = [self joinedChatRoomWithName:targetName]; |
| | 1616 | } |
| | 1617 | |
| | 1618 | if ( ctcp ) { |
| | 1619 | [self _handleCTCP:msgData asRequest:NO fromSender:sender forRoom:room]; |
| | 1620 | } else { |
| | 1621 | NSDictionary *noticeInfo = [NSDictionary dictionaryWithObjectsAndKeys: |
| | 1622 | msgData, @"message", |
| | 1623 | sender, @"user", |
| | 1624 | [NSString locallyUniqueString], @"identifier", |
| | 1625 | [NSNumber numberWithBool:YES], @"notice", |
| | 1626 | room, @"room", // room can be nil, if the notice wasn't directed at a chat-room. |
| | 1627 | nil]; |
| | 1628 | [self performSelectorOnMainThread:@selector(_handleNotice:) withObject:noticeInfo waitUntilDone:NO]; |
| | 1629 | } |
| 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]]; |
| | 1656 | NSDictionary *msgInfo = [NSDictionary dictionaryWithObjectsAndKeys: |
| | 1657 | [arguments mutableCopyWithZone:nil], @"message", |
| | 1658 | sender, @"user", |
| | 1659 | [NSString locallyUniqueString], @"identifier", |
| | 1660 | [NSNumber numberWithBool:YES], @"action", |
| | 1661 | room, @"room", // room can be nil, if the ctcp wasn't directed at a chat-room. |
| | 1662 | nil]; |
| | 1663 | [self _handlePrivmsg:msgInfo]; // No need to explicitly call this on main thread, as we are already in it. |
| | 1664 | |