Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@ 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<DealService>()

data class ShopDealStats(
val dealCount: Int = 0,
val totalSoldItems: Int = 0
)

interface DealService {
val loadedDeals: ObjectSet<Deal>
val loadedDeals: Collection<Deal>

fun loadedDealsSnapshot(): List<Deal> = 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

suspend fun fetchDeals()

companion object : DealService by service
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<ShopService>()

interface ShopService {
val loadedShops: ObjectSet<Shop>
val loadedShops: Collection<Shop>

fun loadedShopsSnapshot(): List<Shop> = loadedShops.toList()
fun getShop(shopUuid: UUID): Shop?
fun getShopByInternalId(internalId: ULong): Shop?

suspend fun createShop(
itemString: String,
Expand All @@ -25,4 +28,4 @@ interface ShopService {
suspend fun fetchShops()

companion object : ShopService by service
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -35,8 +33,13 @@ import java.util.concurrent.ConcurrentHashMap

@AutoService(DealService::class)
class DealServiceImpl : DealService, Services.Fallback {
private val _deals = mutableObject2ObjectMapOf<UUID, Deal>()
override val loadedDeals: ObjectSet<Deal> get() = _deals.values.toObjectSet()
private val _deals = ConcurrentHashMap<UUID, Deal>()
private val _dealStatsByShop = ConcurrentHashMap<ULong, ShopDealStats>()

override val loadedDeals: Collection<Deal> get() = _deals.values

override fun getDealStats(shopInternalId: ULong) =
_dealStatsByShop[shopInternalId] ?: ShopDealStats()

private val shopLocks = ConcurrentHashMap<UUID, Mutex>()

Expand All @@ -60,7 +63,7 @@ class DealServiceImpl : DealService, Services.Fallback {
)
).deal

_deals[bought.dealUuid] = bought
putDeal(bought)
return bought
}

Expand All @@ -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)

Expand Down Expand Up @@ -141,7 +142,7 @@ class DealServiceImpl : DealService, Services.Fallback {
)
).deal

_deals[deal.dealUuid] = deal
putDeal(deal)

val itemStack = shop.item
var remaining = amount
Expand Down Expand Up @@ -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")
}
Expand All @@ -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
}
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -24,8 +21,13 @@ import kotlin.system.measureTimeMillis
@AutoService(ShopService::class)
class ShopServiceImpl : ShopService, Services.Fallback {

private val _shops = mutableObject2ObjectMapOf<UUID, Shop>()
override val loadedShops: ObjectSet<Shop> get() = _shops.values.toObjectSet()
private val _shops = ConcurrentHashMap<UUID, Shop>()
private val _shopsByInternalId = ConcurrentHashMap<ULong, Shop>()

override val loadedShops: Collection<Shop> get() = _shops.values

override fun getShop(shopUuid: UUID) = _shops[shopUuid]
override fun getShopByInternalId(internalId: ULong) = _shopsByInternalId[internalId]

private val shopLocks = ConcurrentHashMap<UUID, Mutex>()

Expand All @@ -52,7 +54,7 @@ class ShopServiceImpl : ShopService, Services.Fallback {
rebuildSearchTokens()
}

_shops[created.shopUuid] = created
putShop(created)
return created
}

Expand All @@ -69,7 +71,7 @@ class ShopServiceImpl : ShopService, Services.Fallback {
rebuildSearchTokens()
}

_shops[shop.shopUuid] = updatedShop
putShop(updatedShop)

PaperShopInstance.rabbitApi.sendRequest(
SaveShopRequestPacket(
Expand All @@ -92,7 +94,7 @@ class ShopServiceImpl : ShopService, Services.Fallback {
).value

if (deleted) {
_shops.remove(shop.shopUuid)
removeShop(shop)
shopLocks.remove(shop.shopUuid)
}

Expand All @@ -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")
}
}

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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -13,27 +12,25 @@ 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<UUID, String> {
Bukkit.getOfflinePlayer(it).name ?: "#Unbekannt"
}

val Shop.sellerName get() = nameCache.get(seller)
private val itemCache = mutableMapOf<Shop, ItemStack>()
private val itemCache = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterAccess(6, TimeUnit.HOURS)
.build<String, ItemStack>()

val Shop.item: ItemStack
get() = itemCache.getOrPut(this) {
itemStackFromString(itemString)
}
get() = itemCache.get(itemString) { itemStackFromString(it) }

val Deal.boughtByName get() = nameCache.get(boughtBy)

Expand Down Expand Up @@ -91,4 +88,4 @@ fun Shop.rebuildSearchTokens() {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import java.util.*

class ShopArgument(nodeName: String) :
CustomArgument<Shop, String>(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()
Expand Down Expand Up @@ -50,4 +52,4 @@ inline fun CommandAPICommand.shopArgument(
optional: Boolean = false,
block: Argument<*>.() -> Unit = {}
): CommandAPICommand =
withArguments(ShopArgument(nodeName).setOptional(optional).apply(block))
withArguments(ShopArgument(nodeName).setOptional(optional).apply(block))
Loading