changeset 468:644b8bf9ca4d

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
author Mikael Berthe <mikael@lilotux.net>
date Sat, 01 Oct 2005 18:53:14 +0200
parents 73aa14eba3c7
children a926523d2392
files mcabber/src/hooks.c mcabber/src/jabglue.c mcabber/src/roster.c mcabber/src/roster.h
diffstat 4 files changed, 91 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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);
--- 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;
--- 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)
--- 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);