diff options
| author | Sho Sakuma <me@m1sk9.dev> | 2026-03-17 20:34:18 +0900 |
|---|---|---|
| committer | Sho Sakuma <me@m1sk9.dev> | 2026-03-17 20:34:18 +0900 |
| commit | 634dd975038bb5b845c28ca6c96aa285ef94e965 (patch) | |
| tree | 4eac57ae6533af6b5dc4c43cd5f4726aeb4f6a7a /platform-paper | |
| parent | 8b806705aa3de33964a0924f9b528189b7004087 (diff) | |
| download | LunaticChat-634dd975038bb5b845c28ca6c96aa285ef94e965.tar.gz LunaticChat-634dd975038bb5b845c28ca6c96aa285ef94e965.tar.bz2 LunaticChat-634dd975038bb5b845c28ca6c96aa285ef94e965.zip | |
feat!: Remove ChatMode feature, followback channel chat mode
Diffstat (limited to 'platform-paper')
15 files changed, 20 insertions, 802 deletions
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/LunaticChat.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/LunaticChat.kt index 880db16..addc3a3 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/LunaticChat.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/LunaticChat.kt @@ -1,6 +1,5 @@ package dev.m1sk9.lunaticChat.paper -import dev.m1sk9.lunaticChat.paper.chat.ChatModeManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelMessageHandler @@ -36,7 +35,6 @@ class LunaticChat : lateinit var languageManager: LanguageManager var channelManager: ChannelManager? = null var channelMembershipManager: ChannelMembershipManager? = null - var chatModeManager: ChatModeManager? = null var channelMessageHandler: ChannelMessageHandler? = null var channelNotificationHandler: ChannelNotificationHandler? = null var velocityConnectionManager: VelocityConnectionManager? = null @@ -79,7 +77,6 @@ class LunaticChat : languageManager = services.languageManager channelManager = services.channelManager channelMembershipManager = services.channelMembershipManager - chatModeManager = services.chatModeManager channelMessageHandler = services.channelMessageHandler channelNotificationHandler = services.channelNotificationHandler velocityConnectionManager = services.velocityConnectionManager diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceContainer.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceContainer.kt index 5ca5e52..0607d82 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceContainer.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceContainer.kt @@ -1,6 +1,5 @@ package dev.m1sk9.lunaticChat.paper -import dev.m1sk9.lunaticChat.paper.chat.ChatModeManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelMessageHandler @@ -24,7 +23,6 @@ import dev.m1sk9.lunaticChat.paper.velocity.VelocityConnectionManager * @property romajiConverter Optional (only when Japanese conversion feature is enabled) * @property channelManager Optional (only when channel chat feature is enabled) * @property channelMembershipManager Optional (only when channel chat feature is enabled) - * @property chatModeManager Optional (only when channel chat feature is enabled) * @property channelMessageHandler Optional (only when channel chat feature is enabled) * @property channelNotificationHandler Optional (only when channel chat feature is enabled) * @property velocityConnectionManager Optional (only when Velocity integration is enabled) @@ -37,7 +35,6 @@ data class ServiceContainer( val romajiConverter: RomanjiConverter? = null, val channelManager: ChannelManager? = null, val channelMembershipManager: ChannelMembershipManager? = null, - val chatModeManager: ChatModeManager? = null, val channelMessageHandler: ChannelMessageHandler? = null, val channelNotificationHandler: ChannelNotificationHandler? = null, val velocityConnectionManager: VelocityConnectionManager? = null, 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 b732a9e..606273b 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 @@ -1,8 +1,6 @@ package dev.m1sk9.lunaticChat.paper import dev.m1sk9.lunaticChat.engine.converter.GoogleIMEClient -import dev.m1sk9.lunaticChat.paper.chat.ChatModeManager -import dev.m1sk9.lunaticChat.paper.chat.ChatModeStorage import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMessageLogger @@ -34,7 +32,6 @@ import kotlin.time.Duration.Companion.milliseconds private data class ChannelComponents( val channelManager: ChannelManager, val channelMembershipManager: ChannelMembershipManager, - val chatModeManager: ChatModeManager, val channelMessageHandler: ChannelMessageHandler, val channelNotificationHandler: ChannelNotificationHandler, ) @@ -54,7 +51,6 @@ class ServiceInitializer( private var conversionCache: ConversionCache? = null private var channelManager: ChannelManager? = null private var channelMembershipManager: ChannelMembershipManager? = null - private var chatModeManager: ChatModeManager? = null private var channelMessageHandler: ChannelMessageHandler? = null private var channelNotificationHandler: ChannelNotificationHandler? = null private var channelMessageLogger: ChannelMessageLogger? = null @@ -96,7 +92,7 @@ class ServiceInitializer( null } - // 4. Initialize channel manager, membership manager, chat mode manager, channel message handler, and notification handler + // 4. Initialize channel manager, membership manager, channel message handler, and notification handler val channelComponents = if (configuration.features.channelChat.enabled) { initializeChannelManager(playerSettingsManager, languageManager) @@ -105,7 +101,6 @@ class ServiceInitializer( } val channelManager = channelComponents?.channelManager val channelMembershipManager = channelComponents?.channelMembershipManager - val chatModeManager = channelComponents?.chatModeManager val channelMessageHandler = channelComponents?.channelMessageHandler val channelNotificationHandler = channelComponents?.channelNotificationHandler @@ -144,7 +139,6 @@ class ServiceInitializer( romajiConverter = romajiConverter, channelManager = channelManager, channelMembershipManager = channelMembershipManager, - chatModeManager = chatModeManager, channelMessageHandler = channelMessageHandler, channelNotificationHandler = channelNotificationHandler, velocityConnectionManager = velocityManager, @@ -213,7 +207,7 @@ class ServiceInitializer( } /** - * Initializes channel manager, membership manager, chat mode manager, channel message handler, and notification handler with storage. + * Initializes channel manager, membership manager, channel message handler, and notification handler with storage. */ private fun initializeChannelManager( settingsManager: PlayerSettingsManager, @@ -244,21 +238,6 @@ class ServiceInitializer( ) channelMembershipManager = membershipManager - val chatModeFile = plugin.dataFolder.resolve("chatmodes.json").toPath() - val chatModeStorage = - ChatModeStorage( - dataFile = chatModeFile, - logger = logger, - ) - - val chatMode = - ChatModeManager( - storage = chatModeStorage, - logger = logger, - ) - chatMode.initialize() - chatModeManager = chatMode - // Initialize channel message logger if enabled val messageLogger = if (configuration.features.channelChat.messageLogging.enabled) { @@ -302,13 +281,12 @@ class ServiceInitializer( channelNotificationHandler = notificationHandler logger.info( - "Channel manager, membership manager, chat mode manager, " + + "Channel manager, membership manager, " + "channel message handler, and notification handler initialized successfully.", ) return ChannelComponents( channelManager = manager, channelMembershipManager = membershipManager, - chatModeManager = chatMode, channelMessageHandler = messageHandler, channelNotificationHandler = notificationHandler, ) @@ -433,7 +411,6 @@ class ServiceInitializer( services.playerSettingsManager.saveToDisk() conversionCache?.saveToDisk() services.channelManager?.saveToDisk() - services.chatModeManager?.shutdown() channelMessageLogger?.shutdown() services.velocityConnectionManager?.shutdown() } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/ChatModeManager.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/ChatModeManager.kt deleted file mode 100644 index 93a7f04..0000000 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/ChatModeManager.kt +++ /dev/null @@ -1,103 +0,0 @@ -package dev.m1sk9.lunaticChat.paper.chat - -import dev.m1sk9.lunaticChat.engine.chat.ChatMode -import dev.m1sk9.lunaticChat.engine.chat.ChatModeData -import java.util.UUID -import java.util.concurrent.ConcurrentHashMap -import java.util.logging.Logger - -/** - * Manages player chat modes with persistence. - * - * Chat modes determine where player messages are sent by default. - * Modes are persisted across server restarts. - * - * @property storage Chat mode storage layer - * @property logger Logger for operations - */ -class ChatModeManager( - private val storage: ChatModeStorage, - private val logger: Logger, -) { - private val chatModes = ConcurrentHashMap<UUID, ChatMode>() - - /** - * Initializes the manager by loading data from storage. - */ - fun initialize() { - val data = storage.loadFromDisk() - chatModes.putAll(data.modes) - logger.info("ChatModeManager initialized with ${chatModes.size} saved modes") - } - - /** - * Gets a player's current chat mode. - * - * @param playerId The player's UUID - * @return The player's chat mode, or DEFAULT if not set - */ - fun getChatMode(playerId: UUID): ChatMode = chatModes.getOrDefault(playerId, ChatMode.Companion.DEFAULT) - - /** - * Sets a player's chat mode. - * - * @param playerId The player's UUID - * @param mode The chat mode to set - */ - fun setChatMode( - playerId: UUID, - mode: ChatMode, - ) { - chatModes[playerId] = mode - saveToStorage() - } - - /** - * Toggles a player's chat mode between GLOBAL and CHANNEL. - * - * @param playerId The player's UUID - * @return The new chat mode after toggling - */ - fun toggleChatMode(playerId: UUID): ChatMode { - val currentMode = getChatMode(playerId) - val newMode = currentMode.toggle() - setChatMode(playerId, newMode) - return newMode - } - - /** - * Removes a player's chat mode setting (reverts to default). - * - * @param playerId The player's UUID - */ - fun removeChatMode(playerId: UUID) { - chatModes.remove(playerId) - saveToStorage() - } - - /** - * Saves current state to storage asynchronously. - */ - private fun saveToStorage() { - val data = ChatModeData(modes = chatModes.toMap()) - storage.queueAsyncSave(data) - } - - /** - * Forces a synchronous save to storage. - * Should only be called during plugin shutdown. - */ - fun saveToDisk() { - val data = ChatModeData(modes = chatModes.toMap()) - storage.saveToDisk(data) - } - - /** - * Shuts down the chat mode manager and its storage executor. - * Should be called during plugin disable to prevent thread leaks. - */ - fun shutdown() { - saveToDisk() - storage.shutdown() - } -} diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/ChatModeStorage.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/ChatModeStorage.kt deleted file mode 100644 index 77fcdb3..0000000 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/ChatModeStorage.kt +++ /dev/null @@ -1,98 +0,0 @@ -package dev.m1sk9.lunaticChat.paper.chat - -import dev.m1sk9.lunaticChat.engine.chat.ChatModeData -import dev.m1sk9.lunaticChat.engine.exception.ChatModeStorageException -import kotlinx.serialization.json.Json -import java.nio.file.Path -import java.util.concurrent.Executors -import java.util.concurrent.TimeUnit -import java.util.logging.Logger -import kotlin.io.path.exists -import kotlin.io.path.readText -import kotlin.io.path.writeText - -/** - * Handles JSON storage for chat mode data. - * Provides async save queue and synchronous save for shutdown. - * - * @property dataFile Path to chatmodes.json - * @property logger Logger for operations - */ -class ChatModeStorage( - private val dataFile: Path, - private val logger: Logger, -) { - private val json = - Json { - prettyPrint = true - ignoreUnknownKeys = true - } - - private val saveExecutor = Executors.newSingleThreadExecutor() - - /** - * Loads chat mode data from disk. - * - * @return ChatModeData loaded from file, or empty data if file doesn't exist - * @throws ChatModeStorageException if loading fails - */ - fun loadFromDisk(): ChatModeData { - if (!dataFile.exists()) { - logger.info("Chat mode data file not found, starting with empty data") - return ChatModeData() - } - - return try { - val jsonContent = dataFile.readText() - json.decodeFromString<ChatModeData>(jsonContent) - } catch (e: Exception) { - throw ChatModeStorageException("Failed to load chat mode data from ${dataFile.fileName}", e) - } - } - - /** - * Queues an asynchronous save operation. - * - * @param data ChatModeData to save - */ - fun queueAsyncSave(data: ChatModeData) { - saveExecutor.submit { - try { - saveToDisk(data) - } catch (e: Exception) { - logger.severe("Failed to save chat mode data: ${e.message}") - } - } - } - - /** - * Saves chat mode data to disk synchronously. - * - * @param data ChatModeData to save - * @throws ChatModeStorageException if saving fails - */ - fun saveToDisk(data: ChatModeData) { - try { - val jsonContent = json.encodeToString(data) - dataFile.writeText(jsonContent) - } catch (e: Exception) { - throw ChatModeStorageException("Failed to save chat mode data to ${dataFile.fileName}", e) - } - } - - /** - * Shuts down the async save executor. - * Should be called during plugin disable. - */ - fun shutdown() { - saveExecutor.shutdown() - try { - if (!saveExecutor.awaitTermination(5, TimeUnit.SECONDS)) { - saveExecutor.shutdownNow() - } - } catch (e: InterruptedException) { - saveExecutor.shutdownNow() - Thread.currentThread().interrupt() - } - } -} diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/ChatModeCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/ChatModeCommand.kt deleted file mode 100644 index d0357f6..0000000 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/ChatModeCommand.kt +++ /dev/null @@ -1,86 +0,0 @@ -package dev.m1sk9.lunaticChat.paper.command.impl.lc - -import com.mojang.brigadier.builder.LiteralArgumentBuilder -import dev.m1sk9.lunaticChat.engine.command.CommandResult -import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode -import dev.m1sk9.lunaticChat.paper.LunaticChat -import dev.m1sk9.lunaticChat.paper.chat.ChatModeManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission -import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly -import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand -import dev.m1sk9.lunaticChat.paper.command.impl.lc.chatmode.ChatModeToggleCommand -import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager -import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter -import io.papermc.paper.command.brigadier.CommandSourceStack -import io.papermc.paper.command.brigadier.Commands -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor - -@PlayerOnly -class ChatModeCommand( - plugin: LunaticChat, - private val chatModeManager: ChatModeManager, - private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - @Permission(LunaticChatPermissionNode.ChatMode::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> { - val chatModeCommand = Commands.literal("chatmode") - - // Add toggle subcommand - chatModeCommand.then( - ChatModeToggleCommand( - plugin, - chatModeManager, - languageManager, - ).buildWithPermissionCheck(), - ) - - // Default behavior: show current chat mode - chatModeCommand.executes { ctx -> - val context = wrapContext(ctx) - checkPlayerOnly(context)?.let { return@executes handleResult(context, it) } - - val result = showCurrentMode(context) - handleResult(context, result) - } - - return chatModeCommand - } - - private fun showCurrentMode(ctx: CommandContext): CommandResult { - val sender = ctx.requirePlayer() - val currentMode = chatModeManager.getChatMode(sender.uniqueId) - - val modeKey = - when (currentMode) { - dev.m1sk9.lunaticChat.engine.chat.ChatMode.GLOBAL -> "chatmode.mode.global" - dev.m1sk9.lunaticChat.engine.chat.ChatMode.CHANNEL -> "chatmode.mode.channel" - } - - val modeColor = - when (currentMode) { - dev.m1sk9.lunaticChat.engine.chat.ChatMode.GLOBAL -> NamedTextColor.GREEN - dev.m1sk9.lunaticChat.engine.chat.ChatMode.CHANNEL -> NamedTextColor.AQUA - } - - sender.sendMessage( - MessageFormatter - .format( - languageManager.getMessage("chatmode.current") + ": ", - ).append(Component.text(languageManager.getMessage(modeKey), modeColor)), - ) - - return CommandResult.Success - } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "Should use build() method instead of buildCommand()", - ) -} diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/LunaticChatCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/LunaticChatCommand.kt index d945737..cd3b33d 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/LunaticChatCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/LunaticChatCommand.kt @@ -68,17 +68,6 @@ class LunaticChatCommand( } } - // Add chatmode command if chat mode manager is available - plugin.chatModeManager?.let { chatModeManager -> - command.then( - ChatModeCommand( - plugin, - chatModeManager, - languageManager, - ).buildWithPermissionCheck(), - ) - } - return command } } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommand.kt deleted file mode 100644 index e447639..0000000 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommand.kt +++ /dev/null @@ -1,71 +0,0 @@ -package dev.m1sk9.lunaticChat.paper.command.impl.lc.chatmode - -import com.mojang.brigadier.builder.LiteralArgumentBuilder -import dev.m1sk9.lunaticChat.engine.command.CommandResult -import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode -import dev.m1sk9.lunaticChat.paper.LunaticChat -import dev.m1sk9.lunaticChat.paper.chat.ChatModeManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission -import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly -import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand -import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager -import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter -import io.papermc.paper.command.brigadier.CommandSourceStack -import io.papermc.paper.command.brigadier.Commands -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor - -@PlayerOnly -class ChatModeToggleCommand( - plugin: LunaticChat, - private val chatModeManager: ChatModeManager, - private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - @Permission(LunaticChatPermissionNode.ChatModeToggle::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = - Commands.literal("toggle").executes { ctx -> - val context = wrapContext(ctx) - checkPlayerOnly(context)?.let { return@executes handleResult(context, it) } - - val result = execute(context) - handleResult(context, result) - } - - internal fun execute(ctx: CommandContext): CommandResult { - val sender = ctx.requirePlayer() - val newMode = chatModeManager.toggleChatMode(sender.uniqueId) - - val modeKey = - when (newMode) { - dev.m1sk9.lunaticChat.engine.chat.ChatMode.GLOBAL -> "chatmode.mode.global" - dev.m1sk9.lunaticChat.engine.chat.ChatMode.CHANNEL -> "chatmode.mode.channel" - } - - val modeColor = - when (newMode) { - dev.m1sk9.lunaticChat.engine.chat.ChatMode.GLOBAL -> NamedTextColor.GREEN - dev.m1sk9.lunaticChat.engine.chat.ChatMode.CHANNEL -> NamedTextColor.AQUA - } - - sender.sendMessage( - Component - .text() - .append(MessageFormatter.formatSuccess(languageManager.getMessage("chatmode.toggle.success") + ": ")) - .append(Component.text(languageManager.getMessage(modeKey), modeColor)) - .build(), - ) - - return CommandResult.Success - } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChatModeToggleCommand should use build() method instead of buildCommand()", - ) -} diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/EventListenerRegistry.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/EventListenerRegistry.kt index 2bdca37..84040b6 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/EventListenerRegistry.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/EventListenerRegistry.kt @@ -37,19 +37,15 @@ object EventListenerRegistry { languageManager = services.languageManager, updateCheckerFlag = updateAvailable, playerSettingsManager = services.playerSettingsManager, - chatModeManager = services.chatModeManager, channelManager = services.channelManager, ), plugin, ) // Register chat listener when channel chat is enabled OR velocity cross-server chat is enabled - // Channel-related services (chatModeManager, channelManager, channelMessageHandler) can be null - // when channel chat is disabled, but cross-server chat can still work val shouldRegisterChatListener = ( - services.chatModeManager != null && - services.channelManager != null && + services.channelManager != null && services.channelMessageHandler != null ) || ( @@ -60,7 +56,6 @@ object EventListenerRegistry { if (shouldRegisterChatListener) { pluginManager.registerEvents( PlayerChatListener( - chatModeManager = services.chatModeManager, channelManager = services.channelManager, channelMessageHandler = services.channelMessageHandler, romajiConverter = services.romajiConverter, 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 8a07336..19b284b 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 @@ -1,7 +1,5 @@ package dev.m1sk9.lunaticChat.paper.listener -import dev.m1sk9.lunaticChat.engine.chat.ChatMode -import dev.m1sk9.lunaticChat.paper.chat.ChatModeManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelMessageHandler import dev.m1sk9.lunaticChat.paper.config.LunaticChatConfiguration @@ -17,7 +15,6 @@ import org.bukkit.event.EventPriority import org.bukkit.event.Listener class PlayerChatListener( - private val chatModeManager: ChatModeManager?, private val channelManager: ChannelManager?, private val channelMessageHandler: ChannelMessageHandler?, private val romajiConverter: RomanjiConverter?, @@ -61,7 +58,7 @@ class PlayerChatListener( val originalMessage = plainTextSerializer.serialize(event.message()) - // Handle chat mode switching with '!' prefix + // Handle '!' prefix for global chat override val hasPrefix = originalMessage.startsWith('!') val messageWithoutPrefix = if (hasPrefix) { @@ -75,19 +72,6 @@ class PlayerChatListener( return } - val effectiveMode = - if (chatModeManager != null) { - if (hasPrefix) { - val currentMode = chatModeManager.getChatMode(player.uniqueId) - currentMode.toggle() - } else { - chatModeManager.getChatMode(player.uniqueId) - } - } else { - // Default to GLOBAL when chatModeManager is not available - ChatMode.GLOBAL - } - val displayMessage = if (settings.japaneseConversionEnabled && romajiConverter != null) { convertWithRomaji(messageWithoutPrefix, romajiConverter) @@ -95,34 +79,25 @@ class PlayerChatListener( messageWithoutPrefix } - // Route message based on chat mode - when (effectiveMode) { - ChatMode.GLOBAL -> { - handleGlobalChat(event, displayMessage) - } - ChatMode.CHANNEL -> { - // Channel chat requires channelManager and channelMessageHandler - if (channelManager != null && channelMessageHandler != null) { - val hasActiveChannel = channelManager.getPlayerChannel(player.uniqueId) != null + // Determine if the player has an active channel + val hasActiveChannel = channelManager?.getPlayerChannel(player.uniqueId) != null - if (hasActiveChannel) { - // Cancel event and clear all data to prevent other plugins from capturing it - // Even MONITOR priority listeners with ignoreCancelled=false won't get useful data - // Message will be delivered by ChannelMessageHandler instead - // Logging is handled by our own ChannelMessageLogger - event.isCancelled = true - event.viewers().clear() - event.message(Component.empty()) - channelMessageHandler.sendChannelMessage(player, displayMessage) - } else { - // Auto-fallback to global chat (with Velocity support if enabled) - handleGlobalChat(event, displayMessage) - } + when { + hasActiveChannel && !hasPrefix -> { + // Channel chat: player is in a channel and no '!' prefix + if (channelManager != null && channelMessageHandler != null) { + event.isCancelled = true + event.viewers().clear() + event.message(Component.empty()) + channelMessageHandler.sendChannelMessage(player, displayMessage) } else { - // Channel chat not available, fallback to global chat (with Velocity support if enabled) handleGlobalChat(event, displayMessage) } } + else -> { + // Global chat: player has no active channel, or used '!' prefix to override + handleGlobalChat(event, displayMessage) + } } } } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerPresenceListener.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerPresenceListener.kt index f4343b6..3979246 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerPresenceListener.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerPresenceListener.kt @@ -1,9 +1,7 @@ package dev.m1sk9.lunaticChat.paper.listener -import dev.m1sk9.lunaticChat.engine.chat.ChatMode import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat -import dev.m1sk9.lunaticChat.paper.chat.ChatModeManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.common.hasAnyPermission import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager @@ -21,7 +19,6 @@ class PlayerPresenceListener( private val languageManager: LanguageManager, private val updateCheckerFlag: AtomicBoolean, private val playerSettingsManager: PlayerSettingsManager, - private val chatModeManager: ChatModeManager? = null, private val channelManager: ChannelManager? = null, ) : Listener { @EventHandler(ignoreCancelled = true) @@ -37,23 +34,6 @@ class PlayerPresenceListener( ) } - // Send chat mode notification - chatModeManager?.let { manager -> - val chatMode = manager.getChatMode(player.uniqueId) - val modeKey = - when (chatMode) { - ChatMode.GLOBAL -> "chatmode.mode.global" - ChatMode.CHANNEL -> "chatmode.mode.channel" - } - val modeText = languageManager.getMessage(modeKey) - val notification = - languageManager.getMessage( - "chatmode.notification.login", - mapOf("mode" to modeText), - ) - player.sendMessage(MessageFormatter.format(notification)) - } - // Send channel notification if in a channel channelManager?.let { manager -> val context = manager.getPlayerChannelContext(player.uniqueId) @@ -81,10 +61,7 @@ class PlayerPresenceListener( // 2. Clear active channel for this player channelManager?.setPlayerChannel(playerId, null) - // 3. Trigger async save of chat mode data - chatModeManager?.saveToDisk() - - // 4. Trigger async save of player settings + // 3. Trigger async save of player settings playerSettingsManager.saveToDisk() } } diff --git a/platform-paper/src/main/resources/languages/en.yml b/platform-paper/src/main/resources/languages/en.yml index 1275ce5..d932105 100644 --- a/platform-paper/src/main/resources/languages/en.yml +++ b/platform-paper/src/main/resources/languages/en.yml @@ -195,16 +195,6 @@ channel: receivedOwnership: "You are now the owner of {channel} (previously owned by {previousOwner})" error: "Failed to transfer ownership" -chatmode: - current: "Current chat mode" - mode: - global: "GLOBAL" - channel: "CHANNEL" - toggle: - success: "Chat mode switched to" - notification: - login: "Current chat mode: {mode}" - general: playerOnlyCommand: "This command can only be executed by players." newUpdateAvailable: "The new version of LunaticChat is now available! You can download it from GitHub or Modrinth." diff --git a/platform-paper/src/main/resources/languages/ja.yml b/platform-paper/src/main/resources/languages/ja.yml index f2d4ae6..fbf09f9 100644 --- a/platform-paper/src/main/resources/languages/ja.yml +++ b/platform-paper/src/main/resources/languages/ja.yml @@ -195,16 +195,6 @@ channel: receivedOwnership: "チャンネル {channel} のオーナーになりました (前のオーナー: {previousOwner})" error: "オーナー権限の譲渡に失敗しました" -chatmode: - current: "現在のチャットモード" - mode: - global: "グローバル" - channel: "チャンネル" - toggle: - success: "チャットモードを切り替えました" - notification: - login: "現在のチャットモード: {mode}" - general: playerOnlyCommand: "このコマンドはプレイヤーのみが実行できます" newUpdateAvailable: "LunaticChat の新しいバージョンが利用可能です。GitHubまたはModrinthからダウンロードできます" diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/ChatModeManagerTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/ChatModeManagerTest.kt deleted file mode 100644 index d548f60..0000000 --- a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/ChatModeManagerTest.kt +++ /dev/null @@ -1,223 +0,0 @@ -package dev.m1sk9.lunaticChat.paper.chat - -import dev.m1sk9.lunaticChat.engine.chat.ChatMode -import dev.m1sk9.lunaticChat.engine.chat.ChatModeData -import dev.m1sk9.lunaticChat.paper.TestUtils -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify -import java.util.UUID -import kotlin.test.Test -import kotlin.test.assertEquals - -/** - * Tests for ChatModeManager. - * Verifies chat mode management, toggling, and persistence. - */ -class ChatModeManagerTest { - private fun createChatModeManager( - initialData: ChatModeData = ChatModeData(), - ): Triple<ChatModeManager, ChatModeStorage, TestUtils.TestLogger> { - val logger = TestUtils.TestLogger() - val storage = mockk<ChatModeStorage>(relaxed = true) - - every { storage.loadFromDisk() } returns initialData - - val manager = ChatModeManager(storage, logger) - return Triple(manager, storage, logger) - } - - @Test - fun `initialize should load data from storage`() { - val playerId = UUID.randomUUID() - val initialData = ChatModeData(modes = mapOf(playerId to ChatMode.CHANNEL)) - val (manager, _, logger) = createChatModeManager(initialData) - - manager.initialize() - - assertEquals(ChatMode.CHANNEL, manager.getChatMode(playerId)) - assert(logger.infoMessages.any { it.contains("ChatModeManager initialized with 1 saved modes") }) - } - - @Test - fun `getChatMode should return DEFAULT for unknown player`() { - val (manager, _, _) = createChatModeManager() - manager.initialize() - - val playerId = UUID.randomUUID() - val mode = manager.getChatMode(playerId) - - assertEquals(ChatMode.DEFAULT, mode) - assertEquals(ChatMode.GLOBAL, mode) // DEFAULT is GLOBAL - } - - @Test - fun `getChatMode should return set mode`() { - val (manager, _, _) = createChatModeManager() - manager.initialize() - - val playerId = UUID.randomUUID() - manager.setChatMode(playerId, ChatMode.CHANNEL) - - assertEquals(ChatMode.CHANNEL, manager.getChatMode(playerId)) - } - - @Test - fun `setChatMode should save to storage`() { - val (manager, storage, _) = createChatModeManager() - manager.initialize() - - val playerId = UUID.randomUUID() - manager.setChatMode(playerId, ChatMode.CHANNEL) - - verify(exactly = 1) { storage.queueAsyncSave(any()) } - } - - @Test - fun `toggleChatMode should switch from GLOBAL to CHANNEL`() { - val (manager, _, _) = createChatModeManager() - manager.initialize() - - val playerId = UUID.randomUUID() - // Initial mode is GLOBAL (default) - assertEquals(ChatMode.GLOBAL, manager.getChatMode(playerId)) - - val newMode = manager.toggleChatMode(playerId) - - assertEquals(ChatMode.CHANNEL, newMode) - assertEquals(ChatMode.CHANNEL, manager.getChatMode(playerId)) - } - - @Test - fun `toggleChatMode should switch from CHANNEL to GLOBAL`() { - val (manager, _, _) = createChatModeManager() - manager.initialize() - - val playerId = UUID.randomUUID() - manager.setChatMode(playerId, ChatMode.CHANNEL) - - val newMode = manager.toggleChatMode(playerId) - - assertEquals(ChatMode.GLOBAL, newMode) - assertEquals(ChatMode.GLOBAL, manager.getChatMode(playerId)) - } - - @Test - fun `toggleChatMode should persist changes`() { - val (manager, storage, _) = createChatModeManager() - manager.initialize() - - val playerId = UUID.randomUUID() - manager.toggleChatMode(playerId) - - verify(atLeast = 1) { storage.queueAsyncSave(any()) } - } - - @Test - fun `removeChatMode should revert to default`() { - val (manager, _, _) = createChatModeManager() - manager.initialize() - - val playerId = UUID.randomUUID() - manager.setChatMode(playerId, ChatMode.CHANNEL) - assertEquals(ChatMode.CHANNEL, manager.getChatMode(playerId)) - - manager.removeChatMode(playerId) - - assertEquals(ChatMode.GLOBAL, manager.getChatMode(playerId)) - } - - @Test - fun `removeChatMode should save to storage`() { - val (manager, storage, _) = createChatModeManager() - manager.initialize() - - val playerId = UUID.randomUUID() - manager.setChatMode(playerId, ChatMode.CHANNEL) - manager.removeChatMode(playerId) - - verify(atLeast = 2) { storage.queueAsyncSave(any()) } // Once for set, once for remove - } - - @Test - fun `saveToDisk should synchronously save`() { - val (manager, storage, _) = createChatModeManager() - manager.initialize() - - val playerId = UUID.randomUUID() - manager.setChatMode(playerId, ChatMode.CHANNEL) - manager.saveToDisk() - - verify { storage.saveToDisk(any()) } - } - - @Test - fun `shutdown should save and shutdown storage`() { - val (manager, storage, _) = createChatModeManager() - manager.initialize() - - manager.shutdown() - - verify { storage.saveToDisk(any()) } - verify { storage.shutdown() } - } - - @Test - fun `manager should handle multiple players independently`() { - val (manager, _, _) = createChatModeManager() - manager.initialize() - - val player1 = UUID.randomUUID() - val player2 = UUID.randomUUID() - - manager.setChatMode(player1, ChatMode.CHANNEL) - manager.setChatMode(player2, ChatMode.GLOBAL) - - assertEquals(ChatMode.CHANNEL, manager.getChatMode(player1)) - assertEquals(ChatMode.GLOBAL, manager.getChatMode(player2)) - } - - @Test - fun `manager should support rapid mode changes`() { - val (manager, storage, _) = createChatModeManager() - manager.initialize() - - val playerId = UUID.randomUUID() - - // Toggle multiple times - manager.toggleChatMode(playerId) // GLOBAL -> CHANNEL - manager.toggleChatMode(playerId) // CHANNEL -> GLOBAL - manager.toggleChatMode(playerId) // GLOBAL -> CHANNEL - - assertEquals(ChatMode.CHANNEL, manager.getChatMode(playerId)) - verify(atLeast = 3) { storage.queueAsyncSave(any()) } - } - - @Test - fun `manager should handle empty initial data`() { - val (manager, _, logger) = createChatModeManager(ChatModeData()) - manager.initialize() - - assert(logger.infoMessages.any { it.contains("ChatModeManager initialized with 0 saved modes") }) - } - - @Test - fun `manager should restore modes after initialization`() { - val player1 = TestUtils.createTestUUID(1) - val player2 = TestUtils.createTestUUID(2) - val initialData = - ChatModeData( - modes = - mapOf( - player1 to ChatMode.CHANNEL, - player2 to ChatMode.GLOBAL, - ), - ) - - val (manager, _, _) = createChatModeManager(initialData) - manager.initialize() - - assertEquals(ChatMode.CHANNEL, manager.getChatMode(player1)) - assertEquals(ChatMode.GLOBAL, manager.getChatMode(player2)) - } -} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommandTest.kt deleted file mode 100644 index d43c867..0000000 --- a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommandTest.kt +++ /dev/null @@ -1,88 +0,0 @@ -package dev.m1sk9.lunaticChat.paper.command.impl.lc.chatmode - -import dev.m1sk9.lunaticChat.engine.chat.ChatMode -import dev.m1sk9.lunaticChat.engine.command.CommandResult -import dev.m1sk9.lunaticChat.paper.LunaticChat -import dev.m1sk9.lunaticChat.paper.TestUtils -import dev.m1sk9.lunaticChat.paper.chat.ChatModeManager -import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify -import net.kyori.adventure.text.Component -import java.util.UUID -import kotlin.test.Test -import kotlin.test.assertIs - -class ChatModeToggleCommandTest { - private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") - - private fun createDependencies(): TestDeps { - val plugin = mockk<LunaticChat>(relaxed = true) - val chatModeManager = mockk<ChatModeManager>(relaxed = true) - val languageManager = mockk<LanguageManager>(relaxed = true) - every { languageManager.getMessage(any(), any()) } returns "test message" - - val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") - val ctx = mockk<CommandContext>(relaxed = true) - every { ctx.requirePlayer() } returns mockPlayer - - val command = ChatModeToggleCommand(plugin, chatModeManager, languageManager) - return TestDeps(command, ctx, chatModeManager, languageManager, mockPlayer) - } - - private data class TestDeps( - val command: ChatModeToggleCommand, - val ctx: CommandContext, - val chatModeManager: ChatModeManager, - val languageManager: LanguageManager, - val mockPlayer: org.bukkit.entity.Player, - ) - - @Test - fun `execute should toggle to CHANNEL mode`() { - val deps = createDependencies() - - every { deps.chatModeManager.toggleChatMode(testUUID) } returns ChatMode.CHANNEL - - val result = deps.command.execute(deps.ctx) - - assertIs<CommandResult.Success>(result) - verify { deps.chatModeManager.toggleChatMode(testUUID) } - } - - @Test - fun `execute should toggle to GLOBAL mode`() { - val deps = createDependencies() - - every { deps.chatModeManager.toggleChatMode(testUUID) } returns ChatMode.GLOBAL - - val result = deps.command.execute(deps.ctx) - - assertIs<CommandResult.Success>(result) - verify { deps.chatModeManager.toggleChatMode(testUUID) } - } - - @Test - fun `execute should send message to player`() { - val deps = createDependencies() - - every { deps.chatModeManager.toggleChatMode(testUUID) } returns ChatMode.CHANNEL - - deps.command.execute(deps.ctx) - - verify { deps.mockPlayer.sendMessage(any<Component>()) } - } - - @Test - fun `execute should return Success`() { - val deps = createDependencies() - - every { deps.chatModeManager.toggleChatMode(testUUID) } returns ChatMode.GLOBAL - - val result = deps.command.execute(deps.ctx) - - assertIs<CommandResult.Success>(result) - } -} |
