diff --git a/src/main/kotlin/xyz/xasmc/hashbook/command/HashBookCommand.kt b/src/main/kotlin/xyz/xasmc/hashbook/command/HashBookCommand.kt index 8b35c2e..e8cf4d5 100644 --- a/src/main/kotlin/xyz/xasmc/hashbook/command/HashBookCommand.kt +++ b/src/main/kotlin/xyz/xasmc/hashbook/command/HashBookCommand.kt @@ -1,8 +1,10 @@ package xyz.xasmc.hashbook.command import dev.jorel.commandapi.CommandAPICommand +import dev.jorel.commandapi.arguments.IntegerArgument import dev.jorel.commandapi.arguments.StringArgument import dev.jorel.commandapi.executors.CommandExecutor +import net.kyori.adventure.text.Component import org.bukkit.Bukkit import org.bukkit.Material import org.bukkit.command.CommandSender @@ -14,6 +16,7 @@ import xyz.xasmc.hashbook.HashBook import xyz.xasmc.hashbook.service.ItemDataServices import xyz.xasmc.hashbook.service.StorageServices import xyz.xasmc.hashbook.util.BookUtil +import xyz.xasmc.hashbook.util.MessageUtil import xyz.xasmc.hashbook.util.MessageUtil.msgTitle import xyz.xasmc.hashbook.util.MessageUtil.sendMiniMessage import xyz.xasmc.hashbook.util.MessageUtil.shortHashMessage @@ -56,22 +59,64 @@ object HashBookCommand { player.sendMiniMessage("$msgTitle new_hash: $newShortHashMsg") }) + val getPage = CommandAPICommand("getPage") + .withPermission("xasmc.hashbook.command.getpage") + .withArguments(StringArgument("hash"), IntegerArgument("page")) + .executes(CommandExecutor { sender, args -> + val hash = args["hash"] as String + val page = args["page"] as Int + val realPage = page - 1 + val data = StorageServices.read(hash) ?: run { + val shortHashMsg = shortHashMessage(hash) + sender.sendMiniMessage("$msgTitle 未找到成书数据") + sender.sendMiniMessage("$msgTitle hash: $shortHashMsg") + return@CommandExecutor + } + val pageList = BookUtil.deserializePages(data) + if (pageList.isEmpty()) { + sender.sendMiniMessage("$msgTitle 该成书没有书页") + return@CommandExecutor + } + if (pageList.size < page || page <= 0) { + sender.sendMiniMessage("$msgTitle 错误的页码") + return@CommandExecutor + } + + val shortHashMsg = shortHashMessage(hash) + val message = Component.text() + .append(MessageUtil.mm.deserialize("$msgTitle Book: $shortHashMsg Page $page\n")) + .append(pageList[realPage]) + sender.sendMessage(message) + + val pageBarMessage = createPageBarMessage(hash, realPage, pageList.size) + sender.sendMessage(pageBarMessage) + }) + val searchBookCommand = CommandAPICommand("searchBook") .withPermission("xasmc.hashbook.command.searchbook") .withArguments(StringArgument("incompleteHash")) .executes(CommandExecutor { sender, args -> val incompleteHash = args["incompleteHash"] as String - sender.sendMiniMessage("$msgTitle 搜索到以下结果") - StorageServices.search(incompleteHash).forEach { - val shortHashMsg = shortHashMessage(it.first) - sender.sendMiniMessage("==============================") + val searchResult = StorageServices.search(incompleteHash) + sender.sendMiniMessage( + if (searchResult.isEmpty()) "$msgTitle 未搜索到结果" + else "$msgTitle 搜索到 ${searchResult.size} 条结果" + ) + searchResult.forEach { result -> + val pageList = BookUtil.deserializePages(result.second) + val totalPage = pageList.size + val shortHashMsg = shortHashMessage(result.first) + sender.sendMiniMessage("========================================") sender.sendMiniMessage("$msgTitle hash: $shortHashMsg") - sender.sendMiniMessage("$msgTitle content:") - sender.sendMiniMessage(it.second) + sender.sendMessage( + Component.text() + .append(MessageUtil.mm.deserialize("$msgTitle content:\n")) + .also { if (totalPage > 0) it.append(pageList.first()) } + ) + sender.sendMessage(createPageBarMessage(result.first, 0, totalPage)) } }) - val storeBookCommand = CommandAPICommand("storeBook") .withPermission("xasmc.hashbook.command.storebook") .executes(CommandExecutor { sender, args -> @@ -109,6 +154,7 @@ object HashBookCommand { reloadCommand, calcHashCommand, setHashCommand, + getPage, searchBookCommand, storeBookCommand, bookInfoCommand @@ -144,4 +190,48 @@ object HashBookCommand { return pair } + private fun generatePageRange(page: Int, total: Int, side: Int = 3): Pair, Pair> { + var start = (page - side).coerceAtMost(total - 1 - 2 * side).coerceAtLeast(0) + var end = (page + 1 + side).coerceAtLeast(2 * side + 1).coerceAtMost(total) + val first = start > 0 + val last = end < total - 1 + if (first) start++ + if (last) end-- + return Pair(Pair(first, last), Pair(start, end)) + } + + private fun createPageBarMessage(hash: String, page: Int, total: Int, side: Int = 3): Component { + val prevPageStr = + "上一页'>< " + val nextPageStr = + "下一页'>> " + val noPrevPageStr = "没有上一页'>< " + val noNextPageStr = "没有下一页'>> " + + val createPageCodeStr = { i: Int, underline: Boolean -> + val str = if (underline) "${i + 1}" else "${i + 1}" + "页码${i + 1}'>$str" + } + + val pageBarSB = StringBuilder() + + pageBarSB.append(if (page == 0) noPrevPageStr else prevPageStr) + pageBarSB.append("Page ${page + 1}/${total} ") + pageBarSB.append(if (page == total - 1) noNextPageStr else nextPageStr) + + val (firstAndLast, startAndEnd) = generatePageRange(page, total, side) + val (first, last) = firstAndLast + val (start, end) = startAndEnd + pageBarSB.append("(") + if (first) pageBarSB.append(createPageCodeStr(0, false)).append(" ... ") + for (i in start until end) { + if (i != start) pageBarSB.append(" | ") + pageBarSB.append(createPageCodeStr(i, i == page)) + } + if (last) pageBarSB.append(" ... ").append(createPageCodeStr(total - 1, false)) + pageBarSB.append(")") + + val pageBarMessage = pageBarSB.toString() + return MessageUtil.mm.deserialize(pageBarMessage) + } } \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 392320f..c042137 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -9,9 +9,19 @@ softdepend: - NBTAPI permissions: - "xasmc.hashbook.command.sethash": - default: op + "xasmc.hashbook.command.hashbook": + default: not op "xasmc.hashbook.command.reload": default: op + "xasmc.hashbook.command.calchash": + default: not op + "xasmc.hashbook.command.sethash": + default: op + "xasmc.hashbook.command.getpage": + default: not op "xasmc.hashbook.command.searchbook": - default: op \ No newline at end of file + default: not op + "xasmc.hashbook.command.storebook": + default: not op + "xasmc.hashbook.command.bookinfo": + default: not op