| 589 jbr = jabber_buddy_track_resource(presence->jb, presence->jid_from->resource, presence->priority, presence->state, presence->status); |
589 jbr = jabber_buddy_track_resource(presence->jb, presence->jid_from->resource, presence->priority, presence->state, presence->status); |
| 590 jbr->commands_fetched = TRUE; |
590 jbr->commands_fetched = TRUE; |
| 591 |
591 |
| 592 jabber_chat_track_handle(chat, presence->jid_from->resource, jid, affiliation, role); |
592 jabber_chat_track_handle(chat, presence->jid_from->resource, jid, affiliation, role); |
| 593 |
593 |
| 594 if(!jabber_chat_find_buddy(chat->conv, presence->jid_from->resource)) |
594 if(!jabber_chat_find_buddy(chat->conv, presence->jid_from->resource)) { |
| 595 purple_chat_conversation_add_user(chat->conv, presence->jid_from->resource, |
595 gboolean new_arrival = FALSE; |
| 596 jid, flags, chat->joined > 0 && ((!presence->delayed) || (presence->sent > chat->joined))); |
596 |
| 597 else |
597 if(chat->joined != NULL) { |
| |
598 gint newer = -1; |
| |
599 |
| |
600 if(presence->sent != NULL) { |
| |
601 newer = g_date_time_compare(presence->sent, chat->joined); |
| |
602 } |
| |
603 |
| |
604 if(!presence->delayed || newer > 0) { |
| |
605 new_arrival = TRUE; |
| |
606 } |
| |
607 } |
| |
608 |
| |
609 purple_chat_conversation_add_user(chat->conv, |
| |
610 presence->jid_from->resource, |
| |
611 jid, flags, new_arrival); |
| |
612 } else { |
| 598 purple_chat_user_set_flags(purple_chat_conversation_find_user(chat->conv, presence->jid_from->resource), |
613 purple_chat_user_set_flags(purple_chat_conversation_find_user(chat->conv, presence->jid_from->resource), |
| 599 flags); |
614 flags); |
| 600 |
615 } |
| 601 if (is_our_resource && chat->joined == 0) |
616 |
| 602 chat->joined = time(NULL); |
617 if (is_our_resource && chat->joined == NULL) { |
| |
618 chat->joined = g_date_time_new_now_utc(); |
| |
619 } |
| 603 |
620 |
| 604 } else if (presence->type == JABBER_PRESENCE_UNAVAILABLE) { |
621 } else if (presence->type == JABBER_PRESENCE_UNAVAILABLE) { |
| 605 gboolean nick_change = FALSE; |
622 gboolean nick_change = FALSE; |
| 606 gboolean kick = FALSE; |
623 gboolean kick = FALSE; |
| 607 gboolean is_our_resource = FALSE; /* Is the presence about us? */ |
624 gboolean is_our_resource = FALSE; /* Is the presence about us? */ |
| 866 PurpleXmlNode *child; |
883 PurpleXmlNode *child; |
| 867 |
884 |
| 868 memset(&presence, 0, sizeof(presence)); |
885 memset(&presence, 0, sizeof(presence)); |
| 869 /* defaults */ |
886 /* defaults */ |
| 870 presence.state = JABBER_BUDDY_STATE_UNKNOWN; |
887 presence.state = JABBER_BUDDY_STATE_UNKNOWN; |
| 871 presence.sent = time(NULL); |
888 presence.sent = g_date_time_new_now_utc(); |
| 872 /* interesting values */ |
889 /* interesting values */ |
| 873 presence.from = purple_xmlnode_get_attrib(packet, "from"); |
890 presence.from = purple_xmlnode_get_attrib(packet, "from"); |
| 874 presence.to = purple_xmlnode_get_attrib(packet, "to"); |
891 presence.to = purple_xmlnode_get_attrib(packet, "to"); |
| 875 type = purple_xmlnode_get_attrib(packet, "type"); |
892 type = purple_xmlnode_get_attrib(packet, "type"); |
| 876 presence.type = str_to_presence_type(type); |
893 presence.type = str_to_presence_type(type); |
| 972 if (pih) |
989 if (pih) |
| 973 pih(js, &presence, child); |
990 pih(js, &presence, child); |
| 974 } |
991 } |
| 975 |
992 |
| 976 if (presence.delayed && presence.idle && presence.adjust_idle_for_delay) { |
993 if (presence.delayed && presence.idle && presence.adjust_idle_for_delay) { |
| |
994 GDateTime *now = g_date_time_new_now_utc(); |
| |
995 GTimeSpan difference = 0; |
| |
996 |
| |
997 difference = g_date_time_difference(now, presence.sent); |
| |
998 |
| |
999 g_date_time_unref(now); |
| |
1000 |
| 977 /* Delayed and idle, so update idle time */ |
1001 /* Delayed and idle, so update idle time */ |
| 978 presence.idle = presence.idle + (time(NULL) - presence.sent); |
1002 presence.idle = presence.idle + (difference / G_TIME_SPAN_SECOND); |
| 979 } |
1003 } |
| 980 |
1004 |
| 981 /* TODO: Handle tracking jb(r) here? */ |
1005 /* TODO: Handle tracking jb(r) here? */ |
| 982 |
1006 |
| 983 if (presence.chat) |
1007 if (presence.chat) |
| 1024 g_slist_free(presence.chat_info.codes); |
1048 g_slist_free(presence.chat_info.codes); |
| 1025 g_free(presence.status); |
1049 g_free(presence.status); |
| 1026 g_free(presence.vcard_avatar_hash); |
1050 g_free(presence.vcard_avatar_hash); |
| 1027 g_free(presence.nickname); |
1051 g_free(presence.nickname); |
| 1028 jabber_id_free(presence.jid_from); |
1052 jabber_id_free(presence.jid_from); |
| |
1053 g_clear_pointer(&presence.sent, g_date_time_unref); |
| 1029 } |
1054 } |
| 1030 |
1055 |
| 1031 void jabber_presence_subscription_set(JabberStream *js, const char *who, const char *type) |
1056 void jabber_presence_subscription_set(JabberStream *js, const char *who, const char *type) |
| 1032 { |
1057 { |
| 1033 PurpleXmlNode *presence = purple_xmlnode_new("presence"); |
1058 PurpleXmlNode *presence = purple_xmlnode_new("presence"); |
| 1116 } |
1141 } |
| 1117 |
1142 |
| 1118 static void |
1143 static void |
| 1119 parse_delay(JabberStream *js, JabberPresence *presence, PurpleXmlNode *delay) |
1144 parse_delay(JabberStream *js, JabberPresence *presence, PurpleXmlNode *delay) |
| 1120 { |
1145 { |
| |
1146 GTimeZone *tz = g_time_zone_new_utc(); |
| 1121 const char *stamp = purple_xmlnode_get_attrib(delay, "stamp"); |
1147 const char *stamp = purple_xmlnode_get_attrib(delay, "stamp"); |
| |
1148 |
| 1122 presence->delayed = TRUE; |
1149 presence->delayed = TRUE; |
| 1123 presence->sent = purple_str_to_time(stamp, TRUE, NULL, NULL, NULL); |
1150 presence->sent = g_date_time_new_from_iso8601(stamp, tz); |
| |
1151 |
| |
1152 g_time_zone_unref(tz); |
| 1124 } |
1153 } |
| 1125 |
1154 |
| 1126 static void |
1155 static void |
| 1127 parse_apple_idle(JabberStream *js, JabberPresence *presence, PurpleXmlNode *x) |
1156 parse_apple_idle(JabberStream *js, JabberPresence *presence, PurpleXmlNode *x) |
| 1128 { |
1157 { |