diff --git a/gradle.properties b/gradle.properties index 2a9e2e1..fa14fd0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ kotlin.code.style=official kotlin.stdlib.default.dependency=false org.gradle.parallel=true -version=1.3.5 +version=1.3.6 \ No newline at end of file diff --git a/surf-shop-core/surf-shop-core-common/src/main/kotlin/dev/slne/surf/shop/core/common/service/DealService.kt b/surf-shop-core/surf-shop-core-common/src/main/kotlin/dev/slne/surf/shop/core/common/service/DealService.kt index 8e6d0d0..a66edde 100644 --- a/surf-shop-core/surf-shop-core-common/src/main/kotlin/dev/slne/surf/shop/core/common/service/DealService.kt +++ b/surf-shop-core/surf-shop-core-common/src/main/kotlin/dev/slne/surf/shop/core/common/service/DealService.kt @@ -3,13 +3,20 @@ package dev.slne.surf.shop.core.common.service import dev.slne.surf.api.core.util.requiredService import dev.slne.surf.shop.api.deal.Deal import dev.slne.surf.shop.api.shop.Shop -import it.unimi.dsi.fastutil.objects.ObjectSet import java.util.* private val service = requiredService() +data class ShopDealStats( + val dealCount: Int = 0, + val totalSoldItems: Int = 0 +) + interface DealService { - val loadedDeals: ObjectSet + val loadedDeals: Collection + + fun loadedDealsSnapshot(): List = loadedDeals.toList() + fun getDealStats(shopInternalId: ULong): ShopDealStats suspend fun buyInternal(shop: Shop, amount: Int, buyer: UUID): Deal suspend fun buy(playerUuid: UUID, shop: Shop, amount: Int): Deal.DealResult @@ -17,4 +24,4 @@ interface DealService { suspend fun fetchDeals() companion object : DealService by service -} \ No newline at end of file +} diff --git a/surf-shop-core/surf-shop-core-common/src/main/kotlin/dev/slne/surf/shop/core/common/service/ShopService.kt b/surf-shop-core/surf-shop-core-common/src/main/kotlin/dev/slne/surf/shop/core/common/service/ShopService.kt index e35a0ed..b47c4a6 100644 --- a/surf-shop-core/surf-shop-core-common/src/main/kotlin/dev/slne/surf/shop/core/common/service/ShopService.kt +++ b/surf-shop-core/surf-shop-core-common/src/main/kotlin/dev/slne/surf/shop/core/common/service/ShopService.kt @@ -2,13 +2,16 @@ package dev.slne.surf.shop.core.common.service import dev.slne.surf.api.core.util.requiredService import dev.slne.surf.shop.api.shop.Shop -import it.unimi.dsi.fastutil.objects.ObjectSet import java.util.* private val service = requiredService() interface ShopService { - val loadedShops: ObjectSet + val loadedShops: Collection + + fun loadedShopsSnapshot(): List = loadedShops.toList() + fun getShop(shopUuid: UUID): Shop? + fun getShopByInternalId(internalId: ULong): Shop? suspend fun createShop( itemString: String, @@ -25,4 +28,4 @@ interface ShopService { suspend fun fetchShops() companion object : ShopService by service -} \ No newline at end of file +} diff --git a/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/service/DealServiceImpl.kt b/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/service/DealServiceImpl.kt index 5bd6e49..0060eea 100644 --- a/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/service/DealServiceImpl.kt +++ b/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/service/DealServiceImpl.kt @@ -4,14 +4,13 @@ import com.github.shynixn.mccoroutine.folia.SuspendingJavaPlugin import com.github.shynixn.mccoroutine.folia.entityDispatcher import com.github.shynixn.mccoroutine.folia.regionDispatcher import com.google.auto.service.AutoService -import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf import dev.slne.surf.api.core.util.objectSetOf -import dev.slne.surf.api.core.util.toObjectSet import dev.slne.surf.shop.api.deal.Deal import dev.slne.surf.shop.api.shop.Shop import dev.slne.surf.shop.core.common.rabbit.packet.request.deal.BuyRequestPacket import dev.slne.surf.shop.core.common.rabbit.packet.request.deal.LoadDealsRequestPacket import dev.slne.surf.shop.core.common.service.DealService +import dev.slne.surf.shop.core.common.service.ShopDealStats import dev.slne.surf.shop.core.common.service.ShopService import dev.slne.surf.shop.core.common.util.logger import dev.slne.surf.shop.core.paper.PaperShopInstance @@ -20,7 +19,6 @@ import dev.slne.surf.transaction.api.currency.Currency import dev.slne.surf.transaction.api.transaction.TransactionResult import dev.slne.surf.transaction.api.transaction.data.TransactionData import dev.slne.surf.transaction.api.user.TransactionUser -import it.unimi.dsi.fastutil.objects.ObjectSet import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext @@ -35,8 +33,13 @@ import java.util.concurrent.ConcurrentHashMap @AutoService(DealService::class) class DealServiceImpl : DealService, Services.Fallback { - private val _deals = mutableObject2ObjectMapOf() - override val loadedDeals: ObjectSet get() = _deals.values.toObjectSet() + private val _deals = ConcurrentHashMap() + private val _dealStatsByShop = ConcurrentHashMap() + + override val loadedDeals: Collection get() = _deals.values + + override fun getDealStats(shopInternalId: ULong) = + _dealStatsByShop[shopInternalId] ?: ShopDealStats() private val shopLocks = ConcurrentHashMap() @@ -60,7 +63,7 @@ class DealServiceImpl : DealService, Services.Fallback { ) ).deal - _deals[bought.dealUuid] = bought + putDeal(bought) return bought } @@ -71,9 +74,7 @@ class DealServiceImpl : DealService, Services.Fallback { ): Deal.DealResult { val player = Bukkit.getPlayer(playerUuid) ?: return Deal.DealResult.PlayerNotFound - val actualShop = - ShopService.loadedShops.firstOrNull { it.shopUuid == shop.shopUuid } - ?: return Deal.DealResult.ShopDeleted + val actualShop = ShopService.getShop(shop.shopUuid) ?: return Deal.DealResult.ShopDeleted val lock = getLock(actualShop.shopUuid) @@ -141,7 +142,7 @@ class DealServiceImpl : DealService, Services.Fallback { ) ).deal - _deals[deal.dealUuid] = deal + putDeal(deal) val itemStack = shop.item var remaining = amount @@ -188,7 +189,8 @@ class DealServiceImpl : DealService, Services.Fallback { val loadedDeals = PaperShopInstance.rabbitApi.sendRequest(LoadDealsRequestPacket()).deals _deals.clear() - loadedDeals.forEach { _deals[it.dealUuid] = it } + _dealStatsByShop.clear() + loadedDeals.forEach(::putDeal) logger.info("Loaded ${_deals.size} deals") } @@ -197,7 +199,20 @@ class DealServiceImpl : DealService, Services.Fallback { shopLocks.remove(shopUuid) } + private fun putDeal(deal: Deal) { + _deals[deal.dealUuid] = deal + _dealStatsByShop.merge( + deal.shopInternalId, + ShopDealStats(dealCount = 1, totalSoldItems = deal.amount) + ) { current, added -> + ShopDealStats( + dealCount = current.dealCount + added.dealCount, + totalSoldItems = current.totalSoldItems + added.totalSoldItems + ) + } + } + companion object { lateinit var plugin: SuspendingJavaPlugin } -} \ No newline at end of file +} diff --git a/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/service/ShopServiceImpl.kt b/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/service/ShopServiceImpl.kt index 983f576..01ff7c6 100644 --- a/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/service/ShopServiceImpl.kt +++ b/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/service/ShopServiceImpl.kt @@ -1,8 +1,6 @@ package dev.slne.surf.shop.core.paper.service import com.google.auto.service.AutoService -import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf -import dev.slne.surf.api.core.util.toObjectSet import dev.slne.surf.shop.api.shop.Shop import dev.slne.surf.shop.core.common.rabbit.packet.request.shop.CreateShopRequestPacket import dev.slne.surf.shop.core.common.rabbit.packet.request.shop.DeleteShopRequestPacket @@ -12,7 +10,6 @@ import dev.slne.surf.shop.core.common.service.ShopService import dev.slne.surf.shop.core.common.util.logger import dev.slne.surf.shop.core.paper.PaperShopInstance import dev.slne.surf.shop.core.paper.util.rebuildSearchTokens -import it.unimi.dsi.fastutil.objects.ObjectSet import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import net.kyori.adventure.util.Services @@ -24,8 +21,13 @@ import kotlin.system.measureTimeMillis @AutoService(ShopService::class) class ShopServiceImpl : ShopService, Services.Fallback { - private val _shops = mutableObject2ObjectMapOf() - override val loadedShops: ObjectSet get() = _shops.values.toObjectSet() + private val _shops = ConcurrentHashMap() + private val _shopsByInternalId = ConcurrentHashMap() + + override val loadedShops: Collection get() = _shops.values + + override fun getShop(shopUuid: UUID) = _shops[shopUuid] + override fun getShopByInternalId(internalId: ULong) = _shopsByInternalId[internalId] private val shopLocks = ConcurrentHashMap() @@ -52,7 +54,7 @@ class ShopServiceImpl : ShopService, Services.Fallback { rebuildSearchTokens() } - _shops[created.shopUuid] = created + putShop(created) return created } @@ -69,7 +71,7 @@ class ShopServiceImpl : ShopService, Services.Fallback { rebuildSearchTokens() } - _shops[shop.shopUuid] = updatedShop + putShop(updatedShop) PaperShopInstance.rabbitApi.sendRequest( SaveShopRequestPacket( @@ -92,7 +94,7 @@ class ShopServiceImpl : ShopService, Services.Fallback { ).value if (deleted) { - _shops.remove(shop.shopUuid) + removeShop(shop) shopLocks.remove(shop.shopUuid) } @@ -110,14 +112,31 @@ class ShopServiceImpl : ShopService, Services.Fallback { PaperShopInstance.rabbitApi.sendRequest(LoadShopsRequestPacket()).shops _shops.clear() + _shopsByInternalId.clear() loadedShops.forEach { - _shops[it.shopUuid] = it.apply { + putShop(it.apply { rebuildSearchTokens() - } + }) } } logger.info("Loaded ${_shops.size} shops in ${ms}ms") } -} \ No newline at end of file + + private fun putShop(shop: Shop) { + _shops[shop.shopUuid]?.let { existing -> + if (existing.internalId != shop.internalId) { + _shopsByInternalId.remove(existing.internalId) + } + } + + _shops[shop.shopUuid] = shop + _shopsByInternalId[shop.internalId] = shop + } + + private fun removeShop(shop: Shop) { + val removed = _shops.remove(shop.shopUuid) + _shopsByInternalId.remove(removed?.internalId ?: shop.internalId) + } +} diff --git a/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/util/shop-util.kt b/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/util/shop-util.kt index 7b5a13b..e259956 100644 --- a/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/util/shop-util.kt +++ b/surf-shop-core/surf-shop-core-paper/src/main/kotlin/dev/slne/surf/shop/core/paper/util/shop-util.kt @@ -4,7 +4,6 @@ import com.github.benmanes.caffeine.cache.Caffeine import com.sksamuel.aedile.core.expireAfterWrite import dev.slne.surf.shop.api.deal.Deal import dev.slne.surf.shop.api.shop.Shop -import dev.slne.surf.shop.core.common.service.DealService import dev.slne.surf.shop.core.common.service.ShopService import org.bukkit.Bukkit import org.bukkit.block.ShulkerBox @@ -13,15 +12,11 @@ import org.bukkit.inventory.meta.BlockStateMeta import org.bukkit.inventory.meta.EnchantmentStorageMeta import org.bukkit.inventory.meta.PotionMeta import java.util.* +import java.util.concurrent.TimeUnit import kotlin.time.Duration.Companion.hours -val Shop.dealCount get() = DealService.loadedDeals.count { it.shopInternalId == this.internalId } -val Shop.totalSoldItems - get() = DealService.loadedDeals - .filter { it.shopInternalId == this.internalId } - .sumOf { it.amount } val Shop.updatedShop - get() = ShopService.loadedShops.firstOrNull { it.internalId == this.internalId } + get() = ShopService.getShopByInternalId(this.internalId) private val nameCache = Caffeine.newBuilder().expireAfterWrite(12.hours).build { @@ -29,11 +24,13 @@ private val nameCache = Caffeine.newBuilder().expireAfterWrite(12.hours).build() +private val itemCache = Caffeine.newBuilder() + .maximumSize(10_000) + .expireAfterAccess(6, TimeUnit.HOURS) + .build() + val Shop.item: ItemStack - get() = itemCache.getOrPut(this) { - itemStackFromString(itemString) - } + get() = itemCache.get(itemString) { itemStackFromString(it) } val Deal.boughtByName get() = nameCache.get(boughtBy) @@ -91,4 +88,4 @@ fun Shop.rebuildSearchTokens() { } } } -} \ No newline at end of file +} diff --git a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestListener.kt b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestListener.kt index 3e432c9..83589b8 100644 --- a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestListener.kt +++ b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestListener.kt @@ -260,7 +260,7 @@ object ShopChestListener : Listener { return } - val shop = ShopService.loadedShops.firstOrNull { it.shopUuid == shopUuid } + val shop = ShopService.getShop(shopUuid) if (shop == null) { player.sendText { appendErrorPrefix() diff --git a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestSelectShopView.kt b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestSelectShopView.kt index e5f96d1..3e62702 100644 --- a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestSelectShopView.kt +++ b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestSelectShopView.kt @@ -10,6 +10,7 @@ import dev.slne.surf.api.paper.builder.buildItem import dev.slne.surf.api.paper.builder.displayName import dev.slne.surf.api.paper.inventory.framework.titleBuilder import dev.slne.surf.shop.api.shopchest.StaticShopChest +import dev.slne.surf.shop.core.common.service.DealService import dev.slne.surf.shop.core.common.service.ShopService import dev.slne.surf.shop.core.common.service.StaticShopChestService import dev.slne.surf.shop.core.paper.util.item @@ -59,7 +60,14 @@ object ShopChestSelectShopView : View() { ShopService.loadedShops .filter { it.seller == context.player.uniqueId } .sortedBy { it.item.type.name } - .map { it to createShopItem(it, context.player.uniqueId, true) } + .map { + it to createShopItem( + it, + context.player.uniqueId, + true, + stats = DealService.getDealStats(it.internalId) + ) + } .toMutableList() } }.elementFactory { _, builder, _, shop -> diff --git a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestSetupView.kt b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestSetupView.kt index 053e825..ffb40fb 100644 --- a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestSetupView.kt +++ b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/chest/ShopChestSetupView.kt @@ -71,7 +71,7 @@ object ShopChestSetupView : View() { val shopUuid = chest.shopUuid val currentShop = if (shopUuid != null) { - ShopService.loadedShops.firstOrNull { it.shopUuid == shopUuid } + ShopService.getShop(shopUuid) } else null if (currentShop != null) { diff --git a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/command/argument/ShopArgument.kt b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/command/argument/ShopArgument.kt index 0cc27d2..62064a0 100644 --- a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/command/argument/ShopArgument.kt +++ b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/command/argument/ShopArgument.kt @@ -13,7 +13,9 @@ import java.util.* class ShopArgument(nodeName: String) : CustomArgument(StringArgument(nodeName), { info -> - ShopService.loadedShops.find { it.shopUuid == runCatching { UUID.fromString(info.input) }.getOrNull() } + runCatching { UUID.fromString(info.input) } + .getOrNull() + ?.let(ShopService::getShop) ?: throw CustomArgumentException.fromAdventureComponent( buildText { appendErrorPrefix() @@ -50,4 +52,4 @@ inline fun CommandAPICommand.shopArgument( optional: Boolean = false, block: Argument<*>.() -> Unit = {} ): CommandAPICommand = - withArguments(ShopArgument(nodeName).setOptional(optional).apply(block)) \ No newline at end of file + withArguments(ShopArgument(nodeName).setOptional(optional).apply(block)) diff --git a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/OwnShopsListView.kt b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/OwnShopsListView.kt index a41b8b5..5839fe4 100644 --- a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/OwnShopsListView.kt +++ b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/OwnShopsListView.kt @@ -26,9 +26,6 @@ import dev.slne.surf.shop.paper.plugin import dev.slne.surf.shop.paper.util.MenuHeads import dev.slne.surf.shop.paper.util.appendBlob import dev.slne.surf.shop.paper.util.searchInputCache -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.future.future import me.devnatan.inventoryframework.View import me.devnatan.inventoryframework.ViewConfigBuilder @@ -444,33 +441,29 @@ private suspend fun getOwnLoadedShopsWithItems( } } - val sorted = when (sortType) { - ShopSortingType.PRICE_ASC -> filtered.sortedBy { it.pricePerItem } - ShopSortingType.PRICE_DESC -> filtered.sortedByDescending { it.pricePerItem } - ShopSortingType.TIME_ASC -> filtered.sortedBy { it.createdAt } - ShopSortingType.TIME_DESC -> filtered.sortedByDescending { it.createdAt } - ShopSortingType.MOST_STORED -> filtered.sortedByDescending { it.storedItemCount } - ShopSortingType.MOST_DEALS -> { - val dealCountMap = DealService.loadedDeals.groupingBy { it.shopInternalId }.eachCount() - filtered.sortedByDescending { dealCountMap[it.internalId] ?: 0 } - } + val withStats = filtered.map { shop -> + shop to DealService.getDealStats(shop.internalId) + } - ShopSortingType.ITEM_NAME -> filtered.sortedBy { it.item.type.name } - ShopSortingType.SELLER_NAME -> filtered.sortedBy { it.sellerName.lowercase() } + val sorted = when (sortType) { + ShopSortingType.PRICE_ASC -> withStats.sortedBy { it.first.pricePerItem } + ShopSortingType.PRICE_DESC -> withStats.sortedByDescending { it.first.pricePerItem } + ShopSortingType.TIME_ASC -> withStats.sortedBy { it.first.createdAt } + ShopSortingType.TIME_DESC -> withStats.sortedByDescending { it.first.createdAt } + ShopSortingType.MOST_STORED -> withStats.sortedByDescending { it.first.storedItemCount } + ShopSortingType.MOST_DEALS -> withStats.sortedByDescending { it.second.dealCount } + ShopSortingType.ITEM_NAME -> withStats.sortedBy { it.first.item.type.name } + ShopSortingType.SELLER_NAME -> withStats.sortedBy { it.first.sellerName.lowercase() } } val playerId = context.player.uniqueId val viewOnly = !context.player.canUseFullShopView() - return coroutineScope { - sorted - .map { shop -> - async { - shop to createShopItem(shop, playerId, viewOnly = viewOnly) - } - } - .awaitAll() - }.toMutableList() + return sorted + .map { (shop, stats) -> + shop to createShopItem(shop, playerId, viewOnly = viewOnly, stats = stats) + } + .toMutableList() } object OwnShopState { diff --git a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/ShopListView.kt b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/ShopListView.kt index 2b1ec71..3d869ec 100644 --- a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/ShopListView.kt +++ b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/ShopListView.kt @@ -15,11 +15,10 @@ import dev.slne.surf.api.paper.inventory.framework.titleBuilder import dev.slne.surf.shop.api.shop.Shop import dev.slne.surf.shop.api.shop.ShopSortingType import dev.slne.surf.shop.core.common.service.DealService +import dev.slne.surf.shop.core.common.service.ShopDealStats import dev.slne.surf.shop.core.common.service.ShopService -import dev.slne.surf.shop.core.paper.util.dealCount import dev.slne.surf.shop.core.paper.util.item import dev.slne.surf.shop.core.paper.util.sellerName -import dev.slne.surf.shop.core.paper.util.totalSoldItems import dev.slne.surf.shop.paper.dialog.searchShopItemDialog import dev.slne.surf.shop.paper.menu.buy.BuyShopItemView import dev.slne.surf.shop.paper.menu.delete.DeleteShopView @@ -472,7 +471,8 @@ fun createShopItem( shop: Shop, viewer: UUID, shopChest: Boolean = false, - viewOnly: Boolean = false + viewOnly: Boolean = false, + stats: ShopDealStats = ShopDealStats() ) = shop.item.clone().apply { amount = 1 @@ -509,25 +509,23 @@ fun createShopItem( variableValue(shop.sellerName) }) - val dealCount = shop.dealCount newEntries.add(buildText { spacer("-") appendSpace() shopColored("Abgeschlossene Käufe: ") - if (dealCount > 0) { - variableValue(dealCount) + if (stats.dealCount > 0) { + variableValue(stats.dealCount) } else { error("Noch keine abgeschlossen") } }) - val totalSold = shop.totalSoldItems newEntries.add(buildText { spacer("-") appendSpace() shopColored("Gesamt verkauft: ") - if (totalSold > 0) { - variableValue("$totalSold Items") + if (stats.totalSoldItems > 0) { + variableValue("${stats.totalSoldItems} Items") } else { error("Noch keine verkauft") } @@ -651,34 +649,29 @@ private suspend fun getLoadedShopsSortedFiltered( } } - val sorted = when (sortType) { - ShopSortingType.PRICE_ASC -> filtered.sortedBy { it.pricePerItem } - ShopSortingType.PRICE_DESC -> filtered.sortedByDescending { it.pricePerItem } - ShopSortingType.TIME_ASC -> filtered.sortedBy { it.createdAt } - ShopSortingType.TIME_DESC -> filtered.sortedByDescending { it.createdAt } - ShopSortingType.MOST_STORED -> filtered.sortedByDescending { it.storedItemCount } - ShopSortingType.MOST_DEALS -> { - val dealCountMap = DealService.loadedDeals.groupingBy { it.shopInternalId }.eachCount() - filtered.sortedByDescending { dealCountMap[it.internalId] ?: 0 } - } + val withStats = filtered.map { shop -> + shop to DealService.getDealStats(shop.internalId) + } - ShopSortingType.ITEM_NAME -> filtered.sortedBy { it.item.type.name } - ShopSortingType.SELLER_NAME -> filtered.sortedBy { it.sellerName.lowercase() } + val sorted = when (sortType) { + ShopSortingType.PRICE_ASC -> withStats.sortedBy { it.first.pricePerItem } + ShopSortingType.PRICE_DESC -> withStats.sortedByDescending { it.first.pricePerItem } + ShopSortingType.TIME_ASC -> withStats.sortedBy { it.first.createdAt } + ShopSortingType.TIME_DESC -> withStats.sortedByDescending { it.first.createdAt } + ShopSortingType.MOST_STORED -> withStats.sortedByDescending { it.first.storedItemCount } + ShopSortingType.MOST_DEALS -> withStats.sortedByDescending { it.second.dealCount } + ShopSortingType.ITEM_NAME -> withStats.sortedBy { it.first.item.type.name } + ShopSortingType.SELLER_NAME -> withStats.sortedBy { it.first.sellerName.lowercase() } } val playerId = context.player.uniqueId val viewOnly = !context.player.canUseFullShopView() - return@withContext coroutineScope { - sorted - .map { shop -> - async { - shop to createShopItem(shop, playerId, viewOnly = viewOnly) - } - } - .awaitAll() - .toMutableList() - } + return@withContext sorted + .map { (shop, stats) -> + shop to createShopItem(shop, playerId, viewOnly = viewOnly, stats = stats) + } + .toMutableList() } diff --git a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/deal/DoneDealsView.kt b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/deal/DoneDealsView.kt index 88f5c93..f5b850b 100644 --- a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/deal/DoneDealsView.kt +++ b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/deal/DoneDealsView.kt @@ -45,11 +45,9 @@ object DoneDealsView : View() { private val paginationState = buildLazyAsyncPaginationState { context -> CompletableFuture.supplyAsync { - val shopsById = ShopService.loadedShops.associateBy { it.internalId } - DealService.loadedDeals.asSequence() .mapNotNull { deal -> - val shop = shopsById[deal.shopInternalId] + val shop = ShopService.getShopByInternalId(deal.shopInternalId) if (shop?.seller == context.player.uniqueId) deal to shop else null } .sortedByDescending { it.first.boughtAt } @@ -189,4 +187,4 @@ object DoneDealsView : View() { lore(oldLore + newEntries) } } -} \ No newline at end of file +} diff --git a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/edit/storage/ItemStorageRemoveView.kt b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/edit/storage/ItemStorageRemoveView.kt index 6a5035e..bc71d6f 100644 --- a/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/edit/storage/ItemStorageRemoveView.kt +++ b/surf-shop-paper/src/main/kotlin/dev/slne/surf/shop/paper/menu/edit/storage/ItemStorageRemoveView.kt @@ -136,7 +136,7 @@ object ItemStorageRemoveView : View() { plugin.launch { val updatedShop = - ShopService.loadedShops.find { it.shopUuid == shop.shopUuid } + ShopService.getShop(shop.shopUuid) if (updatedShop == null) { context.player.sendText { @@ -282,9 +282,10 @@ object ItemStorageRemoveView : View() { } private fun handleIncrement(render: RenderContext, context: SlotClickContext, delta: Int) { - val currentStock = ShopService.loadedShops.find { - it.shopUuid == shopState.get(context)?.shopUuid - }?.storedItemCount ?: 0 + val currentStock = shopState.get(context) + ?.shopUuid + ?.let(ShopService::getShop) + ?.storedItemCount ?: 0 val newAmount = localAmountState.get(render) + delta @@ -308,11 +309,12 @@ object ItemStorageRemoveView : View() { displayName { shopColored("Anzahl: ", TextDecoration.BOLD) appendSpace() - shopColored(("${localAmountState.get(context)}/" + ShopService.loadedShops.find { - it.shopUuid == shopState.get( - context - )?.shopUuid - }?.storedItemCount)) + shopColored( + "${localAmountState.get(context)}/" + shopState.get(context) + ?.shopUuid + ?.let(ShopService::getShop) + ?.storedItemCount + ) } }