about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server_events.c34
-rw-r--r--src/server_events.h4
-rw-r--r--src/ui/core.c49
-rw-r--r--src/ui/ui.h6
-rw-r--r--src/xmpp/presence.c24
-rw-r--r--src/xmpp/stanza.c4
-rw-r--r--src/xmpp/stanza.h4
7 files changed, 104 insertions, 21 deletions
diff --git a/src/server_events.c b/src/server_events.c
index 0086bd7f..7dfff16e 100644
--- a/src/server_events.c
+++ b/src/server_events.c
@@ -738,15 +738,26 @@ handle_muc_self_online(const char * const room, const char * const nick, gboolea
 
 void
 handle_muc_occupant_online(const char * const room, const char * const nick, const char * const jid,
-    const char * const role, const char * const affiliation, const char * const show, const char * const status)
+    const char * const role, const char * const affiliation, const char * const actor, const char * const reason,
+    const char * const show, const char * const status)
 {
-    gboolean existing = muc_roster_contains_nick(room, nick);
+    Occupant *occupant = muc_roster_item(room, nick);
+
+    const char *old_role = NULL;
+    const char *old_affiliation = NULL;
+    if (occupant) {
+        old_role = muc_occupant_role_str(occupant);
+        old_affiliation = muc_occupant_affiliation_str(occupant);
+    }
+
     gboolean updated = muc_roster_add(room, nick, jid, role, affiliation, show, status);
 
+    // not yet finished joining room
     if (!muc_roster_complete(room)) {
         return;
     }
 
+    // handle nickname change
     char *old_nick = muc_roster_nick_change_complete(room, nick);
     if (old_nick) {
         ui_room_member_nick_change(room, old_nick, nick);
@@ -755,7 +766,8 @@ handle_muc_occupant_online(const char * const room, const char * const nick, con
         return;
     }
 
-    if (!existing) {
+    // joined room
+    if (!occupant) {
         char *muc_status_pref = prefs_get_string(PREF_STATUSES_MUC);
         if (g_strcmp0(muc_status_pref, "none") != 0) {
             ui_room_member_online(room, nick, role, affiliation, show, status);
@@ -765,6 +777,7 @@ handle_muc_occupant_online(const char * const room, const char * const nick, con
         return;
     }
 
+    // presence updated
     if (updated) {
         char *muc_status_pref = prefs_get_string(PREF_STATUSES_MUC);
         if (g_strcmp0(muc_status_pref, "all") == 0) {
@@ -772,8 +785,21 @@ handle_muc_occupant_online(const char * const room, const char * const nick, con
         }
         prefs_free_string(muc_status_pref);
         ui_muc_roster(room);
+
+    // presence unchanged, check for role/affiliation change
     } else {
+        // both changed
+        if ((g_strcmp0(role, old_role) != 0) && (g_strcmp0(affiliation, old_affiliation) != 0)) {
+            ui_room_occupant_role_and_affiliation_change(room, nick, role, affiliation, actor, reason);
+
+        // role changed
+        } else if (g_strcmp0(role, old_role) != 0) {
+            ui_room_occupant_role_change(room, nick, role, actor, reason);
+
+        // affiliation changed
+        } else if (g_strcmp0(affiliation, old_affiliation) != 0) {
+            ui_room_occupant_affiliation_change(room, nick, affiliation, actor, reason);
+        }
         ui_muc_roster(room);
     }
-
 }
\ No newline at end of file
diff --git a/src/server_events.h b/src/server_events.h
index 992c68cc..ea366083 100644
--- a/src/server_events.h
+++ b/src/server_events.h
@@ -114,7 +114,7 @@ void handle_muc_self_online(const char * const room, const char * const nick, gb
     const char * const role, const char * const affiliation, const char * const actor, const char * const reason,
     const char * const jid, const char * const show, const char * const status);
 void handle_muc_occupant_online(const char * const room, const char * const nick, const char * const jid,
-    const char * const role, const char * const affiliation, const char * const show_str,
-    const char * const status_str);
+    const char * const role, const char * const affiliation, const char * const actor, const char * const reason,
+    const char * const show_str, const char * const status_str);
 
 #endif
diff --git a/src/ui/core.c b/src/ui/core.c
index 2f8b3670..40157716 100644
--- a/src/ui/core.c
+++ b/src/ui/core.c
@@ -1382,6 +1382,52 @@ _ui_room_role_and_affiliation_change(const char * const room, const char * const
     win_save_print(window, '!', NULL, NO_DATE, COLOUR_ROOMINFO, "", "");
 }
 
+
+static void
+_ui_room_occupant_role_change(const char * const room, const char * const nick, const char * const role,
+    const char * const actor, const char * const reason)
+{
+    ProfWin *window = wins_get_by_recipient(room);
+    win_save_vprint(window, '!', NULL, NO_EOL, COLOUR_ROOMINFO, "", "%s's role has been changed to: %s", nick, role);
+    if (actor) {
+        win_save_vprint(window, '!', NULL, NO_DATE | NO_EOL, COLOUR_ROOMINFO, "", ", by: %s", actor);
+    }
+    if (reason) {
+        win_save_vprint(window, '!', NULL, NO_DATE | NO_EOL, COLOUR_ROOMINFO, "", ", reason: %s", reason);
+    }
+    win_save_print(window, '!', NULL, NO_DATE, COLOUR_ROOMINFO, "", "");
+}
+
+static void
+_ui_room_occupant_affiliation_change(const char * const room, const char * const nick, const char * const affiliation,
+    const char * const actor, const char * const reason)
+{
+    ProfWin *window = wins_get_by_recipient(room);
+    win_save_vprint(window, '!', NULL, NO_EOL, COLOUR_ROOMINFO, "", "%s's affiliation has been changed to: %s", nick, affiliation);
+    if (actor) {
+        win_save_vprint(window, '!', NULL, NO_DATE | NO_EOL, COLOUR_ROOMINFO, "", ", by: %s", actor);
+    }
+    if (reason) {
+        win_save_vprint(window, '!', NULL, NO_DATE | NO_EOL, COLOUR_ROOMINFO, "", ", reason: %s", reason);
+    }
+    win_save_print(window, '!', NULL, NO_DATE, COLOUR_ROOMINFO, "", "");
+}
+
+static void
+_ui_room_occupant_role_and_affiliation_change(const char * const room, const char * const nick, const char * const role,
+    const char * const affiliation, const char * const actor, const char * const reason)
+{
+    ProfWin *window = wins_get_by_recipient(room);
+    win_save_vprint(window, '!', NULL, NO_EOL, COLOUR_ROOMINFO, "", "%s's role and affiliation have been changed, role: %s, affiliation: %s", nick, role, affiliation);
+    if (actor) {
+        win_save_vprint(window, '!', NULL, NO_DATE | NO_EOL, COLOUR_ROOMINFO, "", ", by: %s", actor);
+    }
+    if (reason) {
+        win_save_vprint(window, '!', NULL, NO_DATE | NO_EOL, COLOUR_ROOMINFO, "", ", reason: %s", reason);
+    }
+    win_save_print(window, '!', NULL, NO_DATE, COLOUR_ROOMINFO, "", "");
+}
+
 static void
 _ui_handle_room_info_error(const char * const room, const char * const error)
 {
@@ -3108,5 +3154,8 @@ ui_init_module(void)
     ui_room_affiliation_change = _ui_room_affiliation_change;
     ui_switch_to_room = _ui_switch_to_room;
     ui_room_role_and_affiliation_change = _ui_room_role_and_affiliation_change;
+    ui_room_occupant_role_change = _ui_room_occupant_role_change;
+    ui_room_occupant_affiliation_change = _ui_room_occupant_affiliation_change;
+    ui_room_occupant_role_and_affiliation_change = _ui_room_occupant_role_and_affiliation_change;
 }
 
diff --git a/src/ui/ui.h b/src/ui/ui.h
index 044ea6e9..7c86e933 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -137,6 +137,12 @@ void (*ui_room_affiliation_change)(const char * const room, const char * const a
     const char * const reason);
 void (*ui_room_role_and_affiliation_change)(const char * const room, const char * const role,
     const char * const affiliation, const char * const actor, const char * const reason);
+void (*ui_room_occupant_role_change)(const char * const room, const char * const nick, const char * const role,
+    const char * const actor, const char * const reason);
+void (*ui_room_occupant_affiliation_change)(const char * const room, const char * const nick, const char * const affiliation,
+    const char * const actor, const char * const reason);
+void (*ui_room_occupant_role_and_affiliation_change)(const char * const room, const char * const nick, const char * const role,
+    const char * const affiliation, const char * const actor, const char * const reason);
 void (*ui_room_roster)(const char * const room, GList *roster, const char * const presence);
 void (*ui_room_history)(const char * const room_jid, const char * const nick,
     GTimeVal tv_stamp, const char * const message);
diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c
index 80377703..620a871d 100644
--- a/src/xmpp/presence.c
+++ b/src/xmpp/presence.c
@@ -736,15 +736,15 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void *
 
                 // kicked from room
                 } else if (g_slist_find_custom(status_codes, "307", (GCompareFunc)g_strcmp0) != NULL) {
-                    char *actor = stanza_get_kickban_actor(stanza);
-                    char *reason = stanza_get_kickban_reason(stanza);
+                    char *actor = stanza_get_actor(stanza);
+                    char *reason = stanza_get_reason(stanza);
                     handle_room_kicked(room, actor, reason);
                     free(reason);
 
                 // banned from room
                 } else if (g_slist_find_custom(status_codes, "301", (GCompareFunc)g_strcmp0) != NULL) {
-                    char *actor = stanza_get_kickban_actor(stanza);
-                    char *reason = stanza_get_kickban_reason(stanza);
+                    char *actor = stanza_get_actor(stanza);
+                    char *reason = stanza_get_reason(stanza);
                     handle_room_banned(room, actor, reason);
                     free(reason);
 
@@ -759,8 +759,8 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void *
         // self online
         } else {
             gboolean config_required = stanza_muc_requires_config(stanza);
-            char *actor = stanza_get_kickban_actor(stanza);
-            char *reason = stanza_get_kickban_reason(stanza);
+            char *actor = stanza_get_actor(stanza);
+            char *reason = stanza_get_reason(stanza);
             handle_muc_self_online(room, nick, config_required, role, affiliation, actor, reason, jid, show_str, status_str);
         }
 
@@ -781,15 +781,15 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void *
 
                 // kicked from room
                 if (g_slist_find_custom(status_codes, "307", (GCompareFunc)g_strcmp0) != NULL) {
-                    char *actor = stanza_get_kickban_actor(stanza);
-                    char *reason = stanza_get_kickban_reason(stanza);
+                    char *actor = stanza_get_actor(stanza);
+                    char *reason = stanza_get_reason(stanza);
                     handle_room_occupent_kicked(room, nick, actor, reason);
                     free(reason);
 
                 // banned from room
                 } else if (g_slist_find_custom(status_codes, "301", (GCompareFunc)g_strcmp0) != NULL) {
-                    char *actor = stanza_get_kickban_actor(stanza);
-                    char *reason = stanza_get_kickban_reason(stanza);
+                    char *actor = stanza_get_actor(stanza);
+                    char *reason = stanza_get_reason(stanza);
                     handle_room_occupent_banned(room, nick, actor, reason);
                     free(reason);
 
@@ -807,7 +807,9 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void *
                 _handle_caps(stanza);
             }
 
-            handle_muc_occupant_online(room, nick, jid, role, affiliation, show_str, status_str);
+            char *actor = stanza_get_actor(stanza);
+            char *reason = stanza_get_reason(stanza);
+            handle_muc_occupant_online(room, nick, jid, role, affiliation, actor, reason, show_str, status_str);
         }
     }
 
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index 82cebd6b..019f9629 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -1181,7 +1181,7 @@ stanza_get_muc_destroy_reason(xmpp_stanza_t *stanza)
 }
 
 char *
-stanza_get_kickban_actor(xmpp_stanza_t *stanza)
+stanza_get_actor(xmpp_stanza_t *stanza)
 {
     char *stanza_name = xmpp_stanza_get_name(stanza);
     if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) {
@@ -1207,7 +1207,7 @@ stanza_get_kickban_actor(xmpp_stanza_t *stanza)
 }
 
 char *
-stanza_get_kickban_reason(xmpp_stanza_t *stanza)
+stanza_get_reason(xmpp_stanza_t *stanza)
 {
     char *stanza_name = xmpp_stanza_get_name(stanza);
     if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) {
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index cbb6d23f..1a83c5a6 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -258,7 +258,7 @@ gboolean stanza_room_destroyed(xmpp_stanza_t *stanza);
 char* stanza_get_muc_destroy_alternative_room(xmpp_stanza_t *stanza);
 char* stanza_get_muc_destroy_alternative_password(xmpp_stanza_t *stanza);
 char* stanza_get_muc_destroy_reason(xmpp_stanza_t *stanza);
-char* stanza_get_kickban_actor(xmpp_stanza_t *stanza);
-char* stanza_get_kickban_reason(xmpp_stanza_t *stanza);
+char* stanza_get_actor(xmpp_stanza_t *stanza);
+char* stanza_get_reason(xmpp_stanza_t *stanza);
 
 #endif