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);
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) {
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) {
if (enter_errors.has_key(jid)) return;
Core.XmppStream? stream = stream_interactor.get_stream(account);
if (stream == null) return;
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) => {
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) => {
left(account, new Jid(jid));
});

View file

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

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);
}

View file

@ -42,6 +42,10 @@ public abstract class StanzaEntry {
public virtual unowned string? get_string_content() {
return val;
}
public virtual string to_string(int i = 0) {
return get_string_content() ?? "(null)";
}
}
public class StanzaNode : StanzaEntry {
@ -339,7 +343,7 @@ public class StanzaNode : StanzaEntry {
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);
}

View file

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

View file

@ -11,11 +11,13 @@ private const string NS_URI_USER = NS_URI + "#user";
public enum MucEnterError {
PASSWORD_REQUIRED,
NOT_IN_MEMBER_LIST,
BANNED,
ROOM_DOESNT_EXIST,
CREATION_RESTRICTED,
USE_RESERVED_ROOMNICK,
NOT_IN_MEMBER_LIST,
NICK_CONFLICT,
OCCUPANT_LIMIT_REACHED,
ROOM_DOESNT_EXIST
}
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)) {
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) {
if (flag.get_enter_id(bare_jid) == presence.id) {
print("is enter id\n");
MucEnterError? error = null;
if (error_stanza.condition == ErrorStanza.CONDITION_NOT_AUTHORIZED && ErrorStanza.TYPE_AUTH == error_stanza.type_) {
error = MucEnterError.PASSWORD_REQUIRED;
} else if (ErrorStanza.CONDITION_REGISTRATION_REQUIRED == error_stanza.condition && ErrorStanza.TYPE_AUTH == error_stanza.type_) {
error = MucEnterError.NOT_IN_MEMBER_LIST;
} else if (ErrorStanza.CONDITION_FORBIDDEN == error_stanza.condition && ErrorStanza.TYPE_AUTH == error_stanza.type_) {
error = MucEnterError.BANNED;
} else if (ErrorStanza.CONDITION_CONFLICT == error_stanza.condition && ErrorStanza.TYPE_CANCEL == error_stanza.type_) {
error = MucEnterError.NICK_CONFLICT;
} else if (ErrorStanza.CONDITION_SERVICE_UNAVAILABLE == error_stanza.condition && ErrorStanza.TYPE_WAIT == error_stanza.type_) {
error = MucEnterError.OCCUPANT_LIMIT_REACHED;
} else if (ErrorStanza.CONDITION_ITEM_NOT_FOUND == error_stanza.condition && ErrorStanza.TYPE_CANCEL == error_stanza.type_) {
error = MucEnterError.ROOM_DOESNT_EXIST;
print(@"$(error_stanza.condition) $(error_stanza.type_)\n");
switch (error_stanza.condition) {
case ErrorStanza.CONDITION_NOT_AUTHORIZED:
if (ErrorStanza.TYPE_AUTH == error_stanza.type_) error = MucEnterError.PASSWORD_REQUIRED;
break;
case ErrorStanza.CONDITION_REGISTRATION_REQUIRED:
if (ErrorStanza.TYPE_AUTH == error_stanza.type_) error = MucEnterError.NOT_IN_MEMBER_LIST;
break;
case ErrorStanza.CONDITION_FORBIDDEN:
if (ErrorStanza.TYPE_AUTH == error_stanza.type_) error = MucEnterError.BANNED;
break;
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);
flag.finish_muc_enter(bare_jid);
@ -289,31 +306,35 @@ public class Module : XmppStreamModule {
private void query_room_info(XmppStream stream, string jid) {
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>();
foreach (string feature in query_result.features) {
Feature? parsed = null;
switch (feature) {
case "http://jabber.org/protocol/muc#register": parsed = Feature.REGISTER; break;
case "http://jabber.org/protocol/muc#roomconfig": parsed = Feature.ROOMCONFIG; break;
case "http://jabber.org/protocol/muc#roominfo": parsed = Feature.ROOMINFO; break;
case "muc_hidden": parsed = Feature.HIDDEN; break;
case "muc_membersonly": parsed = Feature.MEMBERS_ONLY; break;
case "muc_moderated": parsed = Feature.MODERATED; break;
case "muc_nonanonymous": parsed = Feature.NON_ANONYMOUS; break;
case "muc_open": parsed = Feature.OPEN; break;
case "muc_passwordprotected": parsed = Feature.PASSWORD_PROTECTED; break;
case "muc_persistent": parsed = Feature.PERSISTENT; break;
case "muc_public": parsed = Feature.PUBLIC; break;
case "muc_rooms": parsed = Feature.ROOMS; break;
case "muc_semianonymous": parsed = Feature.SEMI_ANONYMOUS; break;
case "muc_temporary": parsed = Feature.TEMPORARY; break;
case "muc_unmoderated": parsed = Feature.UNMODERATED; break;
case "muc_unsecured": parsed = Feature.UNSECURED; break;
if (query_result != null) {
foreach (string feature in query_result.features) {
Feature? parsed = null;
switch (feature) {
case "http://jabber.org/protocol/muc#register": parsed = Feature.REGISTER; break;
case "http://jabber.org/protocol/muc#roomconfig": parsed = Feature.ROOMCONFIG; break;
case "http://jabber.org/protocol/muc#roominfo": parsed = Feature.ROOMINFO; break;
case "muc_hidden": parsed = Feature.HIDDEN; break;
case "muc_membersonly": parsed = Feature.MEMBERS_ONLY; break;
case "muc_moderated": parsed = Feature.MODERATED; break;
case "muc_nonanonymous": parsed = Feature.NON_ANONYMOUS; break;
case "muc_open": parsed = Feature.OPEN; break;
case "muc_passwordprotected": parsed = Feature.PASSWORD_PROTECTED; break;
case "muc_persistent": parsed = Feature.PERSISTENT; break;
case "muc_public": parsed = Feature.PUBLIC; break;
case "muc_rooms": parsed = Feature.ROOMS; break;
case "muc_semianonymous": parsed = Feature.SEMI_ANONYMOUS; break;
case "muc_temporary": parsed = Feature.TEMPORARY; 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);
}, null);
stream.get_flag(Flag.IDENTITY).set_room_features(tuple.a, features);
}, Tuple.create(jid, "")); //TODO ugly
}
[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?>;
OnResult on_result = tuple.a;
Gee.List<Conference> conferences = get_conferences_from_stanza(node);
stream.get_module(Module.IDENTITY).received_conferences(stream, conferences);
on_result(stream, conferences, tuple.b);
}, Tuple.create(listener, store));
}