Fixed talisman fetching performance
This commit is contained in:
@@ -3,6 +3,7 @@ version rootProject.version
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT'
|
||||
compileOnly 'com.github.ben-manes.caffeine:caffeine:3.0.5'
|
||||
}
|
||||
|
||||
build.dependsOn publishToMavenLocal
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.willfp.talismans.talismans.util
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache
|
||||
import com.github.benmanes.caffeine.cache.Caffeine
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.config.updating.ConfigUpdater
|
||||
import com.willfp.talismans.TalismansPlugin.Companion.instance
|
||||
@@ -15,11 +17,18 @@ import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.BlockStateMeta
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.function.Function
|
||||
|
||||
object TalismanChecks {
|
||||
private val CACHED_TALISMANS = Collections.synchronizedMap(HashMap<UUID, Set<Talisman>>())
|
||||
private val CACHED_TALISMAN_ITEMS = Collections.synchronizedMap(WeakHashMap<UUID, Set<ItemStack>>())
|
||||
private val CACHED_TALISMANS: Cache<Player, Set<Talisman>> = Caffeine.newBuilder()
|
||||
.expireAfterWrite(2, TimeUnit.SECONDS)
|
||||
.build()
|
||||
|
||||
private val CACHED_TALISMAN_ITEMS: Cache<Player, Set<ItemStack>> = Caffeine.newBuilder()
|
||||
.expireAfterWrite(2, TimeUnit.SECONDS)
|
||||
.build()
|
||||
|
||||
private val PROVIDERS: MutableSet<Function<Player, List<ItemStack>>> = HashSet()
|
||||
|
||||
private var readEnderChest = true
|
||||
@@ -76,17 +85,6 @@ object TalismanChecks {
|
||||
return getByID(id)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all talismans that a player has active.
|
||||
*
|
||||
* @param player The player to query.
|
||||
* @return A set of all found talismans.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getTalismansOnPlayer(player: Player): Set<Talisman> {
|
||||
return getTalismansOnPlayer(player, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all talismans ItemStacks that a player has active.
|
||||
*
|
||||
@@ -98,117 +96,92 @@ object TalismanChecks {
|
||||
@JvmStatic
|
||||
fun getTalismanItemsOnPlayer(
|
||||
player: Player,
|
||||
useCache: Boolean,
|
||||
vararg extra: ItemStack?
|
||||
): Set<ItemStack> {
|
||||
if (useCache) {
|
||||
val cached = CACHED_TALISMAN_ITEMS[player.uniqueId]
|
||||
if (cached != null) {
|
||||
return cached
|
||||
return CACHED_TALISMAN_ITEMS.get(player) {
|
||||
val contents = mutableListOf<ItemStack>()
|
||||
val rawContents = it.inventory.contents.toMutableList()
|
||||
|
||||
if (readEnderChest) {
|
||||
val enderChest = it.enderChest as Inventory?
|
||||
|
||||
// Not always true, bug reported where it was null.
|
||||
if (enderChest != null) {
|
||||
rawContents.addAll(enderChest.contents)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val contents = mutableListOf<ItemStack>()
|
||||
val rawContents = player.inventory.contents.toMutableList()
|
||||
|
||||
if (readEnderChest) {
|
||||
val enderChest = player.enderChest as Inventory?
|
||||
|
||||
// Not always true, bug reported where it was null.
|
||||
if (enderChest != null) {
|
||||
rawContents.addAll(enderChest.contents)
|
||||
if (offhandOnly) {
|
||||
rawContents.clear()
|
||||
rawContents.add(it.inventory.itemInOffHand)
|
||||
}
|
||||
}
|
||||
|
||||
if (offhandOnly) {
|
||||
rawContents.clear()
|
||||
rawContents.add(player.inventory.itemInOffHand)
|
||||
}
|
||||
|
||||
rawContents.addAll(extra)
|
||||
for (provider in PROVIDERS) {
|
||||
rawContents.addAll(provider.apply(player))
|
||||
}
|
||||
|
||||
for (rawContent in rawContents) {
|
||||
if (rawContent == null) {
|
||||
continue
|
||||
rawContents.addAll(extra)
|
||||
for (provider in PROVIDERS) {
|
||||
rawContents.addAll(provider.apply(it))
|
||||
}
|
||||
if (readShulkerBoxes) {
|
||||
val meta = rawContent.itemMeta
|
||||
if (meta is BlockStateMeta) {
|
||||
val shulkerMeta = meta
|
||||
if (!shulkerMeta.hasBlockState()) {
|
||||
continue
|
||||
|
||||
for (rawContent in rawContents) {
|
||||
if (rawContent == null) {
|
||||
continue
|
||||
}
|
||||
if (readShulkerBoxes) {
|
||||
val meta = rawContent.itemMeta
|
||||
if (meta is BlockStateMeta) {
|
||||
val shulkerMeta = meta
|
||||
if (!shulkerMeta.hasBlockState()) {
|
||||
continue
|
||||
}
|
||||
val state = shulkerMeta.blockState
|
||||
if (state is ShulkerBox) {
|
||||
contents.addAll(state.inventory.contents)
|
||||
continue
|
||||
}
|
||||
}
|
||||
val state = shulkerMeta.blockState
|
||||
if (state is ShulkerBox) {
|
||||
contents.addAll(state.inventory.contents)
|
||||
continue
|
||||
}
|
||||
contents.add(rawContent)
|
||||
}
|
||||
|
||||
val items = mutableMapOf<Talisman, ItemStack>()
|
||||
|
||||
for (itemStack in contents) {
|
||||
convert(itemStack)
|
||||
val talis = getTalismanOnItem(itemStack) ?: continue
|
||||
if (items.size >= getLimit(it)) {
|
||||
break
|
||||
}
|
||||
items[talis] = itemStack
|
||||
}
|
||||
|
||||
if (PLUGIN.configYml.getBool("top-level-only")) {
|
||||
for ((talisman, _) in items.toMap()) {
|
||||
var lowerLevel = talisman.lowerLevel
|
||||
while (lowerLevel != null) {
|
||||
items.remove(lowerLevel)
|
||||
lowerLevel = lowerLevel.lowerLevel
|
||||
}
|
||||
}
|
||||
}
|
||||
contents.add(rawContent)
|
||||
|
||||
items.values.toSet()
|
||||
}
|
||||
|
||||
val items = mutableMapOf<Talisman, ItemStack>()
|
||||
|
||||
for (itemStack in contents) {
|
||||
convert(itemStack)
|
||||
val talis = getTalismanOnItem(itemStack) ?: continue
|
||||
if (items.size >= getLimit(player)) {
|
||||
break
|
||||
}
|
||||
items[talis] = itemStack
|
||||
}
|
||||
|
||||
if (PLUGIN.configYml.getBool("top-level-only")) {
|
||||
for ((talisman, _) in items.toMap()) {
|
||||
var lowerLevel = talisman.lowerLevel
|
||||
while (lowerLevel != null) {
|
||||
items.remove(lowerLevel)
|
||||
lowerLevel = lowerLevel.lowerLevel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (useCache) {
|
||||
CACHED_TALISMAN_ITEMS[player.uniqueId] = items.values.toSet()
|
||||
PLUGIN.scheduler.runLater({ CACHED_TALISMAN_ITEMS.remove(player.uniqueId) }, 40)
|
||||
}
|
||||
|
||||
return items.values.toSet()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all talismans that a player has active.
|
||||
*
|
||||
* @param player The player to query.
|
||||
* @param useCache If the cache should be checked.
|
||||
* @param extra Bonus items.
|
||||
* @return A set of all found talismans.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getTalismansOnPlayer(
|
||||
player: Player,
|
||||
useCache: Boolean,
|
||||
vararg extra: ItemStack?
|
||||
): Set<Talisman> {
|
||||
if (useCache) {
|
||||
val cached = CACHED_TALISMANS[player.uniqueId]
|
||||
if (cached != null) {
|
||||
return cached
|
||||
}
|
||||
return CACHED_TALISMANS.get(player) {
|
||||
getTalismanItemsOnPlayer(it, *extra).mapNotNull { itemStack -> getTalismanOnItem(itemStack) }.toSet()
|
||||
}
|
||||
|
||||
val found = getTalismanItemsOnPlayer(player, useCache, *extra).mapNotNull { getTalismanOnItem(it) }.toSet()
|
||||
|
||||
if (useCache) {
|
||||
CACHED_TALISMANS[player.uniqueId] = found
|
||||
PLUGIN.scheduler.runLater({ CACHED_TALISMANS.remove(player.uniqueId) }, 40)
|
||||
}
|
||||
|
||||
return found
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -218,12 +191,12 @@ object TalismanChecks {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun clearCache(player: Player) {
|
||||
CACHED_TALISMAN_ITEMS.remove(player.uniqueId)
|
||||
CACHED_TALISMANS.remove(player.uniqueId)
|
||||
CACHED_TALISMAN_ITEMS.invalidate(player)
|
||||
CACHED_TALISMANS.invalidate(player)
|
||||
}
|
||||
|
||||
/**
|
||||
* Register ItemStack provider (inventory extension, eg talisman bag).
|
||||
* Register ItemStack provider (inventory extension, e.g. talisman bag).
|
||||
*
|
||||
* @param provider The provider.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user