Skip to content

Commit

Permalink
ref: Do not use ParticipantStatusListener
Browse files Browse the repository at this point in the history
Generate left/kicked events internally. In the future we want different
handling based on content of the presence which we can't do with
ParticipantStatusListener. Plus, we've had problems with them executing
in inconsistent order.
  • Loading branch information
bgrozev authored and damencho committed Sep 18, 2024
1 parent 79aeb9f commit 1effdfd
Showing 1 changed file with 9 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ import org.jivesoftware.smackx.muc.MucConfigFormManager
import org.jivesoftware.smackx.muc.MultiUserChat
import org.jivesoftware.smackx.muc.MultiUserChatManager
import org.jivesoftware.smackx.muc.Occupant
import org.jivesoftware.smackx.muc.ParticipantStatusListener
import org.jivesoftware.smackx.muc.UserStatusListener
import org.jivesoftware.smackx.muc.packet.MUCAdmin
import org.jivesoftware.smackx.muc.packet.MUCInitialPresence
Expand Down Expand Up @@ -121,7 +120,6 @@ class ChatRoomImpl(
/** Smack multi user chat backend instance. */
private val muc: MultiUserChat =
MultiUserChatManager.getInstanceFor(xmppProvider.xmppConnection).getMultiUserChat(this.roomJid).apply {
addParticipantStatusListener(memberListener)
addUserStatusListener(userListener)
addParticipantListener(this@ChatRoomImpl)
}
Expand Down Expand Up @@ -313,7 +311,6 @@ class ChatRoomImpl(

override fun leave() {
muc.removePresenceInterceptor(presenceInterceptor)
muc.removeParticipantStatusListener(memberListener)
muc.removeUserStatusListener(userListener)
muc.removeParticipantListener(this)
leaveCallback(this)
Expand Down Expand Up @@ -544,9 +541,11 @@ class ChatRoomImpl(
// Trigger member "joined"
eventEmitter.fireEvent { memberJoined(member) }
} else if (memberLeft) {
// In some cases smack fails to call left(). We'll call it here
// any time we receive presence unavailable
memberListener.left(jid)
if (MUCUser.from(presence).status.contains(MUCUser.Status.KICKED_307)) {
memberListener.kicked(jid)
} else {
memberListener.left(jid)
}
}
if (!memberLeft) {
eventEmitter.fireEvent { memberPresenceChanged(member) }
Expand Down Expand Up @@ -595,18 +594,7 @@ class ChatRoomImpl(
const val VISITORS_ENABLED = "muc#roominfo_visitorsEnabled"
}

internal inner class MemberListener : ParticipantStatusListener {
override fun joined(mucJid: EntityFullJid?) {
// When a new member joins, Smack seems to fire ParticipantStatusListener#joined and
// PresenceListener#processPresence in a non-deterministic order.

// In order to ensure that we have all the information contained in presence at the time that we create a
// new ChatMemberImpl, we completely ignore this joined event. Instead, we rely on processPresence to detect
// when a new member has joined and trigger the creation of a ChatMemberImpl by calling
// ChatRoomImpl#memberJoined()
logger.debug { "Ignore a member joined event for $mucJid" }
}

private inner class MemberListener {
private fun removeMember(occupantJid: EntityFullJid?): ChatRoomMemberImpl? {
synchronized(membersMap) {
val removed = membersMap.remove(occupantJid)
Expand All @@ -623,28 +611,20 @@ class ChatRoomImpl(
}
}

/**
* This needs to be prepared to run twice for the same member.
*/
override fun left(occupantJid: EntityFullJid?) {
/** This needs to be prepared to run twice for the same member. */
fun left(occupantJid: EntityFullJid) {
logger.debug { "Left $occupantJid room: $roomJid" }

val member = synchronized(membersMap) { removeMember(occupantJid) }
member?.let { eventEmitter.fireEvent { memberLeft(it) } }
?: logger.info("Member left event for non-existing member: $occupantJid")
}

override fun kicked(occupantJid: EntityFullJid?, actor: Jid?, reason: String?) {
logger.debug { "Kicked: $occupantJid, $actor, $reason" }

fun kicked(occupantJid: EntityFullJid) {
val member = synchronized(membersMap) { removeMember(occupantJid) }
member?.let { eventEmitter.fireEvent { memberKicked(it) } }
?: logger.error("Kicked member does not exist: $occupantJid")
}

override fun nicknameChanged(oldNickname: EntityFullJid?, newNickname: Resourcepart?) {
logger.error("nicknameChanged - NOT IMPLEMENTED")
}
}

/**
Expand Down

0 comments on commit 1effdfd

Please sign in to comment.