summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSho Sakuma <me@m1sk9.dev>2026-01-17 16:06:56 +0900
committerSho Sakuma <me@m1sk9.dev>2026-01-17 16:06:56 +0900
commitf49e9b6ba9ad452192b084befc42e0c55874740b (patch)
tree9ee68d96f397442edf3c35c2304f6e6bce4fb909
parent489cb88c059ebc9f37c3b1410f2fe073a4b159a8 (diff)
downloadLunaticChat-f49e9b6ba9ad452192b084befc42e0c55874740b.tar.gz
LunaticChat-f49e9b6ba9ad452192b084befc42e0c55874740b.tar.bz2
LunaticChat-f49e9b6ba9ad452192b084befc42e0c55874740b.zip
feat: Add direct message notice toggle command
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/LunaticChat.kt3
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/handler/DirectMessageHandler.kt16
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/DirectMessageNoticeToggleCommand.kt89
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/common/SoundCollector.kt48
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/settings/PlayerSettingsManager.kt13
5 files changed, 164 insertions, 5 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 25bf33f..544fc36 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,6 +3,7 @@ package dev.m1sk9.lunaticChat.paper
import dev.m1sk9.lunaticChat.engine.converter.GoogleIMEClient
import dev.m1sk9.lunaticChat.paper.command.core.CommandRegistry
import dev.m1sk9.lunaticChat.paper.command.handler.DirectMessageHandler
+import dev.m1sk9.lunaticChat.paper.command.impl.DirectMessageNoticeToggleCommand
import dev.m1sk9.lunaticChat.paper.command.impl.ReplyCommand
import dev.m1sk9.lunaticChat.paper.command.impl.RomajiConvertToggleCommand
import dev.m1sk9.lunaticChat.paper.command.impl.TellCommand
@@ -167,9 +168,9 @@ class LunaticChat :
private fun registerCommands(configuration: LunaticChatConfiguration) {
commandRegistry = CommandRegistry(this)
- // Always register /tell command
commandRegistry.registerAll(
TellCommand(this, directMessageHandler),
+ DirectMessageNoticeToggleCommand(this, playerSettingsManager!!)
)
// Register /reply command if quick replies are enabled
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/command/handler/DirectMessageHandler.kt
index 60adb7e..4683c08 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/command/handler/DirectMessageHandler.kt
@@ -1,6 +1,8 @@
package dev.m1sk9.lunaticChat.paper.command.handler
import dev.m1sk9.lunaticChat.paper.common.SpyPermissionManager
+import dev.m1sk9.lunaticChat.paper.common.playDirectMessageNotification
+import dev.m1sk9.lunaticChat.paper.common.playDirectMessageSendNotification
import dev.m1sk9.lunaticChat.paper.config.ConfigManager
import dev.m1sk9.lunaticChat.paper.converter.RomanjiConverter
import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager
@@ -78,6 +80,8 @@ class DirectMessageHandler(
recordMessage(sender, recipient)
val senderSettings = settingsManager?.getSettings(sender.uniqueId)
+ val recipientSettings = settingsManager?.getSettings(recipient.uniqueId)
+
val displayMessage =
senderSettings
?.takeIf { it.japaneseConversionEnabled }
@@ -98,8 +102,16 @@ class DirectMessageHandler(
.forEach { it.sendMessage(spyMessage) }
val userMessage = formatMessage(format, sender.name, recipient.name, displayMessage)
- sender.sendMessage(userMessage)
- recipient.sendMessage(userMessage)
+ sender.apply {
+ sendMessage(userMessage)
+ takeIf { senderSettings?.directMessageNotificationEnabled == true }
+ ?.playDirectMessageSendNotification()
+ }
+ recipient.apply {
+ sendMessage(userMessage)
+ takeIf { recipientSettings?.directMessageNotificationEnabled == true }
+ ?.playDirectMessageNotification()
+ }
return true
}
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/DirectMessageNoticeToggleCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/DirectMessageNoticeToggleCommand.kt
new file mode 100644
index 0000000..7906ca9
--- /dev/null
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/DirectMessageNoticeToggleCommand.kt
@@ -0,0 +1,89 @@
+package dev.m1sk9.lunaticChat.paper.command.impl
+
+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.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.settings.PlayerSettingsManager
+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
+
+@Command(
+ name = "notice",
+ aliases = ["dmnotice"],
+ description = "Toggle direct message notification",
+)
+@Permission(LunaticChatPermissionNode.NoticeToggle::class)
+@PlayerOnly
+class DirectMessageNoticeToggleCommand(
+ plugin: LunaticChat,
+ private val settingsManager: PlayerSettingsManager,
+) : LunaticCommand(plugin) {
+ override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> =
+ Commands
+ .literal(name)
+ .then(
+ Commands
+ .literal("on")
+ .executes { ctx ->
+ val context = wrapContext(ctx)
+ checkPlayerOnly(context)?.let { return@executes handleResult(context, it) }
+ val result = execute(context, true)
+ handleResult(context, result)
+ },
+ ).then(
+ Commands
+ .literal("off")
+ .executes { ctx ->
+ val context = wrapContext(ctx)
+ checkPlayerOnly(context)?.let { return@executes handleResult(context, it) }
+ val result = execute(context, false)
+ handleResult(context, result)
+ },
+ ).executes { ctx ->
+ val context = wrapContext(ctx)
+ checkPlayerOnly(context)?.let { return@executes handleResult(context, it) }
+ val result = showStatus(context)
+ handleResult(context, result)
+ }
+
+ private fun execute(
+ ctx: CommandContext,
+ enable: Boolean,
+ ): CommandResult {
+ val player = ctx.requirePlayer()
+ val currentSettings = settingsManager.getSettings(player.uniqueId)
+ val updatedSettings = currentSettings.copy(directMessageNotificationEnabled = enable)
+ settingsManager.updateSettings(updatedSettings)
+
+ val statusText = if (enable) "enabled" else "disabled"
+ val message =
+ Component
+ .text("Direct message notification has been $statusText.")
+ .color(NamedTextColor.GREEN)
+
+ player.sendMessage(message)
+ return CommandResult.Success
+ }
+
+ private fun showStatus(ctx: CommandContext): CommandResult {
+ val player = ctx.requirePlayer()
+ val settings = settingsManager.getSettings(player.uniqueId)
+
+ val statusText = if (settings.directMessageNotificationEnabled) "enabled" else "disabled"
+ val message =
+ Component
+ .text("Direct message notification is currently $statusText.")
+ .color(NamedTextColor.YELLOW)
+
+ player.sendMessage(message)
+ return CommandResult.Success
+ }
+}
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/common/SoundCollector.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/common/SoundCollector.kt
new file mode 100644
index 0000000..16c8d75
--- /dev/null
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/common/SoundCollector.kt
@@ -0,0 +1,48 @@
+package dev.m1sk9.lunaticChat.paper.common
+
+import net.kyori.adventure.key.Key
+import net.kyori.adventure.sound.Sound
+import org.bukkit.entity.Player
+
+/**
+ * Collection of sounds used in LunaticChat.
+ */
+object SoundCollector {
+ val LUNATIC_CLEAR_SOUND: Sound =
+ Sound.sound(
+ Key.key("block.note_block.chime"),
+ Sound.Source.PLAYER,
+ 0.8f,
+ 1.5f,
+ )
+
+ val LUNATIC_POP_SOUND: Sound =
+ Sound.sound(
+ Key.key("entity.experience_orb.pickup"),
+ Sound.Source.PLAYER,
+ 0.9f,
+ 1.4f,
+ )
+
+ val LUNATIC_SOFT_SOUND: Sound =
+ Sound.sound(
+ Key.key("block.note_block.pling"),
+ Sound.Source.PLAYER,
+ 0.6f,
+ 2.0f,
+ )
+}
+
+/**
+ * Plays the direct message notification sound to the player.
+ */
+fun Player.playDirectMessageNotification() {
+ playSound(SoundCollector.LUNATIC_CLEAR_SOUND)
+}
+
+/**
+ * Plays the message sent sound to the player.
+ */
+fun Player.playDirectMessageSendNotification() {
+ playSound(SoundCollector.LUNATIC_POP_SOUND)
+}
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/settings/PlayerSettingsManager.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/settings/PlayerSettingsManager.kt
index 76d5776..a30618b 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/settings/PlayerSettingsManager.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/settings/PlayerSettingsManager.kt
@@ -18,6 +18,7 @@ class PlayerSettingsManager(
private val logger: Logger,
) {
private val japaneseConversionCache = ConcurrentHashMap<UUID, Boolean>()
+ private val directMessageNotificationCache = ConcurrentHashMap<UUID, Boolean>()
private lateinit var settingsData: PlayerSettingsData
/**
@@ -27,6 +28,7 @@ class PlayerSettingsManager(
fun initialize() {
settingsData = storage.loadFromDisk()
japaneseConversionCache.putAll(settingsData.japaneseConversion)
+ directMessageNotificationCache.putAll(settingsData.directMessageNotification)
logger.info("Loaded settings for ${japaneseConversionCache.size} players")
}
@@ -38,8 +40,13 @@ class PlayerSettingsManager(
* @return The player's settings
*/
fun getSettings(uuid: UUID): PlayerChatSettings {
- val enabled = japaneseConversionCache.getOrDefault(uuid, true)
- return PlayerChatSettings(uuid = uuid, japaneseConversionEnabled = enabled)
+ val japaneseConversionEnabled = japaneseConversionCache.getOrDefault(uuid, true)
+ val directMessageNotificationEnabled = directMessageNotificationCache.getOrDefault(uuid, true)
+ return PlayerChatSettings(
+ uuid = uuid,
+ japaneseConversionEnabled = japaneseConversionEnabled,
+ directMessageNotificationEnabled = directMessageNotificationEnabled,
+ )
}
/**
@@ -49,10 +56,12 @@ class PlayerSettingsManager(
*/
fun updateSettings(settings: PlayerChatSettings) {
japaneseConversionCache[settings.uuid] = settings.japaneseConversionEnabled
+ directMessageNotificationCache[settings.uuid] = settings.directMessageNotificationEnabled
settingsData =
settingsData.copy(
japaneseConversion = japaneseConversionCache.toMap(),
+ directMessageNotification = directMessageNotificationCache.toMap(),
)
storage.queueAsyncSave(settingsData)