| 180 | | static void MVChatJoinedRoom( CHANNEL_REC *channel ) { |
|---|
| 181 | | MVIRCChatConnection *self = [MVIRCChatConnection _connectionForServer:channel -> server]; |
|---|
| 182 | | if( ! self ) return; |
|---|
| 183 | | |
|---|
| 184 | | MVChatRoom *room = [self joinedChatRoomWithName:[self stringWithEncodedBytes:channel -> name]]; |
|---|
| 185 | | [room _setDateJoined:[NSDate date]]; |
|---|
| 186 | | [room _setDateParted:nil]; |
|---|
| 187 | | [room _clearMemberUsers]; |
|---|
| 188 | | [room _clearBannedUsers]; |
|---|
| 189 | | |
|---|
| 190 | | GSList *nicks = nicklist_getnicks( channel ); |
|---|
| 191 | | GSList *nickItem = NULL; |
|---|
| 192 | | |
|---|
| 193 | | for( nickItem = nicks; nickItem != NULL; nickItem = g_slist_next( nickItem ) ) { |
|---|
| 194 | | NICK_REC *nick = nickItem -> data; |
|---|
| 195 | | MVChatUser *member = [self chatUserWithUniqueIdentifier:[self stringWithEncodedBytes:nick -> nick]]; |
|---|
| 196 | | |
|---|
| 197 | | [room _addMemberUser:member]; |
|---|
| 198 | | |
|---|
| 199 | | if( nick -> op ) [room _setMode:MVChatRoomMemberOperatorMode forMemberUser:member]; |
|---|
| 200 | | if( nick -> halfop ) [room _setMode:MVChatRoomMemberHalfOperatorMode forMemberUser:member]; |
|---|
| 201 | | if( nick -> voice ) [room _setMode:MVChatRoomMemberVoicedMode forMemberUser:member]; |
|---|
| 202 | | } |
|---|
| 203 | | |
|---|
| 204 | | NSData *topic = ( channel -> topic ? [[NSData allocWithZone:nil] initWithBytes:channel -> topic length:strlen( channel -> topic )] : nil ); |
|---|
| 205 | | NSString *author = ( channel -> topic_by ? [self stringWithEncodedBytes:channel -> topic_by] : nil ); |
|---|
| 206 | | MVChatUser *authorUser = ( author ? [self chatUserWithUniqueIdentifier:author] : nil ); |
|---|
| 207 | | NSDate *time = ( channel -> topic_time ? [NSDate dateWithTimeIntervalSince1970:channel -> topic_time] : nil ); |
|---|
| 208 | | |
|---|
| 209 | | [room _setTopic:topic byAuthor:authorUser withDate:time]; |
|---|
| 210 | | [topic release]; |
|---|
| 211 | | |
|---|
| 212 | | NSNotification *note = [NSNotification notificationWithName:MVChatRoomJoinedNotification object:room userInfo:nil]; |
|---|
| 213 | | [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; |
|---|
| 214 | | } |
|---|
| 215 | | |
|---|
| 216 | | static void MVChatJoinedWhoList( CHANNEL_REC *channel ) { |
|---|
| 217 | | MVIRCChatConnection *self = [MVIRCChatConnection _connectionForServer:channel -> server]; |
|---|
| 218 | | if( ! self ) return; |
|---|
| 219 | | |
|---|
| 220 | | GSList *nicks = nicklist_getnicks( channel ); |
|---|
| 221 | | GSList *nickItem = NULL; |
|---|
| 222 | | |
|---|
| 223 | | for( nickItem = nicks; nickItem != NULL; nickItem = g_slist_next( nickItem ) ) { |
|---|
| 224 | | NICK_REC *nick = nickItem -> data; |
|---|
| 225 | | MVChatUser *member = [self chatUserWithUniqueIdentifier:[self stringWithEncodedBytes:nick -> nick]]; |
|---|
| 226 | | |
|---|
| 227 | | if( nick -> realname ) [member _setRealName:[self stringWithEncodedBytes:nick -> realname]]; |
|---|
| 228 | | [member _setServerOperator:nick -> serverop]; |
|---|
| 229 | | |
|---|
| 230 | | if( nick -> host ) { |
|---|
| 231 | | NSString *hostmask = [self stringWithEncodedBytes:nick -> host]; |
|---|
| 232 | | NSArray *parts = [hostmask componentsSeparatedByString:@"@"]; |
|---|
| 233 | | if( [parts count] == 2 ) { |
|---|
| 234 | | [member _setUsername:[parts objectAtIndex:0]]; |
|---|
| 235 | | [member _setAddress:[parts objectAtIndex:1]]; |
|---|
| 236 | | } |
|---|
| 237 | | } |
|---|
| 238 | | } |
|---|
| 239 | | |
|---|
| 240 | | MVChatRoom *room = [self joinedChatRoomWithName:[self stringWithEncodedBytes:channel -> name]]; |
|---|
| 241 | | if( ! room ) return; |
|---|
| 242 | | |
|---|
| 243 | | NSNotification *note = [NSNotification notificationWithName:MVChatRoomMemberUsersSyncedNotification object:room userInfo:nil]; |
|---|
| 244 | | [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; |
|---|
| 245 | | } |
|---|
| 246 | | |
|---|
| 247 | | static void MVChatLeftRoom( CHANNEL_REC *channel ) { |
|---|
| 248 | | if( channel -> kicked || channel -> server -> disconnected ) return; |
|---|
| 249 | | |
|---|
| 250 | | MVIRCChatConnection *self = [MVIRCChatConnection _connectionForServer:channel -> server]; |
|---|
| 251 | | if( ! self ) return; |
|---|
| 252 | | |
|---|
| 253 | | MVChatRoom *room = [self joinedChatRoomWithName:[self stringWithEncodedBytes:channel -> name]]; |
|---|
| 254 | | [room _setDateParted:[NSDate date]]; |
|---|
| 255 | | |
|---|
| 256 | | NSNotification *note = [NSNotification notificationWithName:MVChatRoomPartedNotification object:room userInfo:nil]; |
|---|
| 257 | | [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; |
|---|
| 258 | | } |
|---|
| 259 | | |
|---|
| 260 | | static void MVChatRoomTopicChanged( IRC_SERVER_REC *server, const char *data, const char *nick, const char *address ) { |
|---|
| 261 | | MVIRCChatConnection *self = [MVIRCChatConnection _connectionForServer:(SERVER_REC *)server]; |
|---|
| 262 | | if( ! self || ! data ) return; |
|---|
| 263 | | |
|---|
| 264 | | char *channel = NULL; |
|---|
| 265 | | char *topic = NULL; |
|---|
| 266 | | char *params = event_get_params( data, 2, &channel, &topic ); |
|---|
| 267 | | |
|---|
| 268 | | if( ! topic || ! channel ) return; |
|---|
| 269 | | |
|---|
| 270 | | NSData *msgData = [[NSData allocWithZone:nil] initWithBytes:topic length:strlen( topic )]; |
|---|
| 271 | | |
|---|
| 272 | | NSString *author = ( nick ? [self stringWithEncodedBytes:nick] : nil ); |
|---|
| 273 | | MVChatUser *authorUser = ( author ? [self chatUserWithUniqueIdentifier:author] : nil ); |
|---|
| 274 | | |
|---|
| 275 | | MVChatRoom *room = [self joinedChatRoomWithName:[self stringWithEncodedBytes:channel]]; |
|---|
| 276 | | [room _setTopic:msgData byAuthor:authorUser withDate:[NSDate date]]; |
|---|
| 277 | | |
|---|
| 278 | | [msgData release]; |
|---|
| 279 | | g_free( params ); |
|---|
| 280 | | } |
|---|
| 281 | | |
|---|
| 282 | | #pragma mark - |
|---|
| 283 | | |
|---|
| 284 | | static void MVChatUserJoinedRoom( IRC_SERVER_REC *server, const char *data, const char *nick, const char *address ) { |
|---|
| 285 | | MVIRCChatConnection *self = [MVIRCChatConnection _connectionForServer:(SERVER_REC *)server]; |
|---|
| 286 | | if( ! self ) return; |
|---|
| 287 | | |
|---|
| 288 | | char *channel = NULL; |
|---|
| 289 | | char *params = event_get_params( data, 1, &channel ); |
|---|
| 290 | | |
|---|
| 291 | | if( [[self nickname] isEqualToString:[self stringWithEncodedBytes:nick]] ) { |
|---|
| 292 | | // this is the local user, create the room object now as early as possible |
|---|
| 293 | | MVChatRoom *room = [self joinedChatRoomWithName:[self stringWithEncodedBytes:channel]]; |
|---|
| 294 | | if( ! room ) { |
|---|
| 295 | | room = [[MVIRCChatRoom allocWithZone:nil] initWithName:[self stringWithEncodedBytes:channel] andConnection:self]; |
|---|
| 296 | | [self _addJoinedRoom:room]; |
|---|
| 297 | | [room release]; |
|---|
| 298 | | } |
|---|
| 299 | | |
|---|
| 300 | | goto finish; // the rest of this function doesn't apply since it is just the local user |
|---|
| 301 | | } |
|---|
| 302 | | |
|---|
| 303 | | CHANNEL_REC *chan = channel_find( (SERVER_REC *) server, channel ); |
|---|
| 304 | | NICK_REC *nickname = nicklist_find( chan, nick ); |
|---|
| 305 | | |
|---|
| 306 | | if( ! nickname ) goto finish; |
|---|
| 307 | | |
|---|
| 308 | | MVChatRoom *room = [self joinedChatRoomWithName:[self stringWithEncodedBytes:channel]]; |
|---|
| 309 | | MVChatUser *member = [self chatUserWithUniqueIdentifier:[self stringWithEncodedBytes:nick]]; |
|---|
| 310 | | if( [member status] != MVChatUserAwayStatus ) [member _setStatus:MVChatUserAvailableStatus]; |
|---|
| 311 | | |
|---|
| 312 | | [room _addMemberUser:member]; |
|---|
| 313 | | |
|---|
| 314 | | if( nickname -> op ) [room _setMode:MVChatRoomMemberOperatorMode forMemberUser:member]; |
|---|
| 315 | | if( nickname -> halfop ) [room _setMode:MVChatRoomMemberHalfOperatorMode forMemberUser:member]; |
|---|
| 316 | | if( nickname -> voice ) [room _setMode:MVChatRoomMemberVoicedMode forMemberUser:member]; |
|---|
| 317 | | |
|---|
| 318 | | if( nickname -> realname ) [member _setRealName:[self stringWithEncodedBytes:nickname -> realname]]; |
|---|
| 319 | | [member _setServerOperator:nickname -> serverop]; |
|---|
| 320 | | |
|---|
| 321 | | if( nickname -> host ) { |
|---|
| 322 | | NSString *hostmask = [self stringWithEncodedBytes:nickname -> host]; |
|---|
| 323 | | NSArray *parts = [hostmask componentsSeparatedByString:@"@"]; |
|---|
| 324 | | if( [parts count] == 2 ) { |
|---|
| 325 | | [member _setUsername:[parts objectAtIndex:0]]; |
|---|
| 326 | | [member _setAddress:[parts objectAtIndex:1]]; |
|---|
| 327 | | } |
|---|
| 328 | | } |
|---|
| 329 | | |
|---|
| 330 | | NSNotification *note = [NSNotification notificationWithName:MVChatRoomUserJoinedNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:member, @"user", nil]]; |
|---|
| 331 | | [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; |
|---|
| 332 | | |
|---|
| 333 | | finish: |
|---|
| 334 | | g_free( params ); |
|---|
| 335 | | } |
|---|
| 336 | | |
|---|
| 337 | | static void MVChatUserLeftRoom( IRC_SERVER_REC *server, const char *data, const char *nick, const char *address ) { |
|---|
| 338 | | MVIRCChatConnection *self = [MVIRCChatConnection _connectionForServer:(SERVER_REC *)server]; |
|---|
| 339 | | if( ! self ) return; |
|---|
| 340 | | |
|---|
| 341 | | if( [[self nickname] isEqualToString:[self stringWithEncodedBytes:nick]] ) return; |
|---|
| 342 | | |
|---|
| 343 | | char *channel = NULL; |
|---|
| 344 | | char *reason = NULL; |
|---|
| 345 | | char *params = event_get_params( data, 2 | PARAM_FLAG_GETREST, &channel, &reason ); |
|---|
| 346 | | |
|---|
| 347 | | MVChatRoom *room = [self joinedChatRoomWithName:[self stringWithEncodedBytes:channel]]; |
|---|
| 348 | | MVChatUser *member = [self chatUserWithUniqueIdentifier:[self stringWithEncodedBytes:nick]]; |
|---|
| 349 | | |
|---|
| 350 | | [room _removeMemberUser:member]; |
|---|
| 351 | | |
|---|
| 352 | | NSData *reasonData = [[NSData allocWithZone:nil] initWithBytes:reason length:strlen( reason )]; |
|---|
| 353 | | NSNotification *note = [NSNotification notificationWithName:MVChatRoomUserPartedNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:member, @"user", reasonData, @"reason", nil]]; |
|---|
| 354 | | [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; |
|---|
| 355 | | |
|---|
| 356 | | [reasonData release]; |
|---|
| 357 | | g_free( params ); |
|---|
| 358 | | } |
|---|
| 359 | | |
|---|
| 360 | | static void MVChatUserQuit( IRC_SERVER_REC *server, const char *data, const char *nick, const char *address ) { |
|---|
| 361 | | MVIRCChatConnection *self = [MVIRCChatConnection _connectionForServer:(SERVER_REC *)server]; |
|---|
| 362 | | if( ! self ) return; |
|---|
| 363 | | |
|---|
| 364 | | if( [[self nickname] isEqualToString:[self stringWithEncodedBytes:nick]] ) return; |
|---|
| 365 | | |
|---|
| 366 | | if( *data == ':' ) data++; |
|---|
| 367 | | |
|---|
| 368 | | MVChatUser *member = [self chatUserWithUniqueIdentifier:[self stringWithEncodedBytes:nick]]; |
|---|
| 369 | | NSData *reasonData = [[NSData allocWithZone:nil] initWithBytes:data length:strlen( data )]; |
|---|
| 370 | | NSEnumerator *enumerator = [[self joinedChatRooms] objectEnumerator]; |
|---|
| 371 | | MVChatRoom *room = nil; |
|---|
| 372 | | |
|---|
| 373 | | [member _setDateDisconnected:[NSDate date]]; |
|---|
| 374 | | [member _setStatus:MVChatUserOfflineStatus]; |
|---|
| 375 | | |
|---|
| 376 | | NSDictionary *info = [[NSDictionary allocWithZone:nil] initWithObjectsAndKeys:member, @"user", reasonData, @"reason", nil]; |
|---|
| 377 | | while( ( room = [enumerator nextObject] ) ) { |
|---|
| 378 | | if( ! [room isJoined] || ! [room hasUser:member] ) continue; |
|---|
| 379 | | [room _removeMemberUser:member]; |
|---|
| 380 | | NSNotification *note = [NSNotification notificationWithName:MVChatRoomUserPartedNotification object:room userInfo:info]; |
|---|
| 381 | | [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; |
|---|
| 382 | | } |
|---|
| 383 | | |
|---|
| 384 | | [info release]; |
|---|
| 385 | | [reasonData release]; |
|---|
| 386 | | } |
|---|
| 387 | | |
|---|
| 459 | | } |
|---|
| 460 | | |
|---|
| 461 | | #pragma mark - |
|---|
| 462 | | |
|---|
| 463 | | static void MVChatGetMessage( IRC_SERVER_REC *server, const char *data, const char *nick, const char *address ) { |
|---|
| 464 | | MVIRCChatConnection *self = [MVIRCChatConnection _connectionForServer:(SERVER_REC *)server]; |
|---|
| 465 | | if( ! self ) return; |
|---|
| 466 | | if( ! nick ) return; |
|---|
| 467 | | |
|---|
| 468 | | char *target = NULL, *message = NULL; |
|---|
| 469 | | char *params = event_get_params( data, 2 | PARAM_FLAG_GETREST, &target, &message ); |
|---|
| 470 | | if( ! address ) address = ""; |
|---|
| 471 | | |
|---|
| 472 | | if( *target == '@' && ischannel( target[1] ) ) target++; |
|---|
| 473 | | |
|---|
| 474 | | NSData *msgData = [[NSData allocWithZone:nil] initWithBytes:message length:strlen( message )]; |
|---|
| 475 | | NSNotification *note = nil; |
|---|
| 476 | | |
|---|
| 477 | | if( ischannel( *target ) ) { |
|---|
| 478 | | MVChatRoom *room = [self joinedChatRoomWithName:[self stringWithEncodedBytes:target]]; |
|---|
| 479 | | MVChatUser *user = [self chatUserWithUniqueIdentifier:[self stringWithEncodedBytes:nick]]; |
|---|
| 480 | | if( [user status] != MVChatUserAwayStatus ) [user _setStatus:MVChatUserAvailableStatus]; |
|---|
| 481 | | [user _setIdleTime:0.]; |
|---|
| 482 | | note = [NSNotification notificationWithName:MVChatRoomGotMessageNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:user, @"user", msgData, @"message", [NSString locallyUniqueString], @"identifier", nil]]; |
|---|
| 483 | | } else { |
|---|
| 484 | | MVChatUser *user = [self chatUserWithUniqueIdentifier:[self stringWithEncodedBytes:nick]]; |
|---|
| 485 | | if( [user status] != MVChatUserAwayStatus ) [user _setStatus:MVChatUserAvailableStatus]; |
|---|
| 486 | | [user _setIdleTime:0.]; |
|---|
| 487 | | note = [NSNotification notificationWithName:MVChatConnectionGotPrivateMessageNotification object:user userInfo:[NSDictionary dictionaryWithObjectsAndKeys:msgData, @"message", [NSString locallyUniqueString], @"identifier", nil]]; |
|---|
| 488 | | } |
|---|
| 489 | | |
|---|
| 490 | | [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; |
|---|
| 491 | | |
|---|
| 492 | | [msgData release]; |
|---|
| 493 | | g_free( params ); |
|---|
| 494 | | } |
|---|
| 495 | | |
|---|
| 496 | | static void MVChatGetAutoMessage( IRC_SERVER_REC *server, const char *data, const char *nick, const char *address ) { |
|---|
| 497 | | MVIRCChatConnection *self = [MVIRCChatConnection _connectionForServer:(SERVER_REC *)server]; |
|---|
| 498 | | if( ! self ) return; |
|---|
| 499 | | if( ! nick ) return; |
|---|
| 500 | | |
|---|
| 501 | | char *target = NULL, *message = NULL; |
|---|
| 502 | | char *params = event_get_params( data, 2 | PARAM_FLAG_GETREST, &target, &message ); |
|---|
| 503 | | if( ! address ) address = ""; |
|---|
| 504 | | |
|---|
| 505 | | if( *target == '@' && ischannel( target[1] ) ) target++; |
|---|
| 506 | | |
|---|
| 507 | | NSNotification *note = nil; |
|---|
| 508 | | NSData *msgData = [[NSData allocWithZone:nil] initWithBytes:message length:strlen( message )]; |
|---|
| 509 | | |
|---|
| 510 | | if( ischannel( *target ) ) { |
|---|
| 511 | | MVChatRoom *room = [self joinedChatRoomWithName:[self stringWithEncodedBytes:target]]; |
|---|
| 512 | | MVChatUser *user = [self chatUserWithUniqueIdentifier:[self stringWithEncodedBytes:nick]]; |
|---|
| 513 | | if( [user status] != MVChatUserAwayStatus ) [user _setStatus:MVChatUserAvailableStatus]; |
|---|
| 514 | | note = [NSNotification notificationWithName:MVChatRoomGotMessageNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:user, @"user", msgData, @"message", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"notice", nil]]; |
|---|
| 515 | | } else { |
|---|
| 516 | | MVChatUser *user = [self chatUserWithUniqueIdentifier:[self stringWithEncodedBytes:nick]]; |
|---|
| 517 | | if( [user status] != MVChatUserAwayStatus ) [user _setStatus:MVChatUserAvailableStatus]; |
|---|
| 518 | | note = [NSNotification notificationWithName:MVChatConnectionGotPrivateMessageNotification object:user userInfo:[NSDictionary dictionaryWithObjectsAndKeys:msgData, @"message", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"notice", nil]]; |
|---|
| 519 | | if( ! strncasecmp( nick, "NickServ", 8 ) && message ) { |
|---|
| 520 | | if( strstr( message, nick ) && strstr( message, "IDENTIFY" ) ) { |
|---|
| 521 | | if( ! [self nicknamePassword] ) { |
|---|
| 522 | | NSNotification *note = [NSNotification notificationWithName:MVChatConnectionNeedNicknamePasswordNotification object:self userInfo:nil]; |
|---|
| 523 | | [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; |
|---|
| 524 | | } else irc_send_cmdv( server, "PRIVMSG %s :IDENTIFY %s", nick, [self encodedBytesWithString:[self nicknamePassword]] ); |
|---|
| 525 | | } else if( strstr( message, "Password accepted" ) ) { |
|---|
| 526 | | [[self localUser] _setIdentified:YES]; |
|---|
| 527 | | } else if( strstr( message, "authentication required" ) ) { |
|---|
| 528 | | [[self localUser] _setIdentified:NO]; |
|---|
| 529 | | } |
|---|
| 530 | | } |
|---|
| 531 | | } |
|---|
| 532 | | |
|---|
| 533 | | [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; |
|---|
| 534 | | |
|---|
| 535 | | [msgData release]; |
|---|
| 536 | | g_free( params ); |
|---|
| 537 | | } |
|---|
| 538 | | |
|---|
| 539 | | static void MVChatGetActionMessage( IRC_SERVER_REC *server, const char *data, const char *nick, const char *address, const char *target ) { |
|---|
| 540 | | MVIRCChatConnection *self = [MVIRCChatConnection _connectionForServer:(SERVER_REC *)server]; |
|---|
| 541 | | if( ! self ) return; |
|---|
| 542 | | if( ! nick ) return; |
|---|
| 543 | | if( ! address ) address = ""; |
|---|
| 544 | | |
|---|
| 545 | | NSData *msgData = [[NSData allocWithZone:nil] initWithBytes:data length:strlen( data )]; |
|---|
| 546 | | NSNotification *note = nil; |
|---|
| 547 | | |
|---|
| 548 | | if( ischannel( *target ) ) { |
|---|
| 549 | | MVChatRoom *room = [self joinedChatRoomWithName:[self stringWithEncodedBytes:target]]; |
|---|
| 550 | | MVChatUser *user = [self chatUserWithUniqueIdentifier:[self stringWithEncodedBytes:nick]]; |
|---|
| 551 | | if( [user status] != MVChatUserAwayStatus ) [user _setStatus:MVChatUserAvailableStatus]; |
|---|
| 552 | | [user _setIdleTime:0.]; |
|---|
| 553 | | note = [NSNotification notificationWithName:MVChatRoomGotMessageNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:user, @"user", msgData, @"message", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"action", nil]]; |
|---|
| 554 | | } else { |
|---|
| 555 | | MVChatUser *user = [self chatUserWithUniqueIdentifier:[self stringWithEncodedBytes:nick]]; |
|---|
| 556 | | if( [user status] != MVChatUserAwayStatus ) [user _setStatus:MVChatUserAvailableStatus]; |
|---|
| 557 | | [user _setIdleTime:0.]; |
|---|
| 558 | | note = [NSNotification notificationWithName:MVChatConnectionGotPrivateMessageNotification object:user userInfo:[NSDictionary dictionaryWithObjectsAndKeys:msgData, @"message", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"action", nil]]; |
|---|
| 559 | | } |
|---|
| 560 | | |
|---|
| 561 | | [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; |
|---|
| 562 | | [msgData release]; |
|---|
| 1744 | | - (void) _handleJoinWithParameters:(NSArray *) parameters fromSender:(id) sender { |
|---|
| | 1434 | - (void) _handlePrivmsgWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { |
|---|
| | 1435 | if( [parameters count] == 2 ) { |
|---|
| | 1436 | NSString *targetName = [parameters objectAtIndex:0]; |
|---|
| | 1437 | if( ! [targetName length] ) return; |
|---|
| | 1438 | |
|---|
| | 1439 | if( [targetName characterAtIndex:0] == '@' ) { |
|---|
| | 1440 | targetName = [targetName substringFromIndex:1]; // a message to only room operators |
|---|
| | 1441 | if( ! [targetName length] ) return; |
|---|
| | 1442 | } |
|---|
| | 1443 | |
|---|
| | 1444 | NSData *msgData = [parameters objectAtIndex:1]; |
|---|
| | 1445 | if( [[self chatRoomNamePrefixes] characterIsMember:[targetName characterAtIndex:0]] ) { |
|---|
| | 1446 | MVChatRoom *room = [self joinedChatRoomWithName:targetName]; |
|---|
| | 1447 | if( [sender status] != MVChatUserAwayStatus ) [sender _setStatus:MVChatUserAvailableStatus]; |
|---|
| | 1448 | [sender _setIdleTime:0.]; |
|---|
| | 1449 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomGotMessageNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:sender, @"user", msgData, @"message", [NSString locallyUniqueString], @"identifier", nil]]; |
|---|
| | 1450 | } else { |
|---|
| | 1451 | if( [sender status] != MVChatUserAwayStatus ) [sender _setStatus:MVChatUserAvailableStatus]; |
|---|
| | 1452 | [sender _setIdleTime:0.]; |
|---|
| | 1453 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotPrivateMessageNotification object:sender userInfo:[NSDictionary dictionaryWithObjectsAndKeys:msgData, @"message", [NSString locallyUniqueString], @"identifier", nil]]; |
|---|
| | 1454 | } |
|---|
| | 1455 | } |
|---|
| | 1456 | } |
|---|
| | 1457 | |
|---|
| | 1458 | - (void) _handleNoticeWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { |
|---|
| | 1459 | if( [parameters count] == 2 ) { |
|---|
| | 1460 | NSString *targetName = [parameters objectAtIndex:0]; |
|---|
| | 1461 | if( ! [targetName length] ) return; |
|---|
| | 1462 | |
|---|
| | 1463 | if( [targetName characterAtIndex:0] == '@' ) { |
|---|
| | 1464 | targetName = [targetName substringFromIndex:1]; // a message to only room operators |
|---|
| | 1465 | if( ! [targetName length] ) return; |
|---|
| | 1466 | } |
|---|
| | 1467 | |
|---|
| | 1468 | NSData *msgData = [parameters objectAtIndex:1]; |
|---|
| | 1469 | if( [[self chatRoomNamePrefixes] characterIsMember:[targetName characterAtIndex:0]] ) { |
|---|
| | 1470 | MVChatRoom *room = [self joinedChatRoomWithName:targetName]; |
|---|
| | 1471 | if( [sender status] != MVChatUserAwayStatus ) [sender _setStatus:MVChatUserAvailableStatus]; |
|---|
| | 1472 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomGotMessageNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:sender, @"user", msgData, @"message", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"notice", nil]]; |
|---|
| | 1473 | } else { |
|---|
| | 1474 | if( [sender status] != MVChatUserAwayStatus ) [sender _setStatus:MVChatUserAvailableStatus]; |
|---|
| | 1475 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotPrivateMessageNotification object:sender userInfo:[NSDictionary dictionaryWithObjectsAndKeys:msgData, @"message", [NSString locallyUniqueString], @"identifier", [NSNumber numberWithBool:YES], @"notice", nil]]; |
|---|
| | 1476 | if( [[sender nickname] isEqualToString:@"NickServ"] ) { |
|---|
| | 1477 | NSString *msg = [[NSString allocWithZone:nil] initWithData:msgData encoding:[self encoding]]; |
|---|
| | 1478 | if( [msg rangeOfString:@"NickServ"].location != NSNotFound && [msg rangeOfString:@"IDENTIFY"].location != NSNotFound ) { |
|---|
| | 1479 | if( ! [self nicknamePassword] ) { |
|---|
| | 1480 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionNeedNicknamePasswordNotification object:self userInfo:nil]; |
|---|
| | 1481 | } else [self sendRawMessageWithFormat:@"PRIVMSG %@ :IDENTIFY %@", [self nickname], [self nicknamePassword]]; |
|---|
| | 1482 | } else if( [msg rangeOfString:@"Password accepted"].location != NSNotFound ) { |
|---|
| | 1483 | [[self localUser] _setIdentified:YES]; |
|---|
| | 1484 | } else if( [msg rangeOfString:@"authentication required"].location != NSNotFound ) { |
|---|
| | 1485 | [[self localUser] _setIdentified:NO]; |
|---|
| | 1486 | } |
|---|
| | 1487 | [msg release]; |
|---|
| | 1488 | } |
|---|
| | 1489 | } |
|---|
| | 1490 | } |
|---|
| | 1491 | } |
|---|
| | 1492 | |
|---|
| | 1493 | - (void) _handleJoinWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { |
|---|
| | 1518 | |
|---|
| | 1519 | [name release]; |
|---|
| | 1520 | } |
|---|
| | 1521 | } |
|---|
| | 1522 | |
|---|
| | 1523 | - (void) _handlePartWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { |
|---|
| | 1524 | if( [parameters count] == 2 ) { |
|---|
| | 1525 | MVChatRoom *room = [self joinedChatRoomWithName:[parameters objectAtIndex:0]]; |
|---|
| | 1526 | if( ! room ) return; |
|---|
| | 1527 | if( [sender isLocalUser] ) { |
|---|
| | 1528 | [room _setDateParted:[NSDate date]]; |
|---|
| | 1529 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomPartedNotification object:room]; |
|---|
| | 1530 | } else { |
|---|
| | 1531 | [room _removeMemberUser:sender]; |
|---|
| | 1532 | NSData *reason = [parameters objectAtIndex:1]; |
|---|
| | 1533 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomUserPartedNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:sender, @"user", reason, @"reason", nil]]; |
|---|
| | 1534 | } |
|---|
| | 1535 | } |
|---|
| | 1536 | } |
|---|
| | 1537 | |
|---|
| | 1538 | - (void) _handleQuitWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { |
|---|
| | 1539 | if( [sender isLocalUser] ) return; |
|---|
| | 1540 | if( [parameters count] ) { |
|---|
| | 1541 | [sender _setDateDisconnected:[NSDate date]]; |
|---|
| | 1542 | [sender _setStatus:MVChatUserOfflineStatus]; |
|---|
| | 1543 | |
|---|
| | 1544 | NSData *reason = [parameters objectAtIndex:0]; |
|---|
| | 1545 | NSDictionary *info = [[NSDictionary allocWithZone:nil] initWithObjectsAndKeys:sender, @"user", reason, @"reason", nil]; |
|---|
| | 1546 | |
|---|
| | 1547 | MVChatRoom *room = nil; |
|---|
| | 1548 | NSEnumerator *enumerator = [[self joinedChatRooms] objectEnumerator]; |
|---|
| | 1549 | while( ( room = [enumerator nextObject] ) ) { |
|---|
| | 1550 | if( ! [room isJoined] || ! [room hasUser:sender] ) continue; |
|---|
| | 1551 | [room _removeMemberUser:sender]; |
|---|
| | 1552 | [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomUserPartedNotification object:room userInfo:info]; |
|---|
| | 1553 | } |
|---|
| | 1554 | |
|---|
| | 1555 | [info release]; |
|---|
| | 1556 | } |
|---|
| | 1557 | } |
|---|
| | 1558 | |
|---|
| | 1559 | - (void) _handleTopicWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { |
|---|
| | 1560 | if( [parameters count] == 2 ) { |
|---|
| | 1561 | MVChatRoom *room = [self joinedChatRoomWithName:[parameters objectAtIndex:0]]; |
|---|
| | 1562 | [room _setTopic:[parameters objectAtIndex:1] byAuthor:sender withDate:[NSDate date]]; |
|---|