diff --git a/build.gradle.kts b/build.gradle.kts index 6e0eff7..0ba6120 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,6 +21,7 @@ taboolib { install("module-ui") install("module-nms-util") install("module-nms") + install("module-kether") install("platform-bukkit") install("expansion-command-helper") classifier = null @@ -31,7 +32,7 @@ taboolib { repositories { mavenCentral() - maven("https://repo.xbaimiao.com/nexus/content/repositories/releases/") + maven("https://maven.xbaimiao.com/repository/maven-public/") } dependencies { @@ -41,6 +42,7 @@ dependencies { compileOnly("public:points:1.0.0") compileOnly("ink.ptms.core:v11902:11902-minimize:mapped") compileOnly("ink.ptms.core:v11902:11902-minimize:universal") + compileOnly("public:Zaphkiel:1.0.0") taboo(kotlin("stdlib")) compileOnly(fileTree("libs")) } diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/Item.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/Item.kt index 6b43abf..fa503b8 100644 --- a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/Item.kt +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/Item.kt @@ -10,11 +10,6 @@ import org.bukkit.inventory.ItemStack import org.bukkit.permissions.Permission import taboolib.module.chat.colored -interface ItemLoader { - val prefix: String? - fun formSection(char: Char, section: ConfigurationSection, shop: Shop): Item - -} interface Item { diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/ItemLoader.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/ItemLoader.kt new file mode 100644 index 0000000..afc06ac --- /dev/null +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/ItemLoader.kt @@ -0,0 +1,45 @@ +package com.github.xbaimiao.shoppro.core.item + +import com.github.xbaimiao.shoppro.core.shop.Shop +import com.github.xbaimiao.shoppro.core.vault.Currency +import com.github.xbaimiao.shoppro.core.vault.CurrencyType +import com.github.xbaimiao.shoppro.core.vault.VaultImpl +import org.bukkit.Material +import org.bukkit.configuration.ConfigurationSection +import taboolib.library.xseries.parseToMaterial +import taboolib.module.chat.colored + +abstract class ItemLoader { + + abstract val prefix: String? + abstract fun formSection(char: Char, section: ConfigurationSection, shop: Shop): Item + + open fun parseToMaterial(section: ConfigurationSection): Material { + return section.getString("material")!!.parseToMaterial() + } + + fun ConfigurationSection.toItemSetting(char: Char, shop: Shop): ShopItem.ItemSetting { + var currency: Currency = VaultImpl + this.getString("currency")?.let { + currency = CurrencyType.formString(it).func.invoke(it) + } + return ShopItem.ItemSetting( + key = char, + material = parseToMaterial(this), + name = this.getString("name")!!.colored(), + lore = this.getStringList("lore").colored(), + vanilla = this.getBoolean("vanilla", true), + commands = this.getStringList("commands"), + shop = shop, + script = this.getString("condition"), + price = this.getDouble("price"), + limitServer = this.getLong("limit"), + limitPlayer = this.getLong("limit-player"), + currency = currency, + conditionIcon = this.getString("condition-icon")?.parseToMaterial(), + conditionLore = this.getStringList("condition-lore"), + conditionName = this.getString("condition-name"), + ) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/KetherCondition.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/KetherCondition.kt new file mode 100644 index 0000000..c320c57 --- /dev/null +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/KetherCondition.kt @@ -0,0 +1,40 @@ +package com.github.xbaimiao.shoppro.core.item + +import com.github.xbaimiao.shoppro.util.KetherUtil +import com.github.xbaimiao.shoppro.util.Util.replacePapi +import org.bukkit.Material +import org.bukkit.entity.Player +import org.bukkit.inventory.ItemStack +import taboolib.module.chat.colored + +/** + * @author 小白 + * @date 2023/5/10 09:43 + **/ +interface KetherCondition { + + val conditionScript: String? + val conditionIcon: Material? + val conditionLore: List + val conditionName: String? + + fun check(player: Player): Boolean { + if (conditionScript == null) { + return true + } + return KetherUtil.instantKether(player, conditionScript!!).asBoolean(false) + } + + fun conditionItem(player: Player): ItemStack { + if (conditionIcon == null || conditionName == null) { + return ItemStack(Material.AIR) + } + return taboolib.platform.util.buildItem(conditionIcon!!) { + name = conditionName!!.colored().replacePapi(player) + conditionLore.forEach { + lore += it.colored().replacePapi(player) + } + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/ShopItem.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/ShopItem.kt index 0852e7e..d4484c3 100644 --- a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/ShopItem.kt +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/ShopItem.kt @@ -3,26 +3,72 @@ package com.github.xbaimiao.shoppro.core.item import com.github.xbaimiao.shoppro.ShopPro import com.github.xbaimiao.shoppro.core.shop.Shop import com.github.xbaimiao.shoppro.core.vault.Currency -import com.github.xbaimiao.shoppro.core.vault.VaultImpl import com.github.xbaimiao.shoppro.util.Util.format import com.github.xbaimiao.shoppro.util.Util.howManyItems import com.github.xbaimiao.shoppro.util.Util.replacePapi +import org.bukkit.Material import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack import taboolib.platform.util.modifyLore -abstract class ShopItem : Item { +abstract class ShopItem( + override val key: Char, + override val material: Material, + override val name: String, + override val lore: List, + override val vanilla: Boolean, + override val commands: List, + override val shop: Shop, + override val conditionScript: String?, + override val conditionIcon: Material?, + override val conditionLore: List, + override val conditionName: String?, + val price: Double, + val limitServer: Long, + val limitPlayer: Long, + val currency: Currency +) : Item, KetherCondition { - abstract val price: Double - abstract val limitServer: Long - abstract val limitPlayer: Long + constructor(itemSetting: ItemSetting) : this( + itemSetting.key, + itemSetting.material, + itemSetting.name, + itemSetting.lore, + itemSetting.vanilla, + itemSetting.commands, + itemSetting.shop, + itemSetting.script, + itemSetting.conditionIcon, + itemSetting.conditionLore, + itemSetting.conditionName, + itemSetting.price, + itemSetting.limitServer, + itemSetting.limitPlayer, + itemSetting.currency + ) + + class ItemSetting( + val key: Char, + val material: Material, + val name: String, + val lore: List, + val vanilla: Boolean, + val commands: List, + val shop: Shop, + val script: String?, + val conditionIcon: Material?, + val conditionLore: List, + val conditionName: String?, + val price: Double, + val limitServer: Long, + val limitPlayer: Long, + var currency: Currency + ) override fun isCommodity(): Boolean { return true } - var currency: Currency = VaultImpl - abstract fun vanillaItem(): ItemStack abstract fun equal(itemStack: ItemStack): Boolean diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/HeadShopItem.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/HeadShopItem.kt index 0944f9a..6e41762 100644 --- a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/HeadShopItem.kt +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/HeadShopItem.kt @@ -4,29 +4,19 @@ import com.github.xbaimiao.shoppro.core.item.Item import com.github.xbaimiao.shoppro.core.item.ItemLoader import com.github.xbaimiao.shoppro.core.item.ShopItem import com.github.xbaimiao.shoppro.core.shop.Shop -import com.github.xbaimiao.shoppro.core.vault.CurrencyType import org.bukkit.Material import org.bukkit.configuration.ConfigurationSection import org.bukkit.inventory.ItemStack import taboolib.library.xseries.XMaterial import taboolib.library.xseries.parseToMaterial -import taboolib.module.chat.colored import taboolib.platform.util.ItemBuilder import java.util.* class HeadShopItem( - override val key: Char, headString: String, - override val price: Double, - override val limitServer: Long, - override val limitPlayer: Long, - override val name: String, - override val lore: List, - override val vanilla: Boolean, - override val commands: List, - override val shop: Shop, + itemSetting: ItemSetting, val item: Material -) : ShopItem() { +) : ShopItem(itemSetting) { override val material: Material = XMaterial.PLAYER_HEAD.parseMaterial()!! @@ -54,28 +44,20 @@ class HeadShopItem( } } - companion object : ItemLoader { + companion object : ItemLoader() { override var prefix: String? = "HEAD" override fun formSection(char: Char, section: ConfigurationSection, shop: Shop): Item { return HeadShopItem( - char, section.getString("material")!!, - section.getDouble("price"), - section.getLong("limit"), - section.getLong("limit-player"), - section.getString("name")!!.colored(), - section.getStringList("lore").colored(), - section.getBoolean("vanilla", true), - section.getStringList("commands"), - shop, + section.toItemSetting(char, shop), section.getString("item")!!.parseToMaterial() - ).also { - section.getString("currency")?.let { currency -> - it.currency = CurrencyType.formString(currency).func.invoke(currency) - } - } + ) + } + + override fun parseToMaterial(section: ConfigurationSection): Material { + return section.getString("item")!!.parseToMaterial() } } diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/ItemImpl.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/ItemImpl.kt index 242a78f..e31a044 100644 --- a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/ItemImpl.kt +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/ItemImpl.kt @@ -15,8 +15,12 @@ import taboolib.platform.util.modifyLore import java.util.* class ItemImpl( - materialString: String, override val lore: List, override val name: String, - override val key: Char, override val vanilla: Boolean, override val commands: List, + materialString: String, + override val lore: List, + override val name: String, + override val key: Char, + override val vanilla: Boolean, + override val commands: List, override val shop: Shop ) : Item { @@ -66,7 +70,7 @@ class ItemImpl( return item } - companion object : ItemLoader { + companion object : ItemLoader() { override var prefix: String? = null diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/ItemsAdderShopItem.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/ItemsAdderShopItem.kt index aed73a9..1dae085 100644 --- a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/ItemsAdderShopItem.kt +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/ItemsAdderShopItem.kt @@ -9,20 +9,11 @@ import org.bukkit.Material import org.bukkit.configuration.ConfigurationSection import org.bukkit.inventory.ItemStack import taboolib.library.xseries.XMaterial -import taboolib.module.chat.colored class ItemsAdderShopItem( - override val key: Char, - override val price: Double, iaMaterial: String, - override val limitServer: Long, - override val limitPlayer: Long, - override val name: String, - override val lore: List, - override val vanilla: Boolean, - override val commands: List, - override val shop: Shop -) : ShopItem() { + itemSetting: ItemSetting +) : ShopItem(itemSetting) { override val material: Material @@ -56,26 +47,21 @@ class ItemsAdderShopItem( } } - companion object : ItemLoader { + companion object : ItemLoader() { override var prefix: String? = "IA" override fun formSection(char: Char, section: ConfigurationSection, shop: Shop): Item { return ItemsAdderShopItem( - char, - section.getDouble("price"), section.getString("material")!!, - section.getLong("limit"), - section.getLong("limit-player"), - section.getString("name")!!.colored(), - section.getStringList("lore").colored(), - section.getBoolean("vanilla", true), - section.getStringList("commands"), - shop - ).also { - section.getString("currency")?.let { currency -> - it.currency = CurrencyType.formString(currency).func.invoke(currency) - } + section.toItemSetting(char, shop) + ) + } + + override fun parseToMaterial(section: ConfigurationSection): Material { + val iaMaterial = section.getString("material")!! + iaMaterial.split(":").let { strings -> + return XMaterial.matchXMaterial(strings[1]).get().parseMaterial()!! } } diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/VanillaShopItem.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/VanillaShopItem.kt index 37fed12..584a515 100644 --- a/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/VanillaShopItem.kt +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/core/item/impl/VanillaShopItem.kt @@ -5,25 +5,13 @@ import com.github.xbaimiao.shoppro.core.item.ItemLoader import com.github.xbaimiao.shoppro.core.item.ShopItem import com.github.xbaimiao.shoppro.core.shop.Shop import com.github.xbaimiao.shoppro.core.vault.CurrencyType -import org.bukkit.Material import org.bukkit.configuration.ConfigurationSection import org.bukkit.inventory.ItemStack -import taboolib.library.xseries.parseToMaterial -import taboolib.module.chat.colored import taboolib.platform.util.hasLore class VanillaShopItem( - override val key: Char, - override val material: Material, - override val price: Double, - override val limitServer: Long, - override val limitPlayer: Long, - override val name: String, - override val lore: List, - override val vanilla: Boolean, - override val commands: List, - override val shop: Shop -) : ShopItem() { + itemSetting: ItemSetting +) : ShopItem(itemSetting) { override fun vanillaItem(): ItemStack { return taboolib.platform.util.buildItem(material) @@ -40,27 +28,12 @@ class VanillaShopItem( } } - companion object : ItemLoader { + companion object : ItemLoader() { override var prefix: String? = null override fun formSection(char: Char, section: ConfigurationSection, shop: Shop): Item { - return VanillaShopItem( - char, - section.getString("material")!!.parseToMaterial(), - section.getDouble("price"), - section.getLong("limit"), - section.getLong("limit-player"), - section.getString("name")!!.colored(), - section.getStringList("lore").colored(), - section.getBoolean("vanilla", true), - section.getStringList("commands"), - shop - ).also { - section.getString("currency")?.let { currency -> - it.currency = CurrencyType.formString(currency).func.invoke(currency) - } - } + return VanillaShopItem(section.toItemSetting(char, shop)) } } diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/core/shop/Shop.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/core/shop/Shop.kt index 03ec651..38bf228 100644 --- a/src/main/kotlin/com/github/xbaimiao/shoppro/core/shop/Shop.kt +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/core/shop/Shop.kt @@ -25,5 +25,4 @@ abstract class Shop { abstract fun open(player: Player) - } \ No newline at end of file diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/core/shop/ShopImpl.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/core/shop/ShopImpl.kt index bdd6f44..7aba0aa 100644 --- a/src/main/kotlin/com/github/xbaimiao/shoppro/core/shop/ShopImpl.kt +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/core/shop/ShopImpl.kt @@ -5,6 +5,7 @@ import com.github.xbaimiao.shoppro.api.ShopProBuyEvent import com.github.xbaimiao.shoppro.api.ShopProSellEvent import com.github.xbaimiao.shoppro.core.database.LimitData import com.github.xbaimiao.shoppro.core.item.Item +import com.github.xbaimiao.shoppro.core.item.KetherCondition import com.github.xbaimiao.shoppro.core.item.ShopItem import com.github.xbaimiao.shoppro.util.Util.howManyItems import com.github.xbaimiao.shoppro.util.Util.replacePapi @@ -88,7 +89,16 @@ class ShopImpl(private val configuration: Configuration) : Shop() { it.isCancelled = true } for (item in this@ShopImpl.items) { + var canBuyOrSell = true + if (item is KetherCondition && !item.check(player)) { + canBuyOrSell = false + } + if (!canBuyOrSell && item is KetherCondition) { + set(item.key, item.conditionItem(player)) + continue + } set(item.key, item.update(player)) + // buy and sell if (item is ShopItem) { if (getType() == ShopType.BUY) { onClick(item.key) { event -> diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/util/EvalResult.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/util/EvalResult.kt new file mode 100644 index 0000000..0e8f8c2 --- /dev/null +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/util/EvalResult.kt @@ -0,0 +1,30 @@ +package com.github.xbaimiao.shoppro.util + +/** + * @author Arasple + * @date 2021/1/31 11:53 + */ +@JvmInline +value class EvalResult(val any: Any? = null) { + + fun asBoolean(def: Boolean = false): Boolean { + return when (any) { + is Boolean -> any + is String -> Regexs.parseBoolean(any) + else -> def || Regexs.parseBoolean(any.toString()) + } + } + + fun asString(): String { + return any.toString() + } + + companion object { + + val TRUE = EvalResult(true) + + val FALSE = EvalResult(false) + + } + +} diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/util/KetherUtil.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/util/KetherUtil.kt new file mode 100644 index 0000000..4867926 --- /dev/null +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/util/KetherUtil.kt @@ -0,0 +1,43 @@ +package com.github.xbaimiao.shoppro.util + +import org.bukkit.entity.Player +import taboolib.common.platform.function.adaptPlayer +import taboolib.library.kether.LocalizedException +import taboolib.module.kether.KetherShell +import java.util.concurrent.CompletableFuture +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException + +/** + * @author 小白 + * @date 2023/5/10 09:47 + **/ +object KetherUtil { + + @JvmStatic + fun eval(player: Player, script: String): CompletableFuture { + return try { + KetherShell.eval(script, namespace = listOf("shoppro")) { + sender = adaptPlayer(player) + } + } catch (e: LocalizedException) { + println("§c[ShopPro] §8Unexpected exception while parsing kether shell:") + e.localizedMessage.split("\n").forEach { + println(" §8$it") + } + CompletableFuture.completedFuture(false) + } + } + + @JvmStatic + fun instantKether(player: Player, script: String, timeout: Long = 100): EvalResult { + return try { + EvalResult(eval(player, script).get(timeout, TimeUnit.MILLISECONDS)) + } catch (e: TimeoutException) { + println("§c[ShopPro] §8Timeout while parsing kether shell:") + e.localizedMessage?.split("\n")?.forEach { println(" §8$it") } + EvalResult.FALSE + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/xbaimiao/shoppro/util/Regexs.kt b/src/main/kotlin/com/github/xbaimiao/shoppro/util/Regexs.kt new file mode 100644 index 0000000..e9994eb --- /dev/null +++ b/src/main/kotlin/com/github/xbaimiao/shoppro/util/Regexs.kt @@ -0,0 +1,27 @@ +package com.github.xbaimiao.shoppro.util + +/** + * @author Arasple + * @date 2021/1/24 16:57 + */ +object Regexs { + + private val PLACEHOLDER_API = "(%)(.+?)(%)|(?!\\{\")((\\{)(.+?)(}))".toRegex() + val JSON_TEXTURE = "\\{\\s*\"".toRegex() + val ICON_KEY = "`(.+?)`".toRegex() + val SENTENCE = "`(.+?)`".toRegex() + val STRING = "\\{(\\w+)}".toRegex() + + private val TRUE = "true|yes|on".toRegex() + val FALSE = "false|no|off".toRegex() + val BOOLEAN = "true|yes|on|false|no|off".toRegex() + + fun containsPlaceholder(string: String): Boolean { + return PLACEHOLDER_API.find(string) != null + } + + fun parseBoolean(string: String): Boolean { + return string.lowercase().matches(TRUE) + } + +} \ No newline at end of file diff --git a/src/main/resources/shops/limit-sell.yml b/src/main/resources/shops/limit-sell.yml index 73ac230..76085d4 100644 --- a/src/main/resources/shops/limit-sell.yml +++ b/src/main/resources/shops/limit-sell.yml @@ -27,6 +27,15 @@ items: limit-player: 500 # 物品金额 price: 1 + # 条件 + condition: 'permission shop.sell.stone' + # 条件不满足无法显示,玩家买不了,但能看到的样子 + condition-icon: barrier + condition-name: '条件不满足' + # 未解锁状态下的lore描述 + condition-lore: + - '未解锁名称描述1' + - '未解锁名称描述2' lore: - '&e| &7这里可以出售你背包里面的&6 ${name}' - '&e| &7收购单价 &6${price}'