Compare commits

..

44 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
Auxilor
54b7e99c82 Updated to 6.13.1 2021-11-03 11:32:41 +00:00
Auxilor
4b6a0ee05d Added option to blacklist inventory types from async display, fixing anvils 2021-11-03 11:32:31 +00:00
Auxilor
89e5d8898b Merge branch 'master' into develop
# Conflicts:
#	eco-core/core-plugin/src/main/resources/config.yml
2021-11-03 11:00:25 +00:00
Auxilor
08c14f4def Cleaned up BentoBox 2021-11-02 19:28:19 +00:00
Auxilor
0fa6f972c0 Fixed BentoBox 2021-11-02 19:26:34 +00:00
Auxilor
8837fecfa0 Added support for BentoBox 2021-11-02 19:24:34 +00:00
Auxilor
af1841770e (Hopefully) fixed HologramCMI 2021-11-02 18:54:21 +00:00
Auxilor
1d85dbf08d Altered rate limit settings 2021-11-02 18:52:57 +00:00
Auxilor
ba9812534a Increased timeframe to 2 2021-11-02 18:46:28 +00:00
Auxilor
1f95a33385 Added log errors option for async display 2021-11-02 18:39:29 +00:00
Auxilor
bc652a8154 MySQLDataHandler changes 2021-11-02 18:37:01 +00:00
Auxilor
0c2e1f0cae Fixed ServerUtils 2021-11-02 18:29:17 +00:00
Auxilor
39d6eb7f9a Updated to 6.13.0 2021-11-02 18:17:57 +00:00
Auxilor
61bae6de55 Rearranged config.yml 2021-11-02 18:17:40 +00:00
Auxilor
86f230c836 Added in config.yml warning 2021-11-02 17:46:47 +00:00
Auxilor
aa4ac4c6d1 Added option to set rate limit timeframe 2021-11-02 17:44:57 +00:00
Auxilor
7141b12e95 Removed redundant explicit type 2021-11-02 17:42:27 +00:00
Auxilor
2382548629 Added in rate limiting for PacketWindowItems.kt 2021-11-02 17:39:41 +00:00
Auxilor
0c4bd182f7 Ignored async exceptions in PacketWindowItems.kt 2021-11-02 17:09:48 +00:00
Auxilor
e90e053b45 Added emergency async display and ServerUtils 2021-11-02 16:50:04 +00:00
Auxilor
742c1abb00 Cleaned up async display 2021-11-02 14:10:57 +00:00
Auxilor
c0686ca386 Added guava and asynchronous window items processing 2021-11-02 13:53:30 +00:00
31 changed files with 739 additions and 143 deletions

View File

@@ -31,10 +31,10 @@ allprojects {
// NMS (for jitpack compilation) // NMS (for jitpack compilation)
maven { url 'https://repo.codemc.org/repository/nms/' } maven { url 'https://repo.codemc.org/repository/nms/' }
// bStats, mcMMO // 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

@@ -1,6 +1,5 @@
package com.willfp.eco.core.display; package com.willfp.eco.core.display;
import lombok.Setter;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -21,7 +20,6 @@ public class Display {
/** /**
* The display handler. * The display handler.
*/ */
@Setter
private static DisplayHandler handler = null; private static DisplayHandler handler = null;
/** /**
@@ -162,4 +160,20 @@ public class Display {
module.display(itemStack, player, args); module.display(itemStack, player, args);
} }
} }
/**
* Set the display handler.
* <p>
* Internal API component, you will cause bugs if you create your own handler.
*
* @param handler The handler.
*/
@ApiStatus.Internal
public static void setHandler(@NotNull final DisplayHandler handler) {
if (Display.handler != null) {
throw new IllegalStateException("Display already initialized!");
}
Display.handler = handler;
}
} }

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

@@ -0,0 +1,48 @@
package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.function.Supplier;
/**
* Utilities / API methods for the server.
*/
@UtilityClass
public class ServerUtils {
/**
* The TPS supplier.
*/
private Supplier<Double> tpsSupplier = null;
/**
* Get the current server TPS.
*
* @return The TPS.
*/
public double getTps() {
Validate.notNull(tpsSupplier, "Not initialized!");
double tps = tpsSupplier.get();
if (tps > 20) {
return 20;
} else {
return tps;
}
}
/**
* Initialize the tps supplier function.
*
* @param function The function.
*/
@ApiStatus.Internal
public void initialize(@NotNull final Supplier<Double> function) {
Validate.isTrue(tpsSupplier == null, "Already initialized!");
tpsSupplier = function;
}
}

View File

@@ -7,4 +7,5 @@ dependencies {
compileOnly 'org.reflections:reflections:0.9.12' compileOnly 'org.reflections:reflections:0.9.12'
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT' compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0' compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
compileOnly 'com.google.guava:guava:31.0.1-jre'
} }

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.internal.display package com.willfp.eco.internal.display
import com.google.common.util.concurrent.ThreadFactoryBuilder
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.display.Display import com.willfp.eco.core.display.Display
import com.willfp.eco.core.display.DisplayHandler import com.willfp.eco.core.display.DisplayHandler
@@ -10,16 +11,11 @@ import org.bukkit.NamespacedKey
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataType import org.bukkit.persistence.PersistentDataType
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler { class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler {
/**
* All registered display modules.
*/
private val registeredModules = mutableMapOf<DisplayPriority, MutableList<DisplayModule>>() private val registeredModules = mutableMapOf<DisplayPriority, MutableList<DisplayModule>>()
/**
* NamespacedKey for finalizing.
*/
private val finalizeKey: NamespacedKey = plugin.namespacedKeyFactory.create("finalized") private val finalizeKey: NamespacedKey = plugin.namespacedKeyFactory.create("finalized")
init { init {

View File

@@ -0,0 +1,11 @@
package com.willfp.eco.proxy.v1_16_R3
import com.willfp.eco.proxy.TPSProxy
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.v1_16_R3.CraftServer
class TPS : TPSProxy {
override fun getTPS(): Double {
return (Bukkit.getServer() as CraftServer).handle.server.recentTps[0]
}
}

View File

@@ -0,0 +1,11 @@
package com.willfp.eco.proxy.v1_17_R1
import com.willfp.eco.proxy.TPSProxy
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.v1_17_R1.CraftServer
class TPS : TPSProxy {
override fun getTPS(): Double {
return (Bukkit.getServer() as CraftServer).handle.server.recentTps[0]
}
}

View File

@@ -38,6 +38,11 @@ dependencies {
compileOnly 'net.essentialsx:EssentialsX:2.19.0' compileOnly 'net.essentialsx:EssentialsX:2.19.0'
compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:latest' compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:latest'
compileOnly 'com.github.MilkBowl:VaultAPI:1.7' compileOnly 'com.github.MilkBowl:VaultAPI:1.7'
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'
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

@@ -22,19 +22,13 @@ import com.willfp.eco.internal.drops.DropManager
import com.willfp.eco.proxy.BlockBreakProxy import com.willfp.eco.proxy.BlockBreakProxy
import com.willfp.eco.proxy.FastItemStackFactoryProxy 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.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
@@ -45,21 +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.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
@@ -72,16 +53,14 @@ import com.willfp.eco.spigot.integrations.multiverseinventories.MultiverseInvent
import com.willfp.eco.spigot.integrations.shop.ShopShopGuiPlus import com.willfp.eco.spigot.integrations.shop.ShopShopGuiPlus
import com.willfp.eco.spigot.recipes.ShapedRecipeListener import com.willfp.eco.spigot.recipes.ShapedRecipeListener
import com.willfp.eco.util.BlockUtils import com.willfp.eco.util.BlockUtils
import com.willfp.eco.util.ServerUtils
import com.willfp.eco.util.SkullUtils import com.willfp.eco.util.SkullUtils
import net.kyori.adventure.platform.bukkit.BukkitAudiences import net.kyori.adventure.platform.bukkit.BukkitAudiences
import net.milkbowl.vault.economy.Economy import net.milkbowl.vault.economy.Economy
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.block.Block
import org.bukkit.entity.Player
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.SkullMeta
abstract class EcoSpigotPlugin : EcoPlugin( abstract class EcoSpigotPlugin : EcoPlugin(
773, 773,
@@ -97,12 +76,15 @@ abstract class EcoSpigotPlugin : EcoPlugin(
val skullProxy = getProxy(SkullProxy::class.java) val skullProxy = getProxy(SkullProxy::class.java)
SkullUtils.initialize( SkullUtils.initialize(
{ meta: SkullMeta, base64: String -> skullProxy.setSkullTexture(meta, base64) }, { meta, base64 -> skullProxy.setSkullTexture(meta, base64) },
{ meta: SkullMeta -> skullProxy.getSkullTexture(meta) } { meta -> skullProxy.getSkullTexture(meta) }
) )
val blockBreakProxy = getProxy(BlockBreakProxy::class.java) val blockBreakProxy = getProxy(BlockBreakProxy::class.java)
BlockUtils.initialize { player: Player, block: Block -> blockBreakProxy.breakBlock(player, block) } BlockUtils.initialize { player, block -> blockBreakProxy.breakBlock(player, block) }
val tpsProxy = getProxy(TPSProxy::class.java)
ServerUtils.initialize { tpsProxy.getTPS() }
postInit() postInit()
} }
@@ -141,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()
} }
@@ -155,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()
@@ -170,7 +156,10 @@ 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("WorldGuard") { AntigriefManager.register(AntigriefWorldGuard()) }, IntegrationLoader("WorldGuard") { AntigriefManager.register(AntigriefWorldGuard()) },
IntegrationLoader("GriefPrevention") { AntigriefManager.register(AntigriefGriefPrevention()) }, IntegrationLoader("GriefPrevention") { AntigriefManager.register(AntigriefGriefPrevention()) },
IntegrationLoader("FactionsUUID") { AntigriefManager.register(AntigriefFactionsUUID()) }, IntegrationLoader("FactionsUUID") { AntigriefManager.register(AntigriefFactionsUUID()) },
@@ -244,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),
@@ -256,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,17 +71,53 @@ 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) {
val column: Column<T> = getColumn(key.toString()) as Column<T>
fun executeTransaction() {
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 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 { transaction {
getPlayer(uuid) getPlayer(uuid)
val column: Column<T> = getColumn(key.toString()) as Column<T>
Players.update({ Players.id eq uuid }) { for (key in Eco.getHandler().keyRegistry.registeredKeys) {
it[column] = value writeAsserted(uuid, key.key, profile.read(key), async = async)
} }
} }
} }
@@ -76,12 +131,14 @@ 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 {
if (this.columns.stream().anyMatch { it.name == key.key.toString() }) {
return@apply
}
when (key.type) { when (key.type) {
PersistentDataKeyType.INT -> registerColumn<Int>(key.key.toString(), IntegerColumnType()) PersistentDataKeyType.INT -> registerColumn<Int>(key.key.toString(), IntegerColumnType())
.default(key.defaultValue as Int) .default(key.defaultValue as Int)
@@ -89,7 +146,7 @@ class MySQLDataHandler(
.default(key.defaultValue as Double) .default(key.defaultValue as Double)
PersistentDataKeyType.BOOLEAN -> registerColumn<Boolean>(key.key.toString(), BooleanColumnType()) PersistentDataKeyType.BOOLEAN -> registerColumn<Boolean>(key.key.toString(), BooleanColumnType())
.default(key.defaultValue as Boolean) .default(key.defaultValue as Boolean)
PersistentDataKeyType.STRING -> registerColumn<String>(key.key.toString(), VarCharColumnType(128)) PersistentDataKeyType.STRING -> registerColumn<String>(key.key.toString(), VarCharColumnType(512))
.default(key.defaultValue as String) .default(key.defaultValue as String)
else -> throw NullPointerException("Null value found!") else -> throw NullPointerException("Null value found!")
@@ -108,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 Players.select { Players.id eq uuid }.first() return if (player != null) {
player
} else {
transaction {
Players.insert { it[id] = uuid }
}
getPlayer(uuid)
}
}
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

@@ -1,8 +1,10 @@
package com.willfp.eco.spigot.display package com.willfp.eco.spigot.display
import com.comphenix.protocol.PacketType import com.comphenix.protocol.PacketType
import com.comphenix.protocol.ProtocolLibrary
import com.comphenix.protocol.events.PacketContainer import com.comphenix.protocol.events.PacketContainer
import com.comphenix.protocol.events.PacketEvent import com.comphenix.protocol.events.PacketEvent
import com.google.common.util.concurrent.ThreadFactoryBuilder
import com.willfp.eco.core.AbstractPacketAdapter import com.willfp.eco.core.AbstractPacketAdapter
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.display.Display import com.willfp.eco.core.display.Display
@@ -10,53 +12,151 @@ import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.spigot.display.frame.DisplayFrame import com.willfp.eco.spigot.display.frame.DisplayFrame
import com.willfp.eco.spigot.display.frame.HashedItem import com.willfp.eco.spigot.display.frame.HashedItem
import com.willfp.eco.spigot.display.frame.lastDisplayFrame import com.willfp.eco.spigot.display.frame.lastDisplayFrame
import com.willfp.eco.util.ServerUtils
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.WINDOW_ITEMS, false) { class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.WINDOW_ITEMS, false) {
private val ignorePacketList = ConcurrentHashMap.newKeySet<String>()
private val playerRates = ConcurrentHashMap<String, Int>()
private val threadFactory = ThreadFactoryBuilder().setNameFormat("eco-display-thread-%d").build()
private val executor = Executors.newCachedThreadPool(threadFactory)
private val scheduledExecutor = Executors.newSingleThreadScheduledExecutor(threadFactory)
override fun onSend( override fun onSend(
packet: PacketContainer, packet: PacketContainer,
player: Player, player: Player,
event: PacketEvent event: PacketEvent
) { ) {
if (ignorePacketList.contains(player.name)) {
ignorePacketList.remove(player.name)
return
}
val windowId = packet.integers.read(0) val windowId = packet.integers.read(0)
if (windowId != 0) { if (windowId != 0) {
player.lastDisplayFrame = DisplayFrame.EMPTY player.lastDisplayFrame = DisplayFrame.EMPTY
} }
packet.itemListModifier.modify(0) { itemStacks: MutableList<ItemStack>? -> val itemStacks = packet.itemListModifier.read(0) ?: return
if (itemStacks == null) {
return@modify null handleRateLimit(player)
if (usingAsync(player)) {
fun modifyAndSend(itemStacks: MutableList<ItemStack>, windowId: Int, player: Player) {
modifyWindowItems(itemStacks, windowId, player)
val newPacket = packet.deepClone()
newPacket.itemListModifier.write(0, itemStacks)
ignorePacketList.add(player.name)
ProtocolLibrary.getProtocolManager().sendServerPacket(player, newPacket)
} }
if (this.getPlugin().configYml.getBool("use-display-frame") && windowId == 0) { executor.execute {
val frameMap = mutableMapOf<Byte, HashedItem>() 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")
}
for (index in itemStacks.indices) { this.getPlugin().scheduler.run {
frameMap[index.toByte()] = modifyAndSend(itemStacks, windowId, player)
HashedItem(FastItemStack.wrap(itemStacks[index]).hashCode(), itemStacks[index]) }
} }
val newFrame = DisplayFrame(frameMap)
val lastFrame = player.lastDisplayFrame
player.lastDisplayFrame = newFrame
val changes = lastFrame.getChangedSlots(newFrame)
for (index in changes) {
Display.display(itemStacks[index.toInt()], player)
}
for (index in (itemStacks.indices subtract changes)) {
itemStacks[index.toInt()] = lastFrame.getItem(index.toByte()) ?: itemStacks[index.toInt()]
}
} else {
itemStacks.forEach { Display.display(it, player) }
} }
itemStacks } else {
packet.itemListModifier.write(0, modifyWindowItems(itemStacks, windowId, player))
} }
} }
private fun handleRateLimit(player: Player) {
fun modifyRateValueBy(player: Player, amount: Int) {
val name = player.name
val current = playerRates[name] ?: 0
val new = current + amount
if (new <= 0) {
playerRates.remove(name)
} else {
playerRates[name] = new
}
}
modifyRateValueBy(player, 1)
scheduledExecutor.schedule(
{ modifyRateValueBy(player, -1) },
this.getPlugin().configYml.getInt("async-display.ratelimit.timeframe").toLong(),
TimeUnit.SECONDS
)
}
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())
) {
return false
}
if (this.getPlugin().configYml.getBool("async-display.enabled")) {
return true
}
if (
this.getPlugin().configYml.getBool("async-display.emergency.enabled")
&& ServerUtils.getTps() <= this.getPlugin().configYml.getDouble("async-display.emergency.cutoff")
) {
return true
}
if (
this.getPlugin().configYml.getBool("async-display.ratelimit.enabled")
&& (playerRates[player.name] ?: 0) >= this.getPlugin().configYml.getInt("async-display.ratelimit.cutoff")
) {
return true
}
return false
}
private fun modifyWindowItems(
itemStacks: MutableList<ItemStack>,
windowId: Int,
player: Player
): MutableList<ItemStack> {
if (this.getPlugin().configYml.getBool("use-display-frame") && windowId == 0) {
val frameMap = mutableMapOf<Byte, HashedItem>()
for (index in itemStacks.indices) {
frameMap[index.toByte()] =
HashedItem(FastItemStack.wrap(itemStacks[index]).hashCode(), itemStacks[index])
}
val newFrame = DisplayFrame(frameMap)
val lastFrame = player.lastDisplayFrame
player.lastDisplayFrame = newFrame
val changes = lastFrame.getChangedSlots(newFrame)
for (index in changes) {
Display.display(itemStacks[index.toInt()], player)
}
for (index in (itemStacks.indices subtract changes.toSet())) {
itemStacks[index.toInt()] = lastFrame.getItem(index.toByte()) ?: itemStacks[index.toInt()]
}
} else {
itemStacks.forEach { Display.display(it, player) }
}
return itemStacks
}
} }

View File

@@ -0,0 +1,75 @@
package com.willfp.eco.spigot.integrations.antigrief
import com.willfp.eco.core.integrations.antigrief.AntigriefWrapper
import org.bukkit.Location
import org.bukkit.World
import org.bukkit.block.Block
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Monster
import org.bukkit.entity.Player
import world.bentobox.bentobox.BentoBox
import world.bentobox.bentobox.api.user.User
import world.bentobox.bentobox.lists.Flags
class AntigriefBentoBox : AntigriefWrapper {
override fun canBreakBlock(
player: Player,
block: Block
): Boolean {
val island = BentoBox.getInstance().islandsManager.getIslandAt(block.location).orElse(null) ?: return true
return island.isAllowed(User.getInstance(player), Flags.BREAK_BLOCKS)
}
override fun canCreateExplosion(
player: Player,
location: Location
): Boolean {
val island = BentoBox.getInstance().islandsManager.getIslandAt(location).orElse(null) ?: return true
return island.isAllowed(User.getInstance(player), Flags.TNT_DAMAGE)
}
override fun canPlaceBlock(
player: Player,
block: Block
): Boolean {
val island = BentoBox.getInstance().islandsManager.getIslandAt(block.location).orElse(null) ?: return true
return island.isAllowed(User.getInstance(player), Flags.PLACE_BLOCKS)
}
override fun canInjure(
player: Player,
victim: LivingEntity
): Boolean {
val island = BentoBox.getInstance().islandsManager.getIslandAt(victim.location).orElse(null) ?: return true
return when (victim) {
is Player -> {
island.isAllowed(
User.getInstance(player), when (victim.world.environment) {
World.Environment.NORMAL -> Flags.PVP_OVERWORLD
World.Environment.NETHER -> Flags.PVP_NETHER
World.Environment.THE_END -> Flags.PVP_END
else -> Flags.PVP_OVERWORLD
}
)
}
is Monster -> island.isAllowed(User.getInstance(player), Flags.HURT_MONSTERS)
else -> island.isAllowed(User.getInstance(player), Flags.HURT_ANIMALS)
}
}
override fun getPluginName(): String {
return "BentoBox"
}
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

@@ -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

@@ -6,18 +6,19 @@ import com.willfp.eco.core.integrations.hologram.Hologram
import com.willfp.eco.core.integrations.hologram.HologramWrapper import com.willfp.eco.core.integrations.hologram.HologramWrapper
import net.Zrips.CMILib.Container.CMILocation import net.Zrips.CMILib.Container.CMILocation
import org.bukkit.Location import org.bukkit.Location
import java.util.* import java.util.UUID
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
class HologramCMI : HologramWrapper { class HologramCMI : HologramWrapper {
override fun createHologram(location: Location, contents: MutableList<String>): Hologram { override fun createHologram(location: Location, contents: MutableList<String>): Hologram {
val cmiHolo = CMIHologram(UUID.randomUUID().toString(), CMILocation(location)) val cmiHolo = CMIHologram(UUID.randomUUID().toString(), CMILocation(location))
cmiHolo.enable()
CMI.getInstance().hologramManager.addHologram(cmiHolo) CMI.getInstance().hologramManager.addHologram(cmiHolo)
val holo = HologramImplCMI(cmiHolo) val holo = HologramImplCMI(cmiHolo)
holo.setContents(contents) holo.setContents(contents)
cmiHolo.enable()
return holo return holo
} }

View File

@@ -3,6 +3,18 @@
# by Auxilor # by Auxilor
# #
mysql:
enabled: false # Set to false, data.yml will be used instead.
host: localhost
port: 3306
database: database
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. # Options to fix villager bugs left behind from old (buggy) versions.
villager-display-fix: false villager-display-fix: false
@@ -17,7 +29,7 @@ use-fast-collated-drops: true
enable-bstats: true enable-bstats: true
# Some plugins use their own item display systems (eg Triton) # Some plugins use their own item display systems (eg Triton)
# And must be ran after eco. Don't enable this unless you run a conflicting plugin # And must be run after eco. Don't enable this unless you run a conflicting plugin
# and have been told to enable it. # and have been told to enable it.
use-lower-protocollib-priority: false use-lower-protocollib-priority: false
@@ -30,15 +42,42 @@ use-display-frame: true
# that display frames will be cleared / deleted. # that display frames will be cleared / deleted.
display-frame-ttl: 17 display-frame-ttl: 17
mysql: # Window items packets have the option to be run asynchronously. This may cause
enabled: false # Set to false, data.yml will be used instead. # some bugs and is considered experimental, however it has been tested without
host: localhost # any apparent issues. Enable this if performance is absolutely crucial or if you
port: 3306 # are experiencing severe display lag.
database: database async-display:
user: username # If async display should always be used.
password: passy enabled: false
autosave: # Log errors that occur in async processing.
ticks: 20000 # The amount of ticks between autosaves log-errors: true
log: false # If auto-save messages should be sent to console
async: false # If saves should be performed asynchronously. May cause bugs without MySQL # The inventory types that should never be processed asynchronously.
# A list of IDs can be found here:
# https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/inventory/InventoryType.html
disable-on-types:
- 'anvil'
# If the server is running under heavy load (below a certain TPS value), enable
# async display automatically. This can prevent some server crashes under load.
emergency:
# If emergency async should be used.
enabled: true
# Below this TPS value, emergency async display will be used.
cutoff: 18
# If players with a large amount of display packets should have their processing
# done asynchronously. This will help if a player is trying to crash the server
# by overloading the display system.
ratelimit:
# If rate limit async display should be used.
enabled: true
# The amount of window items packets per timeframe needed to enable async display
# for a specified player.
cutoff: 4
# The length of the timeframe in seconds.
# Cutoff 5, Timeframe 1 means that if there are more than 5 window items packets
# being sent per second for a player, then that player should have their packets
# handled asynchronously.
timeframe: 1

View File

@@ -32,6 +32,10 @@ softdepend:
- CMI - CMI
- Essentials - Essentials
- Vault - Vault
- 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'
@@ -44,4 +48,5 @@ libraries:
- 'org.jetbrains.exposed:exposed-core:0.35.1' - 'org.jetbrains.exposed:exposed-core:0.35.1'
- 'org.jetbrains.exposed:exposed-dao:0.35.1' - 'org.jetbrains.exposed:exposed-dao:0.35.1'
- 'org.jetbrains.exposed:exposed-jdbc:0.35.1' - 'org.jetbrains.exposed:exposed-jdbc:0.35.1'
- 'mysql:mysql-connector-java:8.0.25' - 'mysql:mysql-connector-java:8.0.25'
- 'com.google.guava:guava:31.0.1-jre'

View File

@@ -0,0 +1,7 @@
package com.willfp.eco.proxy
import com.willfp.eco.core.proxy.AbstractProxy
interface TPSProxy : AbstractProxy {
fun getTPS(): Double
}

View File

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

BIN
lib/DeluxeCombat API.jar Normal file

Binary file not shown.