Compare commits

...

12 Commits

Author SHA1 Message Date
Auxilor
e725811c2f Merge branch 'develop' 2021-11-12 18:07:32 +00:00
Auxilor
f861820572 Fixed key registration 2021-11-12 17:58:43 +00:00
Auxilor
6e310a48c1 DurabilityUtils fix 2021-11-12 17:56:07 +00:00
Auxilor
505234ec13 More data changes 2021-11-12 17:32:50 +00:00
Auxilor
587aeb21a1 Overhauled persistent data storage 2021-11-12 15:55:25 +00:00
Auxilor
cc344bf7ca MySQL Threading changes 2021-11-12 14:12:15 +00:00
Auxilor
c912b97438 Changed PlayerProfileHandler 2021-11-12 11:10:56 +00:00
Auxilor
4788f036ee More data changes 2021-11-12 11:07:43 +00:00
Auxilor
f5ff484086 Revert "Updated dependency structure"
This reverts commit a3ba7cdcf2.
2021-11-12 10:28:17 +00:00
Auxilor
c031534b0d Debugging 2021-11-12 10:28:13 +00:00
Auxilor
62ac49db4b Merge remote-tracking branch 'origin/develop' into develop 2021-11-12 10:15:08 +00:00
Auxilor
a3ba7cdcf2 Updated dependency structure 2021-11-10 19:14:09 +00:00
15 changed files with 143 additions and 151 deletions

View File

@@ -1,7 +1,9 @@
package com.willfp.eco.core.data;
import com.willfp.eco.core.data.keys.PersistentDataKey;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import java.util.UUID;
/**
@@ -17,11 +19,37 @@ public interface PlayerProfileHandler {
PlayerProfile load(@NotNull UUID uuid);
/**
* Save a player profile.
* Unload a player profile from memory.
* <p>
* This will not save the profile first.
*
* @param uuid The uuid.
*/
void savePlayer(@NotNull UUID uuid);
void unloadPlayer(@NotNull UUID uuid);
/**
* Save a player profile.
* <p>
* Can run async if using MySQL.
*
* @param uuid The uuid.
* @deprecated Saving changes is faster and should be used. Saving a player manually is not recommended.
*/
@Deprecated
default void savePlayer(@NotNull UUID uuid) {
this.saveKeysForPlayer(uuid, PersistentDataKey.values());
}
/**
* Save keys for a player.
* <p>
* Can run async if using MySQL.
*
* @param uuid The uuid.
* @param keys The keys.
*/
void saveKeysForPlayer(@NotNull UUID uuid,
@NotNull Set<PersistentDataKey<?>> keys);
/**
* Save all player data.
@@ -36,6 +64,15 @@ public interface PlayerProfileHandler {
/**
* Save all player data.
* <p>
* Can run async if using MySQL.
*/
void saveAll();
/**
* Commit all changes to the file.
* <p>
* Does nothing if using MySQL.
*/
void save();
}

View File

@@ -2,16 +2,43 @@ package com.willfp.eco.internal.data
import com.willfp.eco.core.data.PlayerProfile
import com.willfp.eco.core.data.keys.PersistentDataKey
import java.util.*
import java.util.concurrent.ConcurrentHashMap
class EcoPlayerProfile(
val data: MutableMap<PersistentDataKey<*>, Any>
val data: MutableMap<PersistentDataKey<*>, Any>,
val uuid: UUID
) : PlayerProfile {
override fun <T : Any> write(key: PersistentDataKey<T>, value: T) {
this.data[key] = value
val changedKeys = CHANGE_MAP[uuid] ?: mutableSetOf()
changedKeys.add(key)
CHANGE_MAP[uuid] = changedKeys
}
override fun <T : Any> read(key: PersistentDataKey<T>): T {
@Suppress("UNCHECKED_CAST")
return this.data[key] as T? ?: key.defaultValue
}
override fun equals(other: Any?): Boolean {
if (other !is EcoPlayerProfile) {
return false
}
return this.data == other.data
}
override fun hashCode(): Int {
return data.hashCode()
}
override fun toString(): String {
return "EcoPlayerProfile{$data}"
}
companion object {
val CHANGE_MAP: MutableMap<UUID, MutableSet<PersistentDataKey<*>>> = ConcurrentHashMap()
}
}

View File

@@ -41,7 +41,6 @@ dependencies {
compileOnly 'world.bentobox:bentobox:1.17.3-SNAPSHOT'
compileOnly 'com.google.guava:guava:31.0.1-jre'
compileOnly 'com.iridium:IridiumSkyblock:3.1.2'
compileOnly 'net.md-5:bungeecord-api:1.16-R0.5-SNAPSHOT'
// CombatLogX V10 + NewbieHelper Expansion
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'

View File

@@ -38,6 +38,8 @@ import com.willfp.eco.internal.scheduling.EcoScheduler
import com.willfp.eco.proxy.FastItemStackFactoryProxy
import com.willfp.eco.spigot.data.EcoKeyRegistry
import com.willfp.eco.spigot.data.EcoPlayerProfileHandler
import com.willfp.eco.spigot.data.storage.MySQLDataHandler
import com.willfp.eco.spigot.data.storage.YamlDataHandler
import com.willfp.eco.spigot.integrations.bstats.MetricHandler
import net.kyori.adventure.platform.bukkit.BukkitAudiences
import org.bukkit.inventory.ItemStack
@@ -49,7 +51,10 @@ class EcoHandler : EcoSpigotPlugin(), Handler {
private val requirementFactory = EcoRequirementFactory()
private var adventure: BukkitAudiences? = null
private val keyRegistry = EcoKeyRegistry(this)
private val playerProfileHandler = EcoPlayerProfileHandler(this)
private val playerProfileHandler = EcoPlayerProfileHandler(
if (this.configYml.getBool("mysql.enabled"))
MySQLDataHandler(this) else YamlDataHandler(this)
)
override fun createScheduler(plugin: EcoPlugin): Scheduler {
return EcoScheduler(plugin)

View File

@@ -25,11 +25,8 @@ import com.willfp.eco.proxy.SkullProxy
import com.willfp.eco.proxy.TPSProxy
import com.willfp.eco.spigot.arrows.ArrowDataListener
import com.willfp.eco.spigot.data.DataListener
import com.willfp.eco.spigot.data.EcoPlayerProfileHandler
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.data.storage.ProfileSaver
import com.willfp.eco.spigot.display.*
import com.willfp.eco.spigot.display.frame.clearFrames
import com.willfp.eco.spigot.drops.CollatedRunnable
@@ -70,8 +67,6 @@ abstract class EcoSpigotPlugin : EcoPlugin(
"com.willfp.eco.proxy",
"&a"
) {
lateinit var dataHandler: DataHandler
init {
Items.registerArgParser(EnchantmentArgParser())
Items.registerArgParser(TextureArgParser())
@@ -93,9 +88,6 @@ abstract class EcoSpigotPlugin : EcoPlugin(
private fun postInit() {
Display.setHandler(EcoDisplayHandler(this))
this.dataHandler = if (this.configYml.getBool("mysql.enabled"))
MySQLDataHandler(this) else YamlDataHandler(this)
}
override fun handleEnable() {
@@ -123,20 +115,12 @@ abstract class EcoSpigotPlugin : EcoPlugin(
// Init FIS
this.getProxy(FastItemStackFactoryProxy::class.java).create(ItemStack(Material.AIR)).unwrap()
/*
I'll figure this one out eventually...
if (Prerequisite.HAS_BUNGEECORD.isMet) {
BungeeDataListener.register()
}
*/
}
override fun handleDisable() {
this.logger.info("Saving player data...")
val start = System.currentTimeMillis()
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).saveAllBlocking()
Eco.getHandler().playerProfileHandler.save()
this.logger.info("Saved player data! Took ${System.currentTimeMillis() - start}ms")
Eco.getHandler().adventure?.close()
}
@@ -144,19 +128,12 @@ abstract class EcoSpigotPlugin : EcoPlugin(
override fun handleReload() {
CollatedRunnable(this)
DropManager.update(this)
ProfileSaver(this)
this.scheduler.runTimer(
{ clearFrames() },
this.configYml.getInt("display-frame-ttl").toLong(),
this.configYml.getInt("display-frame-ttl").toLong()
)
this.scheduler.runTimer(
{
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler)
.autosave()
},
this.configYml.getInt("autosave.ticks").toLong(),
this.configYml.getInt("autosave.ticks").toLong()
)
}
override fun handleAfterLoad() {

View File

@@ -1,34 +0,0 @@
package com.willfp.eco.spigot.data
import com.willfp.eco.core.Eco
import net.md_5.bungee.api.ProxyServer
import net.md_5.bungee.api.event.ServerConnectedEvent
import net.md_5.bungee.api.event.ServerDisconnectEvent
import net.md_5.bungee.api.event.ServerSwitchEvent
import net.md_5.bungee.api.plugin.Listener
import net.md_5.bungee.event.EventHandler
class BungeeDataListener : Listener {
@EventHandler
fun onConnected(event: ServerConnectedEvent) {
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).unloadPlayer(event.player.uniqueId)
}
@EventHandler
fun onDisconnect(event: ServerDisconnectEvent) {
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).unloadPlayer(event.player.uniqueId)
}
@EventHandler
fun onSwitch(event: ServerSwitchEvent) {
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).unloadPlayer(event.player.uniqueId)
}
companion object {
fun register() {
ProxyServer.getInstance().pluginManager.registerListener(
null, BungeeDataListener()
)
}
}
}

View File

@@ -5,18 +5,23 @@ import com.willfp.eco.util.PlayerUtils
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.player.PlayerLoginEvent
import org.bukkit.event.player.PlayerQuitEvent
class DataListener : Listener {
@EventHandler
fun onLeave(event: PlayerQuitEvent) {
PlayerUtils.updateSavedDisplayName(event.player)
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).unloadPlayer(event.player.uniqueId)
Eco.getHandler().playerProfileHandler.unloadPlayer(event.player.uniqueId)
}
@EventHandler
fun onJoin(event: PlayerJoinEvent) {
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).unloadPlayerBlocking(event.player.uniqueId)
PlayerUtils.updateSavedDisplayName(event.player)
}
@EventHandler
fun onLogin(event: PlayerLoginEvent) {
Eco.getHandler().playerProfileHandler.unloadPlayer(event.player.uniqueId)
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.spigot.data
import com.willfp.eco.core.Eco
import com.willfp.eco.core.data.keys.KeyRegistry
import com.willfp.eco.core.data.keys.PersistentDataKey
import com.willfp.eco.core.data.keys.PersistentDataKeyType
@@ -20,7 +21,7 @@ class EcoKeyRegistry(
this.registry[key.key] = key
plugin.dataHandler.updateKeys()
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).updateKeys()
}
override fun getRegisteredKeys(): MutableSet<PersistentDataKey<*>> {

View File

@@ -1,19 +1,16 @@
package com.willfp.eco.spigot.data
import com.willfp.eco.core.Eco
import com.willfp.eco.core.data.PlayerProfile
import com.willfp.eco.core.data.PlayerProfileHandler
import com.willfp.eco.core.data.keys.PersistentDataKey
import com.willfp.eco.internal.data.EcoPlayerProfile
import com.willfp.eco.spigot.EcoSpigotPlugin
import org.bukkit.Bukkit
import java.util.*
import com.willfp.eco.spigot.data.storage.DataHandler
import java.util.UUID
class EcoPlayerProfileHandler(
private val plugin: EcoSpigotPlugin
private val handler: DataHandler
) : PlayerProfileHandler {
private val loaded = mutableMapOf<UUID, PlayerProfile>()
private val handler = plugin.dataHandler
override fun load(uuid: UUID): PlayerProfile {
val found = loaded[uuid]
@@ -23,50 +20,36 @@ class EcoPlayerProfileHandler(
val data = mutableMapOf<PersistentDataKey<*>, Any>()
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
for (key in PersistentDataKey.values()) {
data[key] = handler.read(uuid, key.key) ?: key.defaultValue
}
val profile = EcoPlayerProfile(data)
val profile = EcoPlayerProfile(data, uuid)
loaded[uuid] = profile
return profile
}
fun unloadPlayer(uuid: UUID) {
handler.savePlayer(uuid)
loaded.remove(uuid)
override fun saveKeysForPlayer(uuid: UUID, keys: Set<PersistentDataKey<*>>) {
val profile = PlayerProfile.load(uuid)
for (key in keys) {
handler.write(uuid, key.key, profile.read(key))
}
}
fun unloadPlayerBlocking(uuid: UUID) {
handler.saveAllBlocking(listOf(uuid))
override fun unloadPlayer(uuid: UUID) {
loaded.remove(uuid)
}
override fun savePlayer(uuid: UUID) {
handler.savePlayer(uuid)
}
override fun saveAll() {
handler.saveAll(loaded.keys.toList())
}
fun saveAllBlocking() {
handler.saveAllBlocking(loaded.keys.toList())
override fun save() {
handler.save()
}
fun autosave() {
if (Bukkit.getOnlinePlayers().isEmpty()) {
return
}
if (plugin.configYml.getBool("autosave.log")) {
plugin.logger.info("Auto-Saving player data!")
}
saveAll()
if (plugin.configYml.getBool("autosave.log")) {
plugin.logger.info("Saved player data!")
}
fun updateKeys() {
handler.updateKeys()
}
}

View File

@@ -1,7 +1,8 @@
package com.willfp.eco.spigot.data.storage
import com.willfp.eco.core.data.keys.PersistentDataKey
import org.bukkit.NamespacedKey
import java.util.UUID
import java.util.*
interface DataHandler {
fun save() {
@@ -10,15 +11,15 @@ interface DataHandler {
fun saveAll(uuids: Iterable<UUID>)
fun saveAllBlocking(uuids: Iterable<UUID>) {
saveAll(uuids)
}
fun updateKeys() {
}
fun savePlayer(uuid: UUID) {
saveKeysForPlayer(uuid, PersistentDataKey.values())
}
fun <T> write(uuid: UUID, key: NamespacedKey, value: T)
fun savePlayer(uuid: UUID)
fun saveKeysForPlayer(uuid: UUID, keys: Set<PersistentDataKey<*>>)
fun <T> read(uuid: UUID, key: NamespacedKey): T?
}

View File

@@ -9,20 +9,9 @@ import com.willfp.eco.spigot.EcoSpigotPlugin
import org.apache.logging.log4j.Level
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.exposedLogger
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")
@@ -73,26 +62,20 @@ class MySQLDataHandler(
writeAsserted(uuid, key, value)
}
private fun <T> writeAsserted(uuid: UUID, key: NamespacedKey, value: T, async: Boolean = true) {
private fun <T> writeAsserted(uuid: UUID, key: NamespacedKey, value: T) {
val column: Column<T> = getColumn(key.toString()) as Column<T>
fun executeTransaction() {
executor.submit {
transaction {
Players.update({ Players.id eq uuid }) {
it[column] = value
}
}
}
if (async) {
executor.execute { executeTransaction() }
} else {
executeTransaction()
}
}
override fun savePlayer(uuid: UUID) {
savePlayer(uuid, async = false)
override fun saveKeysForPlayer(uuid: UUID, keys: Set<PersistentDataKey<*>>) {
savePlayer(uuid, keys)
}
override fun saveAll(uuids: Iterable<UUID>) {
@@ -101,20 +84,16 @@ class MySQLDataHandler(
}
}
override fun saveAllBlocking(uuids: Iterable<UUID>) {
for (uuid in uuids) {
savePlayer(uuid, async = false)
}
}
private fun savePlayer(uuid: UUID, async: Boolean = true) {
private fun savePlayer(uuid: UUID, keys: Set<PersistentDataKey<*>>) {
val profile = PlayerProfile.load(uuid)
transaction {
getPlayer(uuid)
executor.submit {
transaction {
getPlayer(uuid)
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
writeAsserted(uuid, key.key, profile.read(key), async = async)
for (key in keys) {
writeAsserted(uuid, key.key, profile.read(key))
}
}
}
}
@@ -125,6 +104,7 @@ class MySQLDataHandler(
val player = getPlayer(uuid)
value = player[getColumn(key.toString())] as T?
}
return value
}

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.spigot.data.storage
import com.willfp.eco.core.Eco
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.data.EcoPlayerProfile
class ProfileSaver(plugin: EcoPlugin) {
init {
plugin.scheduler.runTimer({
for ((uuid, set) in EcoPlayerProfile.CHANGE_MAP) {
Eco.getHandler().playerProfileHandler.saveKeysForPlayer(uuid, set)
}
EcoPlayerProfile.CHANGE_MAP.clear()
}, 1, 1)
}
}

View File

@@ -1,11 +1,11 @@
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.core.data.keys.PersistentDataKey
import com.willfp.eco.spigot.EcoSpigotPlugin
import org.bukkit.NamespacedKey
import java.util.UUID
import java.util.*
@Suppress("UNCHECKED_CAST")
class YamlDataHandler(
@@ -25,10 +25,10 @@ class YamlDataHandler(
save()
}
override fun savePlayer(uuid: UUID) {
override fun saveKeysForPlayer(uuid: UUID, keys: Set<PersistentDataKey<*>>) {
val profile = PlayerProfile.load(uuid)
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
for (key in keys) {
write(uuid, key.key, profile.read(key))
}
}

View File

@@ -11,11 +11,6 @@ mysql:
user: username
password: passy
autosave:
ticks: 20000 # The amount of ticks between autosaves
log: false # If auto-save messages should be sent to console
# Options to fix villager bugs left behind from old (buggy) versions.
villager-display-fix: false

View File

@@ -1,2 +1,2 @@
version = 6.13.6
version = 6.13.7
plugin-name = eco