Changeset 3224

Show
Ignore:
Timestamp:
04/29/06 13:56:05 (2 years ago)
Author:
timothy
Message:

Support for PREFIX and CHANTYPE 005 messages. Colloquy will not strip the prefix correctly for modes it didn't support before. The next step is to sort them in the member list correctly and have unique icons. Fixes #606, #615, #524.

Files:

Legend:

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

    r3150 r3224  
    1818        MVChatRoomMemberHalfOperatorMode = 1 << 2, 
    1919        MVChatRoomMemberOperatorMode = 1 << 3, 
    20         MVChatRoomMemberFounderMode = 1 << 4 
     20        MVChatRoomMemberAdministratorMode = 1 << 4, 
     21        MVChatRoomMemberFounderMode = 1 << 5 
    2122} MVChatRoomMemberMode; 
    2223 
  • trunk/Chat Core/MVIRCChatConnection.h

    r3197 r3224  
    1919        NSMutableSet *_pendingWhoisUsers; 
    2020        NSMutableSet *_fileTransfers; 
     21        NSMutableDictionary *_serverInformation; 
    2122        NSString *_server; 
    2223        NSString *_currentNickname; 
     
    2627        NSString *_realName; 
    2728        NSMutableSet *_lastSentIsonNicknames; 
     29        NSCharacterSet *_roomPrefixes; 
    2830        NSConditionLock *_threadWaitLock; 
    2931        unsigned short _serverPort; 
  • trunk/Chat Core/MVIRCChatConnection.m

    r3213 r3224  
    124124        [_matchedUsers release]; 
    125125        [_pendingWhoisUsers release]; 
     126        [_roomPrefixes release]; 
     127        [_serverInformation release]; 
    126128 
    127129        _chatConnection = nil; 
     
    142144        _matchedUsers = nil; 
    143145        _pendingWhoisUsers = nil; 
     146        _roomPrefixes = nil; 
     147        _serverInformation = nil; 
    144148 
    145149        [super dealloc]; 
     
    385389 
    386390- (NSCharacterSet *) chatRoomNamePrefixes { 
    387         static NSCharacterSet *prefixes = nil; 
    388         if( ! prefixes ) prefixes = [[NSCharacterSet characterSetWithCharactersInString:@"#&+!"] retain]; 
    389         return prefixes; 
     391        static NSCharacterSet *defaultPrefixes = nil; 
     392        if( ! _roomPrefixes && ! defaultPrefixes ) 
     393                defaultPrefixes = [[NSCharacterSet characterSetWithCharactersInString:@"#&+!"] retain]; 
     394        if( ! _roomPrefixes ) return defaultPrefixes; 
     395        return _roomPrefixes; 
    390396} 
    391397 
     
    12051211 
    12061212- (void) _handle005WithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { // RPL_ISUPPORT 
     1213        if( ! _serverInformation ) 
     1214                _serverInformation = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:5]; 
     1215 
    12071216        NSEnumerator *enumerator = [parameters objectEnumerator]; 
    12081217        NSString *feature = nil; 
     
    12401249 
    12411250                        [self performSelector:@selector( _whoisWatchedUsers ) withObject:nil afterDelay:JVWatchedUserWHOISDelay]; 
    1242  
    1243                         return; 
     1251                } else if( [feature isKindOfClass:[NSString class]] && [feature hasPrefix:@"CHANTYPES="] ) { 
     1252                        NSString *types = [feature substringFromIndex:10]; // length of "CHANTYPES=" 
     1253                        if( [types length] ) { 
     1254                                id old = _roomPrefixes; 
     1255                                _roomPrefixes = [[NSCharacterSet characterSetWithCharactersInString:types] retain]; 
     1256                                [old release]; 
     1257                        } 
     1258                } else if( [feature isKindOfClass:[NSString class]] && [feature hasPrefix:@"PREFIX="] ) { 
     1259                        NSScanner *scanner = [NSScanner scannerWithString:feature]; 
     1260                        [scanner setScanLocation:7]; // length of "PREFIX=" 
     1261                        if( [scanner scanString:@"(" intoString:NULL] ) { 
     1262                                NSString *modes = nil; 
     1263                                if( [scanner scanUpToString:@")" intoString:&modes] ) { 
     1264                                        [scanner scanString:@")" intoString:NULL]; 
     1265 
     1266                                        NSMutableDictionary *modesTable = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:[modes length]]; 
     1267                                        unsigned length = [modes length]; 
     1268                                        unsigned i = 0; 
     1269                                        for( i = 0; i < length; i++ ) { 
     1270                                                MVChatRoomMemberMode mode = MVChatRoomMemberNoModes; 
     1271                                                switch( [modes characterAtIndex:i] ) { 
     1272                                                        case 'v': mode = MVChatRoomMemberVoicedMode; break; 
     1273                                                        case 'h': mode = MVChatRoomMemberHalfOperatorMode; break; 
     1274                                                        case 'o': mode = MVChatRoomMemberOperatorMode; break; 
     1275                                                        case 'a': mode = MVChatRoomMemberAdministratorMode; break; 
     1276                                                        case 'u': mode = MVChatRoomMemberAdministratorMode; break; 
     1277                                                        case 'q': mode = MVChatRoomMemberFounderMode; break; 
     1278                                                        default: break; 
     1279                                                } 
     1280 
     1281                                                if( mode != MVChatRoomMemberNoModes ) { 
     1282                                                        NSString *key = [[NSString allocWithZone:nil] initWithFormat:@"%c", [modes characterAtIndex:i]]; 
     1283                                                        [modesTable setObject:[NSNumber numberWithUnsignedLong:mode] forKey:key]; 
     1284                                                        [key release]; 
     1285                                                } 
     1286                                        } 
     1287 
     1288                                        if( [modesTable count] ) [_serverInformation setObject:modesTable forKey:@"roomMemberModeTable"]; 
     1289                                        [_serverInformation setObject:[NSCharacterSet characterSetWithCharactersInString:modes] forKey:@"roomMemberModes"]; 
     1290 
     1291                                        NSString *prefixes = [feature substringFromIndex:[scanner scanLocation]]; 
     1292                                        if( [prefixes length] ) { 
     1293                                                NSMutableDictionary *prefixTable = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:[modes length]]; 
     1294                                                unsigned length = [prefixes length]; 
     1295                                                unsigned i = 0; 
     1296                                                for( i = 0; i < length; i++ ) { 
     1297                                                        MVChatRoomMemberMode mode = MVChatRoomMemberNoModes; 
     1298                                                        switch( [prefixes characterAtIndex:i] ) { 
     1299                                                                case '+': mode = MVChatRoomMemberVoicedMode; break; 
     1300                                                                case '%': mode = MVChatRoomMemberHalfOperatorMode; break; 
     1301                                                                case '@': mode = MVChatRoomMemberOperatorMode; break; 
     1302                                                                case '&': mode = MVChatRoomMemberAdministratorMode; break; 
     1303                                                                case '!': mode = MVChatRoomMemberAdministratorMode; break; 
     1304                                                                case '*': mode = MVChatRoomMemberAdministratorMode; break; 
     1305                                                                case '~': mode = MVChatRoomMemberFounderMode; break; 
     1306                                                                case '.': mode = MVChatRoomMemberFounderMode; break; 
     1307                                                                default: break; 
     1308                                                        } 
     1309 
     1310                                                        if( mode != MVChatRoomMemberNoModes ) { 
     1311                                                                NSString *key = [[NSString allocWithZone:nil] initWithFormat:@"%c", [prefixes characterAtIndex:i]]; 
     1312                                                                [prefixTable setObject:[NSNumber numberWithUnsignedLong:mode] forKey:key]; 
     1313                                                                [key release]; 
     1314                                                        } 
     1315                                                } 
     1316 
     1317                                                if( [prefixTable count] ) [_serverInformation setObject:prefixTable forKey:@"roomMemberPrefixTable"]; 
     1318                                                [_serverInformation setObject:[NSCharacterSet characterSetWithCharactersInString:prefixes] forKey:@"roomMemberPrefixes"]; 
     1319                                        } 
     1320                                } 
     1321                        } 
    12441322                } 
    12451323        } 
     
    17351813                                                                        value = MVChatRoomMemberOperatorMode; 
    17361814                                                                        goto queue; 
    1737                                                                 case 'h': 
    1738                                                                         value = MVChatRoomMemberHalfOperatorMode; 
    1739                                                                         goto queue; 
    17401815                                                                case 'v': 
    17411816                                                                        value = MVChatRoomMemberVoicedMode; 
     
    17451820                                                                        [argsNeeded addObject:[NSNumber numberWithUnsignedLong:value]]; 
    17461821                                                                        break; 
    1747                                                                 default: 
    1748                                                                         break; 
     1822                                                                default: { 
     1823                                                                        if( _serverInformation ) { 
     1824                                                                                NSMutableDictionary *supportedModes = [_serverInformation objectForKey:@"roomMemberModeTable"]; 
     1825                                                                                value = [[supportedModes objectForKey:[NSString stringWithFormat:@"%c", chr]] unsignedLongValue]; 
     1826                                                                                if( value ) goto queue; 
     1827                                                                        } 
     1828                                                                } 
    17491829                                                        } 
    17501830                                                } 
     
    19232003 
    19242004                        while( ( memberName = [enumerator nextObject] ) ) { 
    1925                                 unsigned int i = 0, len = [memberName length]
    1926                                 if( ! len ) break; 
    1927  
    1928                                 unsigned long modes = MVChatRoomMemberNoModes; 
    1929                                 BOOL done = NO
    1930  
    1931                                 while( i < len && ! done ) { 
    1932                                         unichar c = [memberName characterAtIndex:i]; 
    1933                                        switch( c )
    1934                                                case '+': modes |= MVChatRoomMemberVoicedMode; break; 
    1935                                                 case '%': modes |= MVChatRoomMemberHalfOperatorMode; break; 
    1936                                                 case '@': modes |= MVChatRoomMemberOperatorMode; break; 
    1937                                                 default: done = YES; break; 
     2005                                if( ! [memberName length] ) break
     2006 
     2007                                MVChatRoomMemberMode modes = MVChatRoomMemberNoModes; 
     2008                                if( _serverInformation ) { 
     2009                                       NSMutableDictionary *prefixes = [_serverInformation objectForKey:@"roomMemberPrefixTable"]
     2010                                        NSString *key = [[NSString allocWithZone:nil] initWithFormat:@"%c", [memberName characterAtIndex:0]]; 
     2011                                       modes = [[prefixes objectForKey:key] unsignedLongValue]; 
     2012                                        [key release]; 
     2013                                } else
     2014                                        switch( [memberName characterAtIndex:0] ) { 
     2015                                                case '+': modes = MVChatRoomMemberVoicedMode; break; 
     2016                                                case '@': modes = MVChatRoomMemberOperatorMode; break; 
     2017                                                default: break; 
    19382018                                        } 
    1939                                         if( ! done ) i++; 
    19402019                                } 
    19412020 
    1942                                 if( i > 0 ) memberName = [memberName substringFromIndex:i]; 
     2021                                if( modes != MVChatRoomMemberNoModes ) 
     2022                                        memberName = [memberName substringFromIndex:1]; 
     2023 
    19432024                                MVChatUser *member = [self chatUserWithUniqueIdentifier:memberName]; 
    19442025                                [room _addMemberUser:member]; 
     
    21202201                NSString *room = nil; 
    21212202 
    2122                 NSCharacterSet *modeChars = [NSCharacterSet characterSetWithCharactersInString:@"@\%+ "]; 
     2203                NSCharacterSet *modeChars = nil; 
     2204                if( _serverInformation ) modeChars = [[_serverInformation objectForKey:@"roomMemberPrefixes"] retain]; 
     2205                if( ! modeChars ) modeChars = [[NSCharacterSet characterSetWithCharactersInString:@"@+"] retain]; 
     2206 
    21232207                while( ( room = [enumerator nextObject] ) ) { 
    21242208                        room = [room stringByTrimmingCharactersInSet:modeChars]; 
    2125                         if( room ) [results addObject:room]; 
     2209                        room = [room stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
     2210                        if( [room length] ) [results addObject:room]; 
    21262211                } 
    21272212 
     
    21312216                } 
    21322217 
     2218                [modeChars release]; 
    21332219                [results release]; 
    21342220        }