diff options
16 files changed, 43 insertions, 282 deletions
diff --git a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/converter/KanaConverter.kt b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/converter/KanaConverter.kt index 24e3560..bdbdf69 100644 --- a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/converter/KanaConverter.kt +++ b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/converter/KanaConverter.kt @@ -4,16 +4,10 @@ package dev.m1sk9.lunaticChat.engine.converter * Converts romanji text to hiragana using Trie data structure. */ object KanaConverter { - sealed class TrieNode { - data class Leaf( - val value: String, - ) : TrieNode() - - data class Branch( - val children: Map<Char, TrieNode>, - val value: String? = null, - ) : TrieNode() - } + private class TrieNode( + val children: Map<Char, TrieNode>, + val value: String? = null, + ) private val romanjiTrie: TrieNode = buildTrie() @@ -216,7 +210,7 @@ object KanaConverter { "n" to "ん", ) - return insertAll(TrieNode.Branch(emptyMap()), mappings) + return insertAll(TrieNode(emptyMap()), mappings) } private fun insertAll( @@ -235,22 +229,33 @@ object KanaConverter { key: String, value: String, ): TrieNode { - if (key.isEmpty()) { - return when (node) { - is TrieNode.Branch -> TrieNode.Branch(node.children, value) - is TrieNode.Leaf -> TrieNode.Leaf(value) - } - } + if (key.isEmpty()) return TrieNode(node.children, value) - return when (node) { - is TrieNode.Branch -> { - val char = key[0] - val child = node.children[char] ?: TrieNode.Branch(emptyMap()) - val newChild = insert(child, key.substring(1), value) - TrieNode.Branch(node.children + (char to newChild), node.value) - } - is TrieNode.Leaf -> node + val char = key[0] + val child = node.children[char] ?: TrieNode(emptyMap()) + return TrieNode(node.children + (char to insert(child, key.substring(1), value)), node.value) + } + + /** + * Walks the trie from [start] and returns the longest mapping that matches, paired with the + * number of characters it consumed, or null when no prefix of the input maps to kana. + */ + private fun longestMatch( + input: String, + start: Int, + ): Pair<String, Int>? { + var node = romanjiTrie + var match: Pair<String, Int>? = null + var i = start + + while (true) { + node.value?.let { match = it to (i - start) } + if (i >= input.length) break + node = node.children[input[i]] ?: break + i++ } + + return match } /** @@ -282,39 +287,8 @@ object KanaConverter { } } - // Try to find the longest match in the trie - var node: TrieNode = romanjiTrie - var matchLength = 0 - var j = i - - while (j < lowerInput.length && lowerInput[j] in 'a'..'z') { - node = - when (node) { - is TrieNode.Branch -> { - if (node.value != null) { - matchLength = j - i - } - node.children[lowerInput[j]] ?: break - } - is TrieNode.Leaf -> { - matchLength = j - i - break - } - } - j++ - } - - // Check for terminal match - if (node is TrieNode.Leaf) { - matchLength = j - i - } else if (node is TrieNode.Branch && node.value != null) { - matchLength = j - i - } - // If no match found, this character cannot be converted - not valid romaji - if (matchLength == 0) { - return false - } + val (_, matchLength) = longestMatch(lowerInput, i) ?: return false i += matchLength } @@ -344,37 +318,10 @@ object KanaConverter { } } - var node: TrieNode = romanjiTrie - var lastMatch: Pair<String, Int>? = null - var j = i - - while (j < lowerInput.length) { - node = - when (node) { - is TrieNode.Branch -> { - if (node.value != null) { - lastMatch = node.value to (j - i) - } - - node.children[lowerInput[j]] ?: break - } - is TrieNode.Leaf -> { - lastMatch = node.value to (j - i) - break - } - } - j++ - } - - if (node is TrieNode.Leaf) { - lastMatch = node.value to (j - i) - } else if (node is TrieNode.Branch && node.value != null) { - lastMatch = node.value to (j - i) - } - - if (lastMatch != null) { - result.append(lastMatch.first) - i += lastMatch.second + val match = longestMatch(lowerInput, i) + if (match != null) { + result.append(match.first) + i += match.second } else { result.append(lowerInput[i]) i++ diff --git a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/PlayerSettingsData.kt b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/PlayerSettingsData.kt index 0e3cd24..91c37b8 100644 --- a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/PlayerSettingsData.kt +++ b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/PlayerSettingsData.kt @@ -30,17 +30,17 @@ import java.util.UUID data class PlayerSettingsData( val version: Int = 1, val japaneseConversion: Map< - @Serializable(with = UUIDASStringSerializer::class) + @Serializable(with = UUIDSerializer::class) UUID, Boolean, > = emptyMap(), val directMessageNotification: Map< - @Serializable(with = UUIDASStringSerializer::class) + @Serializable(with = UUIDSerializer::class) UUID, Boolean, > = emptyMap(), val channelMessageNotification: Map< - @Serializable(with = UUIDASStringSerializer::class) + @Serializable(with = UUIDSerializer::class) UUID, Boolean, > = emptyMap(), diff --git a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDASStringSerializer.kt b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDASStringSerializer.kt deleted file mode 100644 index 7e6b331..0000000 --- a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDASStringSerializer.kt +++ /dev/null @@ -1,27 +0,0 @@ -package dev.m1sk9.lunaticChat.engine.settings - -import kotlinx.serialization.KSerializer -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import java.util.UUID - -/** - * Serializer for UUID that converts to/from String format for YAML compatibility. - * Used in PlayerSettingsData for serializing UUID keys in maps. - */ -object UUIDASStringSerializer : KSerializer<UUID> { - override val descriptor: SerialDescriptor = - PrimitiveSerialDescriptor("UUIDAsString", PrimitiveKind.STRING) - - override fun serialize( - encoder: Encoder, - value: UUID, - ) { - encoder.encodeString(value.toString()) - } - - override fun deserialize(decoder: Decoder): UUID = UUID.fromString(decoder.decodeString()) -} diff --git a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializer.kt b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializer.kt index e03c1c1..dd01616 100644 --- a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializer.kt +++ b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializer.kt @@ -11,6 +11,8 @@ import java.util.UUID /** * Custom serializer for UUID with kotlinx.serialization. * kotlinx.serialization doesn't support UUID by default, so we need a custom serializer. + * + * Used for both UUID properties and UUID map keys (JSON and YAML alike). */ object UUIDSerializer : KSerializer<UUID> { override val descriptor: SerialDescriptor = diff --git a/engine/src/test/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializerTest.kt b/engine/src/test/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializerTest.kt index 599a372..58d9c32 100644 --- a/engine/src/test/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializerTest.kt +++ b/engine/src/test/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializerTest.kt @@ -16,12 +16,6 @@ class UUIDSerializerTest { val uuid: UUID, ) - @Serializable - private data class UUIDAsStringHolder( - @Serializable(with = UUIDASStringSerializer::class) - val uuid: UUID, - ) - @Test fun `UUIDSerializer should serialize UUID to string`() { val uuid = UUID.fromString("12345678-1234-1234-1234-123456789abc") @@ -52,35 +46,6 @@ class UUIDSerializerTest { } @Test - fun `UUIDASStringSerializer should serialize UUID to string`() { - val uuid = UUID.fromString("abcdef01-2345-6789-abcd-ef0123456789") - val holder = UUIDAsStringHolder(uuid) - - val jsonString = json.encodeToString(UUIDAsStringHolder.serializer(), holder) - - assert(jsonString.contains("abcdef01-2345-6789-abcd-ef0123456789")) - } - - @Test - fun `UUIDASStringSerializer should deserialize string to UUID`() { - val jsonString = """{"uuid":"abcdef01-2345-6789-abcd-ef0123456789"}""" - val holder = json.decodeFromString(UUIDAsStringHolder.serializer(), jsonString) - - assertEquals(UUID.fromString("abcdef01-2345-6789-abcd-ef0123456789"), holder.uuid) - } - - @Test - fun `UUIDASStringSerializer round-trip should preserve UUID`() { - val originalUuid = UUID.randomUUID() - val holder = UUIDAsStringHolder(originalUuid) - - val jsonString = json.encodeToString(UUIDAsStringHolder.serializer(), holder) - val decoded = json.decodeFromString(UUIDAsStringHolder.serializer(), jsonString) - - assertEquals(originalUuid, decoded.uuid) - } - - @Test fun `UUIDSerializer should fail on invalid UUID string`() { val jsonString = """{"uuid":"not-a-valid-uuid"}""" @@ -88,13 +53,4 @@ class UUIDSerializerTest { json.decodeFromString(UUIDHolder.serializer(), jsonString) } } - - @Test - fun `UUIDASStringSerializer should fail on invalid UUID string`() { - val jsonString = """{"uuid":"not-a-valid-uuid"}""" - - assertFailsWith<Exception> { - json.decodeFromString(UUIDAsStringHolder.serializer(), jsonString) - } - } } 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 035c578..e006299 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 @@ -60,7 +60,7 @@ class LunaticChat : val httpClient = HttpClient(CIO) // Initialize plugin coroutine scope - pluginScope = PluginCoroutineScope(this, logger) + pluginScope = PluginCoroutineScope(logger) // Initialize all services serviceInitializer = diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PluginCoroutineScope.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PluginCoroutineScope.kt index 114f82d..f67d262 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PluginCoroutineScope.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PluginCoroutineScope.kt @@ -4,7 +4,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel -import org.bukkit.plugin.java.JavaPlugin import java.util.logging.Logger /** @@ -26,7 +25,6 @@ import java.util.logging.Logger * ``` */ class PluginCoroutineScope( - private val plugin: JavaPlugin, private val logger: Logger, ) { private val job = SupervisorJob() diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/CommandContext.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/CommandContext.kt index 53f29f4..c423d0c 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/CommandContext.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/CommandContext.kt @@ -2,7 +2,6 @@ package dev.m1sk9.lunaticChat.paper.command.core import io.papermc.paper.command.brigadier.CommandSourceStack import net.kyori.adventure.text.Component -import net.kyori.adventure.text.event.ClickEvent import org.bukkit.command.CommandSender import org.bukkit.entity.Player @@ -41,28 +40,4 @@ class CommandContext( fun reply(message: Component) { sender.sendMessage(message) } - - /** - * Sends a message with a click event to the command sender. - * - * @param message The message component to send - * @param event The click event to attach to the message - */ - fun replyWithEvent( - message: Component, - event: ClickEvent<*>, - ) { - message - .clickEvent(event) - .let { sender.sendMessage(it) } - } - - /** - * Sends a plain text message to the command sender. - * - * @param message The plain text message to send - */ - fun replyPlain(message: String) { - sender.sendPlainMessage(message) - } } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticCommand.kt index 429a9c9..2447ec4 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticCommand.kt @@ -32,10 +32,6 @@ abstract class LunaticCommand( this::class.annotations.filterIsInstance<Permission>().firstOrNull() } - private val deprecatedAnnotation: Deprecated? by lazy { - this::class.annotations.filterIsInstance<Deprecated>().firstOrNull() - } - private val isPlayerOnly: Boolean by lazy { this::class.annotations.any { it is PlayerOnly } } @@ -65,20 +61,6 @@ abstract class LunaticCommand( * Called by CommandRegistry during registration. */ fun buildWithChecks(): LiteralArgumentBuilder<CommandSourceStack> { - // If command is deprecated, replace with error message handler - deprecatedAnnotation?.let { deprecated -> - return Commands - .literal(name) - .executes { ctx -> - val context = wrapContext(ctx) - val result = - CommandResult.Failure( - MessageFormatter.formatError(deprecated.message), - ) - handleResult(context, result) - } - } - var builder = buildCommand() permission?.let { perm -> builder = diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/common/UpdateChecker.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/common/UpdateChecker.kt index 49d6852..56ceabf 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/common/UpdateChecker.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/common/UpdateChecker.kt @@ -14,12 +14,6 @@ import java.util.logging.Logger data class GitHubRelease( @SerialName("tag_name") val tagName: String, - @SerialName("name") - val name: String, - @SerialName("published_at") - val publishedAt: String, - @SerialName("html_url") - val htmlUrl: String, ) class UpdateChecker( 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 5a2c8e2..5513303 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 @@ -9,12 +9,11 @@ import java.util.concurrent.atomic.AtomicBoolean import java.util.logging.Logger import kotlin.io.path.bufferedReader import kotlin.io.path.exists -import kotlin.io.path.listDirectoryEntries import kotlin.io.path.writeText /** * Handles YAML file I/O operations for player settings. - * Provides backup functionality and async save with debouncing. + * Provides async save with debouncing. * * @property settingsFile The path to the YAML settings file * @property plugin The plugin instance for scheduling async tasks @@ -30,8 +29,7 @@ class YamlPlayerSettingsStorage( /** * Loads player settings from the YAML file. - * If the file doesn't exist, returns empty settings. - * If loading fails, attempts to restore from backup. + * If the file doesn't exist or cannot be parsed, returns empty settings. * * @return The loaded settings or empty settings if file doesn't exist */ @@ -46,18 +44,6 @@ class YamlPlayerSettingsStorage( yaml.decodeFromString(PlayerSettingsData.serializer(), yamlContent) } catch (e: Exception) { logger.severe("Failed to load settings file: ${e.message}") - - val backup = findLatestBackup() - if (backup != null) { - logger.warning("Attempting to restore from backup: $backup") - try { - val content = backup.bufferedReader().use { it.readText() } - return yaml.decodeFromString(PlayerSettingsData.serializer(), content) - } catch (backupError: Exception) { - logger.severe("Backup restoration failed: ${backupError.message}") - } - } - logger.warning("Using empty settings as fallback") PlayerSettingsData() } @@ -98,19 +84,4 @@ class YamlPlayerSettingsStorage( ) } } - - /** - * Finds the most recent backup file. - * - * @return The path to the latest backup, or null if no backups exist - */ - private fun findLatestBackup(): Path? = - try { - settingsFile.parent - .listDirectoryEntries("player-settings.yaml.backup.*") - .maxByOrNull { it.fileName.toString() } - } catch (e: Exception) { - logger.warning("Failed to find backup: ${e.message}") - null - } } diff --git a/platform-paper/src/main/resources/languages/en.yml b/platform-paper/src/main/resources/languages/en.yml index 5a76910..f65474a 100644 --- a/platform-paper/src/main/resources/languages/en.yml +++ b/platform-paper/src/main/resources/languages/en.yml @@ -12,9 +12,6 @@ # ---------------------------------------------- commandDescription: - jp: "Toggle romaji-to-kana conversion on/off" - notice: "Toggle direct message notifications on/off" - chNotice: "Toggle channel message notifications on/off" reply: "Reply to the player who last sent/received a direct message" tell: "Send a direct message to another player" lc: "LunaticChat Main Command" @@ -206,7 +203,6 @@ channel: 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." - noPermission: "You do not have permission to execute this command." spyMessage: "You have been granted permission, so this message is displayed in spy mode." nightlyWarning: "You are running a nightly build. This build may be unstable or contain bugs." nightlyReportIssue: "If you encounter any issues, please report them on GitHub Issues." diff --git a/platform-paper/src/main/resources/languages/ja.yml b/platform-paper/src/main/resources/languages/ja.yml index b2582c4..764951b 100644 --- a/platform-paper/src/main/resources/languages/ja.yml +++ b/platform-paper/src/main/resources/languages/ja.yml @@ -14,9 +14,6 @@ commandDescription: tell: "他のプレイヤーにダイレクトメッセージを送信します" reply: "最後にダイレクトメッセージを送信/受信したプレイヤーに返信します" - jp: "かな・ローマ字変換機能のオン/オフを切り替えます" - notice: "ダイレクトメッセージ通知のオン/オフを切り替えます" - chNotice: "チャンネルメッセージ通知のオン/オフを切り替えます" lc: "LunaticChat のメインコマンド" lcv: "LunaticChat Velocity 連携コマンド" @@ -206,7 +203,6 @@ channel: general: playerOnlyCommand: "このコマンドはプレイヤーのみが実行できます" newUpdateAvailable: "LunaticChat の新しいバージョンが利用可能です。GitHubまたはModrinthからダウンロードできます" - noPermission: "このコマンドを実行する権限がありません" spyMessage: "あなたに権限が付与されているため、このメッセージはスパイ状態で表示されています" nightlyWarning: "ナイトリービルドを使用しています。このビルドは不安定であったり、バグが含まれている可能性があります。" nightlyReportIssue: "問題を発見した場合は、GitHub Issues で報告してください。" diff --git a/platform-velocity/build.gradle.kts b/platform-velocity/build.gradle.kts index 3cd8c2d..65bd27f 100644 --- a/platform-velocity/build.gradle.kts +++ b/platform-velocity/build.gradle.kts @@ -57,9 +57,6 @@ tasks { filesMatching("velocity-plugin.json") { expand(props) } - filesMatching("build-info.properties") { - expand(props) - } } build { diff --git a/platform-velocity/src/main/kotlin/dev/m1sk9/lunaticChat/velocity/BuildInfo.kt b/platform-velocity/src/main/kotlin/dev/m1sk9/lunaticChat/velocity/BuildInfo.kt deleted file mode 100644 index 1cb13d4..0000000 --- a/platform-velocity/src/main/kotlin/dev/m1sk9/lunaticChat/velocity/BuildInfo.kt +++ /dev/null @@ -1,23 +0,0 @@ -package dev.m1sk9.lunaticChat.velocity - -import java.util.Properties - -object BuildInfo { - val version: String - val commitHash: String - val channel: String - - init { - val props = Properties() - BuildInfo::class.java.getResourceAsStream("/build-info.properties")?.use { - props.load(it) - } - version = props.getProperty("version", "unknown") - commitHash = props.getProperty("commit", "unknown") - channel = props.getProperty("channel", "stable") - } - - val isNightly: Boolean get() = channel == "nightly" - - fun versionWithCommit(): String = "$version ($commitHash)" -} diff --git a/platform-velocity/src/main/resources/build-info.properties b/platform-velocity/src/main/resources/build-info.properties deleted file mode 100644 index 1f8dbc2..0000000 --- a/platform-velocity/src/main/resources/build-info.properties +++ /dev/null @@ -1,3 +0,0 @@ -version=${version} -commit=${gitCommitHash} -channel=${channel} |
