Compare commits

..

22 Commits

Author SHA1 Message Date
Auxilor
a6f139c47e Fixed plugin.yml 2021-11-05 14:40:56 +00:00
Auxilor
1bae159f94 Added velocity data listener 2021-11-05 14:30:43 +00:00
Auxilor
43d2835087 Prerequisite changes 2021-11-05 14:18:35 +00:00
Auxilor
cb2d4d6a34 Added ServerDisconnectEvent listener 2021-11-05 14:16:41 +00:00
Auxilor
9bb73d8e90 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/spigot/data/storage/MySQLDataHandler.kt
2021-11-05 14:06:22 +00:00
Auxilor
86c4867206 Added BungeeDataListener and IridiumSkyblock support 2021-11-04 20:28:47 +00:00
Auxilor
43e13248d6 SQL changes (Please be done) and Antigrief changes 2021-11-04 20:15:26 +00:00
Auxilor
f6ff45228a Merge branch 'master' into develop 2021-11-04 20:02:29 +00:00
Will FP
af1c20f5c5 Merge pull request #49
Added DeluxeCombat integration
2021-11-04 20:01:59 +00:00
Auxilor
9ac564c345 Finally got exposed to shut up 2021-11-04 20:00:13 +00:00
Auxilor
857d51a7a1 Added PersistentDataKey#values 2021-11-04 19:16:38 +00:00
Auxilor
ab5f8cee5a Cleaned up DataHandler 2021-11-04 19:04:59 +00:00
Auxilor
bdd518b280 More Persistent Data changes 2021-11-04 19:00:47 +00:00
_OfTeN_
494c1a87b2 Added DeluxeCombat integration 2021-11-04 19:30:16 +03:00
Auxilor
f78f92b5f6 Fixed writing 2021-11-04 15:26:31 +00:00
Auxilor
048b56c58c Disabled Exposed logging 2021-11-04 14:06:09 +00:00
Auxilor
75dec2bf49 Re-added writeSafely to optionally specify predefined player ResultRow 2021-11-04 13:36:35 +00:00
Auxilor
7119da13b7 Bug Fixes 2021-11-04 13:32:23 +00:00
Auxilor
6a8637922b More SQL changes 2021-11-04 13:15:21 +00:00
Auxilor
abce7b898c Changed shutdown order 2021-11-04 13:02:23 +00:00
Auxilor
562d7f382c Updated to 6.13.2 2021-11-04 12:59:52 +00:00
Auxilor
c72b15c3a6 Several performance and stability improvements 2021-11-04 12:57:39 +00:00
22 changed files with 383 additions and 94 deletions

View File

@@ -34,7 +34,7 @@ allprojects {
// bStats, mcMMO, BentoBox // bStats, mcMMO, BentoBox
maven { url 'https://repo.codemc.org/repository/maven-public/' } maven { url 'https://repo.codemc.org/repository/maven-public/' }
// Spigot API // Spigot API, Bungee API
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' } maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
// PlaceholderAPI // PlaceholderAPI
@@ -54,6 +54,12 @@ allprojects {
// CombatLogX // CombatLogX
maven { url 'https://nexus.sirblobman.xyz/repository/public/' } maven { url 'https://nexus.sirblobman.xyz/repository/public/' }
// IridiumSkyblock
maven { url 'https://nexus.iridiumdevelopment.net/repository/maven-releases/' }
// Velocity
maven { url 'https://repo.velocitypowered.com/snapshots/' }
} }
dependencies { dependencies {

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core; package com.willfp.eco.core;
import com.willfp.eco.core.integrations.economy.EconomyManager;
import com.willfp.eco.core.proxy.ProxyConstants; import com.willfp.eco.core.proxy.ProxyConstants;
import com.willfp.eco.util.ClassUtils; import com.willfp.eco.util.ClassUtils;
import lombok.Getter; import lombok.Getter;
@@ -31,8 +32,11 @@ public class Prerequisite {
); );
/** /**
* Requires the server to be running an implementation of paper. * Requires the server to have vault installed.
*
* @deprecated Use {@link EconomyManager#hasRegistrations()} instead.
*/ */
@Deprecated
public static final Prerequisite HAS_VAULT = new Prerequisite( public static final Prerequisite HAS_VAULT = new Prerequisite(
() -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"), () -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"),
"Requires server to have vault" "Requires server to have vault"
@@ -46,6 +50,22 @@ public class Prerequisite {
"Requires server to be running 1.17+" "Requires server to be running 1.17+"
); );
/**
* Requires the server to be running an implementation of BungeeCord.
*/
public static final Prerequisite HAS_BUNGEECORD = new Prerequisite(
() -> ClassUtils.exists("net.md_5.bungee.api.event.ServerConnectedEvent"),
"Requires server to be running BungeeCord (or a fork)"
);
/**
* Requires the server to be running an implementation of Velocity.
*/
public static final Prerequisite HAS_VELOCITY = new Prerequisite(
() -> ClassUtils.exists("com.velocitypowered.api.event.player.ServerConnectedEvent"),
"Requires server to be running Velocity (or a fork)"
);
/** /**
* If the necessary prerequisite condition has been met. * If the necessary prerequisite condition has been met.
*/ */

View File

@@ -27,6 +27,15 @@ public interface PlayerProfileHandler {
* Save all player data. * Save all player data.
* *
* @param async If the saving should be done asynchronously. * @param async If the saving should be done asynchronously.
* @deprecated async is now handled automatically depending on implementation.
*/ */
void saveAll(boolean async); @Deprecated
default void saveAll(boolean async) {
saveAll();
}
/**
* Save all player data.
*/
void saveAll();
} }

View File

@@ -5,6 +5,8 @@ import lombok.Getter;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Set;
/** /**
* A persistent data key is a key with a type that can be stored about an offline player. * A persistent data key is a key with a type that can be stored about an offline player.
* *
@@ -54,4 +56,13 @@ public class PersistentDataKey<T> {
+ ", type=" + type + ", type=" + type
+ '}'; + '}';
} }
/**
* Get all persistent data keys.
*
* @return The keys.
*/
public static Set<PersistentDataKey<?>> values() {
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
}
} }

View File

@@ -15,7 +15,7 @@ public interface AntigriefWrapper extends Integration {
* *
* @param player The player. * @param player The player.
* @param block The block. * @param block The block.
* @return If player cna break block. * @return If player can break block.
*/ */
boolean canBreakBlock(Player player, Block block); boolean canBreakBlock(Player player, Block block);

View File

@@ -73,6 +73,11 @@ public abstract class AbstractItemStackBuilder<T extends ItemMeta, U extends Abs
@Override @Override
public U addEnchantment(@NotNull final Enchantment enchantment, public U addEnchantment(@NotNull final Enchantment enchantment,
final int level) { final int level) {
//noinspection ConstantConditions
if (enchantment == null) {
return (U) this;
}
meta.addEnchant(enchantment, level, true); meta.addEnchant(enchantment, level, true);
return (U) this; return (U) this;
} }

View File

@@ -40,6 +40,9 @@ dependencies {
compileOnly 'com.github.MilkBowl:VaultAPI:1.7' compileOnly 'com.github.MilkBowl:VaultAPI:1.7'
compileOnly 'world.bentobox:bentobox:1.17.3-SNAPSHOT' compileOnly 'world.bentobox:bentobox:1.17.3-SNAPSHOT'
compileOnly 'com.google.guava:guava:31.0.1-jre' 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'
compileOnly 'com.velocitypowered:velocity-api:3.0.0-SNAPSHOT'
// CombatLogX V10 + NewbieHelper Expansion // CombatLogX V10 + NewbieHelper Expansion
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT' compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'

View File

@@ -24,18 +24,11 @@ import com.willfp.eco.proxy.FastItemStackFactoryProxy
import com.willfp.eco.proxy.SkullProxy import com.willfp.eco.proxy.SkullProxy
import com.willfp.eco.proxy.TPSProxy import com.willfp.eco.proxy.TPSProxy
import com.willfp.eco.spigot.arrows.ArrowDataListener import com.willfp.eco.spigot.arrows.ArrowDataListener
import com.willfp.eco.spigot.data.DataListener import com.willfp.eco.spigot.data.*
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.DataHandler
import com.willfp.eco.spigot.data.storage.MySQLDataHandler import com.willfp.eco.spigot.data.storage.MySQLDataHandler
import com.willfp.eco.spigot.data.storage.YamlDataHandler import com.willfp.eco.spigot.data.storage.YamlDataHandler
import com.willfp.eco.spigot.display.PacketAutoRecipe import com.willfp.eco.spigot.display.*
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.frame.clearFrames import com.willfp.eco.spigot.display.frame.clearFrames
import com.willfp.eco.spigot.drops.CollatedRunnable import com.willfp.eco.spigot.drops.CollatedRunnable
import com.willfp.eco.spigot.eventlisteners.EntityDeathByEntityListeners import com.willfp.eco.spigot.eventlisteners.EntityDeathByEntityListeners
@@ -46,22 +39,8 @@ import com.willfp.eco.spigot.eventlisteners.armor.ArmorListener
import com.willfp.eco.spigot.gui.GUIListener import com.willfp.eco.spigot.gui.GUIListener
import com.willfp.eco.spigot.integrations.afk.AFKIntegrationCMI import com.willfp.eco.spigot.integrations.afk.AFKIntegrationCMI
import com.willfp.eco.spigot.integrations.afk.AFKIntegrationEssentials import com.willfp.eco.spigot.integrations.afk.AFKIntegrationEssentials
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAAC import com.willfp.eco.spigot.integrations.anticheat.*
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAlice import com.willfp.eco.spigot.integrations.antigrief.*
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.customitems.CustomItemsHeadDatabase import com.willfp.eco.spigot.integrations.customitems.CustomItemsHeadDatabase
import com.willfp.eco.spigot.integrations.customitems.CustomItemsItemsAdder import com.willfp.eco.spigot.integrations.customitems.CustomItemsItemsAdder
import com.willfp.eco.spigot.integrations.customitems.CustomItemsOraxen import com.willfp.eco.spigot.integrations.customitems.CustomItemsOraxen
@@ -144,6 +123,10 @@ abstract class EcoSpigotPlugin : EcoPlugin(
} }
override fun handleDisable() { override fun handleDisable() {
this.logger.info("Saving player data...")
val start = System.currentTimeMillis()
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).saveAllBlocking()
this.logger.info("Saved player data! Took ${System.currentTimeMillis() - start}ms")
Eco.getHandler().adventure?.close() Eco.getHandler().adventure?.close()
} }
@@ -158,7 +141,7 @@ abstract class EcoSpigotPlugin : EcoPlugin(
this.scheduler.runTimer( this.scheduler.runTimer(
{ {
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler) (Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler)
.autosave(this.configYml.getBool("autosave.async")) .autosave()
}, },
this.configYml.getInt("autosave.ticks").toLong(), this.configYml.getInt("autosave.ticks").toLong(),
this.configYml.getInt("autosave.ticks").toLong() this.configYml.getInt("autosave.ticks").toLong()
@@ -173,6 +156,8 @@ abstract class EcoSpigotPlugin : EcoPlugin(
override fun loadIntegrationLoaders(): List<IntegrationLoader> { override fun loadIntegrationLoaders(): List<IntegrationLoader> {
return listOf( return listOf(
// AntiGrief // AntiGrief
IntegrationLoader("IridiumSkyblock") { AntigriefManager.register(AntigriefIridiumSkyblock()) },
IntegrationLoader("DeluxeCombat") { AntigriefManager.register(AntigriefDeluxeCombat()) },
IntegrationLoader("SuperiorSkyblock2") { AntigriefManager.register(AntigriefSuperiorSkyblock2()) }, IntegrationLoader("SuperiorSkyblock2") { AntigriefManager.register(AntigriefSuperiorSkyblock2()) },
IntegrationLoader("BentoBox") { AntigriefManager.register(AntigriefBentoBox()) }, IntegrationLoader("BentoBox") { AntigriefManager.register(AntigriefBentoBox()) },
IntegrationLoader("WorldGuard") { AntigriefManager.register(AntigriefWorldGuard()) }, IntegrationLoader("WorldGuard") { AntigriefManager.register(AntigriefWorldGuard()) },
@@ -248,7 +233,7 @@ abstract class EcoSpigotPlugin : EcoPlugin(
} }
override fun loadListeners(): List<Listener> { override fun loadListeners(): List<Listener> {
return listOf( val listeners = mutableListOf(
NaturalExpGainListeners(), NaturalExpGainListeners(),
ArmorListener(), ArmorListener(),
EntityDeathByEntityListeners(this), EntityDeathByEntityListeners(this),
@@ -260,5 +245,15 @@ abstract class EcoSpigotPlugin : EcoPlugin(
DataListener(), DataListener(),
PlayerBlockListener(this) PlayerBlockListener(this)
) )
if (Prerequisite.HAS_BUNGEECORD.isMet) {
listeners.add(BungeeDataListener())
}
if (Prerequisite.HAS_VELOCITY.isMet) {
listeners.add(VelocityDataListener())
}
return listeners
} }
} }

View File

@@ -0,0 +1,25 @@
package com.willfp.eco.spigot.data
import com.willfp.eco.core.Eco
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 org.bukkit.event.EventHandler
import org.bukkit.event.Listener
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)
}
}

View File

@@ -11,11 +11,12 @@ class DataListener : Listener {
@EventHandler @EventHandler
fun onLeave(event: PlayerQuitEvent) { fun onLeave(event: PlayerQuitEvent) {
PlayerUtils.updateSavedDisplayName(event.player) PlayerUtils.updateSavedDisplayName(event.player)
Eco.getHandler().playerProfileHandler.savePlayer(event.player.uniqueId) (Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).unloadPlayer(event.player.uniqueId)
} }
@EventHandler @EventHandler
fun onJoin(event: PlayerJoinEvent) { fun onJoin(event: PlayerJoinEvent) {
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).unloadPlayer(event.player.uniqueId)
PlayerUtils.updateSavedDisplayName(event.player) PlayerUtils.updateSavedDisplayName(event.player)
} }
} }

View File

@@ -7,7 +7,7 @@ import com.willfp.eco.core.data.keys.PersistentDataKey
import com.willfp.eco.internal.data.EcoPlayerProfile import com.willfp.eco.internal.data.EcoPlayerProfile
import com.willfp.eco.spigot.EcoSpigotPlugin import com.willfp.eco.spigot.EcoSpigotPlugin
import org.bukkit.Bukkit import org.bukkit.Bukkit
import java.util.* import java.util.UUID
class EcoPlayerProfileHandler( class EcoPlayerProfileHandler(
private val plugin: EcoSpigotPlugin private val plugin: EcoSpigotPlugin
@@ -32,40 +32,24 @@ class EcoPlayerProfileHandler(
return profile return profile
} }
fun unloadPlayer(uuid: UUID) {
handler.savePlayer(uuid)
loaded.remove(uuid)
}
override fun savePlayer(uuid: UUID) { override fun savePlayer(uuid: UUID) {
writeToHandler(uuid) handler.savePlayer(uuid)
saveToHandler()
} }
private fun writeToHandler(uuid: UUID) { override fun saveAll() {
val profile = load(uuid) handler.saveAll(loaded.keys.toList())
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
handler.write(uuid, key.key, profile.read(key) ?: key.defaultValue)
}
} }
private fun saveToHandler() { fun saveAllBlocking() {
handler.save() handler.saveAllBlocking(loaded.keys.toList())
} }
override fun saveAll(async: Boolean) { fun autosave() {
val saver = {
for ((uuid, _) in loaded) {
writeToHandler(uuid)
}
saveToHandler()
}
if (async) {
plugin.scheduler.runAsync(saver)
} else {
saver.invoke()
}
}
fun autosave(async: Boolean) {
if (Bukkit.getOnlinePlayers().isEmpty()) { if (Bukkit.getOnlinePlayers().isEmpty()) {
return return
} }
@@ -74,7 +58,7 @@ class EcoPlayerProfileHandler(
plugin.logger.info("Auto-Saving player data!") plugin.logger.info("Auto-Saving player data!")
} }
saveAll(async) saveAll()
if (plugin.configYml.getBool("autosave.log")) { if (plugin.configYml.getBool("autosave.log")) {
plugin.logger.info("Saved player data!") plugin.logger.info("Saved player data!")

View File

@@ -0,0 +1,19 @@
package com.willfp.eco.spigot.data
import com.velocitypowered.api.event.connection.DisconnectEvent
import com.velocitypowered.api.event.player.ServerConnectedEvent
import com.willfp.eco.core.Eco
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
class VelocityDataListener : Listener {
@EventHandler
fun onConnected(event: ServerConnectedEvent) {
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).unloadPlayer(event.player.uniqueId)
}
@EventHandler
fun onDisconnect(event: DisconnectEvent) {
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler).unloadPlayer(event.player.uniqueId)
}
}

View File

@@ -1,13 +1,24 @@
package com.willfp.eco.spigot.data.storage package com.willfp.eco.spigot.data.storage
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import java.util.* import java.util.UUID
interface DataHandler { interface DataHandler {
fun save() fun save() {
}
fun saveAll(uuids: Iterable<UUID>)
fun saveAllBlocking(uuids: Iterable<UUID>) {
saveAll(uuids)
}
fun updateKeys() {
}
fun <T> write(uuid: UUID, key: NamespacedKey, value: T) fun <T> write(uuid: UUID, key: NamespacedKey, value: T)
fun savePlayer(uuid: UUID)
fun <T> read(uuid: UUID, key: NamespacedKey): T? fun <T> read(uuid: UUID, key: NamespacedKey): T?
fun updateKeys()
} }

View File

@@ -1,9 +1,12 @@
package com.willfp.eco.spigot.data.storage 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.Eco
import com.willfp.eco.core.data.PlayerProfile
import com.willfp.eco.core.data.keys.PersistentDataKey import com.willfp.eco.core.data.keys.PersistentDataKey
import com.willfp.eco.core.data.keys.PersistentDataKeyType import com.willfp.eco.core.data.keys.PersistentDataKeyType
import com.willfp.eco.spigot.EcoSpigotPlugin import com.willfp.eco.spigot.EcoSpigotPlugin
import org.apache.logging.log4j.Level
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.jetbrains.exposed.dao.id.UUIDTable import org.jetbrains.exposed.dao.id.UUIDTable
import org.jetbrains.exposed.sql.BooleanColumnType import org.jetbrains.exposed.sql.BooleanColumnType
@@ -13,18 +16,25 @@ import org.jetbrains.exposed.sql.DoubleColumnType
import org.jetbrains.exposed.sql.IntegerColumnType import org.jetbrains.exposed.sql.IntegerColumnType
import org.jetbrains.exposed.sql.ResultRow import org.jetbrains.exposed.sql.ResultRow
import org.jetbrains.exposed.sql.SchemaUtils import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.VarCharColumnType import org.jetbrains.exposed.sql.VarCharColumnType
import org.jetbrains.exposed.sql.checkMappingConsistence
import org.jetbrains.exposed.sql.exposedLogger
import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update import org.jetbrains.exposed.sql.update
import java.util.UUID import java.util.UUID
import java.util.concurrent.Executors
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
class MySQLDataHandler( class MySQLDataHandler(
plugin: EcoSpigotPlugin plugin: EcoSpigotPlugin
) : DataHandler { ) : DataHandler {
private val columns = mutableMapOf<String, Column<*>>() private val columns = mutableMapOf<String, Column<*>>()
private val threadFactory = ThreadFactoryBuilder().setNameFormat("eco-mysql-thread-%d").build()
private val executor = Executors.newCachedThreadPool(threadFactory)
init { init {
Database.connect( Database.connect(
@@ -40,6 +50,15 @@ class MySQLDataHandler(
transaction { transaction {
SchemaUtils.create(Players) SchemaUtils.create(Players)
} }
// Get Exposed to shut the hell up
exposedLogger::class.java.getDeclaredField("logger").apply { isAccessible = true }
.apply {
get(exposedLogger).apply {
this.javaClass.getDeclaredMethod("setLevel", Level::class.java)
.invoke(this, Level.OFF)
}
}
} }
override fun updateKeys() { override fun updateKeys() {
@@ -52,21 +71,57 @@ class MySQLDataHandler(
} }
} }
override fun save() { override fun <T> write(uuid: UUID, key: NamespacedKey, value: T) {
// Do nothing getPlayer(uuid)
writeAsserted(uuid, key, value)
} }
override fun <T> write(uuid: UUID, key: NamespacedKey, value: T) { private fun <T> writeAsserted(uuid: UUID, key: NamespacedKey, value: T, async: Boolean = true) {
transaction {
getPlayer(uuid)
val column: Column<T> = getColumn(key.toString()) as Column<T> val column: Column<T> = getColumn(key.toString()) as Column<T>
fun executeTransaction() {
transaction {
Players.update({ Players.id eq uuid }) { Players.update({ Players.id eq uuid }) {
it[column] = value it[column] = value
} }
} }
} }
if (async) {
executor.execute { executeTransaction() }
} else {
executeTransaction()
}
}
override fun savePlayer(uuid: UUID) {
savePlayer(uuid, async = false)
}
override fun saveAll(uuids: Iterable<UUID>) {
for (uuid in uuids) {
savePlayer(uuid)
}
}
override fun saveAllBlocking(uuids: Iterable<UUID>) {
for (uuid in uuids) {
savePlayer(uuid, async = false)
}
}
private fun savePlayer(uuid: UUID, async: Boolean = true) {
val profile = PlayerProfile.load(uuid)
transaction {
getPlayer(uuid)
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
writeAsserted(uuid, key.key, profile.read(key), async = async)
}
}
}
override fun <T> read(uuid: UUID, key: NamespacedKey): T? { override fun <T> read(uuid: UUID, key: NamespacedKey): T? {
var value: T? = null var value: T? = null
transaction { transaction {
@@ -76,9 +131,7 @@ class MySQLDataHandler(
return value return value
} }
object Players : UUIDTable("eco_players") { object Players : UUIDTable("eco_players")
}
private fun <T> registerColumn(key: PersistentDataKey<T>, table: UUIDTable) { private fun <T> registerColumn(key: PersistentDataKey<T>, table: UUIDTable) {
table.apply { table.apply {
@@ -112,12 +165,40 @@ class MySQLDataHandler(
} }
private fun getPlayer(uuid: UUID): ResultRow { private fun getPlayer(uuid: UUID): ResultRow {
Players.select { Players.id eq uuid }.firstOrNull() ?: run { val player = transaction {
Players.insert { Players.select { Players.id eq uuid }.limit(1).singleOrNull()
it[id] = uuid }
return if (player != null) {
player
} else {
transaction {
Players.insert { it[id] = uuid }
}
getPlayer(uuid)
} }
} }
return Players.select { Players.id eq uuid }.first() private fun createMissingTablesAndColumnsSilently(table: Table) {
with(TransactionManager.current()) {
fun execStatements(statements: List<String>) {
for (statement in statements) {
exec(statement)
}
}
db.dialect.resetCaches()
val createStatements = SchemaUtils.createStatements(table)
execStatements(createStatements)
commit()
val alterStatements = SchemaUtils.addMissingColumnsStatements(table)
execStatements(alterStatements)
commit()
val executedStatements = createStatements + alterStatements
val modifyTablesStatements = checkMappingConsistence(table).filter { it !in executedStatements }
execStatements(modifyTablesStatements)
commit()
db.dialect.resetCaches()
}
} }
} }

View File

@@ -1,9 +1,11 @@
package com.willfp.eco.spigot.data.storage 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.config.yaml.YamlBaseConfig
import com.willfp.eco.core.data.PlayerProfile
import com.willfp.eco.spigot.EcoSpigotPlugin import com.willfp.eco.spigot.EcoSpigotPlugin
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import java.util.* import java.util.UUID
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
class YamlDataHandler( class YamlDataHandler(
@@ -15,8 +17,20 @@ class YamlDataHandler(
dataYml.save() dataYml.save()
} }
override fun updateKeys() { override fun saveAll(uuids: Iterable<UUID>) {
// Do nothing for (uuid in uuids) {
savePlayer(uuid)
}
save()
}
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) { override fun <T> write(uuid: UUID, key: NamespacedKey, value: T) {

View File

@@ -47,14 +47,8 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
handleRateLimit(player) handleRateLimit(player)
if (usingAsync(player)) { if (usingAsync(player)) {
executor.execute { fun modifyAndSend(itemStacks: MutableList<ItemStack>, windowId: Int, player: Player) {
try {
modifyWindowItems(itemStacks, windowId, player) 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")
}
}
val newPacket = packet.deepClone() val newPacket = packet.deepClone()
newPacket.itemListModifier.write(0, itemStacks) newPacket.itemListModifier.write(0, itemStacks)
@@ -63,6 +57,20 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
ProtocolLibrary.getProtocolManager().sendServerPacket(player, newPacket) 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 { } else {
packet.itemListModifier.write(0, modifyWindowItems(itemStacks, windowId, player)) 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 { private fun usingAsync(player: Player): Boolean {
if (this.getPlugin().configYml.getStrings("async-display.disable-on-types", false) 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 return false
} }

View File

@@ -0,0 +1,34 @@
package com.willfp.eco.spigot.integrations.antigrief
import com.willfp.eco.core.integrations.antigrief.AntigriefWrapper
import nl.marido.deluxecombat.api.DeluxeCombatAPI
import org.bukkit.Location
import org.bukkit.block.Block
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
class AntigriefDeluxeCombat: AntigriefWrapper {
override fun getPluginName(): String {
return "DeluxeCombat";
}
override fun canBreakBlock(player: Player, block: Block): Boolean {
return true;
}
override fun canCreateExplosion(player: Player, location: Location): Boolean {
return true;
}
override fun canPlaceBlock(player: Player, block: Block): Boolean {
return true;
}
override fun canInjure(player: Player, victim: LivingEntity): Boolean {
val api = DeluxeCombatAPI()
return when(victim) {
is Player -> (api.hasProtection(victim) || !api.hasPvPEnabled(victim)) && !api.isInCombat(victim)
else -> true
}
}
}

View File

@@ -0,0 +1,60 @@
package com.willfp.eco.spigot.integrations.antigrief
import com.iridium.iridiumskyblock.PermissionType
import com.iridium.iridiumskyblock.api.IridiumSkyblockAPI
import com.willfp.eco.core.integrations.antigrief.AntigriefWrapper
import org.bukkit.Location
import org.bukkit.block.Block
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
class AntigriefIridiumSkyblock : AntigriefWrapper {
private val api = IridiumSkyblockAPI.getInstance()
override fun canBreakBlock(
player: Player,
block: Block
): Boolean {
return api.getIslandPermission(api.getIslandViaLocation(block.location).orElse(null) ?: return true, api.getUser(player), PermissionType.BLOCK_BREAK)
}
override fun canCreateExplosion(
player: Player,
location: Location
): Boolean {
return api.getIslandPermission(api.getIslandViaLocation(location).orElse(null) ?: return true, api.getUser(player), PermissionType.BLOCK_BREAK)
}
override fun canPlaceBlock(
player: Player,
block: Block
): Boolean {
return api.getIslandPermission(api.getIslandViaLocation(block.location).orElse(null) ?: return true, api.getUser(player), PermissionType.BLOCK_PLACE)
}
override fun canInjure(
player: Player,
victim: LivingEntity
): Boolean {
return when (victim) {
is Player -> api.getIslandViaLocation(victim.location).orElse(null) != null
else -> api.getIslandPermission(api.getIslandViaLocation(victim.location).orElse(null) ?: return true, api.getUser(player), PermissionType.KILL_MOBS)
}
}
override fun getPluginName(): String {
return "IridiumSkyblock"
}
override fun equals(other: Any?): Boolean {
if (other !is AntigriefWrapper) {
return false
}
return other.pluginName == this.pluginName
}
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}

View File

@@ -14,7 +14,6 @@ mysql:
autosave: autosave:
ticks: 20000 # The amount of ticks between autosaves ticks: 20000 # The amount of ticks between autosaves
log: false # If auto-save messages should be sent to console 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. # Options to fix villager bugs left behind from old (buggy) versions.

View File

@@ -33,6 +33,9 @@ softdepend:
- Essentials - Essentials
- Vault - Vault
- BentoBox - BentoBox
- DeluxeCombat
- IridiumSkyblock
- SuperiorSkyblock2
libraries: libraries:
- 'org.reflections:reflections:0.9.12' - 'org.reflections:reflections:0.9.12'
- 'org.apache.maven:maven-artifact:3.0.3' - 'org.apache.maven:maven-artifact:3.0.3'

View File

@@ -1,2 +1,2 @@
version = 6.13.1 version = 6.13.2
plugin-name = eco plugin-name = eco

BIN
lib/DeluxeCombat API.jar Normal file

Binary file not shown.