📄 presence.c
字号:
/* they are unsubscribing from our presence, we don't care */ /* Well, maybe just a little, we might want/need to start * acknowledging this (and the others) at some point. */ jabber_id_free(jid); return; } else { if((y = xmlnode_get_child(packet, "show"))) { char *show = xmlnode_get_data(y); state = jabber_buddy_show_get_state(show); g_free(show); } else { state = JABBER_BUDDY_STATE_ONLINE; } } for(y = packet->child; y; y = y->next) { if(y->type != XMLNODE_TYPE_TAG) continue; if(!strcmp(y->name, "status")) { g_free(status); status = xmlnode_get_data(y); } else if(!strcmp(y->name, "priority")) { char *p = xmlnode_get_data(y); if(p) { priority = atoi(p); g_free(p); } } else if(!strcmp(y->name, "x")) { const char *xmlns = xmlnode_get_namespace(y); if(xmlns && !strcmp(xmlns, "jabber:x:delay")) { /* XXX: compare the time. jabber:x:delay can happen on presence packets that aren't really and truly delayed */ delayed = TRUE; } else if(xmlns && !strcmp(xmlns, "http://jabber.org/protocol/muc#user")) { xmlnode *z; muc = TRUE; if((z = xmlnode_get_child(y, "status"))) { const char *code = xmlnode_get_attrib(z, "code"); if(code && !strcmp(code, "201")) { if((chat = jabber_chat_find(js, jid->node, jid->domain))) { chat->config_dialog_type = PURPLE_REQUEST_ACTION; chat->config_dialog_handle = purple_request_action(js->gc, _("Create New Room"), _("Create New Room"), _("You are creating a new room. Would" " you like to configure it, or" " accept the default settings?"), /* Default Action */ 1, purple_connection_get_account(js->gc), NULL, chat->conv, chat, 2, _("_Configure Room"), G_CALLBACK(jabber_chat_request_room_configure), _("_Accept Defaults"), G_CALLBACK(jabber_chat_create_instant_room)); } } } if((z = xmlnode_get_child(y, "item"))) { real_jid = xmlnode_get_attrib(z, "jid"); affiliation = xmlnode_get_attrib(z, "affiliation"); role = xmlnode_get_attrib(z, "role"); if(affiliation != NULL && !strcmp(affiliation, "owner")) flags |= PURPLE_CBFLAGS_FOUNDER; if (role != NULL) { if (!strcmp(role, "moderator")) flags |= PURPLE_CBFLAGS_OP; else if (!strcmp(role, "participant")) flags |= PURPLE_CBFLAGS_VOICE; } } } else if(xmlns && !strcmp(xmlns, "vcard-temp:x:update")) { xmlnode *photo = xmlnode_get_child(y, "photo"); if(photo) { g_free(avatar_hash); avatar_hash = xmlnode_get_data(photo); } } } } if(jid->node && (chat = jabber_chat_find(js, jid->node, jid->domain))) { static int i = 1; char *room_jid = g_strdup_printf("%s@%s", jid->node, jid->domain); if(state == JABBER_BUDDY_STATE_ERROR) { char *title, *msg = jabber_parse_error(js, packet); if(chat->conv) { title = g_strdup_printf(_("Error in chat %s"), from); serv_got_chat_left(js->gc, chat->id); } else { title = g_strdup_printf(_("Error joining chat %s"), from); } purple_notify_error(js->gc, title, title, msg); g_free(title); g_free(msg); jabber_chat_destroy(chat); jabber_id_free(jid); g_free(status); g_free(room_jid); g_free(avatar_hash); return; } if(type && !strcmp(type, "unavailable")) { gboolean nick_change = FALSE; /* If we haven't joined the chat yet, we don't care that someone * left, or it was us leaving after we closed the chat */ if(!chat->conv) { if(jid->resource && chat->handle && !strcmp(jid->resource, chat->handle)) jabber_chat_destroy(chat); jabber_id_free(jid); g_free(status); g_free(room_jid); g_free(avatar_hash); return; } jabber_buddy_remove_resource(jb, jid->resource); if(chat->muc) { xmlnode *x; for(x = xmlnode_get_child(packet, "x"); x; x = xmlnode_get_next_twin(x)) { const char *xmlns, *nick, *code; xmlnode *stat, *item; if(!(xmlns = xmlnode_get_namespace(x)) || strcmp(xmlns, "http://jabber.org/protocol/muc#user")) continue; if(!(stat = xmlnode_get_child(x, "status"))) continue; if(!(code = xmlnode_get_attrib(stat, "code"))) continue; if(!strcmp(code, "301")) { /* XXX: we got banned */ } else if(!strcmp(code, "303")) { if(!(item = xmlnode_get_child(x, "item"))) continue; if(!(nick = xmlnode_get_attrib(item, "nick"))) continue; nick_change = TRUE; if(!strcmp(jid->resource, chat->handle)) { g_free(chat->handle); chat->handle = g_strdup(nick); } purple_conv_chat_rename_user(PURPLE_CONV_CHAT(chat->conv), jid->resource, nick); jabber_chat_remove_handle(chat, jid->resource); break; } else if(!strcmp(code, "307")) { /* XXX: we got kicked */ } else if(!strcmp(code, "321")) { /* XXX: removed due to an affiliation change */ } else if(!strcmp(code, "322")) { /* XXX: removed because room is now members-only */ } else if(!strcmp(code, "332")) { /* XXX: removed due to system shutdown */ } } } if(!nick_change) { if(!g_utf8_collate(jid->resource, chat->handle)) { serv_got_chat_left(js->gc, chat->id); jabber_chat_destroy(chat); } else { purple_conv_chat_remove_user(PURPLE_CONV_CHAT(chat->conv), jid->resource, status); jabber_chat_remove_handle(chat, jid->resource); } } } else { if(!chat->conv) { chat->id = i++; chat->muc = muc; chat->conv = serv_got_joined_chat(js->gc, chat->id, room_jid); purple_conv_chat_set_nick(PURPLE_CONV_CHAT(chat->conv), chat->handle); jabber_chat_disco_traffic(chat); } jabber_buddy_track_resource(jb, jid->resource, priority, state, status); jabber_chat_track_handle(chat, jid->resource, real_jid, affiliation, role); if(!jabber_chat_find_buddy(chat->conv, jid->resource)) purple_conv_chat_add_user(PURPLE_CONV_CHAT(chat->conv), jid->resource, real_jid, flags, !delayed); else purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(chat->conv), jid->resource, flags); } g_free(room_jid); } else { buddy_name = g_strdup_printf("%s%s%s", jid->node ? jid->node : "", jid->node ? "@" : "", jid->domain); if((b = purple_find_buddy(js->gc->account, buddy_name)) == NULL) { purple_debug_warning("jabber", "Got presence for unknown buddy %s on account %s (%x)", buddy_name, purple_account_get_username(js->gc->account), js->gc->account); jabber_id_free(jid); g_free(avatar_hash); g_free(buddy_name); g_free(status); return; } if(avatar_hash) { const char *avatar_hash2 = purple_buddy_icons_get_checksum_for_user(b); if(!avatar_hash2 || strcmp(avatar_hash, avatar_hash2)) { JabberIq *iq; xmlnode *vcard; /* XXX this is a crappy way of trying to prevent * someone from spamming us with presence packets * and causing us to DoS ourselves...what we really * need is a queue system that can throttle itself, * but i'm too tired to write that right now */ if(!g_slist_find(js->pending_avatar_requests, jb)) { js->pending_avatar_requests = g_slist_prepend(js->pending_avatar_requests, jb); iq = jabber_iq_new(js, JABBER_IQ_GET); xmlnode_set_attrib(iq->node, "to", buddy_name); vcard = xmlnode_new_child(iq->node, "vCard"); xmlnode_set_namespace(vcard, "vcard-temp"); jabber_iq_set_callback(iq, jabber_vcard_parse_avatar, NULL); jabber_iq_send(iq); } } } if(state == JABBER_BUDDY_STATE_ERROR || (type && (!strcmp(type, "unavailable") || !strcmp(type, "unsubscribed")))) { PurpleConversation *conv; jabber_buddy_remove_resource(jb, jid->resource); if((conv = jabber_find_unnormalized_conv(from, js->gc->account))) purple_conversation_set_name(conv, buddy_name); } else { jbr = jabber_buddy_track_resource(jb, jid->resource, priority, state, status); } if((found_jbr = jabber_buddy_find_resource(jb, NULL))) { if(!jbr || jbr == found_jbr) { purple_prpl_got_user_status(js->gc->account, buddy_name, jabber_buddy_state_get_status_id(state), "priority", found_jbr->priority, found_jbr->status ? "message" : NULL, found_jbr->status, NULL); } } else { purple_prpl_got_user_status(js->gc->account, buddy_name, "offline", status ? "message" : NULL, status, NULL); } g_free(buddy_name); } g_free(status); jabber_id_free(jid); g_free(avatar_hash);}void jabber_presence_subscription_set(JabberStream *js, const char *who, const char *type){ xmlnode *presence = xmlnode_new("presence"); xmlnode_set_attrib(presence, "to", who); xmlnode_set_attrib(presence, "type", type); jabber_send(js, presence); xmlnode_free(presence);}void purple_status_to_jabber(const PurpleStatus *status, JabberBuddyState *state, char **msg, int *priority){ const char *status_id = NULL; const char *formatted_msg = NULL; if(state) *state = JABBER_BUDDY_STATE_UNKNOWN; if(msg) *msg = NULL; if(priority) *priority = 0; if(!status) { if(state) *state = JABBER_BUDDY_STATE_UNAVAILABLE; } else { if(state) { status_id = purple_status_get_id(status); *state = jabber_buddy_status_id_get_state(status_id); } if(msg) { formatted_msg = purple_status_get_attr_string(status, "message"); /* if the message is blank, then there really isn't a message */ if(formatted_msg && !*formatted_msg) formatted_msg = NULL; if(formatted_msg) *msg = purple_markup_strip_html(formatted_msg); } if(priority) *priority = purple_status_get_attr_int(status, "priority"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -