summaryrefslogtreecommitdiff
path: root/platform-paper/src
diff options
context:
space:
mode:
authorSho Sakuma <me@m1sk9.dev>2026-01-26 02:34:01 +0900
committerSho Sakuma <me@m1sk9.dev>2026-01-26 02:34:58 +0900
commita7cac6e6b49c017b20c9c1f63b09ae06dc5605a6 (patch)
treeae263379b1d89886d699841869a9effa35bfc87b /platform-paper/src
parent64abf8c7a06839fdf662cb0e781ed1dc14da16a9 (diff)
downloadLunaticChat-a7cac6e6b49c017b20c9c1f63b09ae06dc5605a6.tar.gz
LunaticChat-a7cac6e6b49c017b20c9c1f63b09ae06dc5605a6.tar.bz2
LunaticChat-a7cac6e6b49c017b20c9c1f63b09ae06dc5605a6.zip
refactor: Refactoring logic
Diffstat (limited to 'platform-paper/src')
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/ServiceInitializer.kt2
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/ChatModeManager.kt9
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManager.kt9
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/ChannelMessageHandler.kt4
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/handler/DirectMessageHandler.kt35
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/ReplyCommand.kt5
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/TellCommand.kt5
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/ConfigManager.kt2
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/ConversionCache.kt9
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/EventListenerRegistry.kt9
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerChatListener.kt85
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/listener/PlayerPresenceListener.kt71
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/settings/YamlPlayerSettingsStorage.kt4
-rw-r--r--platform-paper/src/main/resources/languages/en.yml4
-rw-r--r--platform-paper/src/main/resources/languages/ja.yml4
-rw-r--r--platform-paper/src/main/resources/paper-plugin.yml20
16 files changed, 199 insertions, 78 deletions
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 39afbc1..35f70d8 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
@@ -257,6 +257,6 @@ class ServiceInitializer(
services.playerSettingsManager.saveToDisk()
conversionCache?.saveToDisk()
services.channelManager?.saveToDisk()
- services.chatModeManager?.saveToDisk()
+ services.chatModeManager?.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
index 5f92f21..93a7f04 100644
--- 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
@@ -91,4 +91,13 @@ class ChatModeManager(
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/channel/ChannelManager.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelManager.kt
index f7d0812..fc8d6da 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
@@ -9,6 +9,7 @@ import dev.m1sk9.lunaticChat.engine.exception.ChannelNoOwnerPermissionException
import dev.m1sk9.lunaticChat.engine.exception.ChannelNotFoundException
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
+import java.util.concurrent.CopyOnWriteArrayList
import java.util.logging.Logger
import kotlin.collections.forEach
@@ -17,7 +18,7 @@ class ChannelManager(
private val logger: Logger,
) {
private val channelsCache = ConcurrentHashMap<String, Channel>()
- private val membersCache = ConcurrentHashMap<String, MutableList<ChannelMember>>()
+ private val membersCache = ConcurrentHashMap<String, CopyOnWriteArrayList<ChannelMember>>()
private val activeChannels = ConcurrentHashMap<UUID, String>()
/**
@@ -27,7 +28,7 @@ class ChannelManager(
val data = storage.loadFromDisk()
channelsCache.putAll(data.channels)
data.members.forEach { (channelId, members) ->
- membersCache[channelId] = members.toMutableList()
+ membersCache[channelId] = CopyOnWriteArrayList(members)
}
data.activeChannels.forEach { (playerIdStr, channelId) ->
try {
@@ -60,7 +61,7 @@ class ChannelManager(
playerId = channel.ownerId,
role = ChannelRole.OWNER,
)
- membersCache[channel.id] = mutableListOf(ownerMember)
+ membersCache[channel.id] = CopyOnWriteArrayList(listOf(ownerMember))
// Set the owner's active channel
setPlayerChannel(channel.ownerId, channel.id)
@@ -169,7 +170,7 @@ class ChannelManager(
val members =
membersCache.getOrPut(channelId) {
- mutableListOf()
+ CopyOnWriteArrayList()
}
val newMember =
ChannelMember(
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 cf57991..0560939 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
@@ -16,7 +16,7 @@ class ChannelMessageHandler(
) {
private var lunaticChatConfiguration = ConfigManager.getConfiguration()
- suspend fun sendChannelMessage(
+ fun sendChannelMessage(
player: Player,
message: String,
): Boolean {
@@ -33,7 +33,7 @@ class ChannelMessageHandler(
.forEach { it.sendMessage(formattedMessage) }
context.members.forEach { member ->
Bukkit.getPlayer(member.playerId)?.let { memberPlayer ->
- if (memberPlayer.isOnline && member.playerId != playerId) {
+ if (memberPlayer.isOnline) {
memberPlayer.sendMessage(formattedMessage)
}
}
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 7d06ffd..7857221 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
@@ -59,10 +59,18 @@ class DirectMessageHandler(
/**
* Clears message history for a player (called on disconnect).
+ * Removes entries where this player is either the sender or recipient.
*/
fun clearPlayer(player: Player) {
- lastMessager.remove(player.uniqueId)
- lastRecipient.remove(player.uniqueId)
+ val playerId = player.uniqueId
+
+ // Remove entries where this player is the sender
+ lastMessager.remove(playerId)
+ lastRecipient.remove(playerId)
+
+ // Remove entries where this player is the recipient
+ lastMessager.entries.removeIf { it.value == playerId }
+ lastRecipient.entries.removeIf { it.value == playerId }
}
/**
@@ -72,7 +80,7 @@ class DirectMessageHandler(
*
* @return true if message was sent successfully
*/
- suspend fun sendDirectMessage(
+ fun sendDirectMessage(
sender: Player,
recipient: Player,
message: String,
@@ -82,15 +90,20 @@ class DirectMessageHandler(
val senderSettings = settingsManager?.getSettings(sender.uniqueId)
val recipientSettings = settingsManager?.getSettings(recipient.uniqueId)
+ // Handle romaji conversion if enabled (requires blocking for HTTP call)
val displayMessage =
- senderSettings
- ?.takeIf { it.japaneseConversionEnabled }
- ?.let { romanjiConverter }
- ?.runCatching {
- convert(message)
- ?.let { "$message §e($it)" }
- ?: message
- }?.getOrNull() ?: message
+ if (senderSettings?.japaneseConversionEnabled == true && romanjiConverter != null) {
+ runCatching {
+ kotlinx.coroutines.runBlocking {
+ romanjiConverter
+ ?.convert(message)
+ ?.let { "$message §e($it)" }
+ ?: message
+ }
+ }.getOrNull() ?: message
+ } else {
+ message
+ }
val format = lunaticChatConfiguration.messageFormat.directMessageFormat
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 acf8fcf..e1a997e 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
@@ -15,7 +15,6 @@ 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 kotlinx.coroutines.runBlocking
@Command(
name = "reply",
@@ -62,9 +61,7 @@ class ReplyCommand(
),
)
- runBlocking {
- dmHandler.sendDirectMessage(sender, target, message)
- }
+ dmHandler.sendDirectMessage(sender, target, message)
return CommandResult.Success
}
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 16311cf..5375b08 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
@@ -17,7 +17,6 @@ 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 kotlinx.coroutines.runBlocking
import org.bukkit.Bukkit
import java.util.concurrent.CompletableFuture
@@ -81,9 +80,7 @@ class TellCommand(
)
}
- runBlocking {
- directMessageHandler.sendDirectMessage(sender, recipient, message)
- }
+ directMessageHandler.sendDirectMessage(sender, recipient, message)
return CommandResult.Success
}
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 3617df1..9aa563a 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
@@ -8,6 +8,8 @@ import dev.m1sk9.lunaticChat.paper.config.key.QuickRepliesFeatureConfig
import dev.m1sk9.lunaticChat.paper.i18n.Language
import org.bukkit.configuration.file.FileConfiguration
+// FIXME: ConfigManager uses mutable static state which makes testing difficult
+// and creates hidden global dependencies. Consider refactoring to dependency injection.
object ConfigManager {
private var lunaticChatConfiguration: LunaticChatConfiguration? = null
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/ConversionCache.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/ConversionCache.kt
index d2ba632..da79cfa 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/ConversionCache.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/ConversionCache.kt
@@ -110,17 +110,20 @@ class ConversionCache(
private fun queueSaveToDisk() {
if (conversionSaveQueue.compareAndSet(false, true)) {
- Bukkit.getScheduler().runTaskAsynchronously(
+ Bukkit.getScheduler().runTaskLaterAsynchronously(
plugin,
Runnable {
- Thread.sleep(5000) // 5 seconds delay to batch multiple save requests
- conversionSaveQueue.set(true)
+ conversionSaveQueue.set(false)
saveToDisk()
},
+ 100L, // 5 seconds = 100 ticks
)
}
}
+ // FIXME: ConcurrentHashMap keys are unordered, so evicting "oldest" entries
+ // actually evicts random entries. Consider using LinkedHashMap with access-order
+ // or implement proper LRU cache with timestamp tracking.
private fun evictOldestEntry() {
val toRemove = conversionMemoryCache.size / 10
conversionMemoryCache.keys.take(toRemove).forEach {
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 2c22be1..f8e8181 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
@@ -29,7 +29,14 @@ object EventListenerRegistry {
// Always register these listeners
pluginManager.registerEvents(SpyPermissionManager, plugin)
pluginManager.registerEvents(
- PlayerPresenceListener(plugin, services.languageManager, updateAvailable),
+ PlayerPresenceListener(
+ lunaticChat = plugin,
+ languageManager = services.languageManager,
+ updateCheckerFlag = updateAvailable,
+ playerSettingsManager = services.playerSettingsManager,
+ chatModeManager = services.chatModeManager,
+ channelManager = services.channelManager,
+ ),
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 258b0b1..47c8cd4 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
@@ -21,47 +21,58 @@ class PlayerChatListener(
private val plainTextSerializer = PlainTextComponentSerializer.plainText()
@EventHandler(ignoreCancelled = true)
- fun onChat(event: AsyncChatEvent) =
- runBlocking {
- val player = event.player
- val settings = settingsManager.getSettings(player.uniqueId)
+ fun onChat(event: AsyncChatEvent) {
+ val player = event.player
+ val settings = settingsManager.getSettings(player.uniqueId)
- val originalMessage = plainTextSerializer.serialize(event.message())
- val displayMessage =
- settings
- .takeIf {
- it.japaneseConversionEnabled
- }?.runCatching {
- romajiConverter
- .convert(originalMessage)
- ?.let { "$originalMessage §e($it)" }
- ?: originalMessage
- }?.getOrNull() ?: originalMessage
+ val originalMessage = plainTextSerializer.serialize(event.message())
- 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)
- }
+ // Handle chat mode switching with '!' prefix
+ val hasPrefix = originalMessage.startsWith('!')
+ val messageWithoutPrefix =
+ if (hasPrefix) {
+ originalMessage.removePrefix("!").trim()
+ } else {
+ originalMessage
+ }
- when (effectiveMode) {
- ChatMode.GLOBAL -> {
- event.message(Component.text(displayMessage))
- }
- ChatMode.CHANNEL -> {
- event.isCancelled = true
- channelMessageHandler
- .sendChannelMessage(player, originalMessage)
- }
+ if (hasPrefix && messageWithoutPrefix.isEmpty()) {
+ event.isCancelled = true
+ return
+ }
+
+ val effectiveMode =
+ if (hasPrefix) {
+ val currentMode = chatModeManager.getChatMode(player.uniqueId)
+ currentMode.toggle()
+ } else {
+ chatModeManager.getChatMode(player.uniqueId)
}
- event.message(Component.text(displayMessage))
+ // Handle romaji conversion if enabled (requires blocking for HTTP call)
+ val displayMessage =
+ if (settings.japaneseConversionEnabled) {
+ runCatching {
+ runBlocking {
+ romajiConverter
+ .convert(messageWithoutPrefix)
+ ?.let { "$messageWithoutPrefix §e($it)" }
+ ?: messageWithoutPrefix
+ }
+ }.getOrNull() ?: messageWithoutPrefix
+ } else {
+ messageWithoutPrefix
+ }
+
+ // Route message based on chat mode
+ when (effectiveMode) {
+ ChatMode.GLOBAL -> {
+ event.message(Component.text(displayMessage))
+ }
+ ChatMode.CHANNEL -> {
+ event.isCancelled = true
+ channelMessageHandler.sendChannelMessage(player, messageWithoutPrefix)
+ }
}
+ }
}
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 ca73567..fe4239d 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,14 @@
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
+import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter
+import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.event.ClickEvent
import org.bukkit.event.EventHandler
@@ -16,24 +21,72 @@ class PlayerPresenceListener(
private val lunaticChat: LunaticChat,
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)
fun onJoin(event: PlayerJoinEvent) {
val player = event.player
- if (!updateCheckerFlag.get() || !player.hasAnyPermission { +LunaticChatPermissionNode.NoticeUpdate }) return
-
- player.sendMessage {
- Component
- .text(
- languageManager.getMessage("general.newUpdateAvailable"),
- ).clickEvent(
- ClickEvent.openUrl("https://github.com/m1sk9/LunaticChat/releases/latest"),
+
+ // Send update notification if available
+ if (updateCheckerFlag.get() && player.hasAnyPermission { +LunaticChatPermissionNode.NoticeUpdate }) {
+ player.sendMessage {
+ Component
+ .text(
+ languageManager.getMessage("general.newUpdateAvailable"),
+ ).clickEvent(
+ ClickEvent.openUrl("https://github.com/m1sk9/LunaticChat/releases/latest"),
+ )
+ }
+ }
+
+ // 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)
+ context?.let {
+ val notification =
+ languageManager.getMessage(
+ "channel.notification.login",
+ mapOf("channelName" to it.channel.name),
+ )
+ player.sendMessage(Component.text(notification))
+ }
}
}
@EventHandler(ignoreCancelled = true)
fun onQuit(event: PlayerQuitEvent) {
- lunaticChat.directMessageHandler.clearPlayer(event.player)
+ val player = event.player
+ val playerId = player.uniqueId
+
+ // 1. Clear direct message references
+ lunaticChat.directMessageHandler.clearPlayer(player)
+
+ // 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
+ playerSettingsManager.saveToDisk()
}
}
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/settings/YamlPlayerSettingsStorage.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/settings/YamlPlayerSettingsStorage.kt
index 754c82b..0aa8eef 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/settings/YamlPlayerSettingsStorage.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/settings/YamlPlayerSettingsStorage.kt
@@ -87,13 +87,13 @@ class YamlPlayerSettingsStorage(
*/
fun queueAsyncSave(data: PlayerSettingsData) {
if (saveFlag.compareAndSet(false, true)) {
- Bukkit.getScheduler().runTaskAsynchronously(
+ Bukkit.getScheduler().runTaskLaterAsynchronously(
plugin,
Runnable {
- Thread.sleep(5000) // 5 seconds delay to batch multiple save requests
saveFlag.set(false)
saveToDisk(data)
},
+ 100L, // 5 seconds = 100 ticks
)
}
}
diff --git a/platform-paper/src/main/resources/languages/en.yml b/platform-paper/src/main/resources/languages/en.yml
index 91a4f3b..39908d2 100644
--- a/platform-paper/src/main/resources/languages/en.yml
+++ b/platform-paper/src/main/resources/languages/en.yml
@@ -85,6 +85,8 @@ channel:
noChannels: "You are not a member of any channels"
clickToSwitch: "Click to switch"
error: "Failed to retrieve channel status"
+ notification:
+ login: "You are in channel '{channelName}'"
chatmode:
current: "Current chat mode"
@@ -93,6 +95,8 @@ chatmode:
channel: "CHANNEL"
toggle:
success: "Chat mode switched to"
+ notification:
+ login: "Current chat mode: {mode}"
general:
playerOnlyCommand: "This command can only be executed by players."
diff --git a/platform-paper/src/main/resources/languages/ja.yml b/platform-paper/src/main/resources/languages/ja.yml
index 9e93ce9..47399b8 100644
--- a/platform-paper/src/main/resources/languages/ja.yml
+++ b/platform-paper/src/main/resources/languages/ja.yml
@@ -85,6 +85,8 @@ channel:
noChannels: "どのチャンネルにも参加していません"
clickToSwitch: "クリックして切り替え"
error: "チャンネルステータスの取得に失敗しました"
+ notification:
+ login: "チャンネル '{channelName}' に入室中です"
chatmode:
current: "現在のチャットモード"
@@ -93,6 +95,8 @@ chatmode:
channel: "チャンネル"
toggle:
success: "チャットモードを切り替えました"
+ notification:
+ login: "現在のチャットモード: {mode}"
general:
playerOnlyCommand: "このコマンドはプレイヤーのみが実行できます"
diff --git a/platform-paper/src/main/resources/paper-plugin.yml b/platform-paper/src/main/resources/paper-plugin.yml
index 3f991a9..b3a9d8f 100644
--- a/platform-paper/src/main/resources/paper-plugin.yml
+++ b/platform-paper/src/main/resources/paper-plugin.yml
@@ -19,6 +19,26 @@ permissions:
default: true
lunaticchat.command.lc.status:
default: true
+ lunaticchat.command.lc.channel:
+ default: true
+ lunaticchat.command.lc.channel.create:
+ default: true
+ lunaticchat.command.lc.channel.list:
+ default: true
+ lunaticchat.command.lc.channel.join:
+ default: true
+ lunaticchat.command.lc.channel.leave:
+ default: true
+ lunaticchat.command.lc.channel.switch:
+ default: true
+ lunaticchat.command.lc.channel.status:
+ default: true
+ lunaticchat.command.lc.channel.delete:
+ default: true
+ lunaticchat.command.lc.chatmode:
+ default: true
+ lunaticchat.command.lc.chatmode.toggle:
+ default: true
lunaticchat.spy:
default: op