Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6a59fbc91 | ||
|
|
b787f8b76a | ||
|
|
ccc83da5b0 | ||
|
|
f11068f2f1 | ||
|
|
a5cc1a5d32 | ||
|
|
7440749ba5 | ||
|
|
75010d25fa | ||
|
|
bb95376b93 | ||
|
|
ab6d4c7aa2 | ||
|
|
9ab8827e55 | ||
|
|
991290095b | ||
|
|
8735478fc3 | ||
|
|
6e44f09621 | ||
|
|
060106881e | ||
|
|
96cc9706b3 | ||
|
|
3d87b1eb73 | ||
|
|
4c4247b4ec | ||
|
|
b94dc4ac3a | ||
|
|
06bcb10958 | ||
|
|
295095e9ce | ||
|
|
ba9c5865e3 | ||
|
|
d24be4121f | ||
|
|
bcc5e4ef08 | ||
|
|
bf8609666a | ||
|
|
1a02335825 | ||
|
|
f5ef98ec5c | ||
|
|
45135e2b55 | ||
|
|
758b42ff8e | ||
|
|
4a134402da | ||
|
|
e6ad4c9268 | ||
|
|
809dcbae85 | ||
|
|
d7fce6834c | ||
|
|
ac807a991b | ||
|
|
ba315ced3c | ||
|
|
f2e65174f9 | ||
|
|
bd5555ff01 | ||
|
|
5f80b6052d |
@@ -101,7 +101,7 @@ allprojects {
|
||||
implementation("net.kyori:adventure-text-serializer-legacy:4.10.1")
|
||||
|
||||
// Other
|
||||
implementation("com.github.ben-manes.caffeine:caffeine:3.0.6")
|
||||
implementation("com.github.ben-manes.caffeine:caffeine:3.1.0")
|
||||
implementation("org.apache.maven:maven-artifact:3.8.5")
|
||||
}
|
||||
|
||||
|
||||
@@ -376,12 +376,12 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this));
|
||||
}
|
||||
|
||||
this.loadIntegrationLoaders().forEach((integrationLoader -> {
|
||||
this.loadIntegrationLoaders().forEach(integrationLoader -> {
|
||||
if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
|
||||
this.loadedIntegrations.add(integrationLoader.getPluginName());
|
||||
integrationLoader.load();
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations()));
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public class Prerequisite {
|
||||
* Requires the server to be running an implementation of paper.
|
||||
*/
|
||||
public static final Prerequisite HAS_PAPER = new Prerequisite(
|
||||
() -> ClassUtils.exists("com.destroystokyo.paper.event.player.PlayerElytraBoostEvent"),
|
||||
() -> ClassUtils.exists("com.destroystokyo.paper.event.block.BeaconEffectEvent"),
|
||||
"Requires server to be running paper (or a fork)"
|
||||
);
|
||||
|
||||
|
||||
@@ -167,7 +167,10 @@ abstract class HandledCommand implements CommandBase {
|
||||
|
||||
StringUtil.copyPartialMatches(
|
||||
args[0],
|
||||
this.getSubcommands().stream().map(CommandBase::getName).collect(Collectors.toList()),
|
||||
this.getSubcommands().stream()
|
||||
.filter(subCommand -> sender.hasPermission(subCommand.getPermission()))
|
||||
.map(CommandBase::getName)
|
||||
.collect(Collectors.toList()),
|
||||
completions
|
||||
);
|
||||
|
||||
@@ -182,6 +185,10 @@ abstract class HandledCommand implements CommandBase {
|
||||
HandledCommand command = null;
|
||||
|
||||
for (CommandBase subcommand : this.getSubcommands()) {
|
||||
if (!sender.hasPermission(subcommand.getPermission())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase(subcommand.getName())) {
|
||||
command = (HandledCommand) subcommand;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,10 @@ public final class Items {
|
||||
|
||||
if (part == null && PROVIDERS.containsKey(namespace)) {
|
||||
ItemProvider provider = PROVIDERS.get(namespace);
|
||||
item = provider.provideForKey(keyID);
|
||||
|
||||
String reformattedKey = keyID.replace("__", ":");
|
||||
|
||||
item = provider.provideForKey(reformattedKey);
|
||||
if (item instanceof EmptyTestableItem || item == null) {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
|
||||
@@ -23,26 +23,25 @@ public final class BlockUtils {
|
||||
*/
|
||||
private static final int MAX_BLOCKS = 2500;
|
||||
|
||||
private static Set<Block> getNearbyBlocks(@NotNull final Block origin,
|
||||
private static Set<Block> getNearbyBlocks(@NotNull final Block start,
|
||||
@NotNull final List<Material> allowedMaterials,
|
||||
@NotNull final Set<Block> blocks,
|
||||
final int limit) {
|
||||
for (BlockFace face : BlockFace.values()) {
|
||||
Block block = origin.getRelative(face);
|
||||
|
||||
if (!allowedMaterials.contains(block.getType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Block block = start.getRelative(face);
|
||||
if (blocks.contains(block)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (blocks.size() >= limit || blocks.size() > MAX_BLOCKS) {
|
||||
return blocks;
|
||||
}
|
||||
if (allowedMaterials.contains(block.getType())) {
|
||||
blocks.add(block);
|
||||
|
||||
blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit));
|
||||
if (blocks.size() > limit || blocks.size() > MAX_BLOCKS) {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit));
|
||||
}
|
||||
}
|
||||
|
||||
return blocks;
|
||||
|
||||
@@ -43,6 +43,7 @@ public final class StringUtils {
|
||||
.add(Pattern.compile("<G#([0-9A-Fa-f]{6})>(.*?)</G#([0-9A-Fa-f]{6})>", Pattern.CASE_INSENSITIVE))
|
||||
.add(Pattern.compile("<#:([0-9A-Fa-f]{6})>(.*?)</#:([0-9A-Fa-f]{6})>"))
|
||||
.add(Pattern.compile("\\{#:([0-9A-Fa-f]{6})}(.*?)\\{/#:([0-9A-Fa-f]{6})}"))
|
||||
.add(Pattern.compile("\\{#([0-9A-Fa-f]{6})>}(.*?)\\{#([0-9A-Fa-f]{6})<}"))
|
||||
.build();
|
||||
|
||||
/**
|
||||
|
||||
@@ -103,11 +103,13 @@ open class EcoConfig(
|
||||
}
|
||||
|
||||
override fun getSubsectionOrNull(path: String): Config? {
|
||||
return get(path) as? Config
|
||||
return (get(path) as? Config)?.apply { this.addInjectablePlaceholder(injections) }
|
||||
}
|
||||
|
||||
override fun getSubsectionsOrNull(path: String): List<Config>? {
|
||||
return (get(path) as? Iterable<Config>)?.toList()
|
||||
return (get(path) as? Iterable<Config>)
|
||||
?.map { it.apply { this.addInjectablePlaceholder(injections) } }
|
||||
?.toList()
|
||||
}
|
||||
|
||||
override fun getType(): ConfigType {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.3.5"
|
||||
id("io.papermc.paperweight.userdev") version "1.3.6"
|
||||
}
|
||||
|
||||
group = "com.willfp"
|
||||
|
||||
@@ -26,6 +26,8 @@ import org.bukkit.inventory.ItemFlag
|
||||
import org.bukkit.persistence.PersistentDataContainer
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
import kotlin.experimental.and
|
||||
import kotlin.experimental.inv
|
||||
import kotlin.experimental.or
|
||||
|
||||
@Suppress("UsePropertyAccessSyntax")
|
||||
class EcoFastItemStack(
|
||||
@@ -149,35 +151,29 @@ class EcoFastItemStack(
|
||||
override fun getDisplayName(): String = displayNameComponent.toLegacy()
|
||||
|
||||
override fun addItemFlags(vararg hideFlags: ItemFlag) {
|
||||
for (flag in hideFlags) {
|
||||
this.flagBits = this.flagBits or getBitModifier(flag)
|
||||
for (f in hideFlags) {
|
||||
this.flagBits = this.flagBits or getBitModifier(f)
|
||||
}
|
||||
|
||||
apply()
|
||||
}
|
||||
|
||||
override fun removeItemFlags(vararg hideFlags: ItemFlag) {
|
||||
for (flag in hideFlags) {
|
||||
this.flagBits = this.flagBits and getBitModifier(flag)
|
||||
for (f in hideFlags) {
|
||||
this.flagBits = this.flagBits and getBitModifier(f).inv()
|
||||
}
|
||||
|
||||
apply()
|
||||
}
|
||||
|
||||
override fun getItemFlags(): MutableSet<ItemFlag> {
|
||||
val flags = mutableSetOf<ItemFlag>()
|
||||
|
||||
var flagArr: Array<ItemFlag>
|
||||
val size = ItemFlag.values().also { flagArr = it }.size
|
||||
|
||||
for (i in 0 until size) {
|
||||
val flag = flagArr[i]
|
||||
if (this.hasItemFlag(flag)) {
|
||||
flags.add(flag)
|
||||
override fun getItemFlags(): Set<ItemFlag> {
|
||||
val currentFlags = mutableSetOf<ItemFlag>()
|
||||
for (f in ItemFlag.values()) {
|
||||
if (hasItemFlag(f)) {
|
||||
currentFlags.add(f)
|
||||
}
|
||||
}
|
||||
|
||||
return flags
|
||||
return currentFlags
|
||||
}
|
||||
|
||||
override fun hasItemFlag(flag: ItemFlag): Boolean {
|
||||
@@ -194,15 +190,15 @@ class EcoFastItemStack(
|
||||
}
|
||||
|
||||
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
|
||||
private var flagBits: Int
|
||||
private var flagBits: Byte
|
||||
get() =
|
||||
if (handle.hasTag() && handle.getTag()!!.contains(
|
||||
"HideFlags",
|
||||
99
|
||||
)
|
||||
) handle.getTag()!!.getInt("HideFlags") else 0
|
||||
) handle.getTag()!!.getInt("HideFlags").toByte() else 0
|
||||
set(value) =
|
||||
handle.getOrCreateTag().putInt("HideFlags", value)
|
||||
handle.getOrCreateTag().putInt("HideFlags", value.toInt())
|
||||
|
||||
override fun getRepairCost(): Int {
|
||||
return handle.getBaseRepairCost()
|
||||
@@ -268,8 +264,8 @@ class EcoFastItemStack(
|
||||
bukkit.mergeIfNeeded(handle)
|
||||
}
|
||||
|
||||
private fun getBitModifier(hideFlag: ItemFlag): Int {
|
||||
return 1 shl hideFlag.ordinal
|
||||
private fun getBitModifier(hideFlag: ItemFlag): Byte {
|
||||
return (1 shl hideFlag.ordinal).toByte()
|
||||
}
|
||||
|
||||
override fun unwrap(): org.bukkit.inventory.ItemStack {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.3.5"
|
||||
id("io.papermc.paperweight.userdev") version "1.3.6"
|
||||
}
|
||||
|
||||
group = "com.willfp"
|
||||
|
||||
@@ -20,6 +20,10 @@ class Skull : SkullProxy {
|
||||
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
|
||||
setProfile.isAccessible = true
|
||||
}
|
||||
if (base64.length < 20) {
|
||||
return
|
||||
}
|
||||
|
||||
val uuid = UUID(
|
||||
base64.substring(base64.length - 20).hashCode().toLong(),
|
||||
base64.substring(base64.length - 10).hashCode().toLong()
|
||||
@@ -39,6 +43,6 @@ class Skull : SkullProxy {
|
||||
val profile = profile[meta] as GameProfile? ?: return null
|
||||
val properties = profile.properties ?: return null
|
||||
val prop = properties["textures"] ?: return null
|
||||
return prop.toMutableList().firstOrNull()?.value
|
||||
return prop.toMutableList().firstOrNull()?.name
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.3.5"
|
||||
id("io.papermc.paperweight.userdev") version "1.3.6"
|
||||
}
|
||||
|
||||
group = "com.willfp"
|
||||
|
||||
@@ -20,6 +20,10 @@ class Skull : SkullProxy {
|
||||
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
|
||||
setProfile.isAccessible = true
|
||||
}
|
||||
if (base64.length < 20) {
|
||||
return
|
||||
}
|
||||
|
||||
val uuid = UUID(
|
||||
base64.substring(base64.length - 20).hashCode().toLong(),
|
||||
base64.substring(base64.length - 10).hashCode().toLong()
|
||||
@@ -39,6 +43,6 @@ class Skull : SkullProxy {
|
||||
val profile = profile[meta] as GameProfile? ?: return null
|
||||
val properties = profile.properties ?: return null
|
||||
val prop = properties["textures"] ?: return null
|
||||
return prop.toMutableList().firstOrNull()?.value
|
||||
return prop.toMutableList().firstOrNull()?.name
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.3.5"
|
||||
id("io.papermc.paperweight.userdev") version "1.3.6"
|
||||
}
|
||||
|
||||
group = "com.willfp"
|
||||
|
||||
@@ -20,6 +20,10 @@ class Skull : SkullProxy {
|
||||
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
|
||||
setProfile.isAccessible = true
|
||||
}
|
||||
if (base64.length < 20) {
|
||||
return
|
||||
}
|
||||
|
||||
val uuid = UUID(
|
||||
base64.substring(base64.length - 20).hashCode().toLong(),
|
||||
base64.substring(base64.length - 10).hashCode().toLong()
|
||||
@@ -39,6 +43,6 @@ class Skull : SkullProxy {
|
||||
val profile = profile[meta] as GameProfile? ?: return null
|
||||
val properties = profile.properties ?: return null
|
||||
val prop = properties["textures"] ?: return null
|
||||
return prop.toMutableList().firstOrNull()?.value
|
||||
return prop.toMutableList().firstOrNull()?.name
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ dependencies {
|
||||
|
||||
// Included in spigot jar
|
||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||
compileOnly 'io.papermc.paper:paper-api:1.17.1-R0.1-SNAPSHOT'
|
||||
|
||||
// Plugin dependencies
|
||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT'
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.willfp.eco.internal.spigot
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.util.containsIgnoreCase
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.plugin.Plugin
|
||||
import java.io.File
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
object ConflictFinder {
|
||||
fun searchForConflicts(eco: EcoPlugin): List<Conflict> {
|
||||
val conflicts = mutableListOf<Conflict>()
|
||||
|
||||
for (plugin in Bukkit.getPluginManager().plugins) {
|
||||
if (eco.configYml.getStrings("conflicts.whitelist").containsIgnoreCase(plugin.name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
val conflict = plugin.getConflict()
|
||||
|
||||
if (conflict != null) {
|
||||
conflicts.add(conflict)
|
||||
}
|
||||
}
|
||||
|
||||
return conflicts
|
||||
}
|
||||
}
|
||||
|
||||
data class Conflict(
|
||||
val plugin: Plugin,
|
||||
val conflictType: ConflictType
|
||||
) {
|
||||
val conflictMessage: String
|
||||
get() = "${plugin.name} will likely conflict with eco! Reason: ${conflictType.friendlyMessage}"
|
||||
}
|
||||
|
||||
enum class ConflictType(
|
||||
val friendlyMessage: String
|
||||
) {
|
||||
LIB_LOADER("Kotlin found in libraries (lib-loader)"),
|
||||
KOTLIN_SHADE("Kotlin shaded into jar");
|
||||
}
|
||||
|
||||
private fun Plugin.getConflict(): Conflict? {
|
||||
if (this.description.libraries.any { it.contains("kotlin-stdlib") }) {
|
||||
return Conflict(this, ConflictType.LIB_LOADER)
|
||||
}
|
||||
|
||||
val zip = ZipFile(File(this::class.java.protectionDomain.codeSource.location.toURI()))
|
||||
|
||||
for (entry in zip.entries()) {
|
||||
if (entry.name.startsWith("kotlin/")) {
|
||||
return Conflict(this, ConflictType.KOTLIN_SHADE)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
@@ -63,7 +63,8 @@ import com.willfp.eco.internal.spigot.display.PacketWindowItems
|
||||
import com.willfp.eco.internal.spigot.display.frame.clearFrames
|
||||
import com.willfp.eco.internal.spigot.drops.CollatedRunnable
|
||||
import com.willfp.eco.internal.spigot.eventlisteners.EntityDeathByEntityListeners
|
||||
import com.willfp.eco.internal.spigot.eventlisteners.NaturalExpGainListeners
|
||||
import com.willfp.eco.internal.spigot.eventlisteners.NaturalExpGainListenersPaper
|
||||
import com.willfp.eco.internal.spigot.eventlisteners.NaturalExpGainListenersSpigot
|
||||
import com.willfp.eco.internal.spigot.eventlisteners.PlayerJumpListenersPaper
|
||||
import com.willfp.eco.internal.spigot.eventlisteners.PlayerJumpListenersSpigot
|
||||
import com.willfp.eco.internal.spigot.eventlisteners.armor.ArmorChangeEventListeners
|
||||
@@ -191,7 +192,27 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
}
|
||||
|
||||
override fun handleEnable() {
|
||||
this.logger.info("Scanning for conflicts...")
|
||||
val conflicts = ConflictFinder.searchForConflicts(this)
|
||||
for (conflict in conflicts) {
|
||||
this.logger.warning(conflict.conflictMessage)
|
||||
}
|
||||
if (conflicts.isNotEmpty()) {
|
||||
this.logger.warning(
|
||||
"You can fix the conflicts by either removing the conflicting plugins, " +
|
||||
"or by asking on the support discord to have them patched!"
|
||||
)
|
||||
this.logger.warning(
|
||||
"Only remove potentially conflicting plugins if you see " +
|
||||
"Loader Constraint Violation / LinkageError anywhere"
|
||||
)
|
||||
} else {
|
||||
this.logger.info("No conflicts found!")
|
||||
}
|
||||
|
||||
|
||||
CollatedRunnable(this)
|
||||
CustomItemsManager.registerProviders() // Do it again here
|
||||
|
||||
// Register events for ShopSellEvent
|
||||
ShopManager.registerEvents(this)
|
||||
@@ -329,7 +350,6 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
|
||||
override fun loadListeners(): List<Listener> {
|
||||
val listeners = mutableListOf(
|
||||
NaturalExpGainListeners(),
|
||||
ArmorListener(),
|
||||
EntityDeathByEntityListeners(this),
|
||||
CraftingRecipeListener(),
|
||||
@@ -343,8 +363,10 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
|
||||
if (Prerequisite.HAS_PAPER.isMet) {
|
||||
listeners.add(PlayerJumpListenersPaper())
|
||||
listeners.add(NaturalExpGainListenersPaper())
|
||||
} else {
|
||||
listeners.add(PlayerJumpListenersSpigot())
|
||||
listeners.add(NaturalExpGainListenersSpigot())
|
||||
}
|
||||
|
||||
return listeners
|
||||
|
||||
@@ -1,30 +1,20 @@
|
||||
package com.willfp.eco.internal.spigot.display
|
||||
|
||||
import com.comphenix.protocol.PacketType
|
||||
import com.comphenix.protocol.ProtocolLibrary
|
||||
import com.comphenix.protocol.events.PacketContainer
|
||||
import com.comphenix.protocol.events.PacketEvent
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder
|
||||
import com.willfp.eco.core.AbstractPacketAdapter
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.display.Display
|
||||
import com.willfp.eco.core.items.HashedItem
|
||||
import com.willfp.eco.internal.spigot.display.frame.DisplayFrame
|
||||
import com.willfp.eco.internal.spigot.display.frame.lastDisplayFrame
|
||||
import com.willfp.eco.util.ServerUtils
|
||||
import org.bukkit.entity.Player
|
||||
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) {
|
||||
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(
|
||||
packet: PacketContainer,
|
||||
@@ -44,90 +34,9 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
|
||||
|
||||
val itemStacks = packet.itemListModifier.read(0) ?: return
|
||||
|
||||
handleRateLimit(player)
|
||||
|
||||
if (usingAsync(player)) {
|
||||
val newPacket = packet.deepClone()
|
||||
|
||||
executor.execute {
|
||||
runCatchingWithLogs { modifyAndSend(newPacket, itemStacks, windowId, player) }
|
||||
}
|
||||
} else {
|
||||
modifyPacket(packet, itemStacks, windowId, player)
|
||||
}
|
||||
}
|
||||
|
||||
private fun modifyPacket(
|
||||
packet: PacketContainer,
|
||||
itemStacks: MutableList<ItemStack>,
|
||||
windowId: Int,
|
||||
player: Player
|
||||
) {
|
||||
packet.itemListModifier.write(0, modifyWindowItems(itemStacks, windowId, player))
|
||||
}
|
||||
|
||||
private fun modifyAndSend(
|
||||
packet: PacketContainer,
|
||||
itemStacks: MutableList<ItemStack>,
|
||||
windowId: Int,
|
||||
player: Player
|
||||
) {
|
||||
modifyPacket(packet, itemStacks, windowId, player)
|
||||
ignorePacketList.add(player.name)
|
||||
this.getPlugin().scheduler.run {
|
||||
runCatchingWithLogs { ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet) }
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
.map { it.lowercase() }.contains(player.openInventory.type.name.lowercase())
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.getPlugin().configYml.getBool("async-display.always-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,
|
||||
@@ -162,14 +71,3 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
|
||||
return itemStacks
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <T> runCatchingWithLogs(toRun: () -> T): Result<T> {
|
||||
return runCatching { toRun() }.onFailure {
|
||||
if (Eco.getHandler().ecoPlugin.configYml.getBool("async-display.log-errors")) {
|
||||
Eco.getHandler().ecoPlugin.logger.warning(
|
||||
"Error happened in async processing! Disable async display (/plugins/eco/config.yml)" +
|
||||
"if this is a frequent issue. (Remember to disable ratelimit and emergency too)"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,28 @@
|
||||
package com.willfp.eco.internal.spigot.eventlisteners
|
||||
|
||||
import com.willfp.eco.core.events.NaturalExpGainEvent
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.entity.ThrownExpBottle
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.entity.ExpBottleEvent
|
||||
import org.bukkit.event.player.PlayerExpChangeEvent
|
||||
|
||||
class NaturalExpGainListeners : Listener {
|
||||
class NaturalExpGainListenersPaper : Listener {
|
||||
@EventHandler
|
||||
fun onEvent(event: PlayerExpChangeEvent) {
|
||||
val source = event.source
|
||||
|
||||
if (source is ThrownExpBottle) {
|
||||
return
|
||||
}
|
||||
|
||||
val ecoEvent = NaturalExpGainEvent(event)
|
||||
Bukkit.getPluginManager().callEvent(ecoEvent)
|
||||
}
|
||||
}
|
||||
|
||||
class NaturalExpGainListenersSpigot : Listener {
|
||||
private val events: MutableSet<NaturalExpGainBuilder> = HashSet()
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -11,10 +11,7 @@ import com.willfp.eco.core.integrations.antigrief.AntigriefIntegration
|
||||
import org.apache.commons.lang.Validate
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.entity.Animals
|
||||
import org.bukkit.entity.LivingEntity
|
||||
import org.bukkit.entity.Monster
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.entity.*
|
||||
|
||||
class AntigriefWorldGuard : AntigriefIntegration {
|
||||
override fun canBreakBlock(
|
||||
@@ -85,6 +82,7 @@ class AntigriefWorldGuard : AntigriefIntegration {
|
||||
is Player -> Flags.PVP
|
||||
is Monster -> Flags.MOB_DAMAGE
|
||||
is Animals -> Flags.DAMAGE_ANIMALS
|
||||
is ArmorStand -> Flags.INTERACT
|
||||
else -> return true
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ class CustomItemsItemsAdder : CustomItemsIntegration {
|
||||
|
||||
private class ItemsAdderProvider : ItemProvider("itemsadder") {
|
||||
override fun provideForKey(key: String): TestableItem? {
|
||||
val item = CustomStack.getInstance("itemsadder:$key") ?: return null
|
||||
val internalId = if (key.contains(":")) key else "itemsadder:$key"
|
||||
|
||||
val item = CustomStack.getInstance(internalId) ?: return null
|
||||
val id = item.id
|
||||
val namespacedKey = NamespacedKeyUtils.create("itemsadder", key)
|
||||
val stack = item.itemStack
|
||||
@@ -34,6 +36,5 @@ class CustomItemsItemsAdder : CustomItemsIntegration {
|
||||
stack
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,11 @@ mysql:
|
||||
user: username
|
||||
password: passy
|
||||
|
||||
# Options to manage the conflict finder
|
||||
conflicts:
|
||||
whitelist: # Plugins that should never be marked as conflicts
|
||||
- eco
|
||||
|
||||
# Options to fix villager bugs left behind from old (buggy) versions.
|
||||
villager-display-fix: false
|
||||
|
||||
@@ -51,43 +56,3 @@ use-safer-namespacedkey-creation: false
|
||||
# If the stack traces of extensions that failed to load should be logged. Disabled by
|
||||
# default to prevent users from reporting bugs. Enable if you're a developer.
|
||||
log-full-extension-errors: false
|
||||
|
||||
# Window items packets have the option to be run asynchronously. This may cause
|
||||
# some bugs and is considered experimental, however it has been tested without
|
||||
# any apparent issues. Enable this if performance is absolutely crucial or if you
|
||||
# are experiencing severe display lag.
|
||||
async-display:
|
||||
# If async display should always be used.
|
||||
always-enabled: false
|
||||
|
||||
# Log errors that occur in async processing.
|
||||
log-errors: true
|
||||
|
||||
# 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: 17
|
||||
|
||||
# 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: false
|
||||
# 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
|
||||
@@ -1,3 +1,3 @@
|
||||
version = 6.35.1
|
||||
version = 6.35.10
|
||||
plugin-name = eco
|
||||
kotlin.code.style = official
|
||||
Reference in New Issue
Block a user