summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSho Sakuma <me@m1sk9.dev>2026-01-26 01:29:07 +0900
committerSho Sakuma <me@m1sk9.dev>2026-01-26 01:29:07 +0900
commit15b5bb3ebe0b4beb09b70878767db1c13445392b (patch)
treef7b9ebc41ce116a9ea0eb0f9fea8ed8ec85fbe28
parentc5e355b851ad4d71d32d3c10f89aa4ed1f6dc41c (diff)
downloadLunaticChat-15b5bb3ebe0b4beb09b70878767db1c13445392b.tar.gz
LunaticChat-15b5bb3ebe0b4beb09b70878767db1c13445392b.tar.bz2
LunaticChat-15b5bb3ebe0b4beb09b70878767db1c13445392b.zip
feat: Add channel-chat handle
-rw-r--r--docs/src/guide/player/channel-chat.md140
-rw-r--r--engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/chat/channel/ChannelContext.kt7
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/LunaticChat.kt5
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceContainer.kt5
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceInitializer.kt50
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManager.kt19
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelMessageHandler.kt60
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/DirectMessageHandler.kt (renamed from platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/handler/DirectMessageHandler.kt)2
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/ReplyCommand.kt2
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/TellCommand.kt2
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/ConfigManager.kt5
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/MessageFormatConfig.kt1
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/EventListenerRegistry.kt14
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerChatListener.kt32
-rw-r--r--platform-paper/src/main/resources/config.yml3
15 files changed, 328 insertions, 19 deletions
diff --git a/docs/src/guide/player/channel-chat.md b/docs/src/guide/player/channel-chat.md
index ce5a43e..57f86ed 100644
--- a/docs/src/guide/player/channel-chat.md
+++ b/docs/src/guide/player/channel-chat.md
@@ -11,3 +11,143 @@
詳しい実装計画は [ロードマップ (m1sk9/LunaticChat #54)](https://github.com/m1sk9/LunaticChat/issues/54) をご覧ください.
:::
+
+::: tip この機能はサーバーで有効化する必要があります
+
+チャンネルチャットがサーバーで無効化されている場合,これらの機能は使用できません.
+
+サーバー管理者にお問い合わせください.
+
+:::
+
+## 使い方
+
+### チャンネルを作成する
+
+チャンネルチャットを利用するには,まずチャットチャンネルを作成する必要があります.
+
+`/lc channnel create` コマンドを使用して,チャットチャンネルを作成します.
+
+```
+/lc channel create <チャンネルID> <チャンネル名> [チャンネルの説明] [プライベート設定]
+```
+
+- `<チャンネルID>` はチャンネルのIDを指定します.
+- `<チャンネル名>` はチャンネルの名前を指定します.
+- `[チャンネルの説明]` はチャンネルの説明を指定します (省略可能).
+ - `/lc channel list` コマンドでチャンネル一覧を表示した際に,説明が表示されます.
+- `[プライベート設定]` はチャンネルの公開設定を指定します.
+ - `true` を指定するとプライベートチャンネルとして作成され,招待されたプレイヤーのみが参加できます.
+ - `false` を指定するか,省略した場合はパブリックチャンネルとして作成され,誰でも参加できます.
+
+::: tip チャンネルIDの要件
+
+チャンネルIDは次の要件に従う必要があります:
+
+- 3文字以上,30文字以下であること
+- 英数字,アンダースコア(_),ハイフン(-)のみを含むこと
+
+:::
+
+::: warning チャンネル名・チャンネルの説明を入力する際の注意点
+
+チャンネル名・チャンネルの説明を入力する際は,引数を `"` (ダブルクォーテーション) で囲む必要があります.
+
+実行例は次のとおりです:
+
+```
+/lc channel create pvp_channel "PvP大好きクラブ" "PvPが大好きな人たちの集まり" false
+```
+
+:::
+
+チャンネルが正常に作成されると,チャットで確認メッセージが表示されます.
+
+### チャンネルに参加する
+
+作成されたチャンネルに参加するには,`/lc channel join` コマンドを使用します.
+
+```
+/lc channel join <チャンネルID>
+```
+
+チャンネルに参加すると,チャットモードが全体チャットからチャンネルチャットに切り替わります.
+
+### チャンネル一覧を表示する
+
+参加可能なチャンネル一覧を表示するには,`/lc channel list` コマンドを使用します.
+
+```
+/lc channel list
+```
+
+チャット欄に参加可能なチャンネルの一覧が表示されます.クリックするか [`/lc channel join`](#チャンネルに参加する) コマンドを使用して,チャンネルに参加できます.
+
+## プライベートチャンネル
+
+プライベートチャンネルは,招待されたプレイヤーのみが参加できるチャットチャンネルです.
+
+::: tip プライベートチャンネルに対する権限
+
+プライベートチャンネルに対する権限は,チャンネルの作成者にのみ付与されます.
+
+:::
+
+### プレイヤーを招待する
+
+プライベートチャンネルにプレイヤーを招待するには,`/lc channel invite` コマンドを使用します.
+
+なお,招待するにはチャンネルの作成者(オーナー)もしくは管理者である必要があります.
+
+```
+/lc channel invite <チャンネルID> <プレイヤー名>
+```
+
+### 再参加する
+
+プライベートチャンネルから退出した後,再度参加するには,[`/lc channel join`](#チャンネルに参加する) コマンドを使用します.
+
+一度参加したプライベートチャンネルには招待なしで再参加できます.
+
+::: tip 参加できないようにするには
+
+プライベートチャンネルから退出した後,再度参加できないようにするには,`/lc channel kick` コマンドを使用して,プレイヤーをチャンネルから強制退出させる必要があります.
+
+詳しくは [チャンネルの管理]() をご覧ください.
+
+:::
+
+## チャンネルチャットに伴う挙動
+
+### チャットモードについて
+
+LunaticChat では,チャットモードが以下の2種類あります:
+
+1. 全体チャットモード: すべてのプレイヤーとチャットを共有します.
+2. チャンネルチャットモード: 参加している特定のチャンネル内のプレイヤーとチャットを共有します.
+
+チャンネルチャットモード中は,全てのチャットが参加しているチャンネルのプレイヤーのみに表示され,全体チャットには表示されません.
+
+全体チャットモードに切り替えるには一度チャンネルから退出する必要があります.
+
+現在のチャットモードは `/chatmode` コマンドで確認できるほか,サーバーにログインした際にも表示されます.
+
+::: tip 一時的に全体チャットを送信する
+
+チャンネルチャットモード中に,一時的に全体チャットを送信したい場合は,メッセージの先頭に `!` を付けて送信します.
+
+```
+!こんにちは、みんな元気?
+```
+
+:::
+
+#### 一時的にチャットモードを切り替える
+
+チャットモードを一時的に切り替えるには,`/chatmode toggle` コマンドを使用します.
+
+このコマンドで切り替えた場合はチャンネルの入退出なしで,チャットモードを切り替えることができます.
+
+ただし,サーバーに再接続した際には元のチャットモードに戻ります.
+
+
diff --git a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/chat/channel/ChannelContext.kt b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/chat/channel/ChannelContext.kt
new file mode 100644
index 0000000..02dc1d3
--- /dev/null
+++ b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/chat/channel/ChannelContext.kt
@@ -0,0 +1,7 @@
+package dev.m1sk9.lunaticChat.engine.chat.channel
+
+data class ChannelContext(
+ val channelId: String,
+ val channel: Channel,
+ val members: List<ChannelMember>,
+)
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 2473f49..7e51e20 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
@@ -3,8 +3,9 @@ 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
+import dev.m1sk9.lunaticChat.paper.chat.handler.DirectMessageHandler
import dev.m1sk9.lunaticChat.paper.command.core.CommandRegistry
-import dev.m1sk9.lunaticChat.paper.command.handler.DirectMessageHandler
import dev.m1sk9.lunaticChat.paper.command.impl.ReplyCommand
import dev.m1sk9.lunaticChat.paper.command.impl.TellCommand
import dev.m1sk9.lunaticChat.paper.command.impl.lc.LunaticChatCommand
@@ -33,6 +34,7 @@ class LunaticChat :
var channelManager: ChannelManager? = null
var channelMembershipManager: ChannelMembershipManager? = null
var chatModeManager: ChatModeManager? = null
+ var channelMessageHandler: ChannelMessageHandler? = null
// Private services
private lateinit var services: ServiceContainer
@@ -69,6 +71,7 @@ class LunaticChat :
channelManager = services.channelManager
channelMembershipManager = services.channelMembershipManager
chatModeManager = services.chatModeManager
+ channelMessageHandler = services.channelMessageHandler
// Schedule periodic tasks
serviceInitializer.schedulePeriodicTasks()
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 c4e56cd..3cd9e73 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
@@ -3,7 +3,8 @@ 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.command.handler.DirectMessageHandler
+import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelMessageHandler
+import dev.m1sk9.lunaticChat.paper.chat.handler.DirectMessageHandler
import dev.m1sk9.lunaticChat.paper.converter.RomanjiConverter
import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager
import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager
@@ -21,6 +22,7 @@ import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager
* @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)
*/
data class ServiceContainer(
val languageManager: LanguageManager,
@@ -30,4 +32,5 @@ data class ServiceContainer(
val channelManager: ChannelManager? = null,
val channelMembershipManager: ChannelMembershipManager? = null,
val chatModeManager: ChatModeManager? = null,
+ val channelMessageHandler: ChannelMessageHandler? = 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 7865c9c..39afbc1 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
@@ -6,7 +6,8 @@ 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.ChannelStorage
-import dev.m1sk9.lunaticChat.paper.command.handler.DirectMessageHandler
+import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelMessageHandler
+import dev.m1sk9.lunaticChat.paper.chat.handler.DirectMessageHandler
import dev.m1sk9.lunaticChat.paper.config.LunaticChatConfiguration
import dev.m1sk9.lunaticChat.paper.converter.ConversionCache
import dev.m1sk9.lunaticChat.paper.converter.RomanjiConverter
@@ -19,6 +20,16 @@ import java.util.logging.Logger
import kotlin.time.Duration.Companion.milliseconds
/**
+ * Container for channel-related components.
+ */
+private data class ChannelComponents(
+ val channelManager: ChannelManager,
+ val channelMembershipManager: ChannelMembershipManager,
+ val chatModeManager: ChatModeManager,
+ val channelMessageHandler: ChannelMessageHandler,
+)
+
+/**
* Handles initialization and shutdown of all plugin services.
*
* This class centralizes service initialization logic, ensuring proper
@@ -34,6 +45,7 @@ class ServiceInitializer(
private var channelManager: ChannelManager? = null
private var channelMembershipManager: ChannelMembershipManager? = null
private var chatModeManager: ChatModeManager? = null
+ private var channelMessageHandler: ChannelMessageHandler? = null
/**
* Initializes all services in dependency order.
@@ -69,13 +81,17 @@ class ServiceInitializer(
null
}
- // 4. Initialize channel manager, membership manager, and chat mode manager
- val (channelManager, channelMembershipManager, chatModeManager) =
+ // 4. Initialize channel manager, membership manager, chat mode manager, and channel message handler
+ val channelComponents =
if (configuration.features.channelChat.enabled) {
- initializeChannelManager()
+ initializeChannelManager(playerSettingsManager)
} else {
- Triple(null, null, null)
+ null
}
+ val channelManager = channelComponents?.channelManager
+ val channelMembershipManager = channelComponents?.channelMembershipManager
+ val chatModeManager = channelComponents?.chatModeManager
+ val channelMessageHandler = channelComponents?.channelMessageHandler
// 5. Initialize handlers
val directMessageHandler =
@@ -92,6 +108,7 @@ class ServiceInitializer(
channelManager = channelManager,
channelMembershipManager = channelMembershipManager,
chatModeManager = chatModeManager,
+ channelMessageHandler = channelMessageHandler,
)
}
@@ -156,9 +173,9 @@ class ServiceInitializer(
}
/**
- * Initializes channel manager, membership manager, and chat mode manager with storage.
+ * Initializes channel manager, membership manager, chat mode manager, and channel message handler with storage.
*/
- private fun initializeChannelManager(): Triple<ChannelManager, ChannelMembershipManager, ChatModeManager> {
+ private fun initializeChannelManager(settingsManager: PlayerSettingsManager): ChannelComponents {
val channelsFile = plugin.dataFolder.resolve("channels.json").toPath()
val storage =
ChannelStorage(
@@ -197,8 +214,23 @@ class ServiceInitializer(
chatMode.initialize()
chatModeManager = chatMode
- logger.info("Channel manager, membership manager, and chat mode manager initialized successfully.")
- return Triple(manager, membershipManager, chatMode)
+ val messageHandler =
+ ChannelMessageHandler(
+ settingsManager = settingsManager,
+ channelManager = manager,
+ logger =
+ io.ktor.util.logging
+ .KtorSimpleLogger("ChannelMessageHandler"),
+ )
+ channelMessageHandler = messageHandler
+
+ logger.info("Channel manager, membership manager, chat mode manager, and channel message handler initialized successfully.")
+ return ChannelComponents(
+ channelManager = manager,
+ channelMembershipManager = membershipManager,
+ chatModeManager = chatMode,
+ channelMessageHandler = messageHandler,
+ )
}
/**
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 ff3b5d8..f7d0812 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
@@ -1,6 +1,7 @@
package dev.m1sk9.lunaticChat.paper.chat.channel
import dev.m1sk9.lunaticChat.engine.chat.channel.Channel
+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
@@ -249,6 +250,24 @@ class ChannelManager(
fun getPlayerChannel(playerId: UUID): String? = activeChannels[playerId]
/**
+ * Gets the full channel context (channel and members) of a player's active channel.
+ *
+ * @param playerId The UUID of the player.
+ * @return The ChannelContext of the active channel or null if none is set.
+ */
+ fun getPlayerChannelContext(playerId: UUID): ChannelContext? {
+ val channelId = activeChannels[playerId] ?: return null
+ val channel = channelsCache[channelId] ?: return null
+ val members = membersCache[channelId]?.toList() ?: return null
+
+ return ChannelContext(
+ channelId = channelId,
+ channel = channel,
+ members = members,
+ )
+ }
+
+ /**
* Sets the active channel of a player.
*
* @param playerId The UUID of the player.
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
new file mode 100644
index 0000000..cf57991
--- /dev/null
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelMessageHandler.kt
@@ -0,0 +1,60 @@
+package dev.m1sk9.lunaticChat.paper.chat.handler
+
+import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager
+import dev.m1sk9.lunaticChat.paper.common.SpyPermissionManager
+import dev.m1sk9.lunaticChat.paper.config.ConfigManager
+import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager
+import io.ktor.util.logging.Logger
+import net.kyori.adventure.text.Component
+import org.bukkit.Bukkit
+import org.bukkit.entity.Player
+
+class ChannelMessageHandler(
+ private val settingsManager: PlayerSettingsManager?,
+ private val channelManager: ChannelManager,
+ private val logger: Logger,
+) {
+ private var lunaticChatConfiguration = ConfigManager.getConfiguration()
+
+ suspend fun sendChannelMessage(
+ player: Player,
+ message: String,
+ ): Boolean {
+ val playerId = player.uniqueId
+ val context =
+ channelManager.getPlayerChannelContext(playerId)
+ ?: return false
+ val formattedMessage = formatChannelMessage(player.name, context.channel.name, message)
+
+ SpyPermissionManager
+ .getDirectMessageSpyPlayers()
+ .values
+ .filter { it.isOnline && it.uniqueId != playerId }
+ .forEach { it.sendMessage(formattedMessage) }
+ context.members.forEach { member ->
+ Bukkit.getPlayer(member.playerId)?.let { memberPlayer ->
+ if (memberPlayer.isOnline && member.playerId != playerId) {
+ memberPlayer.sendMessage(formattedMessage)
+ }
+ }
+ }
+
+ logger.info("Channel Message from ${player.name} in ${context.channel.name}: $message")
+ return true
+ }
+
+ private fun formatChannelMessage(
+ senderName: String,
+ channelName: String,
+ message: String,
+ ): Component {
+ val format = lunaticChatConfiguration.messageFormat.channelMessageFormat
+ val text =
+ format
+ .replace("{sender}", senderName)
+ .replace("{channel}", channelName)
+ .replace("{message}", message)
+
+ return Component.text(text)
+ }
+}
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/handler/DirectMessageHandler.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/DirectMessageHandler.kt
index 4683c08..7d06ffd 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/handler/DirectMessageHandler.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/DirectMessageHandler.kt
@@ -1,4 +1,4 @@
-package dev.m1sk9.lunaticChat.paper.command.handler
+package dev.m1sk9.lunaticChat.paper.chat.handler
import dev.m1sk9.lunaticChat.paper.common.SpyPermissionManager
import dev.m1sk9.lunaticChat.paper.common.playDirectMessageNotification
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/ReplyCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/ReplyCommand.kt
index 185581a..acf8fcf 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/ReplyCommand.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/ReplyCommand.kt
@@ -5,12 +5,12 @@ 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.handler.DirectMessageHandler
import dev.m1sk9.lunaticChat.paper.command.annotation.Command
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.handler.DirectMessageHandler
import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager
import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter
import io.papermc.paper.command.brigadier.CommandSourceStack
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/TellCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/TellCommand.kt
index c84de33..16311cf 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/TellCommand.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/TellCommand.kt
@@ -7,12 +7,12 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder
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.handler.DirectMessageHandler
import dev.m1sk9.lunaticChat.paper.command.annotation.Command
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.handler.DirectMessageHandler
import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager
import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter
import io.papermc.paper.command.brigadier.CommandSourceStack
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/ConfigManager.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/ConfigManager.kt
index f8c95b6..3617df1 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/ConfigManager.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/ConfigManager.kt
@@ -57,6 +57,11 @@ object ConfigManager {
"messageFormat.directMessageFormat",
"§7[§e{sender} §7>> §e{recipient}§7] §f{message}",
)!!,
+ channelMessageFormat =
+ configFile.getString(
+ "messageFormat.channelMessageFormat",
+ "§7[§b#{channel}§7] §e{sender}: §f{message}",
+ )!!,
),
debug = configFile.getBoolean("debug", false),
checkForUpdates = configFile.getBoolean("checkForUpdates", false),
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/MessageFormatConfig.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/MessageFormatConfig.kt
index 53d4399..2e623fa 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/MessageFormatConfig.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/MessageFormatConfig.kt
@@ -2,4 +2,5 @@ package dev.m1sk9.lunaticChat.paper.config.key
data class MessageFormatConfig(
val directMessageFormat: String = "§7[§e{sender} §7>> §e{recipient}§7] §f{message}",
+ val channelMessageFormat: String = "§7[§b#{channel}§7] §e{sender}: §f{message}",
)
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 8d4070d..2c22be1 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
@@ -33,10 +33,18 @@ object EventListenerRegistry {
plugin,
)
- // Conditionally register Japanese conversion listener
- if (services.romajiConverter != null) {
+ // Conditionally register chat listener when all required components are available
+ if (services.chatModeManager != null &&
+ services.channelMessageHandler != null &&
+ services.romajiConverter != null
+ ) {
pluginManager.registerEvents(
- PlayerChatListener(services.romajiConverter, services.playerSettingsManager),
+ PlayerChatListener(
+ chatModeManager = services.chatModeManager,
+ channelMessageHandler = services.channelMessageHandler,
+ romajiConverter = services.romajiConverter,
+ settingsManager = services.playerSettingsManager,
+ ),
plugin,
)
}
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 17df427..258b0b1 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,5 +1,8 @@
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.handler.ChannelMessageHandler
import dev.m1sk9.lunaticChat.paper.converter.RomanjiConverter
import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager
import io.papermc.paper.event.player.AsyncChatEvent
@@ -10,6 +13,8 @@ import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
class PlayerChatListener(
+ private val chatModeManager: ChatModeManager,
+ private val channelMessageHandler: ChannelMessageHandler,
private val romajiConverter: RomanjiConverter,
private val settingsManager: PlayerSettingsManager,
) : Listener {
@@ -20,9 +25,8 @@ class PlayerChatListener(
runBlocking {
val player = event.player
val settings = settingsManager.getSettings(player.uniqueId)
- val message = event.message()
- val originalMessage = plainTextSerializer.serialize(message)
+ val originalMessage = plainTextSerializer.serialize(event.message())
val displayMessage =
settings
.takeIf {
@@ -34,6 +38,30 @@ class PlayerChatListener(
?: originalMessage
}?.getOrNull() ?: originalMessage
+ val (_, effectiveMode) =
+ if (originalMessage.startsWith('!')) {
+ val withoutPrefix = originalMessage.removePrefix("!").trim()
+ if (withoutPrefix.isEmpty()) {
+ event.isCancelled = true
+ return@runBlocking
+ }
+ val currentMode = chatModeManager.getChatMode(player.uniqueId)
+ withoutPrefix to currentMode.toggle()
+ } else {
+ originalMessage to chatModeManager.getChatMode(player.uniqueId)
+ }
+
+ when (effectiveMode) {
+ ChatMode.GLOBAL -> {
+ event.message(Component.text(displayMessage))
+ }
+ ChatMode.CHANNEL -> {
+ event.isCancelled = true
+ channelMessageHandler
+ .sendChannelMessage(player, originalMessage)
+ }
+ }
+
event.message(Component.text(displayMessage))
}
}
diff --git a/platform-paper/src/main/resources/config.yml b/platform-paper/src/main/resources/config.yml
index 12e5f18..839e0e3 100644
--- a/platform-paper/src/main/resources/config.yml
+++ b/platform-paper/src/main/resources/config.yml
@@ -62,9 +62,12 @@ features:
# {sender} - The name of the message sender
# {recipient} - The name of the message recipient
# {message} - The content of the message
+# {channel} - The name of the chat channel (only for channel chat)
# ----------------------------------------------
messageFormat:
# Configure the format for direct messages sent via /tell or /msg
directMessageFormat: "§7[§e{sender} §7>> §e{recipient}§7] §f{message}"
+ # Configure the format for messages sent in channel chat
+ channelMessageFormat: "§7[§b#{channel}§7] §e{sender}: §f{message}"