From 7a9b5a8563c7cb983566c28a988fba3aeb16d84d Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Sat, 26 Aug 2023 22:13:00 -0500 Subject: [PATCH] Preserve nick/hats/avatar across basic presence change Only require them on join/rename presence, basically. Just sending "away" to the room with no metadata doesn't break you. --- .../siacs/conversations/entities/MucOptions.java | 15 +++++++++------ .../conversations/parser/AbstractParser.java | 10 ++++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index b0fcee489ec12818638bd05a486da4f05c77e79b..25610d68fc8e987bc87dfdb731aa4dbafa8f182e 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -283,6 +283,9 @@ public class MucOptions { synchronized (this.users) { if (old != null) { users.remove(old); + if (old.nick != null && user.nick == null && old.getName().equals(user.getName())) user.nick = old.nick; + if (old.hats != null && user.hats == null) user.hats = old.hats; + if (old.avatar != null && user.avatar == null) user.avatar = old.avatar; } boolean fullJidIsSelf = isOnline && user.getFullJid() != null && user.getFullJid().equals(self.getFullJid()); if ((!membersOnly() || user.getAffiliation().ranks(Affiliation.MEMBER)) @@ -821,17 +824,17 @@ public class MucOptions { private Affiliation affiliation = Affiliation.NONE; private Jid realJid; private Jid fullJid; - private String nick; + protected String nick; private long pgpKeyId = 0; - private Avatar avatar; + protected Avatar avatar; private final MucOptions options; private ChatState chatState = Config.DEFAULT_CHAT_STATE; - private final Set hats; + protected Set hats; public User(MucOptions options, Jid fullJid, final String nick, final Set hats) { this.options = options; this.fullJid = fullJid; - this.nick = nick == null ? getName() : nick; + this.nick = nick; this.hats = hats; } @@ -840,7 +843,7 @@ public class MucOptions { } public String getNick() { - return nick; + return nick == null ? getName() : nick; } public Role getRole() { @@ -860,7 +863,7 @@ public class MucOptions { } public Set getHats() { - return this.hats; + return this.hats == null ? new HashSet<>() : hats; } public long getPgpKeyId() { diff --git a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java index 258e4b63064a771c60b4b81bcff85360357e2c09..91a4869bec9852c1d2f69bad1dd6616f9f91f5e9 100644 --- a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java +++ b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java @@ -137,7 +137,7 @@ public abstract class AbstractParser { return parseItem(conference,item,null,null,new Element("hats", "urn:xmpp:hats:0")); } - public static MucOptions.User parseItem(Conversation conference, Element item, Jid fullJid, final String nickname, final Element hatsEl) { + public static MucOptions.User parseItem(Conversation conference, Element item, Jid fullJid, final String nicknameIn, final Element hatsEl) { final String local = conference.getJid().getLocal(); final String domain = conference.getJid().getDomain().toEscapedString(); String affiliation = item.getAttribute("affiliation"); @@ -152,9 +152,11 @@ public abstract class AbstractParser { } Jid realJid = item.getAttributeAsJid("jid"); if (fullJid != null) nick = fullJid.getResource(); + String nickname = null; + if (nick != null && nicknameIn != null) nickname = nick.equals(nicknameIn) ? nick : null; try { - if (nickname != null && nick != null && !nick.equals(nickname) && gnu.inet.encoding.Punycode.decode(nick).equals(nickname)) { - nick = nickname; + if (nickname == null && nicknameIn != null && nick != null && gnu.inet.encoding.Punycode.decode(nick).equals(nicknameIn)) { + nickname = nicknameIn; } } catch (final gnu.inet.encoding.PunycodeException | ArrayIndexOutOfBoundsException e) { } Set hats = new TreeSet<>(); @@ -163,7 +165,7 @@ public abstract class AbstractParser { hats.add(new MucOptions.Hat(hat)); } } - MucOptions.User user = new MucOptions.User(conference.getMucOptions(), fullJid, nick, hats); + MucOptions.User user = new MucOptions.User(conference.getMucOptions(), fullJid, nickname, hatsEl == null ? null : hats); if (InvalidJid.isValid(realJid)) { user.setRealJid(realJid); }