diff options
| author | Sho Sakuma <me@m1sk9.dev> | 2026-02-01 01:11:39 +0900 |
|---|---|---|
| committer | Sho Sakuma <me@m1sk9.dev> | 2026-02-01 01:11:39 +0900 |
| commit | 14dc6dc4d29b6612f1e5fda5ceda187bc1df9d4d (patch) | |
| tree | 193544787d107a44f30211f952aa1fb81d502355 | |
| parent | 3fa249dfe563040268f656119623e5734b212d93 (diff) | |
| download | LunaticChat-14dc6dc4d29b6612f1e5fda5ceda187bc1df9d4d.tar.gz LunaticChat-14dc6dc4d29b6612f1e5fda5ceda187bc1df9d4d.tar.bz2 LunaticChat-14dc6dc4d29b6612f1e5fda5ceda187bc1df9d4d.zip | |
feat: Support Velocity intergration in Paper module
12 files changed, 544 insertions, 0 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 31a6886..aada4b0 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 @@ -10,6 +10,7 @@ import dev.m1sk9.lunaticChat.paper.command.core.CommandRegistry 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 +import dev.m1sk9.lunaticChat.paper.command.impl.lcv.VelocityStatusCommand import dev.m1sk9.lunaticChat.paper.command.setting.SettingHandlerRegistry import dev.m1sk9.lunaticChat.paper.command.setting.handler.ChannelMessageNoticeSettingHandler import dev.m1sk9.lunaticChat.paper.command.setting.handler.DirectMessageNoticeSettingHandler @@ -151,6 +152,13 @@ class LunaticChat : ) } + // Conditionally register /lcv command if Velocity integration is enabled + services.velocityConnectionManager?.let { velocityManager -> + commandRegistry.registerAll( + VelocityStatusCommand(this, velocityManager, services.languageManager), + ) + } + commandRegistry.initialize() } 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 9069bc4..6843dd3 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 @@ -9,6 +9,7 @@ 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 +import dev.m1sk9.lunaticChat.paper.velocity.VelocityConnectionManager /** * Container for initialized services. @@ -25,6 +26,7 @@ import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager * @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) */ data class ServiceContainer( val languageManager: LanguageManager, @@ -36,4 +38,5 @@ data class ServiceContainer( 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 70495a4..fe6a4e4 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 @@ -16,8 +16,13 @@ import dev.m1sk9.lunaticChat.paper.converter.RomanjiConverter import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager import dev.m1sk9.lunaticChat.paper.settings.YamlPlayerSettingsStorage +import dev.m1sk9.lunaticChat.paper.velocity.VelocityConnectionManager import io.ktor.client.HttpClient +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.plugin.java.JavaPlugin +import java.util.concurrent.atomic.AtomicBoolean import java.util.logging.Logger import kotlin.time.Duration.Companion.milliseconds @@ -51,6 +56,8 @@ class ServiceInitializer( private var channelMessageHandler: ChannelMessageHandler? = null private var channelNotificationHandler: ChannelNotificationHandler? = null private var channelMessageLogger: ChannelMessageLogger? = null + private var velocityConnectionManager: VelocityConnectionManager? = null + private val handshakeCompleted = AtomicBoolean(false) /** * Initializes all services in dependency order. @@ -108,6 +115,14 @@ class ServiceInitializer( languageManager = languageManager, ) + // 6. Initialize Velocity integration (optional) + val velocityManager = + if (configuration.features.velocityIntegration.enabled) { + initializeVelocityIntegration() + } else { + null + } + return ServiceContainer( languageManager = languageManager, playerSettingsManager = playerSettingsManager, @@ -118,6 +133,7 @@ class ServiceInitializer( chatModeManager = chatModeManager, channelMessageHandler = channelMessageHandler, channelNotificationHandler = channelNotificationHandler, + velocityConnectionManager = velocityManager, ) } @@ -286,6 +302,83 @@ class ServiceInitializer( } /** + * Initializes Velocity integration with handshake on first player join. + */ + private fun initializeVelocityIntegration(): VelocityConnectionManager { + val pluginVersion = plugin.pluginMeta.version + val manager = + VelocityConnectionManager( + plugin = plugin, + pluginVersion = pluginVersion, + logger = logger, + ) + manager.initialize() + velocityConnectionManager = manager + + // Register listener for first player join + plugin.server.pluginManager.registerEvents( + object : Listener { + @EventHandler + fun onPlayerJoin(event: PlayerJoinEvent) { + // Only perform handshake once + if (!handshakeCompleted.getAndSet(true)) { + // Schedule handshake 1 second after first player joins + plugin.server.scheduler.runTaskLater( + plugin, + Runnable { + performVelocityHandshake(event.player, manager) + }, + 20L, + ) + } + } + }, + plugin, + ) + + logger.info("Velocity integration initialized. Waiting for first player join to perform handshake.") + return manager + } + + /** + * Performs handshake with Velocity proxy. + */ + private fun performVelocityHandshake( + player: org.bukkit.entity.Player, + manager: VelocityConnectionManager, + ) { + manager + .performHandshake(player) + .thenAccept { result -> + when (result) { + is VelocityConnectionManager.HandshakeResult.Success -> { + logger.info("Velocity handshake successful with version ${result.velocityVersion}") + } + is VelocityConnectionManager.HandshakeResult.Error -> { + logger.severe("Velocity handshake failed: ${result.message}") + logger.severe("Disabling plugin due to Velocity integration failure") + plugin.server.scheduler.runTask( + plugin, + Runnable { + plugin.server.pluginManager.disablePlugin(plugin) + }, + ) + } + } + }.exceptionally { throwable -> + logger.severe("Velocity handshake exception: ${throwable.message}") + throwable.printStackTrace() + plugin.server.scheduler.runTask( + plugin, + Runnable { + plugin.server.pluginManager.disablePlugin(plugin) + }, + ) + null + } + } + + /** * Schedules periodic tasks such as cache saving. */ fun schedulePeriodicTasks() { @@ -311,5 +404,6 @@ class ServiceInitializer( services.channelManager?.saveToDisk() services.chatModeManager?.shutdown() channelMessageLogger?.shutdown() + services.velocityConnectionManager?.shutdown() } } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lcv/VelocityStatusCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lcv/VelocityStatusCommand.kt new file mode 100644 index 0000000..145272c --- /dev/null +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lcv/VelocityStatusCommand.kt @@ -0,0 +1,163 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lcv + +import com.mojang.brigadier.builder.LiteralArgumentBuilder +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode +import dev.m1sk9.lunaticChat.engine.protocol.ProtocolVersion +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.i18n.LanguageManager +import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter +import dev.m1sk9.lunaticChat.paper.velocity.VelocityConnectionManager +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 + +/** + * /lcv status command + * + * Displays Velocity integration status + */ +@Command( + name = "lcv", + aliases = ["lunaticvelocity"], + description = "Velocity integration status", +) +@Permission(LunaticChatPermissionNode.VelocityStatus::class) +@PlayerOnly +class VelocityStatusCommand( + plugin: LunaticChat, + private val velocityConnectionManager: VelocityConnectionManager, + private val languageManager: LanguageManager, +) : LunaticCommand(plugin) { + override val description: String + get() = languageManager.getMessage("commandDescription.lcv") + + override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = + Commands + .literal(name) + .then( + Commands + .literal("status") + .executes { ctx -> + val context = wrapContext(ctx) + checkPlayerOnly(context)?.let { return@executes handleResult(context, it) } + + val result = execute(context) + handleResult(context, result) + }, + ) + + private fun execute(ctx: CommandContext): CommandResult { + val sender = ctx.requirePlayer() + val meta = plugin.pluginMeta + + // Paper plugin version + sender.sendMessage( + MessageFormatter.format( + languageManager.getMessage( + "velocity.status.paperVersion", + mapOf("version" to meta.version), + ), + ), + ) + + // Protocol version + sender.sendMessage( + MessageFormatter.format( + languageManager.getMessage( + "velocity.status.protocolVersion", + mapOf("version" to ProtocolVersion.version), + ), + ), + ) + + // Connection state + val state = velocityConnectionManager.getState() + val stateMessage = + when (state) { + VelocityConnectionManager.ConnectionState.DISCONNECTED -> { + Component.text("Disconnected", NamedTextColor.GRAY) + } + VelocityConnectionManager.ConnectionState.HANDSHAKING -> { + Component.text("Handshaking...", NamedTextColor.YELLOW) + } + VelocityConnectionManager.ConnectionState.CONNECTED -> { + Component.text("Connected", NamedTextColor.GREEN) + } + VelocityConnectionManager.ConnectionState.FAILED -> { + Component.text("Failed", NamedTextColor.RED) + } + } + + sender.sendMessage( + Component + .text(languageManager.getMessage("velocity.status.connectionState")) + .append(Component.text(": ")) + .append(stateMessage), + ) + + // Velocity version (if connected) + velocityConnectionManager.getVelocityVersion()?.let { velocityVersion -> + sender.sendMessage( + MessageFormatter.format( + languageManager.getMessage( + "velocity.status.velocityVersion", + mapOf("version" to velocityVersion), + ), + ), + ) + } + + // Error message (if failed) + velocityConnectionManager.getLastError()?.let { error -> + sender.sendMessage( + Component + .text(languageManager.getMessage("velocity.status.error")) + .append(Component.text(": ", NamedTextColor.RED)) + .append(Component.text(error, NamedTextColor.RED)), + ) + } + + // Live status check (if connected) + if (state == VelocityConnectionManager.ConnectionState.CONNECTED) { + sender.sendMessage( + MessageFormatter.format( + languageManager.getMessage("velocity.status.checkingLiveStatus"), + ), + ) + + velocityConnectionManager + .requestStatus(sender) + .thenAccept { response -> + sender.sendMessage( + MessageFormatter.format( + languageManager.getMessage( + "velocity.status.liveStatusSuccess", + mapOf( + "version" to response.velocityVersion, + "protocol" to response.protocolVersion, + "online" to response.online.toString(), + ), + ), + ), + ) + }.exceptionally { throwable -> + sender.sendMessage( + Component + .text(languageManager.getMessage("velocity.status.liveStatusFailed")) + .color(NamedTextColor.RED) + .append(Component.text(": ${throwable.message}", NamedTextColor.RED)), + ) + null + } + } + + 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 1bd969d..164a0a8 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 @@ -5,6 +5,7 @@ import dev.m1sk9.lunaticChat.paper.config.key.FeaturesConfig import dev.m1sk9.lunaticChat.paper.config.key.JapaneseConversionFeatureConfig import dev.m1sk9.lunaticChat.paper.config.key.MessageFormatConfig import dev.m1sk9.lunaticChat.paper.config.key.QuickRepliesFeatureConfig +import dev.m1sk9.lunaticChat.paper.config.key.VelocityIntegrationConfig import dev.m1sk9.lunaticChat.paper.i18n.Language import org.bukkit.configuration.file.FileConfiguration @@ -51,6 +52,10 @@ class ConfigManager { maxMembersPerChannel = configFile.getInt("features.channelChat.maxMembersPerChannel", 0), maxMembershipPerPlayer = configFile.getInt("features.channelChat.maxMembershipPerPlayer", 0), ), + velocityIntegration = + VelocityIntegrationConfig( + enabled = configFile.getBoolean("features.velocityIntegration.enabled", false), + ), ), messageFormat = MessageFormatConfig( diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/FeaturesConfig.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/FeaturesConfig.kt index 190e00c..044838d 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/FeaturesConfig.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/FeaturesConfig.kt @@ -4,4 +4,5 @@ data class FeaturesConfig( val quickReplies: QuickRepliesFeatureConfig, val japaneseConversion: JapaneseConversionFeatureConfig, val channelChat: ChannelChatFeatureConfig, + val velocityIntegration: VelocityIntegrationConfig, ) diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/VelocityIntegrationConfig.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/VelocityIntegrationConfig.kt new file mode 100644 index 0000000..3cf42bf --- /dev/null +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/config/key/VelocityIntegrationConfig.kt @@ -0,0 +1,5 @@ +package dev.m1sk9.lunaticChat.paper.config.key + +data class VelocityIntegrationConfig( + val enabled: Boolean = false, +) diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/velocity/VelocityConnectionManager.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/velocity/VelocityConnectionManager.kt new file mode 100644 index 0000000..8861528 --- /dev/null +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/velocity/VelocityConnectionManager.kt @@ -0,0 +1,234 @@ +package dev.m1sk9.lunaticChat.paper.velocity + +import dev.m1sk9.lunaticChat.engine.protocol.PluginMessage +import dev.m1sk9.lunaticChat.engine.protocol.PluginMessageCodec +import dev.m1sk9.lunaticChat.engine.protocol.ProtocolVersion +import org.bukkit.entity.Player +import org.bukkit.plugin.Plugin +import org.bukkit.plugin.messaging.PluginMessageListener +import java.util.concurrent.CompletableFuture +import java.util.logging.Logger + +/** + * Manages connection with Velocity proxy + */ +class VelocityConnectionManager( + private val plugin: Plugin, + private val pluginVersion: String, + private val logger: Logger, +) : PluginMessageListener { + companion object { + private const val CHANNEL = "lunaticchat:main" + private const val HANDSHAKE_TIMEOUT_SECONDS = 5L + } + + /** + * Connection state + */ + enum class ConnectionState { + DISCONNECTED, + HANDSHAKING, + CONNECTED, + FAILED, + } + + /** + * Handshake result + */ + sealed class HandshakeResult { + data class Success( + val velocityVersion: String, + ) : HandshakeResult() + + data class Error( + val message: String, + ) : HandshakeResult() + } + + private var state: ConnectionState = ConnectionState.DISCONNECTED + private var handshakeFuture: CompletableFuture<HandshakeResult>? = null + private var statusFuture: CompletableFuture<PluginMessage.StatusResponse>? = null + private var velocityVersion: String? = null + private var lastError: String? = null + + /** + * Initialize + */ + fun initialize() { + plugin.server.messenger.registerOutgoingPluginChannel(plugin, CHANNEL) + plugin.server.messenger.registerIncomingPluginChannel(plugin, CHANNEL, this) + logger.info("Velocity integration channel registered: $CHANNEL") + } + + /** + * Performs handshake + * + * @param player Player to use for sending messages + * @return Handshake result + */ + fun performHandshake(player: Player): CompletableFuture<HandshakeResult> { + if (state == ConnectionState.HANDSHAKING) { + return handshakeFuture ?: CompletableFuture.completedFuture( + HandshakeResult.Error("Handshake already in progress"), + ) + } + + state = ConnectionState.HANDSHAKING + lastError = null + + val future = CompletableFuture<HandshakeResult>() + handshakeFuture = future + + val handshake = + PluginMessage.Handshake( + pluginVersion = pluginVersion, + protocolMajor = ProtocolVersion.MAJOR, + protocolMinor = ProtocolVersion.MINOR, + protocolPatch = ProtocolVersion.PATCH, + ) + + val data = PluginMessageCodec.encode(handshake) + player.sendPluginMessage(plugin, CHANNEL, data) + + logger.info("Sending handshake to Velocity (Plugin: $pluginVersion, Protocol: ${ProtocolVersion.version})") + + // Timeout handling + plugin.server.scheduler.runTaskLater( + plugin, + Runnable { + if (state == ConnectionState.HANDSHAKING) { + state = ConnectionState.FAILED + lastError = "Handshake timeout (${HANDSHAKE_TIMEOUT_SECONDS}s)" + logger.warning("Handshake timeout - Velocity plugin may not be installed") + future.complete(HandshakeResult.Error("Handshake timeout")) + handshakeFuture = null + } + }, + HANDSHAKE_TIMEOUT_SECONDS * 20L, + ) + + return future + } + + /** + * Sends status request + * + * @param player Player to use for sending messages + * @return Status response + */ + fun requestStatus(player: Player): CompletableFuture<PluginMessage.StatusResponse> { + val future = CompletableFuture<PluginMessage.StatusResponse>() + + if (state != ConnectionState.CONNECTED) { + future.completeExceptionally(IllegalStateException("Not connected to Velocity")) + return future + } + + statusFuture = future + + val statusRequest = PluginMessage.StatusRequest + val data = PluginMessageCodec.encode(statusRequest) + player.sendPluginMessage(plugin, CHANNEL, data) + + logger.info("Sending status request to Velocity") + + // Status request with timeout + plugin.server.scheduler.runTaskLater( + plugin, + Runnable { + if (!future.isDone) { + logger.warning("Status request timeout") + future.completeExceptionally(Exception("Status request timeout")) + statusFuture = null + } + }, + 5L * 20L, + ) + + return future + } + + /** + * Plugin message received + */ + override fun onPluginMessageReceived( + channel: String, + player: Player, + message: ByteArray, + ) { + if (channel != CHANNEL) return + + try { + val pluginMessage = PluginMessageCodec.decode(message) + + when (pluginMessage) { + is PluginMessage.HandshakeResponse -> handleHandshakeResponse(pluginMessage) + is PluginMessage.StatusResponse -> handleStatusResponse(pluginMessage) + else -> logger.warning("Unexpected message type: ${pluginMessage::class.simpleName}") + } + } catch (e: Exception) { + logger.severe("Failed to decode plugin message: ${e.message}") + e.printStackTrace() + } + } + + /** + * Handles handshake response + */ + private fun handleHandshakeResponse(response: PluginMessage.HandshakeResponse) { + val future = handshakeFuture ?: return + + if (response.compatible) { + state = ConnectionState.CONNECTED + velocityVersion = response.velocityVersion + logger.info("Successfully connected to Velocity (version: ${response.velocityVersion})") + future.complete(HandshakeResult.Success(response.velocityVersion)) + } else { + state = ConnectionState.FAILED + lastError = response.error ?: "Unknown compatibility error" + logger.severe("Velocity handshake failed: ${response.error}") + future.complete(HandshakeResult.Error(response.error ?: "Unknown error")) + } + + handshakeFuture = null + } + + /** + * Handles status response + */ + private fun handleStatusResponse(response: PluginMessage.StatusResponse) { + logger.info("Received status response from Velocity: version=${response.velocityVersion}, protocol=${response.protocolVersion}, online=${response.online}") + + val future = statusFuture + if (future != null) { + future.complete(response) + statusFuture = null + } else { + logger.warning("Received status response but no future was waiting for it") + } + } + + /** + * Shutdown + */ + fun shutdown() { + plugin.server.messenger.unregisterOutgoingPluginChannel(plugin, CHANNEL) + plugin.server.messenger.unregisterIncomingPluginChannel(plugin, CHANNEL) + logger.info("Velocity integration channel unregistered") + } + + /** + * Gets current connection state + */ + fun getState(): ConnectionState = state + + /** + * Gets Velocity version (if connected) + */ + fun getVelocityVersion(): String? = velocityVersion + + /** + * Gets last error message + */ + fun getLastError(): String? = lastError +} diff --git a/platform-paper/src/main/resources/config.yml b/platform-paper/src/main/resources/config.yml index 0889070..7968717 100644 --- a/platform-paper/src/main/resources/config.yml +++ b/platform-paper/src/main/resources/config.yml @@ -65,6 +65,10 @@ features: retentionDays: 30 # Maximum size of a single log file in megabytes. Files exceeding this size will stop accepting new entries. maxFileSizeMB: 100 + velocityIntegration: + # If enabled, enables integration with Velocity proxy plugin. + # This allows Paper and Velocity instances to communicate and verify compatibility. + enabled: false # ---------------------------------------------- # --------- Message Format Settings -------- diff --git a/platform-paper/src/main/resources/languages/en.yml b/platform-paper/src/main/resources/languages/en.yml index 767a9b3..d8d11fc 100644 --- a/platform-paper/src/main/resources/languages/en.yml +++ b/platform-paper/src/main/resources/languages/en.yml @@ -18,6 +18,7 @@ commandDescription: reply: "Reply to the player who last sent/received a direct message" tell: "Send a direct message to another player" lc: "LunaticChat Main Command" + lcv: "LunaticChat Velocity Integration Command" directMessage: noticeStatus: "Direct message notifications are currently {toggle}" @@ -196,3 +197,15 @@ general: toggle: off: "Disabled" on: "Enabled" + +velocity: + status: + paperVersion: "Paper Plugin Version: v{version}" + velocityVersion: "Velocity Plugin Version: v{version}" + protocolVersion: "Protocol Version: v{version}" + connectionState: "Connection State" + error: "Error" + checkingLiveStatus: "Checking live status..." + liveStatusSuccess: "Live status: Velocity v{version}, Protocol v{protocol}, Online: {online}" + liveStatusFailed: "Live status check failed" + diff --git a/platform-paper/src/main/resources/languages/ja.yml b/platform-paper/src/main/resources/languages/ja.yml index a6f2526..2300754 100644 --- a/platform-paper/src/main/resources/languages/ja.yml +++ b/platform-paper/src/main/resources/languages/ja.yml @@ -18,6 +18,7 @@ commandDescription: notice: "ダイレクトメッセージ通知のオン/オフを切り替えます" chNotice: "チャンネルメッセージ通知のオン/オフを切り替えます" lc: "LunaticChat のメインコマンド" + lcv: "LunaticChat Velocity 連携コマンド" directMessage: noticeToggle: "ダイレクトメッセージ通知を{toggle}にしました" @@ -196,3 +197,14 @@ general: toggle: on: "有効" off: "無効" + +velocity: + status: + paperVersion: "Paper プラグインバージョン: v{version}" + velocityVersion: "Velocity プラグインバージョン: v{version}" + protocolVersion: "プロトコルバージョン: v{version}" + connectionState: "接続状態" + error: "エラー" + checkingLiveStatus: "ライブステータスを確認中..." + liveStatusSuccess: "ライブステータス: Velocity v{version}, プロトコル v{protocol}, オンライン: {online}" + liveStatusFailed: "ライブステータスチェックに失敗しました" diff --git a/platform-paper/src/main/resources/paper-plugin.yml b/platform-paper/src/main/resources/paper-plugin.yml index 38d2026..f8a804b 100644 --- a/platform-paper/src/main/resources/paper-plugin.yml +++ b/platform-paper/src/main/resources/paper-plugin.yml @@ -60,3 +60,5 @@ permissions: default: op lunaticchat.channelbypass: default: op + lunaticchat.command.lcv.status: + default: op |
