Changeset a21a8ac


Ignore:
Timestamp:
2006-10-10T12:05:42Z (14 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
8eb10c9
Parents:
6a1128d
Message:

Added resource selection (based on priority or time of last message) to
budd_by_jid(), added a full_jid property to easily address that resource
without having to rebuild the full JID every time and implemented typing
notification shite.

Location:
protocols/jabber
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/jabber.c

    r6a1128d ra21a8ac  
    4444        s = set_add( &acc->set, "resource", "BitlBee", NULL, acc );
    4545        s->flags |= ACC_SET_OFFLINE_ONLY;
     46       
     47        s = set_add( &acc->set, "resource_select", "priority", NULL, acc );
    4648       
    4749        s = set_add( &acc->set, "server", NULL, set_eval_account, acc );
     
    137139static int jabber_send_im( struct gaim_connection *gc, char *who, char *message, int len, int away )
    138140{
     141        struct jabber_data *jd = gc->proto_data;
     142        struct jabber_buddy *bud;
    139143        struct xt_node *node;
    140144        int st;
    141145       
    142         /*
    143         event = xt_new_node( "active", NULL, NULL );
    144         xt_add_attr( event, "xlmns", "http://jabber.org/protocol/chatstates" );
    145        
    146         event = xt_new_node( "x", NULL, xt_new_node( "composing", NULL, NULL ) );
    147         xt_add_attr( event, "xmlns", "jabber:x:event" );
    148         */
     146        bud = jabber_buddy_by_jid( gc, who );
    149147       
    150148        node = xt_new_node( "body", message, NULL );
    151         node = jabber_make_packet( "message", "chat", who, node );
     149        node = jabber_make_packet( "message", "chat", bud->full_jid, node );
     150       
     151        if( ( jd->flags & JFLAG_WANT_TYPING ) &&
     152            ( ( bud->flags & JBFLAG_DOES_JEP85 ) ||
     153             !( bud->flags & JBFLAG_PROBED_JEP85 ) ) )
     154        {
     155                struct xt_node *act;
     156               
     157                /* If the user likes typing notification and if we don't know
     158                   (and didn't probe before) if this resource supports JEP85,
     159                   include a probe in this packet now. */
     160                act = xt_new_node( "active", NULL, NULL );
     161                xt_add_attr( act, "xmlns", "http://jabber.org/protocol/chatstates" );
     162                xt_add_child( node, act );
     163               
     164                /* Just make sure we do this only once. */
     165                bud->flags |= JBFLAG_PROBED_JEP85;
     166        }
     167       
    152168        st = jabber_write_packet( gc, node );
    153169        xt_free_node( node );
     
    227243           is in the cache for about a minute (which should be enough AFAIK). */
    228244        jabber_cache_clean( gc );
     245}
     246
     247static int jabber_send_typing( struct gaim_connection *gc, char *who, int typing )
     248{
     249        struct jabber_data *jd = gc->proto_data;
     250        struct jabber_buddy *bud;
     251       
     252        /* Enable typing notification related code from now. */
     253        jd->flags |= JFLAG_WANT_TYPING;
     254       
     255        bud = jabber_buddy_by_jid( gc, who );
     256        if( bud->flags & JBFLAG_DOES_JEP85 )
     257        {
     258                /* We're only allowed to send this stuff if we know the other
     259                   side supports it. */
     260               
     261                struct xt_node *node;
     262                char *type;
     263                int st;
     264               
     265                if( typing == 0 )
     266                        type = "active";
     267                else if( typing == 2 )
     268                        type = "paused";
     269                else /* if( typing == 1 ) */
     270                        type = "composing";
     271               
     272                node = xt_new_node( type, NULL, NULL );
     273                xt_add_attr( node, "xmlns", "http://jabber.org/protocol/chatstates" );
     274                node = jabber_make_packet( "message", "chat", bud->full_jid, node );
     275               
     276                st = jabber_write_packet( gc, node );
     277                xt_free_node( node );
     278               
     279                return st;
     280        }
     281       
     282        return 1;
    229283}
    230284
     
    250304//      ret->chat_open = jabber_chat_open;
    251305        ret->keepalive = jabber_keepalive;
    252 //      ret->send_typing = jabber_send_typing;
     306        ret->send_typing = jabber_send_typing;
    253307        ret->handle_cmp = g_strcasecmp;
    254308
  • protocols/jabber/jabber.h

    r6a1128d ra21a8ac  
    3232typedef enum
    3333{
    34         JFLAG_STREAM_STARTED = 1,       /* Set when we detected the beginning of the stream and want to do auth. */
     34        JFLAG_STREAM_STARTED = 1,       /* Set when we detected the beginning of the stream
     35                                           and want to do auth. */
    3536        JFLAG_AUTHENTICATED = 2,        /* Set when we're successfully authenticatd. */
    36         JFLAG_STREAM_RESTART = 4,       /* Set when we want to restart the stream (after SASL or TLS). */
    37         JFLAG_WAIT_SESSION = 8,         /* Set if we sent a <session> tag and need a reply before we continue. */
     37        JFLAG_STREAM_RESTART = 4,       /* Set when we want to restart the stream (after
     38                                           SASL or TLS). */
     39        JFLAG_WAIT_SESSION = 8,         /* Set if we sent a <session> tag and need a reply
     40                                           before we continue. */
    3841        JFLAG_WAIT_BIND = 16,           /* ... for <bind> tag. */
     42        JFLAG_WANT_TYPING = 32,         /* Set if we ever sent a typing notification, this
     43                                           activates all JEP-85 related code. */
    3944} jabber_flags_t;
     45
     46typedef enum
     47{
     48        JBFLAG_PROBED_JEP85 = 1,        /* Set this when we sent our probe packet to make
     49                                           sure it gets sent only once. */
     50        JBFLAG_DOES_JEP85 = 2,          /* Set this when the resource seems to support
     51                                           JEP85 (typing notification shite). */
     52} jabber_buddy_flag_t;
    4053
    4154struct jabber_data
     
    8194{
    8295        char *handle;
     96        char *full_jid;
    8397        char *resource;
    8498       
  • protocols/jabber/jabber_util.c

    r6a1128d ra21a8ac  
    247247       
    248248        *s = '/';
    249         new->resource = g_strdup( s + 1 );
     249        new->full_jid = g_strdup( full_jid );
     250        new->resource = strchr( new->full_jid, '/' ) + 1;
    250251       
    251252        return new;
     
    268269        else
    269270        {
    270                 /* TODO: Add selection. */
    271                 return g_hash_table_lookup( jd->buddies, jid );
     271                struct jabber_buddy *best_prio, *best_time;
     272                char *set;
     273               
     274                best_prio = best_time = bud = g_hash_table_lookup( jd->buddies, jid );
     275                for( ; bud; bud = bud->next )
     276                {
     277                        if( bud->priority > best_prio->priority )
     278                                best_prio = bud;
     279                        if( bud->last_act > best_time->last_act )
     280                                best_time = bud;
     281                }
     282               
     283                if( ( set = set_getstr( &gc->acc->set, "resource_select" ) ) == NULL )
     284                        return NULL;
     285                else if( strcmp( set, "activity" ) == 0 )
     286                        return best_time;
     287                else /* if( strcmp( set, "priority" ) == 0 ) */
     288                        return best_prio;
    272289        }
    273290       
     
    295312                        g_hash_table_remove( jd->buddies, bud->handle );
    296313                        g_free( bud->handle );
    297                         g_free( bud->resource );
     314                        g_free( bud->full_jid );
    298315                        g_free( bud->away_message );
    299316                        g_free( bud );
     
    314331                                        g_hash_table_replace( jd->buddies, bi->handle, bi->next );
    315332                               
    316                                 g_free( bi->resource );
     333                                g_free( bi->full_jid );
    317334                                g_free( bi->away_message );
    318335                                g_free( bi );
  • protocols/jabber/message.c

    r6a1128d ra21a8ac  
    2929        char *from = xt_find_attr( node, "from" );
    3030        char *type = xt_find_attr( node, "type" );
    31         struct xt_node *msg = xt_find_node( node->children, "body" );
     31        struct xt_node *body = xt_find_node( node->children, "body" );
    3232       
    33         if( !type || !msg )
     33        if( !type )
    3434                return XT_HANDLED;      /* Grmbl... FIXME */
    3535       
    3636        if( strcmp( type, "chat" ) == 0 )
    3737        {
    38                 char *s;
     38                struct jabber_buddy *bud = NULL;
    3939               
    40                 s = strchr( from, '/' );
    41                 if( s )
    42                         *s = 0;
     40                if( strchr( from, '/' ) == NULL )
     41                {
     42                        /* It just shouldn't happen. */
     43                        hide_login_progress( gc, "Received message packet from bare JID" );
     44                        signoff( gc );
     45                        return XT_ABORT;
     46                }
    4347               
    44                 serv_got_im( gc, from, msg->text, 0, 0, 0 );
     48                bud = jabber_buddy_by_jid( gc, from );
     49                bud->last_act = time( NULL );
    4550               
    46                 if( s )
    47                         *s = '/';
     51                if( body ) /* Could be just a typing notification. */
     52                        serv_got_im( gc, bud->handle, body->text, 0, 0, 0 );
     53               
     54                if( xt_find_node( node->children, "composing" ) )
     55                {
     56                        bud->flags |= JBFLAG_DOES_JEP85;
     57                        serv_got_typing( gc, bud->handle, 0, 1 );
     58                }
     59                else if( xt_find_node( node->children, "active" ) )
     60                {
     61                        bud->flags |= JBFLAG_DOES_JEP85;
     62                }
    4863        }
    4964        else
    5065        {
    51                 printf( "Received MSG from %s: %s\n", from, msg ? msg->text : "<null>" );
     66                printf( "Received MSG from %s:\n", from );
    5267                xt_print( node );
    5368        }
  • protocols/jabber/presence.c

    r6a1128d ra21a8ac  
    3030        char *type = xt_find_attr( node, "type" );      /* NULL should mean the person is online. */
    3131        struct xt_node *c;
     32        struct jabber_buddy *bud;
    3233       
    3334        if( !from )
     
    3637        if( type == NULL )
    3738        {
    38                 struct jabber_buddy *bud;
     39                if( strchr( from, '/' ) == NULL )
     40                {
     41                        char *s = xt_to_string( node );
     42                        serv_got_crap( gc, "WARNING: Ignoring presence tag with bare JID: %s\n", s );
     43                        g_free( s );
     44                }
    3945               
    4046                if( !( bud = jabber_buddy_by_jid( gc, from ) ) )
     
    5258                        bud->away_state = (void*) jabber_away_state_by_code( c->text );
    5359                else
     60                {
    5461                        bud->away_state = NULL;
     62                        /* Let's only set last_act if there's *no* away state,
     63                           since it could be some auto-away thingy. */
     64                        bud->last_act = time( NULL );
     65                }
    5566               
    5667                if( ( c = xt_find_node( node->children, "priority" ) ) && c->text_len > 0 )
     
    5970                        bud->priority = 0;
    6071               
    61                 serv_got_update( gc, bud->handle, 1, 0, 0, 0, 0, 0 );
     72                serv_got_update( gc, bud->handle, 1, 0, 0, 0,
     73                                 bud->away_state ? UC_UNAVAILABLE : 0, 0 );
    6274        }
    6375        else if( strcmp( type, "unavailable" ) == 0 )
     
    6577                char *s;
    6678               
     79                if( ( s = strchr( from, '/' ) ) == NULL )
     80                {
     81                        char *s = xt_to_string( node );
     82                        serv_got_crap( gc, "WARNING: Ignoring presence tag with bare JID: %s\n", s );
     83                        g_free( s );
     84                }
     85               
    6786                jabber_buddy_remove( gc, from );
    68                
    69                 if( ( s = strchr( from, '/' ) ) )
    70                         *s = 0;
     87                *s = 0;
    7188               
    7289                /* Only count this as offline if there's no other resource
Note: See TracChangeset for help on using the changeset viewer.