Removed async-display
This commit is contained in:
@@ -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)"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,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
|
||||
Reference in New Issue
Block a user