diff options
| author | Sho Sakuma <me@m1sk9.dev> | 2026-03-15 01:30:48 +0900 |
|---|---|---|
| committer | Sho Sakuma <me@m1sk9.dev> | 2026-03-15 01:31:41 +0900 |
| commit | d015409b964ecb4c6352dba9845e926f3862ce90 (patch) | |
| tree | 8a41f079cff5a784d42af10a42e1f2d19317e91f | |
| parent | 384178d694b109c5f83ab73a03b01aa78b06d670 (diff) | |
| download | LunaticChat-d015409b964ecb4c6352dba9845e926f3862ce90.tar.gz LunaticChat-d015409b964ecb4c6352dba9845e926f3862ce90.tar.bz2 LunaticChat-d015409b964ecb4c6352dba9845e926f3862ce90.zip | |
refactor: Optimization of internal logic
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 |
