From a37b5ac823cc5daefac6ab33a16d6f44c747ba9c Mon Sep 17 00:00:00 2001 From: fiaxh Date: Tue, 11 Apr 2017 18:06:01 +0200 Subject: MUC improvements --- xmpp-vala/src/module/presence/module.vala | 4 +- xmpp-vala/src/module/xep/0045_muc/flag.vala | 21 +++-- xmpp-vala/src/module/xep/0045_muc/module.vala | 100 ++++++++------------- xmpp-vala/src/module/xep/0045_muc/status_code.vala | 58 ++++++++++++ 4 files changed, 110 insertions(+), 73 deletions(-) create mode 100644 xmpp-vala/src/module/xep/0045_muc/status_code.vala (limited to 'xmpp-vala/src/module') diff --git a/xmpp-vala/src/module/presence/module.vala b/xmpp-vala/src/module/presence/module.vala index 3c078453..a2cdf1d7 100644 --- a/xmpp-vala/src/module/presence/module.vala +++ b/xmpp-vala/src/module/presence/module.vala @@ -11,7 +11,7 @@ namespace Xmpp.Presence { public signal void initial_presence_sent(XmppStream stream, Presence.Stanza presence); public signal void received_available(XmppStream stream, Presence.Stanza presence); public signal void received_available_show(XmppStream stream, string jid, string show); - public signal void received_unavailable(XmppStream stream, string jid); + public signal void received_unavailable(XmppStream stream, Presence.Stanza presence); public signal void received_subscription_request(XmppStream stream, string jid); public signal void received_unsubscription(XmppStream stream, string jid); @@ -76,7 +76,7 @@ namespace Xmpp.Presence { break; case Presence.Stanza.TYPE_UNAVAILABLE: stream.get_flag(Flag.IDENTITY).remove_presence(presence.from); - received_unavailable(stream, presence.from); + received_unavailable(stream, presence); break; case Presence.Stanza.TYPE_SUBSCRIBE: received_subscription_request(stream, presence.from); diff --git a/xmpp-vala/src/module/xep/0045_muc/flag.vala b/xmpp-vala/src/module/xep/0045_muc/flag.vala index f6340a5c..e5e0af6e 100644 --- a/xmpp-vala/src/module/xep/0045_muc/flag.vala +++ b/xmpp-vala/src/module/xep/0045_muc/flag.vala @@ -7,7 +7,6 @@ namespace Xmpp.Xep.Muc { public class Flag : XmppStreamFlag { public static FlagIdentity IDENTITY = new FlagIdentity(NS_URI, "muc"); - private HashMap enter_listeners = new HashMap(); private HashMap enter_ids = new HashMap(); private HashMap own_nicks = new HashMap(); private HashMap subjects = new HashMap(); @@ -32,8 +31,6 @@ public class Flag : XmppStreamFlag { public string? get_enter_id(string bare_jid) { return enter_ids[bare_jid]; } - public ListenerHolder? get_enter_listener(string bare_jid) { return enter_listeners[bare_jid]; } - public bool is_muc(string jid) { return own_nicks[jid] != null; } public bool is_occupant(string jid) { @@ -45,23 +42,33 @@ public class Flag : XmppStreamFlag { public string? get_muc_subject(string bare_jid) { return subjects[bare_jid]; } - public void set_muc_subject(string full_jid, string subject) { + public void set_muc_subject(string full_jid, string? subject) { string bare_jid = get_bare_jid(full_jid); subjects[bare_jid] = subject; subjects_by[bare_jid] = full_jid; } - public void start_muc_enter(string bare_jid, string presence_id, ListenerHolder listener) { - enter_listeners[bare_jid] = listener; + public void start_muc_enter(string bare_jid, string presence_id) { enter_ids[bare_jid] = presence_id; } public void finish_muc_enter(string bare_jid, string? nick = null) { if (nick != null) own_nicks[bare_jid] = nick; - enter_listeners.unset(bare_jid); enter_ids.unset(bare_jid); } + public void left_muc(XmppStream stream, string muc) { + own_nicks.unset(muc); + subjects.unset(muc); + subjects_by.unset(muc); + Gee.List? occupants = stream.get_flag(Presence.Flag.IDENTITY).get_resources(muc); + if (occupants != null) { + foreach (string occupant in occupants) { + remove_occupant_info(occupant); + } + } + } + public void remove_occupant_info(string full_jid) { occupant_real_jids.unset(full_jid); occupant_affiliation.unset(full_jid); diff --git a/xmpp-vala/src/module/xep/0045_muc/module.vala b/xmpp-vala/src/module/xep/0045_muc/module.vala index 486c342a..714bb2ca 100644 --- a/xmpp-vala/src/module/xep/0045_muc/module.vala +++ b/xmpp-vala/src/module/xep/0045_muc/module.vala @@ -35,8 +35,14 @@ public class Module : XmppStreamModule { public signal void received_occupant_jid(XmppStream stream, string jid, string? real_jid); public signal void received_occupant_role(XmppStream stream, string jid, string? role); public signal void subject_set(XmppStream stream, string subject, string jid); + public signal void room_configuration_changed(XmppStream stream, string jid, StatusCode code); - public void enter(XmppStream stream, string bare_jid, string nick, string? password, ListenerHolder.OnSuccess success_listener, ListenerHolder.OnError error_listener, Object? store) { + public signal void room_entered(XmppStream stream, string jid, string nick); + public signal void room_enter_error(XmppStream stream, string jid, MucEnterError error); + public signal void self_removed_from_room(XmppStream stream, string jid, StatusCode code); + public signal void removed_from_room(XmppStream stream, string jid, StatusCode? code); + + public void enter(XmppStream stream, string bare_jid, string nick, string? password) { Presence.Stanza presence = new Presence.Stanza(); presence.to = bare_jid + "/" + nick; StanzaNode x_node = new StanzaNode.build("x", NS_URI).add_self_xmlns(); @@ -45,8 +51,7 @@ public class Module : XmppStreamModule { } presence.stanza.put_node(x_node); - stream.get_flag(Flag.IDENTITY).start_muc_enter(bare_jid, presence.id, new ListenerHolder(success_listener, error_listener, store)); - + stream.get_flag(Flag.IDENTITY).start_muc_enter(bare_jid, presence.id); stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence); } @@ -129,7 +134,6 @@ public class Module : XmppStreamModule { string bare_jid = get_bare_jid(presence.from); ErrorStanza? error_stanza = presence.get_error(); if (flag.get_enter_id(bare_jid) == error_stanza.original_id) { - ListenerHolder? listener = flag.get_enter_listener(bare_jid); MucEnterError? error = null; if (error_stanza.condition == ErrorStanza.CONDITION_NOT_AUTHORIZED && ErrorStanza.TYPE_AUTH == error_stanza.type_) { error = MucEnterError.PASSWORD_REQUIRED; @@ -144,7 +148,7 @@ public class Module : XmppStreamModule { } else if (ErrorStanza.CONDITION_ITEM_NOT_FOUND == error_stanza.condition && ErrorStanza.TYPE_CANCEL == error_stanza.type_) { error = MucEnterError.ROOM_DOESNT_EXIST; } - if (error != null && listener != null) listener.on_error(stream, error, listener.reference); + if (error != null) room_enter_error(stream, bare_jid, error); flag.finish_muc_enter(bare_jid); } } @@ -158,9 +162,10 @@ public class Module : XmppStreamModule { ArrayList status_codes = get_status_codes(x_node); if (status_codes.contains(StatusCode.SELF_PRESENCE)) { string bare_jid = get_bare_jid(presence.from); - ListenerHolder listener = flag.get_enter_listener(bare_jid); - listener.on_success(stream, listener.reference); - flag.finish_muc_enter(bare_jid, get_resource_part(presence.from)); + if (flag.get_enter_id(bare_jid) != null) { + room_entered(stream, bare_jid, get_resource_part(presence.from)); + flag.finish_muc_enter(bare_jid, get_resource_part(presence.from)); + } } string? affiliation = x_node["item", "affiliation"].val; if (affiliation != null) { @@ -179,10 +184,30 @@ public class Module : XmppStreamModule { } } - private void on_received_unavailable(XmppStream stream, string jid) { + private void on_received_unavailable(XmppStream stream, Presence.Stanza presence) { Flag flag = stream.get_flag(Flag.IDENTITY); - if (flag.is_occupant(jid)) { - flag.remove_occupant_info(jid); + if (!flag.is_occupant(presence.from)) return; + + StanzaNode? x_node = presence.stanza.get_subnode("x", NS_URI_USER); + if (x_node == null) return; + + ArrayList status_codes = get_status_codes(x_node); + + if (StatusCode.SELF_PRESENCE in status_codes) { + flag.remove_occupant_info(presence.from); + } + + foreach (StatusCode code in USER_REMOVED_CODES) { + if (code in status_codes) { + if (StatusCode.SELF_PRESENCE in status_codes) { + flag.left_muc(stream, get_bare_jid(presence.from)); + self_removed_from_room(stream, presence.from, code); + Presence.Flag presence_flag = stream.get_flag(Presence.Flag.IDENTITY); + presence_flag.remove_presence(get_bare_jid(presence.from)); + } else { + removed_from_room(stream, presence.from, code); + } + } } } @@ -195,57 +220,4 @@ public class Module : XmppStreamModule { } } -public enum StatusCode { - /** Inform user that any occupant is allowed to see the user's full JID */ - JID_VISIBLE = 100, - /** Inform user that his or her affiliation changed while not in the room */ - AFFILIATION_CHANGED = 101, - /** Inform occupants that room now shows unavailable members */ - SHOWS_UNAVIABLE_MEMBERS = 102, - /** Inform occupants that room now does not show unavailable members */ - SHOWS_UNAVIABLE_MEMBERS_NOT = 103, - /** Inform occupants that a non-privacy-related room configuration change has occurred */ - CONFIG_CHANGE_NON_PRIVACY = 104, - /** Inform user that presence refers to itself */ - SELF_PRESENCE = 110, - /** Inform occupants that room logging is now enabled */ - LOGGING_ENABLED = 170, - /** Inform occupants that room logging is now disabled */ - LOGGING_DISABLED = 171, - /** Inform occupants that the room is now non-anonymous */ - NON_ANONYMOUS = 172, - /** Inform occupants that the room is now semi-anonymous */ - SEMI_ANONYMOUS = 173, - /** Inform user that a new room has been created */ - NEW_ROOM_CREATED = 201, - /** Inform user that service has assigned or modified occupant's roomnick */ - MODIFIED_NICK = 210, - /** Inform user that he or she has been banned from the room */ - BANNED = 301, - /** Inform all occupants of new room nickname */ - ROOM_NICKNAME = 303, - /** Inform user that he or she has been kicked from the room */ - KICKED = 307, - /** Inform user that he or she is being removed from the room */ - REMOVED_AFFILIATION_CHANGE = 321, - /** Inform user that he or she is being removed from the room because the room has been changed to members-only - and the user is not a member */ - REMOVED_MEMBERS_ONLY = 322, - /** Inform user that he or she is being removed from the room because the MUC service is being shut down */ - REMOVED_SHUTDOWN = 332 -} - -public class ListenerHolder { - [CCode (has_target = false)] public delegate void OnSuccess(XmppStream stream, Object? store); - public OnSuccess on_success { get; private set; } - [CCode (has_target = false)] public delegate void OnError(XmppStream stream, MucEnterError error, Object? store); - public OnError on_error { get; private set; } - public Object? reference { get; private set; } - - public ListenerHolder(OnSuccess on_success, OnError on_error, Object? reference = null) { - this.on_success = on_success; - this.reference = reference; - } -} - } diff --git a/xmpp-vala/src/module/xep/0045_muc/status_code.vala b/xmpp-vala/src/module/xep/0045_muc/status_code.vala new file mode 100644 index 00000000..7cb9421f --- /dev/null +++ b/xmpp-vala/src/module/xep/0045_muc/status_code.vala @@ -0,0 +1,58 @@ +namespace Xmpp.Xep.Muc { + +public const StatusCode[] ROOM_CONFIGURATION_CODES = { + StatusCode.LOGGING_ENABLED, + StatusCode.LOGGING_DISABLED, + StatusCode.NON_ANONYMOUS, + StatusCode.SEMI_ANONYMOUS +}; + +public const StatusCode[] USER_REMOVED_CODES = { + StatusCode.BANNED, + StatusCode.KICKED, + StatusCode.REMOVED_AFFILIATION_CHANGE, + StatusCode.REMOVED_MEMBERS_ONLY, + StatusCode.REMOVED_SHUTDOWN +}; + +public enum StatusCode { + /** Inform user that any occupant is allowed to see the user's full JID */ + JID_VISIBLE = 100, + /** Inform user that his or her affiliation changed while not in the room */ + AFFILIATION_CHANGED = 101, + /** Inform occupants that room now shows unavailable members */ + SHOWS_UNAVIABLE_MEMBERS = 102, + /** Inform occupants that room now does not show unavailable members */ + SHOWS_UNAVIABLE_MEMBERS_NOT = 103, + /** Inform occupants that a non-privacy-related room configuration change has occurred */ + CONFIG_CHANGE_NON_PRIVACY = 104, + /** Inform user that presence refers to itself */ + SELF_PRESENCE = 110, + /** Inform occupants that room logging is now enabled */ + LOGGING_ENABLED = 170, + /** Inform occupants that room logging is now disabled */ + LOGGING_DISABLED = 171, + /** Inform occupants that the room is now non-anonymous */ + NON_ANONYMOUS = 172, + /** Inform occupants that the room is now semi-anonymous */ + SEMI_ANONYMOUS = 173, + /** Inform user that a new room has been created */ + NEW_ROOM_CREATED = 201, + /** Inform user that service has assigned or modified occupant's roomnick */ + MODIFIED_NICK = 210, + /** Inform user that he or she has been banned from the room */ + BANNED = 301, + /** Inform all occupants of new room nickname */ + ROOM_NICKNAME = 303, + /** Inform user that he or she has been kicked from the room */ + KICKED = 307, + /** Inform user that he or she is being removed from the room */ + REMOVED_AFFILIATION_CHANGE = 321, + /** Inform user that he or she is being removed from the room because the room has been changed to members-only + and the user is not a member */ + REMOVED_MEMBERS_ONLY = 322, + /** Inform user that he or she is being removed from the room because the MUC service is being shut down */ + REMOVED_SHUTDOWN = 332 +} + +} \ No newline at end of file -- cgit v1.2.3-70-g09d2