1994 if ((p = xmlnode_get_attrib(x, "stamp")) != NULL) |
1994 if ((p = xmlnode_get_attrib(x, "stamp")) != NULL) |
1995 return from_iso8601(p, 1); |
1995 return from_iso8601(p, 1); |
1996 return 0; |
1996 return 0; |
1997 } |
1997 } |
1998 |
1998 |
|
1999 // muc_get_item_info(...) |
|
2000 // Get room member's information from xmlndata. |
|
2001 // The variables must be initialized before calling this function, |
|
2002 // because they are not touched if the relevant information is missing. |
|
2003 static void muc_get_item_info(const char *from, xmlnode xmldata, |
|
2004 enum imrole *mbrole, enum imaffiliation *mbaffil, |
|
2005 const char **mbjid, const char **mbnick, |
|
2006 const char **actorjid, const char **reason) |
|
2007 { |
|
2008 xmlnode y, z; |
|
2009 char *p; |
|
2010 |
|
2011 y = xmlnode_get_tag(xmldata, "item"); |
|
2012 if (!y) |
|
2013 return; |
|
2014 |
|
2015 p = xmlnode_get_attrib(y, "affiliation"); |
|
2016 if (p) { |
|
2017 if (!strcmp(p, "owner")) *mbaffil = affil_owner; |
|
2018 else if (!strcmp(p, "admin")) *mbaffil = affil_admin; |
|
2019 else if (!strcmp(p, "member")) *mbaffil = affil_member; |
|
2020 else if (!strcmp(p, "outcast")) *mbaffil = affil_outcast; |
|
2021 else if (!strcmp(p, "none")) *mbaffil = affil_none; |
|
2022 else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown affiliation \"%s\"", |
|
2023 from, p); |
|
2024 } |
|
2025 p = xmlnode_get_attrib(y, "role"); |
|
2026 if (p) { |
|
2027 if (!strcmp(p, "moderator")) *mbrole = role_moderator; |
|
2028 else if (!strcmp(p, "participant")) *mbrole = role_participant; |
|
2029 else if (!strcmp(p, "visitor")) *mbrole = role_visitor; |
|
2030 else if (!strcmp(p, "none")) *mbrole = role_none; |
|
2031 else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"", |
|
2032 from, p); |
|
2033 } |
|
2034 *mbjid = xmlnode_get_attrib(y, "jid"); |
|
2035 *mbnick = xmlnode_get_attrib(y, "nick"); |
|
2036 // For kick/ban, there can be actor and reason tags |
|
2037 *reason = xmlnode_get_tag_data(y, "reason"); |
|
2038 z = xmlnode_get_tag(y, "actor"); |
|
2039 if (z) |
|
2040 *actorjid = xmlnode_get_attrib(z, "jid"); |
|
2041 } |
|
2042 |
|
2043 // muc_handle_join(...) |
|
2044 // Handle a join event in a MUC room. |
|
2045 // This function will return the new_member value TRUE if somebody else joins |
|
2046 // the room (and FALSE if _we_ are joining the room). |
|
2047 static bool muc_handle_join(const GSList *room_elt, const char *rname, |
|
2048 const char *roomjid, const char *ournick, |
|
2049 enum room_printstatus printstatus, |
|
2050 time_t usttime, int log_muc_conf) |
|
2051 { |
|
2052 bool new_member = FALSE; // True if somebody else joins the room (not us) |
|
2053 gchar *mbuf; |
|
2054 |
|
2055 if (!buddy_getinsideroom(room_elt->data)) { |
|
2056 // We weren't inside the room yet. Now we are. |
|
2057 // However, this could be a presence packet from another room member |
|
2058 |
|
2059 buddy_setinsideroom(room_elt->data, TRUE); |
|
2060 // Set the message flag unless we're already in the room buffer window |
|
2061 scr_setmsgflag_if_needed(roomjid, FALSE); |
|
2062 // Add a message to the tracelog file |
|
2063 mbuf = g_strdup_printf("You have joined %s as \"%s\"", roomjid, ournick); |
|
2064 scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf); |
|
2065 g_free(mbuf); |
|
2066 mbuf = g_strdup_printf("You have joined as \"%s\"", ournick); |
|
2067 |
|
2068 // The 1st presence message could be for another room member |
|
2069 if (strcmp(ournick, rname)) { |
|
2070 // Display current mbuf and create a new message for the member |
|
2071 // Note: the usttime timestamp is related to the other member, |
|
2072 // so we use 0 here. |
|
2073 scr_WriteIncomingMessage(roomjid, mbuf, 0, |
|
2074 HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); |
|
2075 if (log_muc_conf) |
|
2076 hlog_write_message(roomjid, 0, -1, mbuf); |
|
2077 g_free(mbuf); |
|
2078 if (printstatus != status_none) |
|
2079 mbuf = g_strdup_printf("%s has joined", rname); |
|
2080 else |
|
2081 mbuf = NULL; |
|
2082 new_member = TRUE; |
|
2083 } |
|
2084 } else { |
|
2085 mbuf = NULL; |
|
2086 if (strcmp(ournick, rname)) { |
|
2087 if (printstatus != status_none) |
|
2088 mbuf = g_strdup_printf("%s has joined", rname); |
|
2089 new_member = TRUE; |
|
2090 } |
|
2091 } |
|
2092 |
|
2093 if (mbuf) { |
|
2094 guint msgflags = HBB_PREFIX_INFO; |
|
2095 if (!settings_opt_get_int("muc_flag_joins")) |
|
2096 msgflags |= HBB_PREFIX_NOFLAG; |
|
2097 scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0); |
|
2098 if (log_muc_conf) |
|
2099 hlog_write_message(roomjid, 0, -1, mbuf); |
|
2100 g_free(mbuf); |
|
2101 } |
|
2102 |
|
2103 return new_member; |
|
2104 } |
|
2105 |
1999 static void handle_presence_muc(const char *from, xmlnode xmldata, |
2106 static void handle_presence_muc(const char *from, xmlnode xmldata, |
2000 const char *roomjid, const char *rname, |
2107 const char *roomjid, const char *rname, |
2001 enum imstatus ust, char *ustmsg, |
2108 enum imstatus ust, char *ustmsg, |
2002 time_t usttime, char bpprio) |
2109 time_t usttime, char bpprio) |
2003 { |
2110 { |
2032 // Make sure this is a room (it can be a conversion user->room) |
2139 // Make sure this is a room (it can be a conversion user->room) |
2033 buddy_settype(room_elt->data, ROSTER_TYPE_ROOM); |
2140 buddy_settype(room_elt->data, ROSTER_TYPE_ROOM); |
2034 } |
2141 } |
2035 |
2142 |
2036 // Get room member's information |
2143 // Get room member's information |
2037 y = xmlnode_get_tag(xmldata, "item"); |
2144 muc_get_item_info(from, xmldata, &mbrole, &mbaffil, &mbjid, &mbnick, |
2038 if (y) { |
2145 &actorjid, &reason); |
2039 xmlnode z; |
|
2040 p = xmlnode_get_attrib(y, "affiliation"); |
|
2041 if (p) { |
|
2042 if (!strcmp(p, "owner")) mbaffil = affil_owner; |
|
2043 else if (!strcmp(p, "admin")) mbaffil = affil_admin; |
|
2044 else if (!strcmp(p, "member")) mbaffil = affil_member; |
|
2045 else if (!strcmp(p, "outcast")) mbaffil = affil_outcast; |
|
2046 else if (!strcmp(p, "none")) mbaffil = affil_none; |
|
2047 else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown affiliation \"%s\"", |
|
2048 from, p); |
|
2049 } |
|
2050 p = xmlnode_get_attrib(y, "role"); |
|
2051 if (p) { |
|
2052 if (!strcmp(p, "moderator")) mbrole = role_moderator; |
|
2053 else if (!strcmp(p, "participant")) mbrole = role_participant; |
|
2054 else if (!strcmp(p, "visitor")) mbrole = role_visitor; |
|
2055 else if (!strcmp(p, "none")) mbrole = role_none; |
|
2056 else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"", |
|
2057 from, p); |
|
2058 } |
|
2059 mbjid = xmlnode_get_attrib(y, "jid"); |
|
2060 mbnick = xmlnode_get_attrib(y, "nick"); |
|
2061 // For kick/ban, there can be actor and reason tags |
|
2062 reason = xmlnode_get_tag_data(y, "reason"); |
|
2063 z = xmlnode_get_tag(y, "actor"); |
|
2064 if (z) |
|
2065 actorjid = xmlnode_get_attrib(z, "jid"); |
|
2066 } |
|
2067 |
2146 |
2068 // Get our room nickname |
2147 // Get our room nickname |
2069 ournick = buddy_getnickname(room_elt->data); |
2148 ournick = buddy_getnickname(room_elt->data); |
2070 |
2149 |
2071 if (!ournick) { |
2150 if (!ournick) { |
2206 return; |
2286 return; |
2207 } |
2287 } |
2208 g_free(mbuf); |
2288 g_free(mbuf); |
2209 } else if (buddy_getstatus(room_elt->data, rname) == offline && |
2289 } else if (buddy_getstatus(room_elt->data, rname) == offline && |
2210 ust != offline) { |
2290 ust != offline) { |
2211 |
2291 // Somebody is joining |
2212 if (!buddy_getinsideroom(room_elt->data)) { |
2292 new_member = muc_handle_join(room_elt, rname, roomjid, ournick, |
2213 // We weren't inside the room yet. Now we are. |
2293 printstatus, usttime, log_muc_conf); |
2214 // However, this could be a presence packet from another room member |
|
2215 |
|
2216 buddy_setinsideroom(room_elt->data, TRUE); |
|
2217 // Set the message flag unless we're already in the room buffer window |
|
2218 scr_setmsgflag_if_needed(roomjid, FALSE); |
|
2219 // Add a message to the tracelog file |
|
2220 mbuf = g_strdup_printf("You have joined %s as \"%s\"", roomjid, ournick); |
|
2221 scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf); |
|
2222 g_free(mbuf); |
|
2223 mbuf = g_strdup_printf("You have joined as \"%s\"", ournick); |
|
2224 |
|
2225 // The 1st presence message could be for another room member |
|
2226 if (strcmp(ournick, rname)) { |
|
2227 // Display current mbuf and create a new message for the member |
|
2228 // Note: the usttime timestamp is related to the other member, |
|
2229 // so we use 0 here. |
|
2230 scr_WriteIncomingMessage(roomjid, mbuf, 0, |
|
2231 HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); |
|
2232 if (log_muc_conf) |
|
2233 hlog_write_message(roomjid, 0, -1, mbuf); |
|
2234 g_free(mbuf); |
|
2235 if (printstatus != status_none) |
|
2236 mbuf = g_strdup_printf("%s has joined", rname); |
|
2237 else |
|
2238 mbuf = NULL; |
|
2239 new_member = TRUE; |
|
2240 } |
|
2241 } else { |
|
2242 mbuf = NULL; |
|
2243 if (strcmp(ournick, rname)) { |
|
2244 if (printstatus != status_none) |
|
2245 mbuf = g_strdup_printf("%s has joined", rname); |
|
2246 new_member = TRUE; |
|
2247 } |
|
2248 } |
|
2249 |
|
2250 if (mbuf) { |
|
2251 msgflags = HBB_PREFIX_INFO; |
|
2252 if (!settings_opt_get_int("muc_flag_joins")) |
|
2253 msgflags |= HBB_PREFIX_NOFLAG; |
|
2254 scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0); |
|
2255 if (log_muc_conf) |
|
2256 hlog_write_message(roomjid, 0, -1, mbuf); |
|
2257 g_free(mbuf); |
|
2258 } |
|
2259 } else { |
2294 } else { |
2260 // This is a simple member status change |
2295 // This is a simple member status change |
2261 |
2296 |
2262 if (printstatus == status_all && !nickchange) { |
2297 if (printstatus == status_all && !nickchange) { |
2263 mbuf = g_strdup_printf("Member status has changed: %s [%c] %s", rname, |
2298 mbuf = g_strdup_printf("Member status has changed: %s [%c] %s", rname, |