summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManager.kt38
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManager.kt20
-rw-r--r--platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManagerTest.kt25
3 files changed, 65 insertions, 18 deletions
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManager.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManager.kt
index 47780fb..07b5662 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManager.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManager.kt
@@ -168,6 +168,44 @@ class ChannelManager(
}
/**
+ * Answers whether a player belongs to a channel without handing out the member list.
+ *
+ * [getChannelMembers] copies the list defensively, which is the wrong price to pay for a
+ * question that only needs to scan it.
+ *
+ * @param channelId The ID of the channel.
+ * @param playerId The UUID of the player.
+ * @return Result containing true if the player is a member.
+ * @throws ChannelNotFoundException if the channel does not exist.
+ */
+ fun isMember(
+ channelId: String,
+ playerId: UUID,
+ ): Result<Boolean> {
+ channelsCache[channelId]
+ ?: return Result.failure(ChannelNotFoundException(channelId))
+
+ val members = membersCache[channelId] ?: return Result.success(false)
+ return Result.success(members.any { it.playerId == playerId })
+ }
+
+ /**
+ * Returns the ids of every existing channel the player belongs to.
+ *
+ * Walks the membership lists once in place; asking per channel meant copying every channel's
+ * member list to answer a question about one player.
+ *
+ * @param playerId The UUID of the player.
+ */
+ fun channelIdsOf(playerId: UUID): List<String> =
+ membersCache
+ .asSequence()
+ .filter { (channelId, members) ->
+ channelsCache.containsKey(channelId) && members.any { it.playerId == playerId }
+ }.map { it.key }
+ .toList()
+
+ /**
* Adds a member to a channel.
*
* @param channelId The ID of the channel.
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManager.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManager.kt
index 3833376..6ce2672 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManager.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManager.kt
@@ -45,10 +45,7 @@ class ChannelMembershipManager(
fun isMember(
playerId: UUID,
channelId: String,
- ): Result<Boolean> =
- channelManager.getChannelMembers(channelId).map { members ->
- members.any { it.playerId == playerId }
- }
+ ): Result<Boolean> = channelManager.isMember(channelId, playerId)
/**
* Gets the role of a member in a channel.
@@ -338,18 +335,5 @@ class ChannelMembershipManager(
* @param playerId The UUID of the player.
* @return Result containing a list of channel IDs where the player is a member.
*/
- fun getPlayerChannels(playerId: UUID): Result<List<String>> {
- val allChannels =
- channelManager.getAllChannels().getOrElse {
- return Result.failure(it)
- }
-
- val playerChannels =
- allChannels
- .filter { channel ->
- isMember(playerId, channel.id).getOrElse { false }
- }.map { it.id }
-
- return Result.success(playerChannels)
- }
+ fun getPlayerChannels(playerId: UUID): Result<List<String>> = Result.success(channelManager.channelIdsOf(playerId))
}
diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManagerTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManagerTest.kt
index 28e1c82..02c4d1a 100644
--- a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManagerTest.kt
+++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManagerTest.kt
@@ -472,4 +472,29 @@ class ChannelMembershipManagerTest {
assertIs<ChannelPlayerBannedException>(result.exceptionOrNull())
}
+
+ @Test
+ fun `isMember should fail for a channel that does not exist`() {
+ val (membership, _, _) = createManagers()
+
+ val result = membership.isMember(createTestUUID(1), "no-such-ch")
+
+ assertIs<ChannelNotFoundException>(result.exceptionOrNull())
+ }
+
+ @Test
+ fun `getPlayerChannels should not report a deleted channel`() {
+ val ownerId = createTestUUID(1)
+ val playerId = createTestUUID(2)
+ val (membership, channelManager, _) = createManagers()
+ channelManager.createChannel(createTestChannel(id = "keep-ch", name = "Keep", ownerId = ownerId))
+ channelManager.createChannel(createTestChannel(id = "drop-ch", name = "Drop", ownerId = ownerId))
+ membership.joinChannel(playerId, "keep-ch")
+ channelManager.setPlayerChannel(playerId, null)
+ membership.joinChannel(playerId, "drop-ch")
+
+ channelManager.deleteChannel("drop-ch", ownerId)
+
+ assertEquals(listOf("keep-ch"), membership.getPlayerChannels(playerId).getOrThrow())
+ }
}