simply-minecraft-db/src/main/kotlin/net/hareworks/simplymcdb/Command.kt
Hare 302575fb29 1.2
- kommand-libの外部化
- ビルド設定の見直し
2025-11-28 09:03:48 +09:00

268 lines
9.8 KiB
Kotlin

package net.hareworks.simplymcdb.command
import java.util.UUID
import net.hareworks.kommand_lib.KommandLib
import net.hareworks.kommand_lib.kommand
import net.hareworks.simplymcdb.App
import net.hareworks.simplymcdb.Config
import net.hareworks.simplymcdb.State
import net.hareworks.simplymcdb.database.Database
import net.hareworks.simplymcdb.fetch
import net.hareworks.simplymcdb.findPlayersNeedingMigration
import net.hareworks.simplymcdb.isRegistered
import net.hareworks.simplymcdb.overwritePlayerData
import net.hareworks.simplymcdb.register
import net.hareworks.simplymcdb.update
import net.hareworks.simplymcdb.PlayerSerializer
import net.kyori.adventure.audience.Audience
import net.kyori.adventure.text.minimessage.MiniMessage
import org.bukkit.entity.Player
import org.bukkit.plugin.java.JavaPlugin
private val miniMessage = MiniMessage.miniMessage()
private val commandBuffer = mutableMapOf<UUID, String>()
public fun Audience.sendMM(message: String) {
this.sendMessage(miniMessage.deserialize(message))
}
private fun Audience.sendConfigHelp() {
sendMM(
"<red>simplymcdb config help<newline><gray>reload: <green>reload the config from config.yml<newline><gray>fetch: <green>fetch the config from the database<newline><gray>upload: <green>upload the current config to the database")
}
public fun registerCommands(plugin: JavaPlugin): KommandLib =
kommand(plugin) {
command("smcdb") {
description = "Control Simply-Minecraft-DB"
permission = "simplydb.command"
executes {
sender.sendMessage("simplymcdb command")
}
literal("config") {
requires("simplydb.command.config")
executes { sender.sendConfigHelp() }
literal("reload") {
requires("simplydb.command.config.reload")
executes {
sender.sendMessage("reloading config...")
Config.reload()
sender.sendMessage("reloaded.")
}
}
literal("fetch") {
requires("simplydb.command.config.fetch")
executes { sender.sendMessage("fetching config...") }
}
literal("upload") {
requires("simplydb.command.config.upload")
executes { sender.sendMessage("uploading config...") }
}
literal("help") { executes { sender.sendConfigHelp() } }
}
literal("help") {
executes {
sender.sendMM(
"<red>simplymcdb help<newline><gray>config: <green>configre the plugin<newline><gray>activate: <green>when the plugin is disabled, activate it<newline><gray>deactivate: <green>when the plugin is enabled, deactivate it")
}
}
literal("activate") {
requires("simplydb.command.on")
executes {
if (App.instance.enabled == State.ACTIVE) {
sender.sendMessage("simplymcdb is already enabled.")
return@executes
}
App.instance.enable()
sender.sendMessage("simplymcdb enabled.")
}
}
literal("deactivate") {
requires("simplydb.command.off")
executes {
if (App.instance.enabled == State.DISABLED) {
sender.sendMessage("simplymcdb is already disabled.")
return@executes
}
App.instance.disable()
sender.sendMessage("simplymcdb disabled.")
}
}
literal("database") {
literal("init") {
executes {
Database.initialize()
sender.sendMessage("database initialized.")
}
}
literal("reset") {
executes {
Database.reset()
sender.sendMessage("database reset.")
}
}
}
literal("migrate") {
executes {
val player = sender as? Player
if (player == null) {
sender.sendMM("<red>[SMCDB] This command can only be run by players.")
return@executes
}
when (App.instance.enabled) {
State.DISABLED -> {
sender.sendMM("<red>[SMCDB] simplymcdb is disabled.")
return@executes
}
State.DISCONNECTED -> {
sender.sendMM("<yellow>[SMCDB] Database disconnected. Try again later.")
return@executes
}
else -> {}
}
if (!isRegistered(player.uniqueId)) {
sender.sendMM("<red>[SMCDB] You are not registered in the database.")
return@executes
}
try {
sender.sendMM("<gray>[SMCDB] Applying legacy data...")
fetch(player)
update(player)
sender.sendMM("<green>[SMCDB] Migration complete. Data updated to the latest format.")
} catch (e: Exception) {
App.instance.logger.warning("Failed to migrate data for ${player.uniqueId}: ${e.message}")
sender.sendMM("<red>[SMCDB] Migration failed. Check server logs.")
}
}
literal("all") {
executes {
val executor = sender as? Player
if (executor == null) {
sender.sendMM("<red>[SMCDB] This command can only be run by players.")
return@executes
}
when (App.instance.enabled) {
State.DISABLED -> {
sender.sendMM("<red>[SMCDB] simplymcdb is disabled.")
return@executes
}
State.DISCONNECTED -> {
sender.sendMM("<yellow>[SMCDB] Database disconnected. Try again later.")
return@executes
}
else -> {}
}
val targets = findPlayersNeedingMigration()
if (targets.isEmpty()) {
sender.sendMM("<gray>[SMCDB] No legacy data found.")
return@executes
}
sender.sendMM("<gray>[SMCDB] Migrating ${targets.size} legacy profiles... Please wait.")
val backup = PlayerSerializer.serialize(executor)
var migrated = 0
try {
targets.forEach { entry ->
try {
PlayerSerializer.deserialize(executor, entry.serialized)
val updatedSnapshot = PlayerSerializer.serialize(executor)
overwritePlayerData(entry.uuid, updatedSnapshot)
migrated++
} catch (ex: Exception) {
App.instance.logger.warning("Failed to migrate data for ${entry.uuid}: ${ex.message}")
}
}
} finally {
try {
PlayerSerializer.deserialize(executor, backup)
} catch (restoreEx: Exception) {
App.instance.logger.warning("Failed to restore migration executor state: ${restoreEx.message}")
}
}
sender.sendMM("<green>[SMCDB] Migration finished ($migrated/${targets.size}). Check logs for failures.")
}
}
}
literal("check") {
executes {
sender.sendMM(
"${when (App.instance.enabled) {
State.ACTIVE -> "<green>●"
State.DISCONNECTED -> "<yellow>■"
State.DISABLED -> "<red>○"
}}<white> simply-minecraft-database")
sender.sendMM(
"status: ${when (App.instance.enabled) {
State.ACTIVE -> "<green>active"
State.DISCONNECTED -> "<yellow>disconnected"
State.DISABLED -> "<red>disabled"
}}")
sender.sendMM(
"<gray>- <white>database test: ${if (Database.ping()) "success" else "failed"}")
sender.sendMM(
"<gray>- <white>config test: ${if (Config.config.getBoolean("enabled")) "enabled" else "disabled"}")
}
}
literal("register") {
executes {
val player = sender as? Player
if (player == null) {
sender.sendMM("This command is only available for players.")
return@executes
}
when (App.instance.enabled) {
State.DISABLED -> {
sender.sendMM("<red>[SMCDB] simplymcdb is disabled.<br>Run /smcdb check to check the status.")
return@executes
}
State.DISCONNECTED -> {
sender.sendMM("<red>[SMCDB] simplymcdb is enabled but disconnected.<br>Run /smcdb check to check the status.")
return@executes
}
else -> {}
}
if (!isRegistered(player.uniqueId)) {
sender.sendMM(
"<gray>[SMCDB] <red>The inventory of the other servers will be overwritten.<newline>" +
"Are you sure you want to register?<newline>" +
"<green>/smcdb confirm<gray> to confirm.")
commandBuffer[player.uniqueId] = "register"
} else {
sender.sendMM("<gray>[SMCDB] You are already registered.")
}
}
}
literal("confirm") {
executes {
val player = sender as? Player ?: return@executes
when (commandBuffer[player.uniqueId]) {
"register" -> {
if (App.instance.enabled == State.ACTIVE) {
register(player)
sender.sendMM("<gray>[SMCDB] Successfully registered.")
} else {
sender.sendMM("<red>[SMCDB] simplymcdb is disabled.")
}
}
else -> sender.sendMM("<red>[SMCDB] Invalid command.")
}
commandBuffer.remove(player.uniqueId)
}
}
}
}