comparison libpurple/protocols/jabber/presence.c @ 27509:ebd9630ffc77

propagate from branch 'im.pidgin.pidgin' (head cec487e50b3df746ae8b23771513bf85734f618d) to branch 'im.pidgin.cpw.darkrain42.obsolete' (head 1fc27ec0bc11e95aeff8c890ab68a5ddcb4bfb8d)
author Paul Aurich <paul@darkrain42.org>
date Sun, 12 Jul 2009 04:41:56 +0000
parents 01927ce552bc 3bb1085235d0
children ed284238509b
comparison
equal deleted inserted replaced
27369:01927ce552bc 27509:ebd9630ffc77
57 xmlnode_set_attrib(presence, "to", chat_full_jid); 57 xmlnode_set_attrib(presence, "to", chat_full_jid);
58 jabber_send(chat->js, presence); 58 jabber_send(chat->js, presence);
59 g_free(chat_full_jid); 59 g_free(chat_full_jid);
60 } 60 }
61 61
62 void jabber_presence_fake_to_self(JabberStream *js, const PurpleStatus *gstatus) { 62 void jabber_presence_fake_to_self(JabberStream *js, PurpleStatus *status)
63 char *my_base_jid; 63 {
64 64 PurpleAccount *account;
65 if(!js->user) 65 const char *username;
66 return; 66
67 67 g_return_if_fail(js->user != NULL);
68 my_base_jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain); 68
69 if(purple_find_buddy(js->gc->account, my_base_jid)) { 69 account = purple_connection_get_account(js->gc);
70 JabberBuddy *jb; 70 username = purple_account_get_username(account);
71 if (status == NULL)
72 status = purple_account_get_active_status(account);
73
74 if (purple_find_buddy(account, username)) {
75 JabberBuddy *jb = jabber_buddy_find(js, username, TRUE);
71 JabberBuddyResource *jbr; 76 JabberBuddyResource *jbr;
72 if((jb = jabber_buddy_find(js, my_base_jid, TRUE))) { 77 JabberBuddyState state;
73 JabberBuddyState state; 78 char *msg;
74 char *msg; 79 int priority;
75 int priority; 80
76 81 g_return_if_fail(jb != NULL);
77 purple_status_to_jabber(gstatus, &state, &msg, &priority); 82
78 83 purple_status_to_jabber(status, &state, &msg, &priority);
79 if (state == JABBER_BUDDY_STATE_UNAVAILABLE || state == JABBER_BUDDY_STATE_UNKNOWN) { 84
80 jabber_buddy_remove_resource(jb, js->user->resource); 85 if (state == JABBER_BUDDY_STATE_UNAVAILABLE ||
81 } else { 86 state == JABBER_BUDDY_STATE_UNKNOWN) {
82 jabber_buddy_track_resource(jb, js->user->resource, priority, state, msg); 87 jabber_buddy_remove_resource(jb, js->user->resource);
83 } 88 } else {
84 if((jbr = jabber_buddy_find_resource(jb, NULL))) { 89 jabber_buddy_track_resource(jb, js->user->resource, priority,
85 purple_prpl_got_user_status(js->gc->account, my_base_jid, jabber_buddy_state_get_status_id(jbr->state), "priority", jbr->priority, jbr->status ? "message" : NULL, jbr->status, NULL); 90 state, msg);
86 } else { 91 }
87 purple_prpl_got_user_status(js->gc->account, my_base_jid, "offline", msg ? "message" : NULL, msg, NULL); 92
88 } 93 if ((jbr = jabber_buddy_find_resource(jb, NULL))) {
89 94 purple_prpl_got_user_status(js->gc->account, username, jabber_buddy_state_get_status_id(jbr->state), "priority", jbr->priority, jbr->status ? "message" : NULL, jbr->status, NULL);
90 g_free(msg); 95 } else {
91 } 96 purple_prpl_got_user_status(js->gc->account, username, "offline", msg ? "message" : NULL, msg, NULL);
92 } 97 }
93 g_free(my_base_jid); 98 g_free(msg);
99 }
94 } 100 }
95 101
96 void jabber_set_status(PurpleAccount *account, PurpleStatus *status) 102 void jabber_set_status(PurpleAccount *account, PurpleStatus *status)
97 { 103 {
98 PurpleConnection *gc; 104 PurpleConnection *gc;
131 account = purple_connection_get_account(js->gc); 137 account = purple_connection_get_account(js->gc);
132 p = purple_account_get_presence(account); 138 p = purple_account_get_presence(account);
133 status = purple_presence_get_active_status(p); 139 status = purple_presence_get_active_status(p);
134 140
135 /* we don't want to send presence before we've gotten our roster */ 141 /* we don't want to send presence before we've gotten our roster */
136 if(!js->roster_parsed) { 142 if (js->state != JABBER_STREAM_CONNECTED) {
137 purple_debug_info("jabber", "attempt to send presence before roster retrieved\n"); 143 purple_debug_info("jabber", "attempt to send presence before roster retrieved\n");
138 return; 144 return;
139 } 145 }
140 146
141 purple_status_to_jabber(status, &state, &stripped, &priority); 147 purple_status_to_jabber(status, &state, &stripped, &priority);
757 real_jid, flags, !delayed); 763 real_jid, flags, !delayed);
758 else 764 else
759 purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(chat->conv), jid->resource, 765 purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(chat->conv), jid->resource,
760 flags); 766 flags);
761 } else if (g_str_equal(type, "unavailable")) { 767 } else if (g_str_equal(type, "unavailable")) {
768 xmlnode *x;
762 gboolean nick_change = FALSE; 769 gboolean nick_change = FALSE;
763 gboolean kick = FALSE; 770 gboolean kick = FALSE;
764 gboolean is_our_resource = FALSE; /* Is the presence about us? */ 771 gboolean is_our_resource = FALSE; /* Is the presence about us? */
765 772
766 /* If the chat nick is invalid, we haven't yet joined, or we've 773 /* If the chat nick is invalid, we haven't yet joined, or we've
779 } 786 }
780 787
781 is_our_resource = (0 == g_utf8_collate(jid->resource, chat->handle)); 788 is_our_resource = (0 == g_utf8_collate(jid->resource, chat->handle));
782 789
783 jabber_buddy_remove_resource(jb, jid->resource); 790 jabber_buddy_remove_resource(jb, jid->resource);
784 if(chat->muc) { 791
785 xmlnode *x; 792 x = xmlnode_get_child_with_namespace(packet, "x",
786 for(x = xmlnode_get_child(packet, "x"); x; x = xmlnode_get_next_twin(x)) { 793 "http://jabber.org/protocol/muc#user");
787 const char *xmlns, *nick, *code; 794 if (chat->muc && x) {
788 xmlnode *stat, *item; 795 const char *nick;
789 if(!(xmlns = xmlnode_get_namespace(x)) || 796 const char *code = NULL;
790 strcmp(xmlns, "http://jabber.org/protocol/muc#user")) 797 const char *item_jid = NULL;
791 continue; 798 xmlnode *stat;
792 if(!(stat = xmlnode_get_child(x, "status"))) 799 xmlnode *item;
793 continue; 800
794 if(!(code = xmlnode_get_attrib(stat, "code"))) 801 item = xmlnode_get_child(x, "item");
795 continue; 802 if (item)
796 803 item_jid = xmlnode_get_attrib(item, "jid");
797 item = xmlnode_get_child(x, "item"); 804
798 805
806 stat = xmlnode_get_child(x, "status");
807
808 if (stat)
809 code = xmlnode_get_attrib(stat, "code");
810
811 if (code) {
799 if(!strcmp(code, "301")) { 812 if(!strcmp(code, "301")) {
800 /* XXX: we got banned */ 813 /* XXX: we got banned */
801 } else if(!strcmp(code, "303")) { 814 } else if(!strcmp(code, "303") && item &&
802 if (!item) 815 (nick = xmlnode_get_attrib(item, "nick"))) {
803 continue;
804 if(!(nick = xmlnode_get_attrib(item, "nick")))
805 continue;
806 nick_change = TRUE; 816 nick_change = TRUE;
807 if(!strcmp(jid->resource, chat->handle)) { 817 if(!strcmp(jid->resource, chat->handle)) {
808 g_free(chat->handle); 818 g_free(chat->handle);
809 chat->handle = g_strdup(nick); 819 chat->handle = g_strdup(nick);
810 } 820 }
811 purple_conv_chat_rename_user(PURPLE_CONV_CHAT(chat->conv), jid->resource, nick); 821 purple_conv_chat_rename_user(PURPLE_CONV_CHAT(chat->conv), jid->resource, nick);
812 jabber_chat_remove_handle(chat, jid->resource); 822 jabber_chat_remove_handle(chat, jid->resource);
813 break; 823 /* TODO: Enable this when this is in a for-loop...
824 break; */
814 } else if(!strcmp(code, "307")) { 825 } else if(!strcmp(code, "307")) {
815 /* Someone was kicked from the room */ 826 /* Someone was kicked from the room */
816 xmlnode *reason = NULL, *actor = NULL; 827 xmlnode *reason = NULL, *actor = NULL;
817 const char *actor_name = NULL; 828 const char *actor_name = NULL;
818 char *reason_text = NULL; 829 char *reason_text = NULL;
857 } else if(!strcmp(code, "322")) { 868 } else if(!strcmp(code, "322")) {
858 /* XXX: removed because room is now members-only */ 869 /* XXX: removed because room is now members-only */
859 } else if(!strcmp(code, "332")) { 870 } else if(!strcmp(code, "332")) {
860 /* XXX: removed due to system shutdown */ 871 /* XXX: removed due to system shutdown */
861 } 872 }
873 }
874
875 /*
876 * Possibly another connected resource of our JID (see XEP-0045
877 * v1.24 section 7.1.10) being disconnected. Should be
878 * distinguished by the item_jid.
879 * Also possibly works around bits of an Openfire bug. See
880 * #8319.
881 */
882 if (is_our_resource && !purple_strequal(from, item_jid)) {
883 /* TODO: When the above is a loop, this needs to still act
884 * sanely for all cases (this code is a little fragile). */
885 if (!kick && !nick_change)
886 /* Presumably, kicks and nick changes also affect us. */
887 is_our_resource = FALSE;
862 } 888 }
863 } 889 }
864 if(!nick_change) { 890 if(!nick_change) {
865 if (is_our_resource) { 891 if (is_our_resource) {
866 if (kick) 892 if (kick)