# HG changeset patch # User Mikael Berthe # Date 1128185594 -7200 # Node ID 644b8bf9ca4dec5d1eb8f2432013ab448eb702c6 # Parent 73aa14eba3c78bfb2e1d4af08727df01189c9303 Improve MUC presence messages handling - Display messages when someone joins, leaves, or changes his nickname - Update occupants roles and real jid (if available) - Fix some memory leaks diff -r 73aa14eba3c7 -r 644b8bf9ca4d mcabber/src/hooks.c --- a/mcabber/src/hooks.c Sat Oct 01 16:00:17 2005 +0200 +++ b/mcabber/src/hooks.c Sat Oct 01 18:53:14 2005 +0200 @@ -114,7 +114,7 @@ imstatus2char[roster_getstatus(jid, resname)], imstatus2char[status], jid, rn, ((status_msg) ? status_msg : "")); - roster_setstatus(jid, rn, prio, status, status_msg); + roster_setstatus(jid, rn, prio, status, status_msg, role_none, NULL); buddylist_build(); scr_DrawRoster(); hlog_write_status(jid, 0, status, status_msg); diff -r 73aa14eba3c7 -r 644b8bf9ca4d mcabber/src/jabglue.c --- a/mcabber/src/jabglue.c Sat Oct 01 16:00:17 2005 +0200 +++ b/mcabber/src/jabglue.c Sat Oct 01 18:53:14 2005 +0200 @@ -1017,17 +1017,70 @@ for ( ; x; x = xmlnode_get_nextsibling(x)) { if ((p = xmlnode_get_name(x)) && !strcmp(p, "x")) if ((p = xmlnode_get_attrib(x, "xmlns")) && - !strncasecmp(p, "http://jabber.org/protocol/muc", 30)) + !strcasecmp(p, "http://jabber.org/protocol/muc#user")) break; } if (x) { // This is a MUC presence message - roster_add_user(r, NULL, NULL, ROSTER_TYPE_ROOM); + enum imrole mbrole = role_none; + const char *mbrjid = NULL; + const char *mbnewnick = NULL; + GSList *room_elt; + + // Add room if it doesn't already exist + room_elt = roster_add_user(r, NULL, NULL, ROSTER_TYPE_ROOM); + + // Get room member's information + y = xmlnode_get_tag(x, "item"); + if (y) { + p = xmlnode_get_attrib(y, "role"); + if (p) { + if (!strcmp(p, "moderator")) mbrole = role_moderator; + else if (!strcmp(p, "participant")) mbrole = role_participant; + else if (!strcmp(p, "visitor")) mbrole = role_visitor; + else if (!strcmp(p, "none")) mbrole = role_none; + else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"", + from, p); + } + p = xmlnode_get_attrib(y, "jid"); + if (p) mbrjid = p; + p = xmlnode_get_attrib(y, "nick"); + if (p) mbnewnick = p; + } + // Check for nickname change + y = xmlnode_get_tag(x, "status"); + if (y && mbnewnick) { + p = xmlnode_get_attrib(y, "code"); + if (p && !strcmp(p, "303")) { + gchar *mbuf; + mbuf = g_strdup_printf("%s is now known as %s", rname, mbnewnick); + scr_WriteIncomingMessage(r, mbuf, 0, HBB_PREFIX_INFO); + g_free(mbuf); + buddy_resource_setname(room_elt->data, rname, mbnewnick); + } + } + + // Check for departure/arrival + if (!mbnewnick && mbrole == role_none) { + gchar *mbuf = g_strdup_printf("%s has left", rname); + scr_WriteIncomingMessage(r, mbuf, 0, HBB_PREFIX_INFO); + g_free(mbuf); + } else if (buddy_getstatus(room_elt->data, rname) == offline && + ust != offline) { + gchar *mbuf = g_strdup_printf("%s has joined", rname); + scr_WriteIncomingMessage(r, mbuf, 0, HBB_PREFIX_INFO); + g_free(mbuf); + } + + // Update room member status if (rname) - roster_setstatus(r, rname, bpprio, ust, NULL); + roster_setstatus(r, rname, bpprio, ust, NULL, mbrole, mbrjid); else scr_LogPrint(LPRINT_LOGNORM, "MUC DBG: no rname!"); /* DBG */ + g_free(r); + if (s) g_free(s); + buddylist_build(); scr_DrawRoster(); break; diff -r 73aa14eba3c7 -r 644b8bf9ca4d mcabber/src/roster.c --- a/mcabber/src/roster.c Sat Oct 01 16:00:17 2005 +0200 +++ b/mcabber/src/roster.c Sat Oct 01 18:53:14 2005 +0200 @@ -370,8 +370,11 @@ } } +// roster_setstatus() +// Note: resname, role and realjid are for room members only void roster_setstatus(const char *jid, const char *resname, gchar prio, - enum imstatus bstat, const char *status_msg) + enum imstatus bstat, const char *status_msg, + enum imrole role, const char *realjid) { GSList *sl_user; roster *roster_usr; @@ -403,6 +406,15 @@ } if (status_msg) p_res->status_msg = g_strdup(status_msg); + + p_res->role = role; + + if (p_res->realjid) { + g_free((gchar*)p_res->realjid); + p_res->realjid = NULL; + } + if (realjid) + p_res->realjid = g_strdup(realjid); } // roster_setflags() @@ -835,6 +847,23 @@ return reslist; } +// buddy_resource_setname(roster_data, oldname, newname) +// Useful for nickname change in a MUC room +void buddy_resource_setname(gpointer rosterdata, const char *resname, + const char *newname) +{ + roster *roster_usr = rosterdata; + res *p_res = get_resource(roster_usr, resname); + if (p_res) { + if (p_res->name) { + g_free((gchar*)p_res->name); + p_res->name = NULL; + } + if (newname) + p_res->name = g_strdup(newname); + } +} + // buddy_del_all_resources() // Remove all resources from the specified buddy void buddy_del_all_resources(gpointer rosterdata) diff -r 73aa14eba3c7 -r 644b8bf9ca4d mcabber/src/roster.h --- a/mcabber/src/roster.h Sat Oct 01 16:00:17 2005 +0200 +++ b/mcabber/src/roster.h Sat Oct 01 18:53:14 2005 +0200 @@ -53,7 +53,8 @@ void roster_del_user(const char *jid); void roster_free(void); void roster_setstatus(const char *jid, const char *resname, gchar prio, - enum imstatus bstat, const char *status_msg); + enum imstatus bstat, const char *status_msg, + enum imrole role, const char *realjid); void roster_setflags(const char *jid, guint flags, guint value); void roster_msg_setflag(const char *jid, guint value); void roster_settype(const char *jid, guint type); @@ -78,6 +79,8 @@ const char *buddy_getstatusmsg(gpointer rosterdata, const char *resname); gchar buddy_getresourceprio(gpointer rosterdata, const char *resname); GSList *buddy_getresources(gpointer rosterdata); +void buddy_resource_setname(gpointer rosterdata, const char *resname, + const char *newname); void buddy_del_all_resources(gpointer rosterdata); void buddy_setflags(gpointer rosterdata, guint flags, guint value); guint buddy_getflags(gpointer rosterdata);