| 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) |