summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md4
-rw-r--r--build.gradle.kts2
-rw-r--r--engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/exception/ChannelAlreadyExistsException.kt5
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PluginCoroutineScope.kt5
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceInitializer.kt1
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManager.kt6
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelMessageHandler.kt26
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelNotificationHandler.kt118
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/DirectMessageHandler.kt13
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomajiConversionHelper.kt26
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/i18n/MessageFormatter.kt3
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerChatListener.kt17
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/SpyPermissionManager.kt5
-rw-r--r--platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManagerTest.kt3
14 files changed, 80 insertions, 154 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf22270..c92825c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## v0
+### v0.10.2
+
+- Optimization of internal logic.
+
### v0.10.1
- Codecov was introduced to expand test coverage.
diff --git a/build.gradle.kts b/build.gradle.kts
index d4328b2..43e35d4 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -14,7 +14,7 @@ plugins {
allprojects {
group = "dev.m1sk9"
- version = "0.10.1"
+ version = "0.10.2"
repositories {
mavenCentral()
diff --git a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/exception/ChannelAlreadyExistsException.kt b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/exception/ChannelAlreadyExistsException.kt
new file mode 100644
index 0000000..de98ebf
--- /dev/null
+++ b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/exception/ChannelAlreadyExistsException.kt
@@ -0,0 +1,5 @@
+package dev.m1sk9.lunaticChat.engine.exception
+
+class ChannelAlreadyExistsException(
+ channelId: String,
+) : Exception("Channel with ID $channelId already exists.")
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PluginCoroutineScope.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PluginCoroutineScope.kt
index 34ae0fc..114f82d 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PluginCoroutineScope.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PluginCoroutineScope.kt
@@ -41,9 +41,4 @@ class PluginCoroutineScope(
scope.cancel()
logger.info("Plugin coroutine scope cancelled.")
}
-
- /**
- * Returns true if the scope is still active.
- */
- fun isActive(): Boolean = job.isActive
}
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceInitializer.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceInitializer.kt
index 73657a1..2d237e1 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceInitializer.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceInitializer.kt
@@ -287,7 +287,6 @@ class ServiceInitializer(
configuration = configuration,
settingsManager = settingsManager,
channelManager = manager,
- romanjiConverter = romajiConverter,
languageManager = languageManager,
messageLogger = messageLogger,
logger =
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 f5e1bf2..998414f 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
@@ -5,8 +5,10 @@ import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelContext
import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelData
import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelMember
import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelRole
+import dev.m1sk9.lunaticChat.engine.exception.ChannelAlreadyExistsException
import dev.m1sk9.lunaticChat.engine.exception.ChannelLimitExceededException
import dev.m1sk9.lunaticChat.engine.exception.ChannelMemberLimitExceededException
+import dev.m1sk9.lunaticChat.engine.exception.ChannelMemberNotFoundException
import dev.m1sk9.lunaticChat.engine.exception.ChannelNoOwnerPermissionException
import dev.m1sk9.lunaticChat.engine.exception.ChannelNotFoundException
import dev.m1sk9.lunaticChat.engine.exception.ChannelPlayerAlreadyBannedException
@@ -57,7 +59,7 @@ class ChannelManager(
*/
fun createChannel(channel: Channel): Result<Channel> {
if (channelsCache.containsKey(channel.id)) {
- return Result.failure(ChannelNotFoundException(channel.id))
+ return Result.failure(ChannelAlreadyExistsException(channel.id))
}
// Check if max channels limit is reached (0 means unlimited)
@@ -227,7 +229,7 @@ class ChannelManager(
val removed = members.removeIf { it.playerId == playerId }
if (!removed) {
- return Result.failure(ChannelNotFoundException(channelId))
+ return Result.failure(ChannelMemberNotFoundException(channelId))
}
saveToStorage()
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelMessageHandler.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelMessageHandler.kt
index 810d1ca..28a306c 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelMessageHandler.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelMessageHandler.kt
@@ -7,7 +7,6 @@ import dev.m1sk9.lunaticChat.paper.common.SpyPermissionManager
import dev.m1sk9.lunaticChat.paper.common.playChannelReceiveNotification
import dev.m1sk9.lunaticChat.paper.common.playMessageSendNotification
import dev.m1sk9.lunaticChat.paper.config.LunaticChatConfiguration
-import dev.m1sk9.lunaticChat.paper.converter.RomanjiConverter
import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager
import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager
import io.ktor.util.logging.Logger
@@ -20,7 +19,6 @@ class ChannelMessageHandler(
private val configuration: LunaticChatConfiguration,
private val settingsManager: PlayerSettingsManager?,
private val channelManager: ChannelManager,
- private val romanjiConverter: RomanjiConverter?,
private val languageManager: LanguageManager,
private val messageLogger: ChannelMessageLogger?,
private val logger: Logger,
@@ -36,25 +34,7 @@ class ChannelMessageHandler(
val senderSettings = settingsManager?.getSettings(playerId)
- // Handle romaji conversion if enabled
- // Uses explicit timeout to prevent long blocking (1s max instead of 3s)
- val displayMessage =
- if (senderSettings?.japaneseConversionEnabled == true && romanjiConverter != null) {
- runCatching {
- kotlinx.coroutines.runBlocking {
- kotlinx.coroutines
- .withTimeoutOrNull(1000) {
- romanjiConverter!!
- .convert(message)
- }?.let { "$message §e($it)" } ?: message
- }
- }.getOrElse { message }
- } else {
- message
- }
-
- val formattedMessage = formatChannelMessage(player.name, context.channel.name, displayMessage)
- val spyMessage = formatChannelMessage(player.name, context.channel.name, message)
+ val formattedMessage = formatChannelMessage(player.name, context.channel.name, message)
// Play notification sound to sender if enabled
if (senderSettings?.channelMessageNotificationEnabled == true) {
@@ -69,9 +49,9 @@ class ChannelMessageHandler(
.filter { it.isOnline && it.uniqueId != playerId && it.uniqueId !in memberIds }
.forEach {
it.sendMessage(
- spyMessage.hoverEvent(
+ formattedMessage.hoverEvent(
HoverEvent.showText(
- Component.text(languageManager.getMessage("general.spyMessage")),
+ Component.text(languageManager.getMessage("general.formattedMessage")),
),
),
)
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelNotificationHandler.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelNotificationHandler.kt
index 0352780..415bd82 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelNotificationHandler.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelNotificationHandler.kt
@@ -12,123 +12,61 @@ class ChannelNotificationHandler(
private val channelManager: ChannelManager,
private val languageManager: LanguageManager,
) {
- /**
- * Broadcasts a join notification to all members of a channel.
- *
- * @param channelId The ID of the channel.
- * @param playerName The name of the player who joined.
- */
fun broadcastJoin(
channelId: String,
playerName: String,
) {
- val channel = channelManager.getChannel(channelId).getOrNull() ?: return
- val members = channelManager.getChannelMembers(channelId).getOrNull() ?: return
-
- val message =
- languageManager.getMessage(
- "channel.notification.playerJoined",
- mapOf("player" to playerName, "channel" to channel.name),
- )
- val formattedMessage = MessageFormatter.format(message)
-
- members.forEach { member ->
- Bukkit.getPlayer(member.playerId)?.let { player ->
- if (player.isOnline) {
- player.sendMessage(formattedMessage)
- }
- }
- }
+ broadcastToMembers(
+ channelId,
+ "channel.notification.playerJoined",
+ mapOf("player" to playerName),
+ )
}
- /**
- * Broadcasts a leave notification to all members of a channel.
- *
- * @param channelId The ID of the channel.
- * @param playerName The name of the player who left.
- */
fun broadcastLeave(
channelId: String,
playerName: String,
) {
- val channel = channelManager.getChannel(channelId).getOrNull() ?: return
- val members = channelManager.getChannelMembers(channelId).getOrNull() ?: return
-
- val message =
- languageManager.getMessage(
- "channel.notification.playerLeft",
- mapOf("player" to playerName, "channel" to channel.name),
- )
- val formattedMessage = MessageFormatter.format(message)
-
- members.forEach { member ->
- Bukkit.getPlayer(member.playerId)?.let { player ->
- if (player.isOnline) {
- player.sendMessage(formattedMessage)
- }
- }
- }
+ broadcastToMembers(
+ channelId,
+ "channel.notification.playerLeft",
+ mapOf("player" to playerName),
+ )
}
- /**
- * Broadcasts a kick notification to all members of a channel.
- *
- * @param channelId The ID of the channel.
- * @param kickedPlayerName The name of the player who was kicked.
- * @param kickerName The name of the player who performed the kick.
- */
fun broadcastKick(
channelId: String,
kickedPlayerName: String,
kickerName: String,
) {
- val channel = channelManager.getChannel(channelId).getOrNull() ?: return
- val members = channelManager.getChannelMembers(channelId).getOrNull() ?: return
-
- val message =
- languageManager.getMessage(
- "channel.notification.playerKicked",
- mapOf(
- "player" to kickedPlayerName,
- "channel" to channel.name,
- "kicker" to kickerName,
- ),
- )
- val formattedMessage = MessageFormatter.format(message)
-
- members.forEach { member ->
- Bukkit.getPlayer(member.playerId)?.let { player ->
- if (player.isOnline) {
- player.sendMessage(formattedMessage)
- }
- }
- }
+ broadcastToMembers(
+ channelId,
+ "channel.notification.playerKicked",
+ mapOf("player" to kickedPlayerName, "kicker" to kickerName),
+ )
}
- /**
- * Broadcasts a ban notification to all members of a channel.
- *
- * @param channelId The ID of the channel.
- * @param bannedPlayerName The name of the player who was banned.
- * @param bannerName The name of the player who performed the ban.
- */
fun broadcastBan(
channelId: String,
bannedPlayerName: String,
bannerName: String,
) {
+ broadcastToMembers(
+ channelId,
+ "channel.notification.playerBanned",
+ mapOf("player" to bannedPlayerName, "banner" to bannerName),
+ )
+ }
+
+ private fun broadcastToMembers(
+ channelId: String,
+ messageKey: String,
+ placeholders: Map<String, String>,
+ ) {
val channel = channelManager.getChannel(channelId).getOrNull() ?: return
val members = channelManager.getChannelMembers(channelId).getOrNull() ?: return
- val message =
- languageManager.getMessage(
- "channel.notification.playerBanned",
- mapOf(
- "player" to bannedPlayerName,
- "channel" to channel.name,
- "banner" to bannerName,
- ),
- )
+ val message = languageManager.getMessage(messageKey, placeholders + ("channel" to channel.name))
val formattedMessage = MessageFormatter.format(message)
members.forEach { member ->
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/DirectMessageHandler.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/DirectMessageHandler.kt
index 3f7950a..1963528 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/DirectMessageHandler.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/DirectMessageHandler.kt
@@ -5,6 +5,7 @@ import dev.m1sk9.lunaticChat.paper.common.playDirectMessageNotification
import dev.m1sk9.lunaticChat.paper.common.playMessageSendNotification
import dev.m1sk9.lunaticChat.paper.config.LunaticChatConfiguration
import dev.m1sk9.lunaticChat.paper.converter.RomanjiConverter
+import dev.m1sk9.lunaticChat.paper.converter.convertWithRomaji
import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager
import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager
import net.kyori.adventure.text.Component
@@ -92,19 +93,9 @@ class DirectMessageHandler(
val senderSettings = settingsManager?.getSettings(sender.uniqueId)
val recipientSettings = settingsManager?.getSettings(recipient.uniqueId)
- // Handle romaji conversion if enabled
- // Uses explicit timeout to prevent long blocking (1s max instead of 3s)
val displayMessage =
if (senderSettings?.japaneseConversionEnabled == true && romanjiConverter != null) {
- runCatching {
- kotlinx.coroutines.runBlocking {
- kotlinx.coroutines
- .withTimeoutOrNull(1000) {
- romanjiConverter!!
- .convert(message)
- }?.let { "$message §e($it)" } ?: message
- }
- }.getOrElse { message }
+ convertWithRomaji(message, romanjiConverter)
} else {
message
}
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomajiConversionHelper.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomajiConversionHelper.kt
new file mode 100644
index 0000000..841061a
--- /dev/null
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomajiConversionHelper.kt
@@ -0,0 +1,26 @@
+package dev.m1sk9.lunaticChat.paper.converter
+
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeoutOrNull
+
+/**
+ * Converts a message using romaji-to-Japanese conversion with timeout protection.
+ * Returns the original message appended with the conversion result, or the original message on failure.
+ *
+ * @param message The message to convert.
+ * @param converter The RomanjiConverter to use.
+ * @param timeoutMs Timeout in milliseconds for the conversion (default: 1000ms).
+ * @return The message with conversion appended (e.g., "hello §e(こんにちは)"), or the original message.
+ */
+fun convertWithRomaji(
+ message: String,
+ converter: RomanjiConverter,
+ timeoutMs: Long = 1000,
+): String =
+ runCatching {
+ runBlocking {
+ withTimeoutOrNull(timeoutMs) {
+ converter.convert(message)
+ }?.let { "$message §e($it)" } ?: message
+ }
+ }.getOrElse { message }
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/i18n/MessageFormatter.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/i18n/MessageFormatter.kt
index 862ab61..d20c9f7 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/i18n/MessageFormatter.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/i18n/MessageFormatter.kt
@@ -17,6 +17,7 @@ object MessageFormatter {
private val PLACEHOLDER_COLOR = NamedTextColor.YELLOW
private val ERROR_COLOR = NamedTextColor.RED
private val SUCCESS_COLOR = NamedTextColor.GREEN
+ private val PLACEHOLDER_REGEX = Regex("""\{([^}]+)}""")
/**
* Formats a message with the standard prefix and gray text.
@@ -92,7 +93,7 @@ object MessageFormatter {
baseColor: NamedTextColor,
): Component {
val result = Component.text()
- val regex = Regex("""\{([^}]+)}""")
+ val regex = PLACEHOLDER_REGEX
var lastIndex = 0
regex.findAll(message).forEach { match ->
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerChatListener.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerChatListener.kt
index 4df4889..8a07336 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerChatListener.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerChatListener.kt
@@ -6,10 +6,10 @@ import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager
import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelMessageHandler
import dev.m1sk9.lunaticChat.paper.config.LunaticChatConfiguration
import dev.m1sk9.lunaticChat.paper.converter.RomanjiConverter
+import dev.m1sk9.lunaticChat.paper.converter.convertWithRomaji
import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager
import dev.m1sk9.lunaticChat.paper.velocity.CrossServerChatManager
import io.papermc.paper.event.player.AsyncChatEvent
-import kotlinx.coroutines.runBlocking
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer
import org.bukkit.event.EventHandler
@@ -88,20 +88,9 @@ class PlayerChatListener(
ChatMode.GLOBAL
}
- // Handle romaji conversion if enabled
- // Uses explicit timeout to prevent long blocking (1s max instead of 3s)
- // Note: AsyncChatEvent runs on async thread, so runBlocking here doesn't block main thread
val displayMessage =
if (settings.japaneseConversionEnabled && romajiConverter != null) {
- runCatching {
- runBlocking {
- kotlinx.coroutines
- .withTimeoutOrNull(1000) {
- romajiConverter
- ?.convert(messageWithoutPrefix)
- }?.let { "$messageWithoutPrefix §e($it)" } ?: messageWithoutPrefix
- }
- }.getOrElse { messageWithoutPrefix }
+ convertWithRomaji(messageWithoutPrefix, romajiConverter)
} else {
messageWithoutPrefix
}
@@ -124,7 +113,7 @@ class PlayerChatListener(
event.isCancelled = true
event.viewers().clear()
event.message(Component.empty())
- channelMessageHandler.sendChannelMessage(player, messageWithoutPrefix)
+ channelMessageHandler.sendChannelMessage(player, displayMessage)
} else {
// Auto-fallback to global chat (with Velocity support if enabled)
handleGlobalChat(event, displayMessage)
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/SpyPermissionManager.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/SpyPermissionManager.kt
index 26de098..2c56219 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/SpyPermissionManager.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/SpyPermissionManager.kt
@@ -23,11 +23,6 @@ object SpyPermissionManager : Listener {
fun getDirectMessageSpyPlayers(): Map<UUID, Player> = directMessageSpyPlayers.toMap()
/**
- * Gets all player UUIDs with spy permission.
- */
- fun getDirectMessageSpyPlayerIds(): Set<UUID> = directMessageSpyPlayers.keys
-
- /**
* Updates the cache of players with direct message spy permission.
* Call this on player join/quit/permission change events.
*/
diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManagerTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManagerTest.kt
index acf610f..349903a 100644
--- a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManagerTest.kt
+++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManagerTest.kt
@@ -3,6 +3,7 @@ package dev.m1sk9.lunaticChat.paper.chat.channel
import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelData
import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelMember
import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelRole
+import dev.m1sk9.lunaticChat.engine.exception.ChannelAlreadyExistsException
import dev.m1sk9.lunaticChat.engine.exception.ChannelLimitExceededException
import dev.m1sk9.lunaticChat.engine.exception.ChannelMemberLimitExceededException
import dev.m1sk9.lunaticChat.engine.exception.ChannelNoOwnerPermissionException
@@ -122,7 +123,7 @@ class ChannelManagerTest {
val result = manager.createChannel(channel)
assertTrue(result.isFailure)
- assertIs<ChannelNotFoundException>(result.exceptionOrNull())
+ assertIs<ChannelAlreadyExistsException>(result.exceptionOrNull())
}
@Test