Changeset 06aed9a for protocols/msn


Ignore:
Timestamp:
2012-10-01T22:51:39Z (12 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
4fdb102
Parents:
a992d7a (diff), 4c9d377 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge msnp18 branch. It's stable enough and really not that intrusive.

Location:
protocols/msn
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/msn.c

    ra992d7a r06aed9a  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    9898                g_free( md->lock_key );
    9999                g_free( md->pp_policy );
     100                g_free( md->uuid );
    100101               
    101102                while( md->groups )
     
    139140static int msn_buddy_msg( struct im_connection *ic, char *who, char *message, int away )
    140141{
     142        struct bee_user *bu = bee_user_by_handle( ic->bee, ic, who );
     143        struct msn_buddy_data *bd = bu ? bu->data : NULL;
    141144        struct msn_switchboard *sb;
    142145       
     
    148151        else
    149152#endif
    150         if( ( sb = msn_sb_by_handle( ic, who ) ) )
     153        if( bd && bd->flags & MSN_BUDDY_FED )
     154        {
     155                msn_ns_sendmessage( ic, bu, message );
     156        }
     157        else if( ( sb = msn_sb_by_handle( ic, who ) ) )
    151158        {
    152159                return( msn_sb_sendmessage( sb, message ) );
     
    190197                md->away_state = msn_away_state_list + 1;
    191198       
    192         if( !msn_ns_write( ic, -1, "CHG %d %s\r\n", ++md->trId, md->away_state->code ) )
     199        if( !msn_ns_write( ic, -1, "CHG %d %s %d:%02d\r\n", ++md->trId, md->away_state->code, MSN_CAP1, MSN_CAP2 ) )
    193200                return;
    194201       
    195         uux = g_markup_printf_escaped( "<Data><PSM>%s</PSM><CurrentMedia></CurrentMedia>"
    196                                        "</Data>", message ? message : "" );
     202        uux = g_markup_printf_escaped( "<EndpointData><Capabilities>%d:%02d"
     203                                       "</Capabilities></EndpointData>",
     204                                       MSN_CAP1, MSN_CAP2 );
     205        msn_ns_write( ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen( uux ), uux );
     206        g_free( uux );
     207       
     208        uux = g_markup_printf_escaped( "<PrivateEndpointData><EpName>%s</EpName>"
     209                                       "<Idle>%s</Idle><ClientType>%d</ClientType>"
     210                                       "<State>%s</State></PrivateEndpointData>",
     211                                       md->uuid,
     212                                       strcmp( md->away_state->code, "IDL" ) ? "false" : "true",
     213                                       1, /* ? */
     214                                       md->away_state->code );
     215        msn_ns_write( ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen( uux ), uux );
     216        g_free( uux );
     217       
     218        uux = g_markup_printf_escaped( "<Data><DDP></DDP><PSM>%s</PSM>"
     219                                       "<CurrentMedia></CurrentMedia>"
     220                                       "<MachineGuid>%s</MachineGuid></Data>",
     221                                       message ? message : "", md->uuid );
    197222        msn_ns_write( ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen( uux ), uux );
    198223        g_free( uux );
     
    232257{
    233258        struct msn_switchboard *sb = msn_sb_by_chat( c );
    234         char buf[1024];
    235259       
    236260        if( sb )
    237         {
    238                 g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, who );
    239                 msn_sb_write( sb, buf, strlen( buf ) );
    240         }
     261                msn_sb_write( sb, "CAL %d %s\r\n", ++sb->trId, who );
    241262}
    242263
     
    246267       
    247268        if( sb )
    248                 msn_sb_write( sb, "OUT\r\n", 5 );
     269                msn_sb_write( sb, "OUT\r\n" );
    249270}
    250271
     
    340361{
    341362        struct msn_data *md = bu->ic->proto_data;
    342         bu->data = g_new0( struct msn_buddy_data, 1 );
     363        struct msn_buddy_data *bd;
     364        char *handle;
     365       
     366        bd = bu->data = g_new0( struct msn_buddy_data, 1 );
    343367        g_tree_insert( md->domaintree, bu->handle, bu );
     368       
     369        for( handle = bu->handle; isdigit( *handle ); handle ++ );
     370        if( *handle == ':' )
     371        {
     372                /* Pass a nick hint so hopefully the stupid numeric prefix
     373                   won't show up to the user.  */
     374                char *s = strchr( ++handle, '@' );
     375                if( s )
     376                {
     377                        handle = g_strndup( handle, s - handle );
     378                        imcb_buddy_nick_hint( bu->ic, bu->handle, handle );
     379                        g_free( handle );
     380                }
     381               
     382                bd->flags |= MSN_BUDDY_FED;
     383        }
    344384}
    345385
  • protocols/msn/msn.h

    ra992d7a r06aed9a  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    5353*/
    5454
     55/* <= BitlBee 3.0.5
    5556#define MSNP11_PROD_KEY "ILTXC!4IXB5FB*PX"
    5657#define MSNP11_PROD_ID  "PROD0119GSJUC$18"
    57 #define MSNP_VER        "MSNP15"
    58 #define MSNP_BUILD      "8.5.1288"
     58*/
     59
     60#define MSNP11_PROD_KEY "C1BX{V4W}Q3*10SM"
     61#define MSNP11_PROD_ID  "PROD0120PW!CCV9@"
     62#define MSNP_VER        "MSNP18"
     63#define MSNP_BUILD      "14.0.8117.416"
    5964
    6065#define MSN_SB_NEW         -24062002
     66
     67#define MSN_CAP1        0xC000
     68#define MSN_CAP2        0x0000
    6169
    6270#define MSN_MESSAGE_HEADERS "MIME-Version: 1.0\r\n" \
     
    118126        char *tokens[4];
    119127        char *lock_key, *pp_policy;
     128        char *uuid;
    120129       
    121130        GSList *msgq, *grpq, *soapq;
     
    189198        MSN_BUDDY_PL = 16,
    190199        MSN_BUDDY_ADL_SYNCED = 256,
     200        MSN_BUDDY_FED = 512,
    191201} msn_buddy_flags_t;
    192202
     
    222232
    223233/* ns.c */
    224 int msn_ns_write( struct im_connection *ic, int fd, const char *fmt, ... );
     234int msn_ns_write( struct im_connection *ic, int fd, const char *fmt, ... ) G_GNUC_PRINTF( 3, 4 );
    225235gboolean msn_ns_connect( struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port );
    226236void msn_ns_close( struct msn_handler_data *handler );
     
    228238void msn_auth_got_contact_list( struct im_connection *ic );
    229239int msn_ns_finish_login( struct im_connection *ic );
     240int msn_ns_sendmessage( struct im_connection *ic, struct bee_user *bu, const char *text );
     241void msn_ns_oim_send_queue( struct im_connection *ic, GSList **msgq );
    230242
    231243/* msn_util.c */
     
    242254struct msn_group *msn_group_by_id( struct im_connection *ic, const char *id );
    243255int msn_ns_set_display_name( struct im_connection *ic, const char *value );
     256const char *msn_normalize_handle( const char *handle );
    244257
    245258/* tables.c */
     
    250263
    251264/* sb.c */
    252 int msn_sb_write( struct msn_switchboard *sb, const char *fmt, ... );
     265int msn_sb_write( struct msn_switchboard *sb, const char *fmt, ... ) G_GNUC_PRINTF( 2, 3 );;
    253266struct msn_switchboard *msn_sb_create( struct im_connection *ic, char *host, int port, char *key, int session );
    254 struct msn_switchboard *msn_sb_by_handle( struct im_connection *ic, char *handle );
     267struct msn_switchboard *msn_sb_by_handle( struct im_connection *ic, const char *handle );
    255268struct msn_switchboard *msn_sb_by_chat( struct groupchat *c );
    256269struct msn_switchboard *msn_sb_spare( struct im_connection *ic );
  • protocols/msn/msn_util.c

    ra992d7a r06aed9a  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    537537        return msn_ns_write( ic, -1, "PRP %d MFN %s\r\n", ++md->trId, fn );
    538538}
     539
     540const char *msn_normalize_handle( const char *handle )
     541{
     542        if( strncmp( handle, "1:", 2 ) == 0 )
     543                return handle + 2;
     544        else
     545                return handle;
     546}
  • protocols/msn/ns.c

    ra992d7a r06aed9a  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2525
    2626#include <ctype.h>
     27#include <sys/utsname.h>
    2728#include "nogaim.h"
    2829#include "msn.h"
    2930#include "md5.h"
     31#include "sha1.h"
    3032#include "soap.h"
    3133#include "xmltree.h"
     
    110112        handler->rxlen = 0;
    111113        handler->rxq = g_new0( char, 1 );
     114       
     115        if( md->uuid == NULL )
     116        {
     117                struct utsname name;
     118                sha1_state_t sha[1];
     119               
     120                /* UUID == SHA1("BitlBee" + my hostname + MSN username) */
     121                sha1_init( sha );
     122                sha1_append( sha, (void*) "BitlBee", 7 );
     123                if( uname( &name ) == 0 )
     124                {
     125                        sha1_append( sha, (void*) name.nodename, strlen( name.nodename ) );
     126                }
     127                sha1_append( sha, (void*) ic->acc->user, strlen( ic->acc->user ) );
     128                md->uuid = sha1_random_uuid( sha );
     129                memcpy( md->uuid, "b171be3e", 8 ); /* :-P */
     130        }
    112131       
    113132        if( msn_ns_write( ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER ) )
     
    353372                return st;
    354373        }
    355         else if( strcmp( cmd[0], "ILN" ) == 0 )
     374        else if( strcmp( cmd[0], "ILN" ) == 0 || strcmp( cmd[0], "NLN" ) == 0 )
    356375        {
    357376                const struct msn_away_state *st;
     377                const char *handle;
     378                int cap = 0;
    358379               
    359380                if( num_parts < 6 )
     
    363384                        return( 0 );
    364385                }
    365                
    366                 http_decode( cmd[5] );
    367                 imcb_rename_buddy( ic, cmd[3], cmd[5] );
    368                
    369                 st = msn_away_state_by_code( cmd[2] );
     386                /* ILN and NLN are more or less the same, except ILN has a trId
     387                   at the start, and NLN has a capability field at the end.
     388                   Does ILN still exist BTW? */
     389                if( cmd[0][1] == 'I' )
     390                        cmd ++;
     391                else
     392                        cap = atoi( cmd[4] );
     393
     394                handle = msn_normalize_handle( cmd[2] );
     395                if( strcmp( handle, ic->acc->user ) == 0 )
     396                        return 1; /* That's me! */
     397               
     398                http_decode( cmd[3] );
     399                imcb_rename_buddy( ic, handle, cmd[3] );
     400               
     401                st = msn_away_state_by_code( cmd[1] );
    370402                if( !st )
    371403                {
     
    374406                }
    375407               
    376                 imcb_buddy_status( ic, cmd[3], OPT_LOGGED_IN |
    377                                    ( st != msn_away_state_list ? OPT_AWAY : 0 ),
    378                                    st->name, NULL );
    379         }
    380         else if( strcmp( cmd[0], "FLN" ) == 0 )
    381         {
    382                 if( cmd[1] == NULL )
    383                         return 1;
    384                
    385                 imcb_buddy_status( ic, cmd[1], 0, NULL, NULL );
    386                
    387                 msn_sb_start_keepalives( msn_sb_by_handle( ic, cmd[1] ), TRUE );
    388         }
    389         else if( strcmp( cmd[0], "NLN" ) == 0 )
    390         {
    391                 const struct msn_away_state *st;
    392                 int cap;
    393                
    394                 if( num_parts < 6 )
    395                 {
    396                         imcb_error( ic, "Syntax error" );
    397                         imc_logout( ic, TRUE );
    398                         return( 0 );
    399                 }
    400                
    401                 http_decode( cmd[4] );
    402                 cap = atoi( cmd[5] );
    403                 imcb_rename_buddy( ic, cmd[2], cmd[4] );
    404                
    405                 st = msn_away_state_by_code( cmd[1] );
    406                 if( !st )
    407                 {
    408                         /* FIXME: Warn/Bomb about unknown away state? */
    409                         st = msn_away_state_list + 1;
    410                 }
    411                
    412                 imcb_buddy_status( ic, cmd[2], OPT_LOGGED_IN |
     408                imcb_buddy_status( ic, handle, OPT_LOGGED_IN |
    413409                                   ( st != msn_away_state_list ? OPT_AWAY : 0 ) |
    414410                                   ( cap & 1 ? OPT_MOBILE : 0 ),
    415411                                   st->name, NULL );
    416412               
    417                 msn_sb_stop_keepalives( msn_sb_by_handle( ic, cmd[2] ) );
     413                msn_sb_stop_keepalives( msn_sb_by_handle( ic, handle ) );
     414        }
     415        else if( strcmp( cmd[0], "FLN" ) == 0 )
     416        {
     417                const char *handle;
     418               
     419                if( cmd[1] == NULL )
     420                        return 1;
     421               
     422                handle = msn_normalize_handle( cmd[1] );
     423                imcb_buddy_status( ic, handle, 0, NULL, NULL );
     424                msn_sb_start_keepalives( msn_sb_by_handle( ic, handle ), TRUE );
    418425        }
    419426        else if( strcmp( cmd[0], "RNG" ) == 0 )
     
    462469                else
    463470                {
    464                         sb->who = g_strdup( cmd[5] );
     471                        sb->who = g_strdup( msn_normalize_handle( cmd[5] ) );
    465472                }
    466473        }
     
    555562        {
    556563                /* Status message. */
    557                 if( num_parts >= 4 )
    558                         handler->msglen = atoi( cmd[3] );
     564                if( num_parts >= 3 )
     565                        handler->msglen = atoi( cmd[2] );
    559566        }
    560567        else if( strcmp( cmd[0], "NOT" ) == 0 )
     
    564571                if( num_parts >= 2 )
    565572                        handler->msglen = atoi( cmd[1] );
     573        }
     574        else if( strcmp( cmd[0], "UBM" ) == 0 )
     575        {
     576                if( num_parts >= 7 )
     577                        handler->msglen = atoi( cmd[6] );
    566578        }
    567579        else if( isdigit( cmd[0][0] ) )
     
    668680                        else if( g_strncasecmp( ct, "text/x-msmsgsactivemailnotification", 35 ) == 0 )
    669681                        {
    670                                 /* Sorry, but this one really is *USELESS* */
     682                        }
     683                        else if( g_strncasecmp( ct, "text/x-msmsgsinitialmdatanotification", 37 ) == 0 ||
     684                                 g_strncasecmp( ct, "text/x-msmsgsoimnotification", 28 ) == 0 )
     685                        {
     686                                /* We received an offline message. Or at least notification
     687                                   that there is one waiting for us. Fetching the message(s)
     688                                   and purging them from the server is a lot of SOAPy work
     689                                   not worth doing IMHO. Also I thought it was possible to
     690                                   have the notification server send them directly, I was
     691                                   pretty sure I saw Pidgin do it..
     692                                   
     693                                   At least give a notification for now, seems like a
     694                                   reasonable thing to do. Only problem is, they'll keep
     695                                   coming back at login time until you read them using a
     696                                   different client. :-( */
     697                               
     698                                char *xml = get_rfc822_header( body, "Mail-Data:", blen );
     699                                struct xt_node *md, *m;
     700                               
     701                                if( !xml )
     702                                        return 1;
     703                                md = xt_from_string( xml, 0 );
     704                                if( !md )
     705                                        return 1;
     706                               
     707                                for( m = md->children; ( m = xt_find_node( m, "M" ) ); m = m->next )
     708                                {
     709                                        struct xt_node *e = xt_find_node( m->children, "E" );
     710                                        struct xt_node *rt = xt_find_node( m->children, "RT" );
     711                                        struct tm tp;
     712                                        time_t msgtime = 0;
     713                                       
     714                                        if( !e || !e->text )
     715                                                continue;
     716                                       
     717                                        memset( &tp, 0, sizeof( tp ) );
     718                                        if( rt && rt->text &&
     719                                            sscanf( rt->text, "%4d-%2d-%2dT%2d:%2d:%2d.",
     720                                                    &tp.tm_year, &tp.tm_mon, &tp.tm_mday,
     721                                                    &tp.tm_hour, &tp.tm_min, &tp.tm_sec ) == 6 )
     722                                        {
     723                                                tp.tm_year -= 1900;
     724                                                tp.tm_mon --;
     725                                                msgtime = mktime_utc( &tp );
     726                                               
     727                                        }
     728                                        imcb_buddy_msg( ic, e->text, "<< \002BitlBee\002 - Received offline message. BitlBee can't show these. >>", 0, msgtime );
     729                                }
     730                               
     731                                g_free( xml );
     732                                xt_free_node( md );
    671733                        }
    672734                        else
     
    688750                        psm_text = psm->text;
    689751               
    690                 imcb_buddy_status_msg( ic, cmd[1], psm_text );
     752                imcb_buddy_status_msg( ic, msn_normalize_handle( cmd[1] ), psm_text );
    691753                xt_free_node( ubx );
    692754        }
     
    716778                                        continue;
    717779                               
     780                                /* FIXME: Use "t" here, guess I should just add it
     781                                   as a prefix like elsewhere in the protocol. */
    718782                                handle = g_strdup_printf( "%s@%s", cn, dn );
    719783                                if( !( ( bu = bee_user_by_handle( ic->bee, ic, handle ) ) ||
     
    741805                }
    742806        }
    743        
    744         return( 1 );
     807        else if( strcmp( cmd[0], "UBM" ) == 0 )
     808        {
     809                /* This one will give us msgs from federated networks. Technically
     810                   it should also get us offline messages, but I don't know how
     811                   I can signal MSN servers to use it. */
     812                char *ct, *handle;
     813               
     814                if( strcmp( cmd[1], ic->acc->user ) == 0 )
     815                {
     816                        /* With MPOP, you'll get copies of your own msgs from other
     817                           sessions. Discard those at least for now. */
     818                        return 1;
     819                }
     820               
     821                ct = get_rfc822_header( msg, "Content-Type", msglen );
     822                if( strncmp( ct, "text/plain", 10 ) != 0 )
     823                {
     824                        /* Typing notification or something? */
     825                        g_free( ct );
     826                        return 1;
     827                }
     828                if( strcmp( cmd[2], "1" ) != 0 )
     829                        handle = g_strdup_printf( "%s:%s", cmd[2], cmd[1] );
     830                else
     831                        handle = g_strdup( cmd[1] );
     832               
     833                imcb_buddy_msg( ic, handle, body, 0, 0 );
     834                g_free( handle );
     835        }
     836       
     837        return 1;
    745838}
    746839
     
    757850        if( token )
    758851        {
    759                 msn_ns_write( ic, -1, "USR %d SSO S %s %s\r\n", ++md->trId, md->tokens[0], token );
     852                msn_ns_write( ic, -1, "USR %d SSO S %s %s {%s}\r\n", ++md->trId, md->tokens[0], token, md->uuid );
    760853        }
    761854        else
     
    809902        xt_add_attr( c, "n", handle );
    810903        xt_add_attr( c, "l", l );
    811         xt_add_attr( c, "t", "1" ); /* 1 means normal, 4 means mobile? */
     904        xt_add_attr( c, "t", "1" ); /* FIXME: Network type, i.e. 32 for Y!MSG */
    812905        xt_insert_child( d, c );
    813906       
     
    886979        return 1;
    887980}
     981
     982int msn_ns_sendmessage( struct im_connection *ic, bee_user_t *bu, const char *text )
     983{
     984        struct msn_data *md = ic->proto_data;
     985        int type = 0;
     986        char *buf, *handle;
     987       
     988        if( strncmp( text, "\r\r\r", 3 ) == 0 )
     989                /* Err. Shouldn't happen but I guess it can. Don't send others
     990                   any of the "SHAKE THAT THING" messages. :-D */
     991                return 1;
     992       
     993        /* This might be a federated contact. Get its network number,
     994           prefixed to bu->handle with a colon. Default is 1. */
     995        for( handle = bu->handle; isdigit( *handle ); handle ++ )
     996                type = type * 10 + *handle - '0';
     997        if( *handle == ':' )
     998                handle ++;
     999        else
     1000                type = 1;
     1001       
     1002        buf = g_strdup_printf( "%s%s", MSN_MESSAGE_HEADERS, text );
     1003       
     1004        if( msn_ns_write( ic, -1, "UUM %d %s %d %d %zd\r\n%s",
     1005                                  ++md->trId, handle, type,
     1006                                  1, /* type == IM (not nudge/typing) */
     1007                                  strlen( buf ), buf ) )
     1008                return 1;
     1009        else
     1010                return 0;
     1011}
     1012
     1013void msn_ns_oim_send_queue( struct im_connection *ic, GSList **msgq )
     1014{
     1015        GSList *l;
     1016       
     1017        for( l = *msgq; l; l = l->next )
     1018        {
     1019                struct msn_message *m = l->data;
     1020                bee_user_t *bu = bee_user_by_handle( ic->bee, ic, m->who );
     1021               
     1022                if( bu )
     1023                        if( !msn_ns_sendmessage( ic, bu, m->text ) )
     1024                                return;
     1025        }
     1026       
     1027        while( *msgq != NULL )
     1028        {
     1029                struct msn_message *m = (*msgq)->data;
     1030               
     1031                g_free( m->who );
     1032                g_free( m->text );
     1033                g_free( m );
     1034               
     1035                *msgq = g_slist_remove( *msgq, m );
     1036        }
     1037}
  • protocols/msn/sb.c

    ra992d7a r06aed9a  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    122122}
    123123
    124 struct msn_switchboard *msn_sb_by_handle( struct im_connection *ic, char *handle )
     124struct msn_switchboard *msn_sb_by_handle( struct im_connection *ic, const char *handle )
    125125{
    126126        struct msn_data *md = ic->proto_data;
     
    308308        struct msn_switchboard *sb = data;
    309309        struct im_connection *ic;
     310        struct msn_data *md;
    310311        char buf[1024];
    311312       
     
    315316       
    316317        ic = sb->ic;
     318        md = ic->proto_data;
    317319       
    318320        if( source != sb->fd )
     
    332334       
    333335        if( sb->session == MSN_SB_NEW )
    334                 g_snprintf( buf, sizeof( buf ), "USR %d %s %s\r\n", ++sb->trId, ic->acc->user, sb->key );
     336                g_snprintf( buf, sizeof( buf ), "USR %d %s;{%s} %s\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key );
    335337        else
    336                 g_snprintf( buf, sizeof( buf ), "ANS %d %s %s %d\r\n", ++sb->trId, ic->acc->user, sb->key, sb->session );
     338                g_snprintf( buf, sizeof( buf ), "ANS %d %s;{%s} %s %d\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key, sb->session );
    337339       
    338340        if( msn_sb_write( sb, "%s", buf ) )
     
    453455                        char buf[1024];
    454456                       
    455                         if( num == 1 )
     457                        /* For as much as I understand this MPOP stuff now, a
     458                           switchboard has two (or more) roster entries per
     459                           participant. One "bare JID" and one JID;UUID. Ignore
     460                           the latter. */
     461                        if( !strchr( cmd[4], ';' ) )
    456462                        {
    457                                 g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session );
    458                                 sb->chat = imcb_chat_new( ic, buf );
     463                                /* HACK: Since even 1:1 chats now have >2 participants
     464                                   (ourselves included) it gets hard to tell them apart
     465                                   from rooms. Let's hope this is enough: */
     466                                if( sb->chat == NULL && num != tot )
     467                                {
     468                                        g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session );
     469                                        sb->chat = imcb_chat_new( ic, buf );
     470                                       
     471                                        g_free( sb->who );
     472                                        sb->who = NULL;
     473                                }
    459474                               
    460                                 g_free( sb->who );
    461                                 sb->who = NULL;
    462                         }
    463                        
    464                         imcb_chat_add_buddy( sb->chat, cmd[4] );
    465                        
    466                         if( num == tot )
     475                                if( sb->chat )
     476                                        imcb_chat_add_buddy( sb->chat, cmd[4] );
     477                        }
     478                       
     479                        /* We have the full roster, start showing the channel to
     480                           the user. */
     481                        if( num == tot && sb->chat )
    467482                        {
    468483                                imcb_chat_add_buddy( sb->chat, ic->acc->user );
     
    506521                        return( 0 );
    507522                }
     523               
     524                /* See IRO above. Handle "bare JIDs" only. */
     525                if( strchr( cmd[1], ';' ) )
     526                        return 1;
    508527               
    509528                if( sb->who && g_strcasecmp( cmd[1], sb->who ) == 0 )
     
    541560                        return( st );
    542561                }
     562                else if( strcmp( cmd[1], ic->acc->user ) == 0 )
     563                {
     564                        /* Well, gee thanks. Thanks for letting me know I've arrived.. */
     565                }
    543566                else if( sb->who )
    544567                {
     
    613636                           The server will clean it up when it's idle for too long. */
    614637                }
    615                 else if( sb->chat )
     638                else if( sb->chat && !strchr( cmd[1], ';' ) )
    616639                {
    617640                        imcb_chat_remove_buddy( sb->chat, cmd[1], "" );
     
    629652                /* If the person is offline, send an offline message instead,
    630653                   and don't report an error. */
    631                 /* TODO: Support for OIMs that works. (#874) */
    632                 /*
    633654                if( num == 217 )
    634                         msn_soap_oim_send_queue( ic, &sb->msgq );
     655                        msn_ns_oim_send_queue( ic, &sb->msgq );
    635656                else
    636                 */
    637657                        imcb_error( ic, "Error reported by switchboard server: %s", err->text );
    638658               
Note: See TracChangeset for help on using the changeset viewer.