diff --git a/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/command/SyncCommand.kt b/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/command/SyncCommand.kt index 6a80a41..c66f6ca 100644 --- a/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/command/SyncCommand.kt +++ b/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/command/SyncCommand.kt @@ -1,21 +1,38 @@ package com.aiyostudio.esync.internal.command +import com.aiyostudio.esync.common.repository.IRepository import com.aiyostudio.esync.internal.config.SyncConfig +import com.aiyostudio.esync.internal.handler.ModuleHandler +import com.aiyostudio.esync.internal.handler.RepositoryHandler import com.aiyostudio.esync.internal.i18n.I18n +import com.aiyostudio.esync.internal.module.entity.EnderChestEntity +import com.aiyostudio.esync.internal.module.entity.PlayerInventoryEntity import com.aiyostudio.esync.internal.plugin.EfficientSyncBukkit +import com.aiyostudio.esync.internal.util.LoggerUtil +import com.aiyostudio.esync.internal.view.EnderChestView +import com.aiyostudio.esync.internal.view.InventoryView import org.bukkit.Bukkit import org.bukkit.command.Command import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender +import org.bukkit.entity.Player +import java.lang.Exception +import java.util.UUID class SyncCommand : CommandExecutor { private val plugin = EfficientSyncBukkit.instance override fun onCommand(sender: CommandSender, cmd: Command, label: String, params: Array): Boolean { - if (!sender.hasPermission("esync.admin") || params.size < 1) return false + if (!sender.hasPermission("esync.admin")) return false + if (params.isEmpty()) { + I18n.getArrayOption("commands").forEach { sender.sendMessage(it.replace("%c", label)) } + return false + } when (params[0].lowercase()) { "kickall" -> this.kickAll(sender) "reload" -> this.reload(sender) + "inv" -> this.view("inventory", sender, params) + "ender" -> this.view("enderchest", sender, params) } return false } @@ -26,7 +43,64 @@ class SyncCommand : CommandExecutor { } private fun reload(sender: CommandSender) { + LoggerUtil.printHeader() SyncConfig.init() + LoggerUtil.printFooter() sender.sendMessage(I18n.getStrAndHeader("reload")) } + + private fun view(type: String, sender: CommandSender, params: Array) { + if (sender !is Player) return + if (params.size == 1) { + sender.sendMessage(I18n.getStrAndHeader("params.enter-uuid")) + return + } + val repo = RepositoryHandler.repository ?: let { + sender.sendMessage(I18n.getStrAndHeader("repo-failure")) + return + } + try { + val uuid = UUID.fromString(params[1]) + when (type) { + "inventory" -> this.viewInv(uuid, sender, repo) + "enderchest" -> this.viewEnderChest(uuid, sender, repo) + } + } catch (e: Exception) { + sender.sendMessage(I18n.getStrAndHeader("params.uuid-failure")) + } + } + + private fun viewInv(target: UUID, sender: Player, repo: IRepository) { + val module = ModuleHandler.findByKey("inventory") ?: let { + sender.sendMessage(I18n.getStrAndHeader("module-failure")) + return + } + val result = repo.queryData(target, "inventory") ?: let { + sender.sendMessage(I18n.getStrAndHeader("empty-data")) + return + } + if (result.isEmpty()) { + sender.sendMessage(I18n.getStrAndHeader("empty-data")) + return + } + val entity = module.wrapper(result) as PlayerInventoryEntity + InventoryView(sender, entity) + } + + private fun viewEnderChest(target: UUID, sender: Player, repo: IRepository) { + val module = ModuleHandler.findByKey("ender-chest") ?: let { + sender.sendMessage(I18n.getStrAndHeader("module-failure")) + return + } + val result = repo.queryData(target, "ender-chest") ?: let { + sender.sendMessage(I18n.getStrAndHeader("empty-data")) + return + } + if (result.isEmpty()) { + sender.sendMessage(I18n.getStrAndHeader("empty-data")) + return + } + val entity = module.wrapper(result) as EnderChestEntity + EnderChestView(sender, entity) + } } \ No newline at end of file diff --git a/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/util/TextUtil.kt b/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/util/TextUtil.kt new file mode 100644 index 0000000..2200758 --- /dev/null +++ b/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/util/TextUtil.kt @@ -0,0 +1,17 @@ +package com.aiyostudio.esync.internal.util + +import org.bukkit.ChatColor +import org.bukkit.configuration.ConfigurationSection + +object TextUtil { + + fun String.colorify(): String { + return ChatColor.translateAlternateColorCodes('&', this) + } + + fun ConfigurationSection.getColorifyStringList(key: String): MutableList { + return this.getStringList(key).apply { + this.replaceAll { ChatColor.translateAlternateColorCodes('&', it) } + } + } +} \ No newline at end of file diff --git a/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/view/EnderChestView.kt b/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/view/EnderChestView.kt new file mode 100644 index 0000000..8d293c0 --- /dev/null +++ b/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/view/EnderChestView.kt @@ -0,0 +1,44 @@ +package com.aiyostudio.esync.internal.view + +import com.aiyostudio.esync.internal.module.entity.EnderChestEntity +import com.aiyostudio.esync.internal.plugin.EfficientSyncBukkit +import com.aiyostudio.esync.internal.util.TextUtil.colorify +import com.aiyostudio.esync.internal.util.TextUtil.getColorifyStringList +import com.aystudio.core.bukkit.util.common.CommonUtil +import com.aystudio.core.bukkit.util.inventory.GuiModel +import org.bukkit.Material +import org.bukkit.configuration.file.YamlConfiguration +import org.bukkit.entity.Player +import org.bukkit.inventory.ItemStack + +class EnderChestView( + val player: Player, + val entity: EnderChestEntity +) { + private lateinit var gui: GuiModel + + init { + EfficientSyncBukkit.instance.saveResource("view/enderChest.yml", "view/enderChest.yml", false) { + val data = YamlConfiguration.loadConfiguration(it) + this.gui = GuiModel(data.getString("title"), data.getInt("size")) + this.gui.registerListener(EfficientSyncBukkit.instance) + data.getConfigurationSection("items")?.getKeys(false)?.forEach { key -> + val section = data.getConfigurationSection("items.$key") + val item = ItemStack( + Material.valueOf(section.getString("type").uppercase()), + section.getInt("amount"), + section.getInt("data").toShort() + ) + val meta = item.itemMeta + meta.displayName = section.getString("name").colorify() + meta.lore = section.getColorifyStringList("lore") + item.setItemMeta(meta) + CommonUtil.formatSlots(section.getString("slot")).forEach { slot -> this.gui.setItem(slot, item) } + } + val contentSlots = CommonUtil.formatSlots(data.getString("contents")) + contentSlots.forEach { slot -> slot.takeIf { it < 27 }?.let { this.gui.setItem(it, entity.items.get(it)) } } + this.gui.execute { it.isCancelled = true } + this.gui.openInventory(player) + } + } +} \ No newline at end of file diff --git a/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/view/InventoryView.kt b/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/view/InventoryView.kt new file mode 100644 index 0000000..f8f89de --- /dev/null +++ b/bukkit/src/main/kotlin/com/aiyostudio/esync/internal/view/InventoryView.kt @@ -0,0 +1,55 @@ +package com.aiyostudio.esync.internal.view + +import com.aiyostudio.esync.internal.module.entity.PlayerInventoryEntity +import com.aiyostudio.esync.internal.plugin.EfficientSyncBukkit +import com.aiyostudio.esync.internal.util.TextUtil.colorify +import com.aiyostudio.esync.internal.util.TextUtil.getColorifyStringList +import com.aystudio.core.bukkit.util.common.CommonUtil +import com.aystudio.core.bukkit.util.inventory.GuiModel +import org.bukkit.Material +import org.bukkit.configuration.file.YamlConfiguration +import org.bukkit.entity.Player +import org.bukkit.inventory.ItemStack + +class InventoryView( + val player: Player, + val entity: PlayerInventoryEntity +) { + private lateinit var gui: GuiModel + + init { + EfficientSyncBukkit.instance.saveResource("view/inventory.yml", "view/inventory.yml", false) { + val data = YamlConfiguration.loadConfiguration(it) + this.gui = GuiModel(data.getString("title"), data.getInt("size")) + this.gui.registerListener(EfficientSyncBukkit.instance) + data.getConfigurationSection("items")?.getKeys(false)?.forEach { key -> + val section = data.getConfigurationSection("items.$key") + val item = ItemStack( + Material.valueOf(section.getString("type").uppercase()), + section.getInt("amount"), + section.getInt("data").toShort() + ) + val meta = item.itemMeta + meta.displayName = section.getString("name").colorify() + meta.lore = section.getColorifyStringList("lore") + item.setItemMeta(meta) + CommonUtil.formatSlots(section.getString("slot")).forEach { slot -> this.gui.setItem(slot, item) } + } + val contentSlots = CommonUtil.formatSlots(data.getString("contents")) + (0 until 36).forEach { slot -> + if (slot < contentSlots.size && entity.inventory.containsKey(slot)) { + this.gui.setItem(contentSlots[slot], entity.inventory.get(slot)) + } + } + val armorSlots = CommonUtil.formatSlots(data.getString("armor")) + (36 until 41).forEach { slot -> + val finalIndex = slot - 36 + if (finalIndex < armorSlots.size && entity.inventory.containsKey(slot)) { + this.gui.setItem(armorSlots[finalIndex], entity.inventory.get(slot)) + } + } + this.gui.execute { it.isCancelled = true } + this.gui.openInventory(player) + } + } +} \ No newline at end of file diff --git a/bukkit/src/main/resources/language/zh_CN.yml b/bukkit/src/main/resources/language/zh_CN.yml index 79f71ad..0b0a37d 100644 --- a/bukkit/src/main/resources/language/zh_CN.yml +++ b/bukkit/src/main/resources/language/zh_CN.yml @@ -1,9 +1,24 @@ prefix: "&beSync&f " +commands: + - "&6eSync" + - "&e/%c kickAll &f踢出全部玩家(触发保存)" + - "&e/%c inv &f查看玩家背包数据" + - "&e/%c ender &f查看玩家末影箱" + - "&e/%c reload &f重载插件配置" + +params: + enter-uuid: "请输入玩家UUID." + uuid-failure: "请输入正确的UUID." + sync: success: "数据同步完成." failed: "数据同步失败." kick-all: reason: "&e服务器维护." message: "已将全部玩家踢出服务器." -reload: "插件配置重载完成." \ No newline at end of file +reload: "插件配置重载完成." + +repo-failure: "没有找到可用的数据同步源." +module-failure: "没有找到可用的数据模块." +empty-data: "没有找到玩家数据." \ No newline at end of file diff --git a/bukkit/src/main/resources/view/enderChest.yml b/bukkit/src/main/resources/view/enderChest.yml new file mode 100644 index 0000000..f65e211 --- /dev/null +++ b/bukkit/src/main/resources/view/enderChest.yml @@ -0,0 +1,11 @@ +title: "&8玩家末影箱预览" +size: 27 +contents: 0-26 +items: + panel: + type: STAINED_GLASS_PANE + amount: 1 + data: 15 + name: "&f" + lore: [ ] + slot: 0,1,6,8-17 \ No newline at end of file diff --git a/bukkit/src/main/resources/view/inventory.yml b/bukkit/src/main/resources/view/inventory.yml new file mode 100644 index 0000000..5c56b8f --- /dev/null +++ b/bukkit/src/main/resources/view/inventory.yml @@ -0,0 +1,12 @@ +title: "&8玩家背包预览" +size: 54 +contents: 18-53 +armor: 2,3,4,5,7 +items: + panel: + type: STAINED_GLASS_PANE + amount: 1 + data: 15 + name: "&f" + lore: [ ] + slot: 0,1,6,8-17 \ No newline at end of file