Several performance and stability improvements
This commit is contained in:
@@ -30,12 +30,7 @@ import com.willfp.eco.spigot.data.PlayerBlockListener
|
||||
import com.willfp.eco.spigot.data.storage.DataHandler
|
||||
import com.willfp.eco.spigot.data.storage.MySQLDataHandler
|
||||
import com.willfp.eco.spigot.data.storage.YamlDataHandler
|
||||
import com.willfp.eco.spigot.display.PacketAutoRecipe
|
||||
import com.willfp.eco.spigot.display.PacketChat
|
||||
import com.willfp.eco.spigot.display.PacketOpenWindowMerchant
|
||||
import com.willfp.eco.spigot.display.PacketSetCreativeSlot
|
||||
import com.willfp.eco.spigot.display.PacketSetSlot
|
||||
import com.willfp.eco.spigot.display.PacketWindowItems
|
||||
import com.willfp.eco.spigot.display.*
|
||||
import com.willfp.eco.spigot.display.frame.clearFrames
|
||||
import com.willfp.eco.spigot.drops.CollatedRunnable
|
||||
import com.willfp.eco.spigot.eventlisteners.EntityDeathByEntityListeners
|
||||
@@ -46,22 +41,8 @@ import com.willfp.eco.spigot.eventlisteners.armor.ArmorListener
|
||||
import com.willfp.eco.spigot.gui.GUIListener
|
||||
import com.willfp.eco.spigot.integrations.afk.AFKIntegrationCMI
|
||||
import com.willfp.eco.spigot.integrations.afk.AFKIntegrationEssentials
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAAC
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAlice
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatMatrix
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatNCP
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatSpartan
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatVulcan
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefBentoBox
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefCombatLogXV10
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefCombatLogXV11
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefFactionsUUID
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefGriefPrevention
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefKingdoms
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefLands
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefSuperiorSkyblock2
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefTowny
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefWorldGuard
|
||||
import com.willfp.eco.spigot.integrations.anticheat.*
|
||||
import com.willfp.eco.spigot.integrations.antigrief.*
|
||||
import com.willfp.eco.spigot.integrations.customitems.CustomItemsHeadDatabase
|
||||
import com.willfp.eco.spigot.integrations.customitems.CustomItemsItemsAdder
|
||||
import com.willfp.eco.spigot.integrations.customitems.CustomItemsOraxen
|
||||
@@ -145,6 +126,8 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
|
||||
override fun handleDisable() {
|
||||
Eco.getHandler().adventure?.close()
|
||||
this.logger.info("Saving player data...")
|
||||
Eco.getHandler().playerProfileHandler.saveAll()
|
||||
}
|
||||
|
||||
override fun handleReload() {
|
||||
@@ -158,7 +141,7 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
this.scheduler.runTimer(
|
||||
{
|
||||
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler)
|
||||
.autosave(this.configYml.getBool("autosave.async"))
|
||||
.autosave()
|
||||
},
|
||||
this.configYml.getInt("autosave.ticks").toLong(),
|
||||
this.configYml.getInt("autosave.ticks").toLong()
|
||||
|
||||
@@ -33,39 +33,18 @@ class EcoPlayerProfileHandler(
|
||||
}
|
||||
|
||||
override fun savePlayer(uuid: UUID) {
|
||||
writeToHandler(uuid)
|
||||
saveToHandler()
|
||||
handler.savePlayer(uuid)
|
||||
}
|
||||
|
||||
private fun writeToHandler(uuid: UUID) {
|
||||
val profile = load(uuid)
|
||||
|
||||
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
|
||||
handler.write(uuid, key.key, profile.read(key) ?: key.defaultValue)
|
||||
override fun saveAll() {
|
||||
for ((uuid, _) in loaded) {
|
||||
handler.savePlayer(uuid)
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveToHandler() {
|
||||
handler.save()
|
||||
}
|
||||
|
||||
override fun saveAll(async: Boolean) {
|
||||
val saver = {
|
||||
for ((uuid, _) in loaded) {
|
||||
writeToHandler(uuid)
|
||||
}
|
||||
|
||||
saveToHandler()
|
||||
}
|
||||
|
||||
if (async) {
|
||||
plugin.scheduler.runAsync(saver)
|
||||
} else {
|
||||
saver.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
fun autosave(async: Boolean) {
|
||||
fun autosave() {
|
||||
if (Bukkit.getOnlinePlayers().isEmpty()) {
|
||||
return
|
||||
}
|
||||
@@ -74,7 +53,7 @@ class EcoPlayerProfileHandler(
|
||||
plugin.logger.info("Auto-Saving player data!")
|
||||
}
|
||||
|
||||
saveAll(async)
|
||||
saveAll()
|
||||
|
||||
if (plugin.configYml.getBool("autosave.log")) {
|
||||
plugin.logger.info("Saved player data!")
|
||||
|
||||
@@ -4,10 +4,15 @@ import org.bukkit.NamespacedKey
|
||||
import java.util.*
|
||||
|
||||
interface DataHandler {
|
||||
fun save()
|
||||
fun save() {
|
||||
|
||||
}
|
||||
|
||||
fun updateKeys() {
|
||||
|
||||
}
|
||||
|
||||
fun <T> write(uuid: UUID, key: NamespacedKey, value: T)
|
||||
fun savePlayer(uuid: UUID)
|
||||
fun <T> read(uuid: UUID, key: NamespacedKey): T?
|
||||
|
||||
fun updateKeys()
|
||||
}
|
||||
@@ -1,30 +1,25 @@
|
||||
package com.willfp.eco.spigot.data.storage
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.data.PlayerProfile
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||
import com.willfp.eco.spigot.EcoSpigotPlugin
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.jetbrains.exposed.dao.id.UUIDTable
|
||||
import org.jetbrains.exposed.sql.BooleanColumnType
|
||||
import org.jetbrains.exposed.sql.Column
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
import org.jetbrains.exposed.sql.DoubleColumnType
|
||||
import org.jetbrains.exposed.sql.IntegerColumnType
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import org.jetbrains.exposed.sql.SchemaUtils
|
||||
import org.jetbrains.exposed.sql.VarCharColumnType
|
||||
import org.jetbrains.exposed.sql.insert
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import java.util.UUID
|
||||
import java.util.*
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class MySQLDataHandler(
|
||||
plugin: EcoSpigotPlugin
|
||||
) : DataHandler {
|
||||
private val columns = mutableMapOf<String, Column<*>>()
|
||||
private val threadFactory = ThreadFactoryBuilder().setNameFormat("eco-mysql-thread-%d").build()
|
||||
private val executor = Executors.newCachedThreadPool(threadFactory)
|
||||
|
||||
init {
|
||||
Database.connect(
|
||||
@@ -52,17 +47,39 @@ class MySQLDataHandler(
|
||||
}
|
||||
}
|
||||
|
||||
override fun save() {
|
||||
// Do nothing
|
||||
override fun <T> write(uuid: UUID, key: NamespacedKey, value: T) {
|
||||
writeSafely(uuid, key, value)
|
||||
}
|
||||
|
||||
override fun <T> write(uuid: UUID, key: NamespacedKey, value: T) {
|
||||
transaction {
|
||||
getPlayer(uuid)
|
||||
val column: Column<T> = getColumn(key.toString()) as Column<T>
|
||||
private fun <T> writeSafely(
|
||||
uuid: UUID,
|
||||
key: NamespacedKey,
|
||||
value: T,
|
||||
assumeCreated: Boolean = false
|
||||
) {
|
||||
val column: Column<T> = getColumn(key.toString()) as Column<T>
|
||||
|
||||
Players.update({ Players.id eq uuid }) {
|
||||
it[column] = value
|
||||
executor.execute {
|
||||
if (!assumeCreated) {
|
||||
getPlayer(uuid)
|
||||
}
|
||||
|
||||
transaction {
|
||||
Players.update({ Players.id eq uuid }) {
|
||||
it[column] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun savePlayer(uuid: UUID) {
|
||||
val profile = PlayerProfile.load(uuid)
|
||||
|
||||
getPlayer(uuid)
|
||||
|
||||
transaction {
|
||||
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
|
||||
writeSafely(uuid, key.key, profile.read(key), assumeCreated = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,12 +129,15 @@ class MySQLDataHandler(
|
||||
}
|
||||
|
||||
private fun getPlayer(uuid: UUID): ResultRow {
|
||||
Players.select { Players.id eq uuid }.firstOrNull() ?: run {
|
||||
Players.insert {
|
||||
it[id] = uuid
|
||||
}
|
||||
}
|
||||
val player = Players.select { Players.id eq uuid }.limit(1).singleOrNull()
|
||||
|
||||
return Players.select { Players.id eq uuid }.first()
|
||||
return if (player != null) {
|
||||
player
|
||||
} else {
|
||||
transaction {
|
||||
Players.insert { it[id] = uuid }
|
||||
}
|
||||
getPlayer(uuid)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.willfp.eco.spigot.data.storage
|
||||
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.config.yaml.YamlBaseConfig
|
||||
import com.willfp.eco.core.data.PlayerProfile
|
||||
import com.willfp.eco.spigot.EcoSpigotPlugin
|
||||
import org.bukkit.NamespacedKey
|
||||
import java.util.*
|
||||
@@ -15,8 +17,12 @@ class YamlDataHandler(
|
||||
dataYml.save()
|
||||
}
|
||||
|
||||
override fun updateKeys() {
|
||||
// Do nothing
|
||||
override fun savePlayer(uuid: UUID) {
|
||||
val profile = PlayerProfile.load(uuid)
|
||||
|
||||
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
|
||||
write(uuid, key.key, profile.read(key))
|
||||
}
|
||||
}
|
||||
|
||||
override fun <T> write(uuid: UUID, key: NamespacedKey, value: T) {
|
||||
|
||||
@@ -47,14 +47,8 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
|
||||
handleRateLimit(player)
|
||||
|
||||
if (usingAsync(player)) {
|
||||
executor.execute {
|
||||
try {
|
||||
modifyWindowItems(itemStacks, windowId, player)
|
||||
} catch (e: Exception) {
|
||||
if (this.getPlugin().configYml.getBool("async-display.log-errors")) {
|
||||
this.getPlugin().logger.warning("Error happened in async processing! Disable async display (/plugins/eco/config.yml) if this is a frequent issue")
|
||||
}
|
||||
}
|
||||
fun modifyAndSend(itemStacks: MutableList<ItemStack>, windowId: Int, player: Player) {
|
||||
modifyWindowItems(itemStacks, windowId, player)
|
||||
|
||||
val newPacket = packet.deepClone()
|
||||
newPacket.itemListModifier.write(0, itemStacks)
|
||||
@@ -63,6 +57,20 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
|
||||
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, newPacket)
|
||||
}
|
||||
|
||||
executor.execute {
|
||||
try {
|
||||
modifyAndSend(itemStacks, windowId, player)
|
||||
} catch (e: Exception) {
|
||||
if (this.getPlugin().configYml.getBool("async-display.log-errors")) {
|
||||
this.getPlugin().logger.warning("Error happened in async processing! Disable async display (/plugins/eco/config.yml) if this is a frequent issue")
|
||||
}
|
||||
|
||||
this.getPlugin().scheduler.run {
|
||||
modifyAndSend(itemStacks, windowId, player)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
packet.itemListModifier.write(0, modifyWindowItems(itemStacks, windowId, player))
|
||||
}
|
||||
@@ -91,7 +99,8 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
|
||||
|
||||
private fun usingAsync(player: Player): Boolean {
|
||||
if (this.getPlugin().configYml.getStrings("async-display.disable-on-types", false)
|
||||
.map { it.lowercase() }.contains(player.openInventory.type.name.lowercase())) {
|
||||
.map { it.lowercase() }.contains(player.openInventory.type.name.lowercase())
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ mysql:
|
||||
autosave:
|
||||
ticks: 20000 # The amount of ticks between autosaves
|
||||
log: false # If auto-save messages should be sent to console
|
||||
async: false # If saves should be performed asynchronously. May cause bugs without MySQL
|
||||
|
||||
|
||||
# Options to fix villager bugs left behind from old (buggy) versions.
|
||||
|
||||
Reference in New Issue
Block a user