From 2c15aba92a8288e41bea6e12933a14ffe390e1f4 Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 21 Apr 2014 00:37:04 +0100 Subject: Chat room windows now created only after successful join --- src/command/commands.c | 5 +++-- src/muc.c | 23 +++++++++++++++++++++-- src/muc.h | 4 +++- src/server_events.c | 36 +++++++++++++++++------------------- src/server_events.h | 2 +- src/ui/core.c | 12 ++++++++++-- src/ui/ui.h | 3 ++- src/xmpp/bookmark.c | 2 +- src/xmpp/presence.c | 22 ++++++++++++++++++++-- src/xmpp/stanza.h | 1 + 10 files changed, 79 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/command/commands.c b/src/command/commands.c index 8e026b50..0a96d318 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -1591,9 +1591,10 @@ cmd_join(gchar **args, struct cmd_help_t help) if (!muc_room_is_active(room)) { presence_join_room(room, nick, passwd); + muc_join_room(room, nick, passwd, FALSE); + } else if (muc_get_roster_received(room)) { + ui_room_join(room, TRUE); } - ui_room_join(room, TRUE); - muc_remove_invite(room); jid_destroy(room_arg); g_string_free(room_str, TRUE); diff --git a/src/muc.c b/src/muc.c index 11a707a4..4ba88191 100644 --- a/src/muc.c +++ b/src/muc.c @@ -34,6 +34,7 @@ typedef struct _muc_room_t { char *nick; // e.g. Some User char *password; char *subject; + gboolean autojoin; gboolean pending_nick_change; GHashTable *roster; Autocomplete nick_ac; @@ -126,7 +127,8 @@ muc_clear_invites(void) * Join the chat room with the specified nickname */ void -muc_join_room(const char * const room, const char * const nick, const char * const password) +muc_join_room(const char * const room, const char * const nick, + const char * const password, gboolean autojoin) { if (rooms == NULL) { rooms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, @@ -149,6 +151,7 @@ muc_join_room(const char * const room, const char * const nick, const char * con g_free, g_free); new_room->roster_received = FALSE; new_room->pending_nick_change = FALSE; + new_room->autojoin = autojoin; g_hash_table_insert(rooms, strdup(room), new_room); } @@ -183,6 +186,22 @@ muc_room_is_active(const char * const room) } } +gboolean +muc_room_is_autojoin(const char * const room) +{ + if (rooms != NULL) { + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + + if (chat_room != NULL) { + return chat_room->autojoin; + } else { + return FALSE; + } + } else { + return FALSE; + } +} + char * muc_get_old_nick(const char * const room, const char * const new_nick) { @@ -504,4 +523,4 @@ gint _compare_participants(PContact a, PContact b) g_free(key_b); return result; -} +} \ No newline at end of file diff --git a/src/muc.h b/src/muc.h index fc8c4668..34058bfe 100644 --- a/src/muc.h +++ b/src/muc.h @@ -31,9 +31,11 @@ void muc_init(void); void muc_close(void); -void muc_join_room(const char * const room, const char * const nick, const char * const password); +void muc_join_room(const char * const room, const char * const nick, + const char * const password, gboolean autojoin); void muc_leave_room(const char * const room); gboolean muc_room_is_active(const char * const room); +gboolean muc_room_is_autojoin(const char * const room); GList* muc_get_active_room_list(void); char * muc_get_room_nick(const char * const room); diff --git a/src/server_events.c b/src/server_events.c index afb29bcd..79cc0e26 100644 --- a/src/server_events.c +++ b/src/server_events.c @@ -36,23 +36,22 @@ #include "ui/ui.h" +void +handle_room_join_error(const char * const room, const char * const err) +{ + if (muc_room_is_active(room)) { + muc_leave_room(room); + } + ui_handle_room_join_error(room, err); +} + // handle presence stanza errors void handle_presence_error(const char *from, const char * const type, const char *err_msg) { - // handle nickname conflict on entering room - if ((from != NULL) && g_strcmp0(err_msg, "conflict") == 0) { - // remove the room from muc - Jid *room_jid = jid_create(from); - if (!muc_get_roster_received(room_jid->barejid)) { - muc_leave_room(room_jid->barejid); - ui_handle_recipient_error(room_jid->barejid, err_msg); - } - jid_destroy(room_jid); - - // handle any other error from recipient - } else if (from != NULL) { + // handle error from recipient + if (from != NULL) { ui_handle_recipient_error(from, err_msg); // handle errors from no recipient @@ -404,6 +403,12 @@ handle_room_nick_change(const char * const room, void handle_room_roster_complete(const char * const room) { + if (muc_room_is_autojoin(room)) { + ui_room_join(room, FALSE); + } else { + ui_room_join(room, TRUE); + } + muc_remove_invite(room); muc_set_roster_received(room); GList *roster = muc_get_roster(room); ui_room_roster(room, roster, NULL); @@ -499,13 +504,6 @@ handle_autoping_cancel(void) ui_current_page_off(); } -void -handle_bookmark_autojoin(char *jid) -{ - ui_room_join(jid, FALSE); - muc_remove_invite(jid); -} - void handle_xmpp_stanza(const char * const msg) { diff --git a/src/server_events.h b/src/server_events.h index ea49e1f1..98e00731 100644 --- a/src/server_events.h +++ b/src/server_events.h @@ -43,6 +43,7 @@ void handle_room_history(const char * const room_jid, const char * const nick, GTimeVal tv_stamp, const char * const message); void handle_room_message(const char * const room_jid, const char * const nick, const char * const message); +void handle_room_join_error(const char * const room, const char * const err); void handle_duck_result(const char * const result); void handle_incoming_message(char *from, char *message, gboolean priv); void handle_delayed_message(char *from, char *message, GTimeVal tv_stamp, @@ -78,7 +79,6 @@ void handle_message_error(const char * const from, const char * const type, const char * const err_msg); void handle_presence_error(const char *from, const char * const type, const char *err_msg); -void handle_bookmark_autojoin(char *jid); void handle_xmpp_stanza(const char * const msg); #endif diff --git a/src/ui/core.c b/src/ui/core.c index a84d5856..8f385cf2 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -1272,7 +1272,7 @@ _ui_outgoing_msg(const char * const from, const char * const to, } static void -_ui_room_join(char *room, gboolean focus) +_ui_room_join(const char * const room, gboolean focus) { ProfWin *window = wins_get_by_recipient(room); int num = 0; @@ -1289,7 +1289,8 @@ _ui_room_join(char *room, gboolean focus) } else { status_bar_active(num); ProfWin *console = wins_get_console(); - win_vprint_line(console, '!', COLOUR_ONLINE, "-> Autojoined %s (%d).", room, num); + char *nick = muc_get_room_nick(room); + win_vprint_line(console, '!', COLOUR_TYPING, "-> Autojoined %s as %s (%d).", room, nick, num); win_update_virtual(console); } } @@ -1349,6 +1350,12 @@ _ui_room_roster(const char * const room, GList *roster, const char * const prese } } +static void +_ui_handle_room_join_error(const char * const room, const char * const err) +{ + cons_show_error("Error joining room %s, reason: %s", room, err); +} + static void _ui_room_member_offline(const char * const room, const char * const nick) { @@ -1979,4 +1986,5 @@ ui_init_module(void) ui_handle_stanza = _ui_handle_stanza; ui_create_xmlconsole_win = _ui_create_xmlconsole_win; ui_xmlconsole_exists = _ui_xmlconsole_exists; + ui_handle_room_join_error = _ui_handle_room_join_error; } diff --git a/src/ui/ui.h b/src/ui/ui.h index a93cc3d0..14f7137c 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -102,7 +102,7 @@ void (*ui_disconnected)(void); void (*ui_recipient_gone)(const char * const barejid); void (*ui_outgoing_msg)(const char * const from, const char * const to, const char * const message); -void (*ui_room_join)(char *room, gboolean focus); +void (*ui_room_join)(const char * const room, gboolean focus); 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); @@ -132,6 +132,7 @@ void (*ui_handle_recipient_not_found)(const char * const recipient, const char * void (*ui_handle_recipient_error)(const char * const recipient, const char * const err_msg); void (*ui_handle_error)(const char * const err_msg); void (*ui_clear_win_title)(void); +void (*ui_handle_room_join_error)(const char * const room, const char * const err); // contact status functions void (*ui_status_room)(const char * const contact); diff --git a/src/xmpp/bookmark.c b/src/xmpp/bookmark.c index 2e4f70db..c73f3db3 100644 --- a/src/xmpp/bookmark.c +++ b/src/xmpp/bookmark.c @@ -260,7 +260,7 @@ _bookmark_handle_result(xmpp_conn_t * const conn, room_jid = jid_create_from_bare_and_resource(jid, name); if (!muc_room_is_active(room_jid->barejid)) { presence_join_room(jid, name, NULL); - handle_bookmark_autojoin(jid); + muc_join_room(jid, name, NULL, TRUE); } jid_destroy(room_jid); } else { diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index 433c05f3..1cb86645 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -283,7 +283,6 @@ _presence_join_room(char *room, char *nick, char * passwd) xmpp_send(conn, presence); xmpp_stanza_release(presence); - muc_join_room(jid->barejid, jid->resourcepart, passwd); jid_destroy(jid); } @@ -342,11 +341,31 @@ _presence_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, char *id = xmpp_stanza_get_id(stanza); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); + xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); + char *xmlns = xmpp_stanza_get_ns(x); char *type = NULL; if (error_stanza != NULL) { type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE); } + // handle MUC join errors + if (g_strcmp0(xmlns, STANZA_NS_MUC) == 0) { + Jid *fulljid = jid_create(from); + + char *error_cond = NULL; + xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_ns(error_stanza, STANZA_NS_STANZAS); + if (reason_st != NULL) { + error_cond = xmpp_stanza_get_name(reason_st); + } + if (error_cond == NULL) { + error_cond = "unknown"; + } + + log_info("Error joining room: %s, reason: %s", fulljid->barejid, error_cond); + handle_room_join_error(fulljid->barejid, error_cond); + return 1; + } + // stanza_get_error never returns NULL char *err_msg = stanza_get_error_message(stanza); @@ -676,7 +695,6 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, // handle roster complete } else if (!muc_get_roster_received(room)) { handle_room_roster_complete(room); - } // handle presence from room members diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index d71d3ea1..486421a2 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -124,6 +124,7 @@ #define STANZA_TEXT_XA "xa" #define STANZA_TEXT_ONLINE "online" +#define STANZA_NS_STANZAS "urn:ietf:params:xml:ns:xmpp-stanzas" #define STANZA_NS_CHATSTATES "http://jabber.org/protocol/chatstates" #define STANZA_NS_MUC "http://jabber.org/protocol/muc" #define STANZA_NS_MUC_USER "http://jabber.org/protocol/muc#user" -- cgit 1.4.1-2-gfad0