限购支持

This commit is contained in:
小白
2022-09-09 23:53:26 +08:00
parent dae9931df4
commit 2b3ce52758
15 changed files with 424 additions and 32 deletions
@@ -1,6 +1,8 @@
package com.github.xbaimiao.shoppro
import com.github.xbaimiao.shoppro.core.database.Database
import com.github.xbaimiao.shoppro.core.database.MysqlDatabase
import com.github.xbaimiao.shoppro.core.database.SQLiteDatabase
import com.github.xbaimiao.shoppro.core.shop.ShopManager
import taboolib.common.platform.Plugin
import taboolib.module.configuration.Config
@@ -16,11 +18,14 @@ object ShopPro : Plugin() {
override fun onEnable() {
ShopManager.load()
database = if (config.getBoolean("mysql.enable")) MysqlDatabase(config) else SQLiteDatabase()
}
fun reload() {
config.reload()
ShopManager.shops.clear()
ShopManager.load()
database = if (config.getBoolean("mysql.enable")) MysqlDatabase(config) else SQLiteDatabase()
}
}
@@ -1,5 +1,6 @@
package com.github.xbaimiao.shoppro.core
import com.github.xbaimiao.shoppro.ShopPro
import com.github.xbaimiao.shoppro.core.shop.ShopManager
import org.bukkit.Bukkit
import org.bukkit.command.CommandSender
@@ -7,6 +8,7 @@ import org.bukkit.entity.Player
import taboolib.common.platform.command.*
import taboolib.expansion.createHelper
import taboolib.platform.util.onlinePlayers
import taboolib.platform.util.sendLang
@CommandHeader("shoppro", aliases = ["sp"], permissionDefault = PermissionDefault.TRUE)
object Commands {
@@ -39,4 +41,20 @@ object Commands {
}
}
@CommandBody(permission = "admin")
val resetLimit = subCommand {
execute<CommandSender> { sender, _, _ ->
ShopPro.database.reset()
sender.sendLang("reset")
}
}
@CommandBody(permission = "admin")
val reload = subCommand {
execute<CommandSender> { sender, _, _ ->
ShopPro.reload()
sender.sendLang("reload")
}
}
}
@@ -0,0 +1,151 @@
package com.github.xbaimiao.shoppro.core.database
import com.github.xbaimiao.shoppro.core.item.Item
import com.github.xbaimiao.shoppro.core.item.ItemsAdderShopItem
import org.bukkit.entity.Player
import taboolib.module.database.Host
import taboolib.module.database.Table
import javax.sql.DataSource
abstract class ADatabase : Database {
abstract val host: Host<*>
abstract val playerTable: Table<*, *>
abstract val serverTable: Table<*, *>
abstract val dataSource: DataSource
val serverTableName = "server"
val playerTableName = "player"
val itemKeyLine = "item-key"
val itemMaterialLine = "item-material"
val itemCustomLine = "item-custom"
val dataLine = "data"
// ServerTable 无 User
val playerLine = "user"
override fun reset() {
serverTable.workspace(dataSource) {
executeUpdate("DELETE FROM '$serverTableName';").run()
}.run()
playerTable.workspace(dataSource) {
executeUpdate("DELETE FROM '$playerTableName';").run()
}.run()
}
override fun getServerAlreadyData(item: Item): LimitData {
return serverTable.workspace(dataSource) {
select {
where {
itemKeyLine eq item.key.toString()
itemMaterialLine eq item.material.toString()
if (item is ItemsAdderShopItem) {
itemCustomLine eq item.custom
}
}
}
}.firstOrNull {
LimitData.formString(this.getString(dataLine))
} ?: LimitData.ofNull()
}
override fun getPlayerAlreadyData(player: Player, item: Item): LimitData {
return playerTable.workspace(dataSource) {
select {
where {
playerLine eq player.uniqueId.toString()
itemKeyLine eq item.key.toString()
itemMaterialLine eq item.material.toString()
if (item is ItemsAdderShopItem) {
itemCustomLine eq item.custom
}
}
}
}.firstOrNull {
LimitData.formString(this.getString(dataLine))
} ?: LimitData.ofNull()
}
override fun addAmount(item: Item, player: Player, amount: LimitData) {
setPlayerAlreadyData(player, item, amount.add(getPlayerAlreadyData(player, item)))
setServerAlreadyData(item, amount.add(getServerAlreadyData(item)))
}
override fun setServerAlreadyData(item: Item, amount: LimitData) {
if (serverTable.workspace(dataSource) {
select {
where {
itemKeyLine eq item.key.toString()
itemMaterialLine eq item.material.toString()
if (item is ItemsAdderShopItem) {
itemCustomLine eq item.custom
}
}
}
}.find()) {
serverTable.workspace(dataSource) {
update {
where {
itemKeyLine eq item.key.toString()
itemMaterialLine eq item.material.toString()
if (item is ItemsAdderShopItem) {
itemCustomLine eq item.custom
}
}
set(dataLine, amount.toString())
}
}.run()
} else {
val custom = if (item is ItemsAdderShopItem) item.custom else 0
serverTable.workspace(dataSource) {
insert {
value(item.key.toString(), item.material.toString(), custom, amount.toString())
}
}.run()
}
}
override fun setPlayerAlreadyData(player: Player, item: Item, amount: LimitData) {
if (playerTable.workspace(dataSource) {
select {
where {
playerLine eq player.uniqueId.toString()
itemKeyLine eq item.key.toString()
itemMaterialLine eq item.material.toString()
if (item is ItemsAdderShopItem) {
itemCustomLine eq item.custom
}
}
}
}.find()) {
playerTable.workspace(dataSource) {
update {
where {
playerLine eq player.uniqueId.toString()
itemKeyLine eq item.key.toString()
itemMaterialLine eq item.material.toString()
if (item is ItemsAdderShopItem) {
itemCustomLine eq item.custom
}
}
set(dataLine, amount.toString())
}
}.run()
} else {
val custom = if (item is ItemsAdderShopItem) item.custom else 0
playerTable.workspace(dataSource) {
insert {
value(
item.key.toString(),
item.material.toString(),
custom,
amount.toString(),
player.uniqueId.toString()
)
}
}.run()
}
}
}
@@ -8,21 +8,25 @@ interface Database {
/**
* 获取该物品该玩家今日已购买多少次了
*/
fun getPlayerLimit(player: Player, item: Item): Long
fun getPlayerAlreadyData(player: Player, item: Item): LimitData
/**
* 设置该物品该玩家今日已购买多少次了
*/
fun setPlayerLimit(player: Player, item: Item, amount: Long)
fun setPlayerAlreadyData(player: Player, item: Item, amount: LimitData)
/**
* 获取该物品今日已购买多少次了
*/
fun getServerLimit(item: Item)
fun getServerAlreadyData(item: Item): LimitData
/**
* 设置该物品今日已购买多少次了
*/
fun setServerLimit(item: Item, amount: Long)
fun setServerAlreadyData(item: Item, amount: LimitData)
fun addAmount(item: Item, player: Player, amount: LimitData)
fun reset()
}
@@ -0,0 +1,31 @@
package com.github.xbaimiao.shoppro.core.database
data class LimitData(
val buy: Long,
val sell: Long
) {
companion object {
fun ofNull(): LimitData = LimitData(0L, 0L)
fun formString(string: String): LimitData {
if (!string.contains("/")) {
error("错误的String,非 LimitData")
}
return string.split("/").let {
LimitData(it[0].toLong(), it[1].toLong())
}
}
}
fun add(limitData: LimitData): LimitData {
return LimitData(limitData.buy + buy, limitData.sell + sell)
}
override fun toString(): String {
return "$buy/$sell"
}
}
@@ -0,0 +1,63 @@
package com.github.xbaimiao.shoppro.core.database
import com.github.xbaimiao.shoppro.ShopPro
import taboolib.common.platform.function.submit
import taboolib.module.configuration.Configuration
import taboolib.module.database.ColumnTypeSQL
import taboolib.module.database.Table
import taboolib.module.database.getHost
import java.util.*
class MysqlDatabase(configuration: Configuration) : ADatabase() {
override val host = configuration.getHost("mysql")
override val playerTable = Table(playerTableName, host) {
add(itemKeyLine) {
type(ColumnTypeSQL.VARCHAR, 255)
}
add(itemMaterialLine) {
type(ColumnTypeSQL.VARCHAR, 255)
}
add(itemCustomLine) {
type(ColumnTypeSQL.INT, 10)
}
add(dataLine) {
type(ColumnTypeSQL.VARCHAR, 255)
}
add(playerLine) {
type(ColumnTypeSQL.VARCHAR, 255)
}
}
override val serverTable = Table(serverTableName, host) {
add(itemKeyLine) {
type(ColumnTypeSQL.VARCHAR, 255)
}
add(itemMaterialLine) {
type(ColumnTypeSQL.VARCHAR, 255)
}
add(itemCustomLine) {
type(ColumnTypeSQL.INT, 10)
}
add(dataLine) {
type(ColumnTypeSQL.VARCHAR, 255)
}
}
override val dataSource = host.createDataSource()
init {
serverTable.workspace(dataSource) { createTable() }.run()
playerTable.workspace(dataSource) { createTable() }.run()
submit(async = true, delay = 20, period = 20) {
val currentDay = Date().day
if (currentDay != ShopPro.config.getInt("date")) {
reset()
ShopPro.config["date"] = currentDay
ShopPro.config.saveToFile()
}
}
}
}
@@ -0,0 +1,63 @@
package com.github.xbaimiao.shoppro.core.database
import com.github.xbaimiao.shoppro.ShopPro
import taboolib.common.io.newFile
import taboolib.common.platform.function.submit
import taboolib.module.database.ColumnTypeSQLite
import taboolib.module.database.Table
import taboolib.module.database.getHost
import taboolib.platform.BukkitPlugin
import java.util.*
class SQLiteDatabase : ADatabase() {
override val host = newFile(BukkitPlugin.getInstance().dataFolder, "sqlite.db").getHost()
override val playerTable = Table(playerTableName, host) {
add(itemKeyLine) {
type(ColumnTypeSQLite.TEXT, 255)
}
add(itemMaterialLine) {
type(ColumnTypeSQLite.TEXT, 255)
}
add(itemCustomLine) {
type(ColumnTypeSQLite.INTEGER, 10)
}
add(dataLine) {
type(ColumnTypeSQLite.TEXT, 255)
}
add(playerLine) {
type(ColumnTypeSQLite.TEXT, 255)
}
}
override val serverTable = Table(serverTableName, host) {
add(itemKeyLine) {
type(ColumnTypeSQLite.TEXT, 255)
}
add(itemMaterialLine) {
type(ColumnTypeSQLite.TEXT, 255)
}
add(itemCustomLine) {
type(ColumnTypeSQLite.INTEGER, 10)
}
add(dataLine) {
type(ColumnTypeSQLite.TEXT, 255)
}
}
override val dataSource = host.createDataSource()
init {
serverTable.workspace(dataSource) { createTable() }.run()
playerTable.workspace(dataSource) { createTable() }.run()
submit(async = true, delay = 20, period = 20) {
val currentDay = Date().day
if (currentDay != ShopPro.config.getInt("date")) {
reset()
ShopPro.config["date"] = currentDay
ShopPro.config.saveToFile()
}
}
}
}
@@ -1,5 +1,6 @@
package com.github.xbaimiao.shoppro.core.item
import com.github.xbaimiao.shoppro.core.shop.Shop
import com.github.xbaimiao.shoppro.core.shop.ShopManager
import com.github.xbaimiao.shoppro.core.vault.Vault
import com.github.xbaimiao.shoppro.core.vault.VaultImpl
@@ -18,13 +19,14 @@ interface Item {
val name: String
val vanilla: Boolean
val commands: List<String>
val shop: Shop
val vault: Vault
get() = VaultImpl
fun isCommodity(): Boolean
fun buildItem(): ItemStack
fun update(player: Player, itemStack: ItemStack)
fun update(player: Player): ItemStack
fun exeCommands(player: Player) {
commands.map { it.replace("%player%", player.name) }.forEach { command ->
@@ -1,5 +1,6 @@
package com.github.xbaimiao.shoppro.core.item
import com.github.xbaimiao.shoppro.core.shop.Shop
import me.clip.placeholderapi.PlaceholderAPI
import org.bukkit.Material
import org.bukkit.entity.Player
@@ -8,7 +9,8 @@ import taboolib.platform.util.modifyLore
open class ItemImpl(
override val material: Material, override val lore: List<String>, override val name: String,
override val key: Char, override val vanilla: Boolean, override val commands: List<String>
override val key: Char, override val vanilla: Boolean, override val commands: List<String>,
override val shop: Shop
) : Item {
override fun isCommodity(): Boolean {
@@ -22,8 +24,8 @@ open class ItemImpl(
}
}
override fun update(player: Player, itemStack: ItemStack) {
itemStack.modifyLore {
override fun update(player: Player): ItemStack {
val item = buildItem().modifyLore {
val newLore = ArrayList<String>()
for (line in this) {
newLore.add(PlaceholderAPI.setPlaceholders(player, line))
@@ -31,6 +33,7 @@ open class ItemImpl(
this.clear()
this.addAll(newLore)
}
return item
}
}
@@ -1,5 +1,6 @@
package com.github.xbaimiao.shoppro.core.item
import com.github.xbaimiao.shoppro.core.shop.Shop
import org.bukkit.Material
import org.bukkit.inventory.ItemStack
import taboolib.library.xseries.XMaterial
@@ -14,12 +15,13 @@ class ItemsAdderShopItem(
override val name: String,
override val lore: List<String>,
override val vanilla: Boolean,
override val commands: List<String>
override val commands: List<String>,
override val shop: Shop
) : ShopItem() {
override val material: Material
private val custom: Int
val custom: Int
private var customPotionColor: Int? = null
@@ -1,5 +1,7 @@
package com.github.xbaimiao.shoppro.core.item
import com.github.xbaimiao.shoppro.ShopPro
import com.github.xbaimiao.shoppro.core.shop.Shop
import me.clip.placeholderapi.PlaceholderAPI
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
@@ -23,11 +25,19 @@ abstract class ShopItem : Item {
return limitPlayer != 0L && limitServer != 0L
}
override fun update(player: Player, itemStack: ItemStack) {
val playerLimit = "1"
val serverLimit = "1"
val priceAll = "1"
itemStack.modifyLore {
override fun update(player: Player): ItemStack {
val playerLimit = if (shop.getType() == Shop.ShopType.BUY) {
ShopPro.database.getPlayerAlreadyData(player, this).buy
} else {
ShopPro.database.getPlayerAlreadyData(player, this).sell
}
val serverLimit = if (shop.getType() == Shop.ShopType.BUY) {
ShopPro.database.getServerAlreadyData(this).buy
} else {
ShopPro.database.getServerAlreadyData(this).sell
}
val priceAll = "正在开发"
val item = buildItem().modifyLore {
val newLore = ArrayList<String>()
for (line in this) {
val newLine = line.replace("\${name}", name)
@@ -35,15 +45,16 @@ abstract class ShopItem : Item {
.replace("\${money}", vault.getMoney(player).toString())
.replace("\${price64}", (price * 64).toString())
.replace("\${limit}", limitPlayer.toString())
.replace("\${priceAll}", priceAll)
.replace("\${priceAll}", priceAll.toString())
.replace("\${allLimit}", limitServer.toString())
.replace("\${limit-player}", playerLimit)
.replace("\${limit-server}", serverLimit)
.replace("\${limit-player}", playerLimit.toString())
.replace("\${limit-server}", (limitServer - serverLimit).toString())
newLore.add(PlaceholderAPI.setPlaceholders(player, newLine))
}
this.clear()
this.addAll(newLore)
}
return item
}
}
@@ -1,5 +1,6 @@
package com.github.xbaimiao.shoppro.core.item
import com.github.xbaimiao.shoppro.core.shop.Shop
import org.bukkit.Material
import org.bukkit.inventory.ItemStack
@@ -12,7 +13,8 @@ class VanillaShopItem(
override val name: String,
override val lore: List<String>,
override val vanilla: Boolean,
override val commands: List<String>
override val commands: List<String>,
override val shop: Shop
) : ShopItem() {
override fun vanillaItem(): ItemStack {
@@ -1,7 +1,9 @@
package com.github.xbaimiao.shoppro.core.shop
import com.github.xbaimiao.shoppro.ShopPro
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.*
import org.bukkit.Bukkit
import org.bukkit.configuration.Configuration
@@ -38,7 +40,8 @@ class ShopImpl(private val configuration: Configuration) : Shop() {
section.getString("$key.name")!!.colored(),
section.getStringList("$key.lore").colored(),
section.getBoolean("$key.vanilla", true),
section.getStringList("$key.commands")
section.getStringList("$key.commands"),
this
)
)
} else {
@@ -52,7 +55,8 @@ class ShopImpl(private val configuration: Configuration) : Shop() {
section.getString("$key.name")!!.colored(),
section.getStringList("$key.lore").colored(),
section.getBoolean("$key.vanilla", true),
section.getStringList("$key.commands")
section.getStringList("$key.commands"),
this
)
)
}
@@ -64,7 +68,8 @@ class ShopImpl(private val configuration: Configuration) : Shop() {
section.getString("$key.name")!!.colored(),
key[0],
section.getBoolean("$key.vanilla", true),
section.getStringList("$key.commands")
section.getStringList("$key.commands"),
this
)
)
}
@@ -91,9 +96,7 @@ class ShopImpl(private val configuration: Configuration) : Shop() {
it.isCancelled = true
}
for (item in this@ShopImpl.items) {
val itemStack = item.buildItem()
item.update(player, itemStack)
set(item.key, itemStack)
set(item.key, item.update(player))
if (item is ShopItem) {
if (getType() == ShopType.BUY) {
onClick(item.key) { event ->
@@ -106,7 +109,9 @@ class ShopImpl(private val configuration: Configuration) : Shop() {
else -> 1
}
buy(amount, item, player)
event.currentItem?.let { item.update(player, it) }
event.currentItem?.let {
event.clickEvent().inventory.setItem(event.rawSlot, item.update(player))
}
}
}
if (getType() == ShopType.SELL) {
@@ -120,7 +125,9 @@ class ShopImpl(private val configuration: Configuration) : Shop() {
else -> 1
}
sell(amount, item, player)
event.currentItem?.let { item.update(player, it) }
event.currentItem?.let {
event.clickEvent().inventory.setItem(event.rawSlot, item.update(player))
}
}
}
} else {
@@ -134,7 +141,14 @@ class ShopImpl(private val configuration: Configuration) : Shop() {
private fun buy(amount: Int, item: ShopItem, player: Player) {
if (item.isLimit()) {
// TODO
if (ShopPro.database.getPlayerAlreadyData(player, item).buy + amount > item.limitPlayer) {
player.sendLang("buy-limit-player", item.limitPlayer)
return
}
if (ShopPro.database.getServerAlreadyData(item).buy + amount > item.limitServer) {
player.sendLang("buy-limit-player", item.limitServer)
return
}
}
if (item.vault.takeMoney(player, item.price * amount)) {
if (item.vanilla) {
@@ -143,6 +157,7 @@ class ShopImpl(private val configuration: Configuration) : Shop() {
player.giveItem(vanilla)
}
Bukkit.getPluginManager().callEvent(ShopProBuyEvent(item, amount, player))
ShopPro.database.addAmount(item, player, LimitData(amount.toLong(), 0L))
item.exeCommands(player)
player.sendLang("buy-item", amount, item.name, item.price * amount)
} else {
@@ -152,12 +167,20 @@ class ShopImpl(private val configuration: Configuration) : Shop() {
private fun sell(amount: Int, item: ShopItem, player: Player) {
if (item.isLimit()) {
// TODO
if (ShopPro.database.getPlayerAlreadyData(player, item).sell + amount > item.limitPlayer) {
player.sendLang("sell-limit-player", item.limitPlayer)
return
}
if (ShopPro.database.getServerAlreadyData(item).sell + amount > item.limitServer) {
player.sendLang("sell-limit-server", item.limitServer)
return
}
}
if (player.inventory.hasItem(amount) { item.equal(it) }) {
player.inventory.takeItem(amount) { item.equal(it) }
item.vault.giveMoney(player, item.price * amount)
Bukkit.getPluginManager().callEvent(ShopProSellEvent(item, amount, player))
ShopPro.database.addAmount(item, player, LimitData(0L, amount.toLong()))
player.sendLang("sell-item", amount, item.name, item.price * amount)
} else {
player.sendLang("not-item")
+9
View File
@@ -0,0 +1,9 @@
# 请勿修改此项
date: 0
mysql:
enable: false
host: localhost
port: 3306
user: "root"
password: "123456"
database: "shoppro"
+6 -1
View File
@@ -1,6 +1,11 @@
shop-not-found: "&7[&e&l!&7] 你需要打开什么商店呢"
not-item: "&7[&e&l!&7] 你没有足够的可以出售的物品"
sell-item: "&7[&e&l!&7] 你出售了§6 {0}个 §7{1}§7获得了§6 {2}"
sell-limit: "&7[&e&l!&7] 此物品已达到今日收购限制"
sell-limit-player: "&7[&e&l!&7] 此物品每人每日限制收购{0}个,已达到今日收购限制"
sell-limit-server: "&7[&e&l!&7] 此物品全服每日限制收购{0}个,已达到今日收购限制"
buy-limit-player: "&7[&e&l!&7] 此物品每人每日限制购买{0}个,今日购买限制"
buy-limit-server: "&7[&e&l!&7] 此物品全服每日限制购买{0}个,今日购买限制"
buy-item: "&7[&e&l!&7] 你购买了§6 {0}个 §7{1} §7花费了§6 {2}"
not-money: "&7[&e&l!&7] 你没有足够的钱"
reload: "&7[&e&l!&7] 重载完成"
reset: "&7[&e&l!&7] 限购数据重置成功"