Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/msn.c

    r3058c30 r8bcd160  
    3030int msn_chat_id;
    3131GSList *msn_connections;
     32GSList *msn_switchboards;
    3233
    3334static char *set_eval_display_name(set_t *set, char *value);
     
    4748
    4849        set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc);
     50        set_add(&acc->set, "switchboard_keepalives", "false", set_eval_bool, acc);
    4951
    5052        acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE |
     
    6264
    6365        if (!server) {
    64                 server = "geo.gateway.messenger.live.com";
     66                imcb_error(ic, "The msn protocol is disabled in this version because most servers disabled MSNP18 over port 1863.");
     67                imcb_error(ic, "If you find a working server, you can change the 'server' setting of this account. Good luck!");
     68                imcb_error(ic, "See also: http://ismsndeadyet.com/"); // shameless plug
     69                imc_logout(ic, FALSE);
     70                return;
    6571        }
    6672
     
    7480        md->away_state = msn_away_state_list;
    7581        md->domaintree = g_tree_new(msn_domaintree_cmp);
    76         md->fd = -1;
    77         md->is_http = TRUE;
     82        md->ns->fd = -1;
    7883
    7984        msn_connections = g_slist_prepend(msn_connections, ic);
    8085
    8186        imcb_log(ic, "Connecting");
    82         msn_ns_connect(ic, server,
     87        msn_ns_connect(ic, md->ns, server,
    8388                       set_getint(&ic->acc->set, "port"));
    8489}
     
    9196
    9297        if (md) {
    93                 msn_ns_close(md);
    94 
     98                msn_ns_close(md->ns);
     99
     100                while (md->switchboards) {
     101                        msn_sb_destroy(md->switchboards->data);
     102                }
     103
     104                msn_msgq_purge(ic, &md->msgq);
    95105                msn_soapq_flush(ic, FALSE);
    96106
     
    144154{
    145155        struct bee_user *bu = bee_user_by_handle(ic->bee, ic, who);
     156        struct msn_buddy_data *bd = bu ? bu->data : NULL;
     157        struct msn_switchboard *sb;
    146158
    147159#ifdef DEBUG
    148160        if (strcmp(who, "raw") == 0) {
    149161                msn_ns_write(ic, -1, "%s\r\n", message);
    150                 return 0;
    151         }
     162        } else
    152163#endif
    153 
    154         msn_ns_sendmessage(ic, bu, message);
     164        if (bd && bd->flags & MSN_BUDDY_FED) {
     165                msn_ns_sendmessage(ic, bu, message);
     166        } else if ((sb = msn_sb_by_handle(ic, who))) {
     167                return(msn_sb_sendmessage(sb, message));
     168        } else {
     169                struct msn_message *m;
     170
     171                /* Create a message. We have to arrange a usable switchboard, and send the message later. */
     172                m = g_new0(struct msn_message, 1);
     173                m->who = g_strdup(who);
     174                m->text = g_strdup(message);
     175
     176                return msn_sb_write_msg(ic, m);
     177        }
     178
    155179        return(0);
    156180}
     
    174198static void msn_set_away(struct im_connection *ic, char *state, char *message)
    175199{
     200        char *uux;
    176201        struct msn_data *md = ic->proto_data;
    177         char *nick, *psm, *idle, *statecode, *body, *buf;
    178202
    179203        if (state == NULL) {
     
    183207        }
    184208
    185         statecode = (char *) md->away_state->code;
    186         nick = set_getstr(&ic->acc->set, "display_name");
    187         psm = message ? message : "";
    188         idle = (strcmp(statecode, "IDL") == 0) ? "false" : "true";
    189 
    190         body = g_markup_printf_escaped(MSN_PUT_USER_BODY,
    191                 nick, psm, psm, md->uuid, statecode, md->uuid, idle, statecode,
    192                 MSN_CAP1, MSN_CAP2, MSN_CAP1, MSN_CAP2
    193         );
    194 
    195         buf = g_strdup_printf(MSN_PUT_HEADERS, ic->acc->user, ic->acc->user, md->uuid,
    196                 "/user", "application/user+xml",
    197                 strlen(body), body);
    198         msn_ns_write(ic, -1, "PUT %d %zd\r\n%s", ++md->trId, strlen(buf), buf);
    199 
    200         g_free(buf);
    201         g_free(body);
     209        if (!msn_ns_write(ic, -1, "CHG %d %s %d:%02d\r\n", ++md->trId, md->away_state->code, MSN_CAP1, MSN_CAP2)) {
     210                return;
     211        }
     212
     213        uux = g_markup_printf_escaped("<EndpointData><Capabilities>%d:%02d"
     214                                      "</Capabilities></EndpointData>",
     215                                      MSN_CAP1, MSN_CAP2);
     216        msn_ns_write(ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen(uux), uux);
     217        g_free(uux);
     218
     219        uux = g_markup_printf_escaped("<PrivateEndpointData><EpName>%s</EpName>"
     220                                      "<Idle>%s</Idle><ClientType>%d</ClientType>"
     221                                      "<State>%s</State></PrivateEndpointData>",
     222                                      md->uuid,
     223                                      strcmp(md->away_state->code, "IDL") ? "false" : "true",
     224                                      1,  /* ? */
     225                                      md->away_state->code);
     226        msn_ns_write(ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen(uux), uux);
     227        g_free(uux);
     228
     229        uux = g_markup_printf_escaped("<Data><DDP></DDP><PSM>%s</PSM>"
     230                                      "<CurrentMedia></CurrentMedia>"
     231                                      "<MachineGuid>%s</MachineGuid></Data>",
     232                                      message ? message : "", md->uuid);
     233        msn_ns_write(ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen(uux), uux);
     234        g_free(uux);
    202235}
    203236
     
    225258static void msn_chat_msg(struct groupchat *c, char *message, int flags)
    226259{
    227         /* TODO: groupchats*/
     260        struct msn_switchboard *sb = msn_sb_by_chat(c);
     261
     262        if (sb) {
     263                msn_sb_sendmessage(sb, message);
     264        }
     265        /* FIXME: Error handling (although this can't happen unless something's
     266           already severely broken) disappeared here! */
    228267}
    229268
    230269static void msn_chat_invite(struct groupchat *c, char *who, char *message)
    231270{
    232         /* TODO: groupchats*/
     271        struct msn_switchboard *sb = msn_sb_by_chat(c);
     272
     273        if (sb) {
     274                msn_sb_write(sb, "CAL %d %s\r\n", ++sb->trId, who);
     275        }
    233276}
    234277
    235278static void msn_chat_leave(struct groupchat *c)
    236279{
    237         /* TODO: groupchats*/
     280        struct msn_switchboard *sb = msn_sb_by_chat(c);
     281
     282        if (sb) {
     283                msn_sb_write(sb, "OUT\r\n");
     284        }
    238285}
    239286
    240287static struct groupchat *msn_chat_with(struct im_connection *ic, char *who)
    241288{
    242         /* TODO: groupchats*/
     289        struct msn_switchboard *sb;
    243290        struct groupchat *c = imcb_chat_new(ic, who);
    244         return c;
     291
     292        if ((sb = msn_sb_by_handle(ic, who))) {
     293                debug("Converting existing switchboard to %s to a groupchat", who);
     294                return msn_sb_to_chat(sb);
     295        } else {
     296                struct msn_message *m;
     297
     298                /* Create a magic message. This is quite hackish, but who cares? :-P */
     299                m = g_new0(struct msn_message, 1);
     300                m->who = g_strdup(who);
     301                m->text = g_strdup(GROUPCHAT_SWITCHBOARD_MESSAGE);
     302
     303                msn_sb_write_msg(ic, m);
     304
     305                return c;
     306        }
    245307}
    246308
     
    262324static void msn_add_deny(struct im_connection *ic, char *who)
    263325{
     326        struct msn_switchboard *sb;
     327
    264328        msn_buddy_list_add(ic, MSN_BUDDY_BL, who, who, NULL);
     329
     330        /* If there's still a conversation with this person, close it. */
     331        if ((sb = msn_sb_by_handle(ic, who))) {
     332                msn_sb_destroy(sb);
     333        }
    265334}
    266335
Note: See TracChangeset for help on using the changeset viewer.