@@ -2717,6 +2717,71 @@ public class XmppConnectionService extends Service {
return false;
}
+ public void maybeRegisterWithMuc(Conversation c, String nickArg) {
+ final var nick = nickArg == null ? c.getMucOptions().getSelf().getFullJid().getResource() : nickArg;
+ final IqPacket register = new IqPacket(IqPacket.TYPE.GET);
+ register.query(Namespace.REGISTER);
+ register.setTo(c.getJid().asBareJid());
+ sendIqPacket(c.getAccount(), register, (a, response) -> {
+ if (response.getType() == IqPacket.TYPE.RESULT) {
+ final Element query = response.query(Namespace.REGISTER);
+ String username = query.findChildContent("username", Namespace.REGISTER);
+ if (username == null) username = query.findChildContent("nick", Namespace.REGISTER);
+ if (username != null && username.equals(nick)) {
+ // Already registered with this nick, done
+ Log.d(Config.LOGTAG, "Already registered with " + c.getJid().asBareJid() + " as " + username);
+ return;
+ }
+ Data form = Data.parse(query.findChild("x", Namespace.DATA));
+ if (form != null) {
+ final var field = form.getFieldByName("muc#register_roomnick");
+ if (field != null && nick.equals(field.getValue())) {
+ Log.d(Config.LOGTAG, "Already registered with " + c.getJid().asBareJid() + " as " + field.getValue());
+ return;
+ }
+ }
+ if (form == null || !"form".equals(form.getFormType()) || !form.getFields().stream().anyMatch(f -> f.isRequired() && !"muc#register_roomnick".equals(f.getFieldName()))) {
+ // No form, result form, or no required fields other than nickname, let's just send nickname
+ if (form == null || !"form".equals(form.getFormType())) {
+ form = new Data();
+ form.put("FORM_TYPE", "http://jabber.org/protocol/muc#register");
+ }
+ form.put("muc#register_roomnick", nick);
+ form.submit();
+ final IqPacket finish = new IqPacket(IqPacket.TYPE.SET);
+ finish.query(Namespace.REGISTER).addChild(form);
+ finish.setTo(c.getJid().asBareJid());
+ sendIqPacket(c.getAccount(), finish, (a2, response2) -> {
+ if (response.getType() == IqPacket.TYPE.RESULT) {
+ Log.w(Config.LOGTAG, "Success registering with channel " + c.getJid().asBareJid() + "/" + nick);
+ } else {
+ Log.w(Config.LOGTAG, "Error registering with channel: " + response2);
+ }
+ });
+ } else {
+ // TODO: offer registration form to user
+ Log.d(Config.LOGTAG, "Complex registration form for " + c.getJid().asBareJid() + ": " + response);
+ }
+ } else {
+ // We said maybe. Guess not
+ Log.d(Config.LOGTAG, "Could not register with " + c.getJid().asBareJid() + ": " + response);
+ }
+ });
+ }
+
+ public void deregisterWithMuc(Conversation c) {
+ final IqPacket register = new IqPacket(IqPacket.TYPE.GET);
+ register.query(Namespace.REGISTER).addChild("remove");
+ register.setTo(c.getJid().asBareJid());
+ sendIqPacket(c.getAccount(), register, (a, response) -> {
+ if (response.getType() == IqPacket.TYPE.RESULT) {
+ Log.d(Config.LOGTAG, "deregistered with " + c.getJid().asBareJid());
+ } else {
+ Log.w(Config.LOGTAG, "Could not deregister with " + c.getJid().asBareJid() + ": " + response);
+ }
+ });
+ }
+
public Conversation findOrCreateConversation(Account account, Jid jid, boolean muc, final boolean async) {
return this.findOrCreateConversation(account, jid, muc, false, async);
}
@@ -2829,6 +2894,7 @@ public class XmppConnectionService extends Service {
}
}
}
+ deregisterWithMuc(conversation);
leaveMuc(conversation);
} else {
if (conversation.getContact().getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
@@ -3455,6 +3521,8 @@ public class XmppConnectionService extends Service {
databaseBackend.updateConversation(conversation);
}
+ maybeRegisterWithMuc(conversation, null);
+
if (mucOptions.mamSupport()) {
getMessageArchiveService().catchupMUC(conversation);
}
@@ -3732,6 +3800,8 @@ public class XmppConnectionService extends Service {
return false;
}
if (options.online()) {
+ maybeRegisterWithMuc(conversation, nick);
+
Account account = conversation.getAccount();
options.setOnRenameListener(new OnRenameListener() {