MUC join behaviour + small MUC error changes

This commit is contained in:
fiaxh 2017-06-13 16:04:26 +02:00
parent e63d59eb34
commit dabc2a8b1d
8 changed files with 74 additions and 43 deletions

View file

@ -14,6 +14,7 @@ public class MucManager : StreamInteractionModule, Object {
public signal void bookmarks_updated(Account account, Gee.List<Xep.Bookmarks.Conference> conferences); public signal void bookmarks_updated(Account account, Gee.List<Xep.Bookmarks.Conference> conferences);
private StreamInteractor stream_interactor; private StreamInteractor stream_interactor;
private HashMap<Jid, Xep.Muc.MucEnterError> enter_errors = new HashMap<Jid, Xep.Muc.MucEnterError>(Jid.hash_func, Jid.equals_func);
public static void start(StreamInteractor stream_interactor) { public static void start(StreamInteractor stream_interactor) {
MucManager m = new MucManager(stream_interactor); MucManager m = new MucManager(stream_interactor);
@ -28,6 +29,8 @@ public class MucManager : StreamInteractionModule, Object {
} }
public void join(Account account, Jid jid, string? nick, string? password) { public void join(Account account, Jid jid, string? nick, string? password) {
if (enter_errors.has_key(jid)) return;
Core.XmppStream? stream = stream_interactor.get_stream(account); Core.XmppStream? stream = stream_interactor.get_stream(account);
if (stream == null) return; if (stream == null) return;
string nick_ = nick ?? account.bare_jid.localpart ?? account.bare_jid.domainpart; string nick_ = nick ?? account.bare_jid.localpart ?? account.bare_jid.domainpart;
@ -204,6 +207,9 @@ public class MucManager : StreamInteractionModule, Object {
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).room_entered.connect( (stream, jid, nick) => { stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).room_entered.connect( (stream, jid, nick) => {
joined(account, new Jid(jid), nick); joined(account, new Jid(jid), nick);
}); });
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).room_enter_error.connect( (stream, jid, error) => {
enter_errors[new Jid(jid)] = error;
});
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).self_removed_from_room.connect( (stream, jid, code) => { stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).self_removed_from_room.connect( (stream, jid, code) => {
left(account, new Jid(jid)); left(account, new Jid(jid));
}); });

View file

@ -54,4 +54,4 @@ class AccountComboBox : ComboBox {
} }
} }
} }

View file

@ -43,6 +43,7 @@ protected class AddGroupchatDialog : Gtk.Dialog {
ok_button.sensitive = true; ok_button.sensitive = true;
accounts_stack.set_visible_child_name("label"); accounts_stack.set_visible_child_name("label");
account_label.label = account.bare_jid.to_string(); account_label.label = account.bare_jid.to_string();
account_combobox.selected = account;
jid_entry.text = conference.jid; jid_entry.text = conference.jid;
nick_entry.text = conference.nick ?? ""; nick_entry.text = conference.nick ?? "";
autojoin_checkbutton.active = conference.autojoin; autojoin_checkbutton.active = conference.autojoin;
@ -78,4 +79,4 @@ protected class AddGroupchatDialog : Gtk.Dialog {
} }
} }
} }

View file

@ -32,7 +32,7 @@ public class StanzaAttribute : StanzaEntry {
} }
} }
public string to_string() { public override string to_string(int i = 0) {
return printf(ATTRIBUTE_STRING_FORMAT); return printf(ATTRIBUTE_STRING_FORMAT);
} }

View file

@ -42,6 +42,10 @@ public abstract class StanzaEntry {
public virtual unowned string? get_string_content() { public virtual unowned string? get_string_content() {
return val; return val;
} }
public virtual string to_string(int i = 0) {
return get_string_content() ?? "(null)";
}
} }
public class StanzaNode : StanzaEntry { public class StanzaNode : StanzaEntry {
@ -339,7 +343,7 @@ public class StanzaNode : StanzaEntry {
return sb.str; return sb.str;
} }
public string to_string(int i = 0) { public override string to_string(int i = 0) {
return printf(i, TAG_START_BEGIN_FORMAT, TAG_START_EMPTY_END, TAG_START_CONTENT_END, TAG_END_FORMAT, StanzaAttribute.ATTRIBUTE_STRING_FORMAT); return printf(i, TAG_START_BEGIN_FORMAT, TAG_START_EMPTY_END, TAG_START_CONTENT_END, TAG_END_FORMAT, StanzaAttribute.ATTRIBUTE_STRING_FORMAT);
} }

View file

@ -55,7 +55,7 @@ namespace Xmpp {
} }
public string type_ { public string type_ {
get { return stanza.get_attribute("type"); } get { return error_node.get_attribute("type"); }
} }
public StanzaNode stanza; public StanzaNode stanza;

View file

@ -11,11 +11,13 @@ private const string NS_URI_USER = NS_URI + "#user";
public enum MucEnterError { public enum MucEnterError {
PASSWORD_REQUIRED, PASSWORD_REQUIRED,
NOT_IN_MEMBER_LIST,
BANNED, BANNED,
ROOM_DOESNT_EXIST,
CREATION_RESTRICTED,
USE_RESERVED_ROOMNICK,
NOT_IN_MEMBER_LIST,
NICK_CONFLICT, NICK_CONFLICT,
OCCUPANT_LIMIT_REACHED, OCCUPANT_LIMIT_REACHED,
ROOM_DOESNT_EXIST
} }
public enum Affiliation { public enum Affiliation {
@ -205,20 +207,35 @@ public class Module : XmppStreamModule {
if (presence.is_error() && flag.is_muc_enter_outstanding() && flag.is_occupant(presence.from)) { if (presence.is_error() && flag.is_muc_enter_outstanding() && flag.is_occupant(presence.from)) {
string bare_jid = get_bare_jid(presence.from); string bare_jid = get_bare_jid(presence.from);
ErrorStanza? error_stanza = presence.get_error(); ErrorStanza? error_stanza = presence.get_error();
if (flag.get_enter_id(bare_jid) == error_stanza.original_id) { if (flag.get_enter_id(bare_jid) == presence.id) {
print("is enter id\n");
MucEnterError? error = null; MucEnterError? error = null;
if (error_stanza.condition == ErrorStanza.CONDITION_NOT_AUTHORIZED && ErrorStanza.TYPE_AUTH == error_stanza.type_) { print(@"$(error_stanza.condition) $(error_stanza.type_)\n");
error = MucEnterError.PASSWORD_REQUIRED; switch (error_stanza.condition) {
} else if (ErrorStanza.CONDITION_REGISTRATION_REQUIRED == error_stanza.condition && ErrorStanza.TYPE_AUTH == error_stanza.type_) { case ErrorStanza.CONDITION_NOT_AUTHORIZED:
error = MucEnterError.NOT_IN_MEMBER_LIST; if (ErrorStanza.TYPE_AUTH == error_stanza.type_) error = MucEnterError.PASSWORD_REQUIRED;
} else if (ErrorStanza.CONDITION_FORBIDDEN == error_stanza.condition && ErrorStanza.TYPE_AUTH == error_stanza.type_) { break;
error = MucEnterError.BANNED; case ErrorStanza.CONDITION_REGISTRATION_REQUIRED:
} else if (ErrorStanza.CONDITION_CONFLICT == error_stanza.condition && ErrorStanza.TYPE_CANCEL == error_stanza.type_) { if (ErrorStanza.TYPE_AUTH == error_stanza.type_) error = MucEnterError.NOT_IN_MEMBER_LIST;
error = MucEnterError.NICK_CONFLICT; break;
} else if (ErrorStanza.CONDITION_SERVICE_UNAVAILABLE == error_stanza.condition && ErrorStanza.TYPE_WAIT == error_stanza.type_) { case ErrorStanza.CONDITION_FORBIDDEN:
error = MucEnterError.OCCUPANT_LIMIT_REACHED; if (ErrorStanza.TYPE_AUTH == error_stanza.type_) error = MucEnterError.BANNED;
} else if (ErrorStanza.CONDITION_ITEM_NOT_FOUND == error_stanza.condition && ErrorStanza.TYPE_CANCEL == error_stanza.type_) { break;
error = MucEnterError.ROOM_DOESNT_EXIST; case ErrorStanza.CONDITION_SERVICE_UNAVAILABLE:
if (ErrorStanza.TYPE_WAIT == error_stanza.type_) error = MucEnterError.OCCUPANT_LIMIT_REACHED;
break;
case ErrorStanza.CONDITION_ITEM_NOT_FOUND:
if (ErrorStanza.TYPE_CANCEL == error_stanza.type_) error = MucEnterError.ROOM_DOESNT_EXIST;
break;
case ErrorStanza.CONDITION_CONFLICT:
if (ErrorStanza.TYPE_CANCEL == error_stanza.type_) error = MucEnterError.NICK_CONFLICT;
break;
case ErrorStanza.CONDITION_NOT_ALLOWED:
if (ErrorStanza.TYPE_CANCEL == error_stanza.type_) error = MucEnterError.CREATION_RESTRICTED;
break;
case ErrorStanza.CONDITION_NOT_ACCEPTABLE:
if (ErrorStanza.TYPE_CANCEL == error_stanza.type_) error = MucEnterError.USE_RESERVED_ROOMNICK;
break;
} }
if (error != null) room_enter_error(stream, bare_jid, error); if (error != null) room_enter_error(stream, bare_jid, error);
flag.finish_muc_enter(bare_jid); flag.finish_muc_enter(bare_jid);
@ -289,31 +306,35 @@ public class Module : XmppStreamModule {
private void query_room_info(XmppStream stream, string jid) { private void query_room_info(XmppStream stream, string jid) {
stream.get_module(ServiceDiscovery.Module.IDENTITY).request_info(stream, jid, (stream, query_result, store) => { stream.get_module(ServiceDiscovery.Module.IDENTITY).request_info(stream, jid, (stream, query_result, store) => {
Tuple<string, string> tuple = store as Tuple<string, string>;
Gee.List<Feature> features = new ArrayList<Feature>(); Gee.List<Feature> features = new ArrayList<Feature>();
foreach (string feature in query_result.features) { if (query_result != null) {
Feature? parsed = null; foreach (string feature in query_result.features) {
switch (feature) { Feature? parsed = null;
case "http://jabber.org/protocol/muc#register": parsed = Feature.REGISTER; break; switch (feature) {
case "http://jabber.org/protocol/muc#roomconfig": parsed = Feature.ROOMCONFIG; break; case "http://jabber.org/protocol/muc#register": parsed = Feature.REGISTER; break;
case "http://jabber.org/protocol/muc#roominfo": parsed = Feature.ROOMINFO; break; case "http://jabber.org/protocol/muc#roomconfig": parsed = Feature.ROOMCONFIG; break;
case "muc_hidden": parsed = Feature.HIDDEN; break; case "http://jabber.org/protocol/muc#roominfo": parsed = Feature.ROOMINFO; break;
case "muc_membersonly": parsed = Feature.MEMBERS_ONLY; break; case "muc_hidden": parsed = Feature.HIDDEN; break;
case "muc_moderated": parsed = Feature.MODERATED; break; case "muc_membersonly": parsed = Feature.MEMBERS_ONLY; break;
case "muc_nonanonymous": parsed = Feature.NON_ANONYMOUS; break; case "muc_moderated": parsed = Feature.MODERATED; break;
case "muc_open": parsed = Feature.OPEN; break; case "muc_nonanonymous": parsed = Feature.NON_ANONYMOUS; break;
case "muc_passwordprotected": parsed = Feature.PASSWORD_PROTECTED; break; case "muc_open": parsed = Feature.OPEN; break;
case "muc_persistent": parsed = Feature.PERSISTENT; break; case "muc_passwordprotected": parsed = Feature.PASSWORD_PROTECTED; break;
case "muc_public": parsed = Feature.PUBLIC; break; case "muc_persistent": parsed = Feature.PERSISTENT; break;
case "muc_rooms": parsed = Feature.ROOMS; break; case "muc_public": parsed = Feature.PUBLIC; break;
case "muc_semianonymous": parsed = Feature.SEMI_ANONYMOUS; break; case "muc_rooms": parsed = Feature.ROOMS; break;
case "muc_temporary": parsed = Feature.TEMPORARY; break; case "muc_semianonymous": parsed = Feature.SEMI_ANONYMOUS; break;
case "muc_unmoderated": parsed = Feature.UNMODERATED; break; case "muc_temporary": parsed = Feature.TEMPORARY; break;
case "muc_unsecured": parsed = Feature.UNSECURED; break; case "muc_unmoderated": parsed = Feature.UNMODERATED; break;
case "muc_unsecured": parsed = Feature.UNSECURED; break;
}
if (parsed != null) features.add(parsed);
} }
if (parsed != null) features.add(parsed);
} }
stream.get_flag(Flag.IDENTITY).set_room_features(query_result.iq.from, features); stream.get_flag(Flag.IDENTITY).set_room_features(tuple.a, features);
}, null); }, Tuple.create(jid, "")); //TODO ugly
} }
[CCode (has_target = false)] public delegate void OnAffiliationResult(XmppStream stream, Gee.List<string> jids, Object? store); [CCode (has_target = false)] public delegate void OnAffiliationResult(XmppStream stream, Gee.List<string> jids, Object? store);

View file

@ -17,7 +17,6 @@ public class Module : XmppStreamModule {
Tuple<OnResult, Object?> tuple = o as Tuple<OnResult, Object?>; Tuple<OnResult, Object?> tuple = o as Tuple<OnResult, Object?>;
OnResult on_result = tuple.a; OnResult on_result = tuple.a;
Gee.List<Conference> conferences = get_conferences_from_stanza(node); Gee.List<Conference> conferences = get_conferences_from_stanza(node);
stream.get_module(Module.IDENTITY).received_conferences(stream, conferences);
on_result(stream, conferences, tuple.b); on_result(stream, conferences, tuple.b);
}, Tuple.create(listener, store)); }, Tuple.create(listener, store));
} }