Skip to content

Commit

Permalink
✨ support show mark on lectern
Browse files Browse the repository at this point in the history
  • Loading branch information
XiYang6666 committed Aug 8, 2024
1 parent 9cf0eac commit 329a372
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 69 deletions.
4 changes: 2 additions & 2 deletions src/main/kotlin/xyz/xasmc/hashbook/HashBook.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.bukkit.plugin.java.JavaPlugin
import xyz.xasmc.hashbook.command.HashBookCommand
import xyz.xasmc.hashbook.config.ConfigLoader
import xyz.xasmc.hashbook.config.PluginConfig
import xyz.xasmc.hashbook.listener.BookshelfListener
import xyz.xasmc.hashbook.listener.MarkListener
import xyz.xasmc.hashbook.listener.OpenBookListener
import xyz.xasmc.hashbook.service.ItemDataServices
import xyz.xasmc.hashbook.service.StorageServices
Expand All @@ -18,7 +18,7 @@ class HashBook : JavaPlugin() {
instance = this
this.load()

Bukkit.getPluginManager().registerEvents(BookshelfListener(), this)
Bukkit.getPluginManager().registerEvents(MarkListener(), this)
Bukkit.getPluginManager().registerEvents(OpenBookListener(), this)
HashBookCommand.create().register(this)
}
Expand Down
57 changes: 28 additions & 29 deletions src/main/kotlin/xyz/xasmc/hashbook/command/HashBookCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ 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
import org.bukkit.entity.Player
Expand All @@ -17,7 +16,7 @@ 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.MSG_TITLE
import xyz.xasmc.hashbook.util.MessageUtil.sendMiniMessage
import xyz.xasmc.hashbook.util.MessageUtil.shortHashMessage

Expand All @@ -26,9 +25,9 @@ object HashBookCommand {
val reloadCommand = CommandAPICommand("reload")
.withPermission("xasmc.hashbook.command.reload")
.executes(CommandExecutor { sender, _ ->
sender.sendMiniMessage("$msgTitle <dark_green>重新加载中")
sender.sendMiniMessage("$MSG_TITLE <dark_green>重新加载中")
HashBook.load()
sender.sendMiniMessage("$msgTitle <dark_green>重新加载完成")
sender.sendMiniMessage("$MSG_TITLE <dark_green>重新加载完成")
})

val calcHashCommand = CommandAPICommand("calcHash")
Expand All @@ -39,7 +38,7 @@ object HashBookCommand {
val bookMeta = item.itemMeta as BookMeta
val hash = BookUtil.generateHash(bookMeta)
val shortHashMsg = shortHashMessage(hash)
player.sendMiniMessage("$msgTitle <aqua>hash</aqua>: <green>$shortHashMsg")
player.sendMiniMessage("$MSG_TITLE <aqua>hash</aqua>: <green>$shortHashMsg")
})

val setHashCommand = CommandAPICommand("setHash")
Expand All @@ -54,9 +53,9 @@ object HashBookCommand {
ItemDataServices.setItemData(item, "HashBook.hash", ItemDataServices.DataType.String, newHash)
val oldShortHashMsg = shortHashMessage(oldHash)
val newShortHashMsg = shortHashMessage(newHash)
player.sendMiniMessage("$msgTitle <dark_green>已修改成书哈希")
player.sendMiniMessage("$msgTitle <aqua>old_hash</aqua>: <green>$oldShortHashMsg")
player.sendMiniMessage("$msgTitle <aqua>new_hash</aqua>: <green>$newShortHashMsg")
player.sendMiniMessage("$MSG_TITLE <dark_green>已修改成书哈希")
player.sendMiniMessage("$MSG_TITLE <aqua>old_hash</aqua>: <green>$oldShortHashMsg")
player.sendMiniMessage("$MSG_TITLE <aqua>new_hash</aqua>: <green>$newShortHashMsg")
})

val getPage = CommandAPICommand("getPage")
Expand All @@ -68,23 +67,23 @@ object HashBookCommand {
val realPage = page - 1
val data = StorageServices.read(hash) ?: run {
val shortHashMsg = shortHashMessage(hash)
sender.sendMiniMessage("$msgTitle <dark_green>未找到成书数据")
sender.sendMiniMessage("$msgTitle <aqua>hash</aqua>: <green>$shortHashMsg")
sender.sendMiniMessage("$MSG_TITLE <dark_green>未找到成书数据")
sender.sendMiniMessage("$MSG_TITLE <aqua>hash</aqua>: <green>$shortHashMsg")
return@CommandExecutor
}
val pageList = BookUtil.deserializePages(data)
if (pageList.isEmpty()) {
sender.sendMiniMessage("$msgTitle <dark_green>该成书没有书页")
sender.sendMiniMessage("$MSG_TITLE <dark_green>该成书没有书页")
return@CommandExecutor
}
if (pageList.size < page || page <= 0) {
sender.sendMiniMessage("$msgTitle <dark_green>错误的页码")
sender.sendMiniMessage("$MSG_TITLE <dark_green>错误的页码")
return@CommandExecutor
}

val shortHashMsg = shortHashMessage(hash)
val message = Component.text()
.append(MessageUtil.mm.deserialize("$msgTitle <dark_green>Book: <green>$shortHashMsg</green> Page $page</dark_green>\n"))
.append(MessageUtil.mm.deserialize("$MSG_TITLE <dark_green>Book: <green>$shortHashMsg</green> Page $page</dark_green>\n"))
.append(pageList[realPage])
sender.sendMessage(message)

Expand All @@ -99,18 +98,18 @@ object HashBookCommand {
val incompleteHash = args["incompleteHash"] as String
val searchResult = StorageServices.search(incompleteHash)
sender.sendMiniMessage(
if (searchResult.isEmpty()) "$msgTitle <dark_green>未搜索到结果"
else "$msgTitle <dark_green>搜索到 ${searchResult.size} 条结果"
if (searchResult.isEmpty()) "$MSG_TITLE <dark_green>未搜索到结果"
else "$MSG_TITLE <dark_green>搜索到 ${searchResult.size} 条结果"
)
searchResult.forEach { result ->
val pageList = BookUtil.deserializePages(result.second)
val totalPage = pageList.size
val shortHashMsg = shortHashMessage(result.first)
sender.sendMiniMessage("<light_purple>========================================")
sender.sendMiniMessage("$msgTitle <aqua>hash</aqua>: <green>$shortHashMsg")
sender.sendMiniMessage("$MSG_TITLE <aqua>hash</aqua>: <green>$shortHashMsg")
sender.sendMessage(
Component.text()
.append(MessageUtil.mm.deserialize("$msgTitle <aqua>content</aqua>:\n"))
.append(MessageUtil.mm.deserialize("$MSG_TITLE <aqua>content</aqua>:\n"))
.also { if (totalPage > 0) it.append(pageList.first()) }
)
sender.sendMessage(createPageBarMessage(result.first, 0, totalPage))
Expand All @@ -123,7 +122,7 @@ object HashBookCommand {
val player = checkPlayer(sender) ?: return@CommandExecutor
val (item, hand) = checkWrittenBook(player) ?: return@CommandExecutor
BookUtil.storeBook(item, player, hand)
player.sendMiniMessage("$msgTitle <dark_green>完成")
player.sendMiniMessage("$MSG_TITLE <dark_green>完成")
})

val bookInfoCommand = CommandAPICommand("bookInfo")
Expand All @@ -139,13 +138,13 @@ object HashBookCommand {
item, "HashBook.Hash", ItemDataServices.DataType.String
) ?: "<null>"

Bukkit.getLogger().info(hash.javaClass.name)
HashBook.instance.logger.info(hash.javaClass.name)

val shortHashMsg = shortHashMessage(hash)
player.sendMiniMessage("$msgTitle <blue>HashBook Book Info")
player.sendMiniMessage("$msgTitle <aqua>title</aqua>: <green>$title")
player.sendMiniMessage("$msgTitle <aqua>author</aqua>: <green>$author")
player.sendMiniMessage("$msgTitle <aqua>hash</aqua>: <green>$shortHashMsg")
player.sendMiniMessage("$MSG_TITLE <blue>HashBook Book Info")
player.sendMiniMessage("$MSG_TITLE <aqua>title</aqua>: <green>$title")
player.sendMiniMessage("$MSG_TITLE <aqua>author</aqua>: <green>$author")
player.sendMiniMessage("$MSG_TITLE <aqua>hash</aqua>: <green>$shortHashMsg")
})

val command = CommandAPICommand("hashbook")
Expand All @@ -160,12 +159,12 @@ object HashBookCommand {
bookInfoCommand
)
.executes(CommandExecutor { sender, _ ->
sender.sendMiniMessage("$msgTitle HashBook is Running!")
sender.sendMiniMessage("$msgTitle <aqua>debug</aqua>: <green>${HashBook.config.debug}")
sender.sendMiniMessage("$msgTitle <aqua>storage_mode</aqua>: <green>${HashBook.config.storageMode}")
sender.sendMiniMessage("$msgTitle <aqua>item_data_mode</aqua>: <green>${HashBook.config.itemDataMode}")
sender.sendMiniMessage("$msgTitle <aqua>set_lore</aqua>: <green>${HashBook.config.setLore}")
sender.sendMiniMessage("$msgTitle <aqua>lore_content</aqua>: <i><green>${HashBook.config.loreContent}</i>")
sender.sendMiniMessage("$MSG_TITLE HashBook is Running!")
sender.sendMiniMessage("$MSG_TITLE <aqua>debug</aqua>: <green>${HashBook.config.debug}")
sender.sendMiniMessage("$MSG_TITLE <aqua>storage_mode</aqua>: <green>${HashBook.config.storageMode}")
sender.sendMiniMessage("$MSG_TITLE <aqua>item_data_mode</aqua>: <green>${HashBook.config.itemDataMode}")
sender.sendMiniMessage("$MSG_TITLE <aqua>set_lore</aqua>: <green>${HashBook.config.setLore}")
sender.sendMiniMessage("$MSG_TITLE <aqua>lore_content</aqua>: <i><green>${HashBook.config.loreContent}</i>")
})

return command
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
package xyz.xasmc.hashbook.listener

import org.bukkit.Material
import org.bukkit.block.Block
import org.bukkit.block.ChiseledBookshelf
import org.bukkit.block.Lectern
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerMoveEvent
import org.bukkit.event.player.PlayerQuitEvent
import org.bukkit.inventory.meta.BookMeta
import org.bukkit.inventory.meta.EnchantmentStorageMeta
import xyz.xasmc.hashbook.util.I18nUtil
import org.bukkit.util.Vector
import xyz.xasmc.hashbook.util.BookUtil
import xyz.xasmc.hashbook.util.MarkUtil


class BookshelfListener : Listener {
class MarkListener : Listener {


@EventHandler
fun onPlayerMode(event: PlayerMoveEvent) {
fun onPlayerMove(event: PlayerMoveEvent) {
val player = event.player
val world = player.world
val direction = player.eyeLocation.direction
val maxDistance = 4.0
val result = player.world.rayTraceBlocks(player.eyeLocation, direction, maxDistance)
Expand All @@ -32,10 +33,16 @@ class BookshelfListener : Listener {
return
}
val hitPosition = result.hitPosition
if (hitBlock.type != Material.CHISELED_BOOKSHELF) {
MarkUtil.removeMark(player)
return
when (hitBlock.type) {
Material.CHISELED_BOOKSHELF -> updateChiseledBookshelfMark(hitBlock, hitPosition, player)
Material.LECTERN -> updateLecternMark(hitBlock, player)

else -> MarkUtil.removeMark(player)
}
}

private fun updateChiseledBookshelfMark(hitBlock: Block, hitPosition: Vector, player: Player) {
val world = player.world
val bookshelf = hitBlock.state as ChiseledBookshelf
val blockHitPosition = hitPosition.clone().subtract(hitBlock.location.toVector())
val item = bookshelf.inventory.getItem(bookshelf.getSlot(blockHitPosition))
Expand All @@ -45,25 +52,23 @@ class BookshelfListener : Listener {
}
val normalizedEyeDirection = player.eyeLocation.direction.clone().normalize()
val markLocation = hitPosition.clone().subtract(normalizedEyeDirection.multiply(0.1))
val nameSb = StringBuilder(I18nUtil.translate(item.type))
when (item.type) {
Material.WRITTEN_BOOK -> {
val meta = item.itemMeta as BookMeta
nameSb.append("\n").append(meta.title)
nameSb.append("\n<gray>").append(I18nUtil.getTranslate("book.byAuthor").format(meta.author))
nameSb.append("\n<gray>").append(I18nUtil.translate(meta.generation))
}

Material.ENCHANTED_BOOK -> {
val meta = item.itemMeta as EnchantmentStorageMeta
meta.storedEnchants.forEach {
nameSb.append("\n<gray>").append(I18nUtil.translate(it.key, it.value))
}
}
val abstract = BookUtil.getAbstract(item)
MarkUtil.updateMark(player, markLocation.toLocation(world), abstract)
}

else -> {}
private fun updateLecternMark(hitBlock: Block, player: Player) {
val lectern = hitBlock.state as Lectern
val item = lectern.inventory.getItem(0)
if (item == null) {
MarkUtil.removeMark(player)
return
}
MarkUtil.updateMark(player, markLocation.toLocation(world), nameSb.toString())
val markLocation = hitBlock.location.clone()
markLocation.x += 0.5
markLocation.y += 1.5
markLocation.z += 0.5
val abstract = BookUtil.getAbstract(item)
MarkUtil.updateMark(player, markLocation, abstract)
}

@EventHandler
Expand Down
44 changes: 34 additions & 10 deletions src/main/kotlin/xyz/xasmc/hashbook/util/BookUtil.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package xyz.xasmc.hashbook.util

import net.kyori.adventure.text.Component
import org.bukkit.Material
import org.bukkit.entity.Player
import org.bukkit.inventory.EquipmentSlot
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.BookMeta
import org.bukkit.inventory.meta.EnchantmentStorageMeta
import org.json.simple.JSONArray
import org.json.simple.parser.JSONParser
import xyz.xasmc.hashbook.HashBook
import xyz.xasmc.hashbook.service.ItemDataServices
import xyz.xasmc.hashbook.service.StorageServices
import xyz.xasmc.hashbook.util.MessageUtil.debugMiniMessage
import xyz.xasmc.hashbook.util.MessageUtil.msgTitle
import xyz.xasmc.hashbook.util.MessageUtil.MSG_TITLE
import xyz.xasmc.hashbook.util.MessageUtil.sendMiniMessage
import xyz.xasmc.hashbook.util.MessageUtil.shortHashMessage
import java.util.*
Expand Down Expand Up @@ -68,17 +70,17 @@ object BookUtil {
}

val serialized = serializePages(bookMeta.pages())
val hash = HashUtil.HashString(serialized)
val hash = HashUtil.hashString(serialized)
StorageServices.save(hash, serialized)
val shortHashMsg = shortHashMessage(hash)
player.debugMiniMessage("$msgTitle <aqua>[debug]<dark_green>已存储成书书页</dark_green>")
player.debugMiniMessage("$msgTitle <aqua>[debug]<aqua>hash</aqua>: <green>$shortHashMsg")
player.debugMiniMessage("$msgTitle <aqua>[debug]<aqua>meta</aqua>: <green>$bookMeta")
player.debugMiniMessage("$MSG_TITLE <aqua>[debug]<dark_green>已存储成书书页</dark_green>")
player.debugMiniMessage("$MSG_TITLE <aqua>[debug]<aqua>hash</aqua>: <green>$shortHashMsg")
player.debugMiniMessage("$MSG_TITLE <aqua>[debug]<aqua>meta</aqua>: <green>$bookMeta")

newItem = ItemDataServices.setItemData(
newItem, "HashBook.Hash", ItemDataServices.DataType.String, hash
) ?: run {
player.sendMiniMessage("$msgTitle <yellow>[warn] 写入哈希失败")
player.sendMiniMessage("$MSG_TITLE <yellow>[warn] 写入哈希失败")
return false
}
setHash = true
Expand All @@ -88,16 +90,38 @@ object BookUtil {
EquipmentSlot.HAND -> player.inventory.setItemInMainHand(newItem)
EquipmentSlot.OFF_HAND -> player.inventory.setItemInOffHand(newItem)
else -> return run {
player.sendMiniMessage("$msgTitle <yellow>[warn] 错误的装备槽")
player.sendMiniMessage("$MSG_TITLE <yellow>[warn] 错误的装备槽")
false
}
}

when (Pair(cleanedPages, setHash)) {
Pair(true, true) -> player.sendMiniMessage("$msgTitle <dark_green>已清除书页并记录哈希值")
Pair(false, true) -> player.sendMiniMessage("$msgTitle <dark_green>已记录哈希值")
Pair(true, false) -> player.sendMiniMessage("$msgTitle <dark_green>已清除书页")
Pair(true, true) -> player.sendMiniMessage("$MSG_TITLE <dark_green>已清除书页并记录哈希值")
Pair(false, true) -> player.sendMiniMessage("$MSG_TITLE <dark_green>已记录哈希值")
Pair(true, false) -> player.sendMiniMessage("$MSG_TITLE <dark_green>已清除书页")
}
return true
}

fun getAbstract(item: ItemStack): String {
val nameSb = StringBuilder(I18nUtil.translate(item.type))
when (item.type) {
Material.WRITTEN_BOOK -> {
val meta = item.itemMeta as BookMeta
nameSb.append("\n").append(meta.title)
nameSb.append("\n<gray>").append(I18nUtil.getTranslate("book.byAuthor").format(meta.author))
nameSb.append("\n<gray>").append(I18nUtil.translate(meta.generation))
}

Material.ENCHANTED_BOOK -> {
val meta = item.itemMeta as EnchantmentStorageMeta
meta.storedEnchants.forEach {
nameSb.append("\n<gray>").append(I18nUtil.translate(it.key, it.value))
}
}

else -> {}
}
return nameSb.toString()
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/xyz/xasmc/hashbook/util/HashUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object HashUtil {
val md = MessageDigest.getInstance("SHA-256")

@OptIn(ExperimentalStdlibApi::class)
fun HashString(str: String): String {
fun hashString(str: String): String {
return md.digest(str.toByteArray()).toHexString()
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/xyz/xasmc/hashbook/util/MessageUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.bukkit.entity.Player
import xyz.xasmc.hashbook.HashBook

object MessageUtil {
val msgTitle = "<dark_aqua>[HashBook]</dark_aqua>"
const val MSG_TITLE = "<dark_aqua>[HashBook]</dark_aqua>"
val mm = MiniMessage.miniMessage()

fun copyMsg(message: String, copy: String, hover: String? = null): String {
Expand Down

0 comments on commit 329a372

Please sign in to comment.