Fix renamed Shards duplication by only checking for the key

This commit is contained in:
SKBotNL committed 2026-09-19 00:08:24 +02:00
1 parent 0f2c29acde
commit fc6ea8180b
7 files changed
+70 -8

No files matched your search

@@ -10,6 +10,7 @@ import net.trueog.diamondbankog.DiamondBankOG.Companion.transactionLock
import net.trueog.diamondbankog.balance.shard.Shard
import net.trueog.diamondbankog.transaction.InventoryLockExtensions.withInventoryLockSuspend
import net.trueog.diamondbankog.transaction.InventorySnapshot
import net.trueog.diamondbankog.util.InventoryExtensions.removeItemWithSameKey
import net.trueog.diamondbankog.util.MainThreadBlock.runOnMainThread
import net.trueog.diamondbankog.util.PlayerInventoryExtensions.countDiamondBlocks
import net.trueog.diamondbankog.util.PlayerInventoryExtensions.countDiamonds
@@ -98,7 +99,8 @@ internal object AutoCompress {
}
if (changeInShards < 0) {
val removeMap = inventorySnapshot.removeItem(Shard.createItemStack(abs(changeInShards)))
val removeMap =
inventorySnapshot.removeItemWithSameKey(Shard.createItemStack(abs(changeInShards)))
if (removeMap.isNotEmpty()) {
player.sendMessage(
mm.deserialize(
@@ -243,9 +243,7 @@ private constructor(
toDelete -= removed
if (itemStack.amount == 0) {
contents[firstSlot] = null
} else {
contents[firstSlot] = itemStack
setItem(firstSlot, null)
}
}
}
@@ -5,6 +5,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage
import net.trueog.diamondbankog.balance.BalanceManager
import net.trueog.diamondbankog.balance.shard.Shard
import net.trueog.diamondbankog.config.Config
import net.trueog.diamondbankog.util.InventoryExtensions.removeItemWithSameKey
import net.trueog.diamondbankog.util.PlayerInventoryExtensions.countDiamondBlocks
import net.trueog.diamondbankog.util.PlayerInventoryExtensions.countDiamonds
import net.trueog.diamondbankog.util.PlayerInventoryExtensions.countShards
@@ -25,7 +26,7 @@ object InventorySnapshotUtils {
val shards = shards.toInt()
val notRemovedShards = inventory.removeItem(Shard.createItemStack(shards)).values.sumOf { it.amount }
val notRemovedShards = inventory.removeItemWithSameKey(Shard.createItemStack(shards)).values.sumOf { it.amount }
if (notRemovedShards == 0) return Result.success(shards)
val diamondsToBeRemoved = ceil(notRemovedShards / 9.0).toInt()
@@ -103,7 +104,7 @@ object InventorySnapshotUtils {
/** @return the amount of shards that could be removed */
fun removeAllShards(inventory: InventorySnapshot): Int {
val shards = inventory.countShards().toInt()
inventory.removeItem(Shard.createItemStack(shards))
inventory.removeItemWithSameKey(Shard.createItemStack(shards))
return shards
}
@@ -15,6 +15,7 @@ import net.trueog.diamondbankog.util.CommonCommandInterlude
import net.trueog.diamondbankog.util.InventoryExtensions.countDiamondBlocks
import net.trueog.diamondbankog.util.InventoryExtensions.countDiamonds
import net.trueog.diamondbankog.util.InventoryExtensions.countShards
import net.trueog.diamondbankog.util.InventoryExtensions.removeItemWithSameKey
import net.trueog.diamondbankog.util.MainThreadBlock.runOnMainThread
import net.trueog.diamondbankog.util.PlayerInventoryExtensions.countDiamondBlocks
import net.trueog.diamondbankog.util.PlayerInventoryExtensions.countDiamonds
@@ -166,7 +167,8 @@ internal class Compress(
val summaryStringBuilder = StringBuilder("Compression Summary:")
if (changeInShards < 0) {
val removeMap = inventory.removeItem(Shard.createItemStack(abs(changeInShards)))
val removeMap =
inventory.removeItemWithSameKey(Shard.createItemStack(abs(changeInShards)))
if (removeMap.isNotEmpty()) {
sender.sendMessage(
mm.deserialize(
@@ -4,6 +4,7 @@ import net.trueog.diamondbankog.balance.shard.Shard
import org.bukkit.Material
import org.bukkit.block.ShulkerBox
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.BlockStateMeta
internal object InventoryExtensions {
@@ -31,4 +32,41 @@ internal object InventoryExtensions {
val inventoryDiamondBlocks = this.all(Material.DIAMOND_BLOCK).values.sumOf { it.amount }
return inventoryDiamondBlocks.toLong()
}
fun Inventory.removeItemWithSameKey(vararg items: ItemStack): HashMap<Int, ItemStack> {
val leftover = HashMap<Int, ItemStack>()
items.forEachIndexed { index, item ->
if (item.type.isAir) return@forEachIndexed
var toDelete = item.amount
while (toDelete > 0) {
val firstSlot = firstWithSameKey(item)
if (firstSlot == -1) {
item.amount = toDelete
leftover[index] = item
toDelete = 0
} else {
val itemStack = contents[firstSlot]!!
val removed = minOf(itemStack.amount, toDelete)
itemStack.amount -= removed
toDelete -= removed
if (itemStack.amount == 0) {
setItem(firstSlot, null)
}
}
}
}
return leftover
}
fun Inventory.firstWithSameKey(item: ItemStack): Int {
return contents.indexOfFirst {
it != null && item.itemMeta.persistentDataContainer.keys == it.itemMeta.persistentDataContainer.keys
}
}
}
@@ -105,7 +105,7 @@ object BukkitMock {
{
val itemMeta = firstArg<ItemMeta>()
val persistentDataContainerKeys = mutableSetOf<NamespacedKey>()
val displayName = itemMeta.displayName()
var displayName = itemMeta.displayName()
itemMeta.persistentDataContainer.keys.forEach { persistentDataContainerKeys.add(it) }
val material = secondArg<Material>()
@@ -118,6 +118,7 @@ object BukkitMock {
every { newItemMeta.clone() } returns newItemMeta
every { newItemMeta.displayName() } answers { displayName }
every { newItemMeta.displayName(any()) } answers { displayName = firstArg<Component>() }
every { newItemMeta.persistentDataContainer.has(any()) } answers
{
val key = firstArg<NamespacedKey>()
@@ -177,6 +178,10 @@ object BukkitMock {
var contents = arrayOfNulls<ItemStack>(36)
every { inventory.contents = any<Array<ItemStack?>>() } answers { contents = firstArg<Array<ItemStack?>>() }
every { inventory.contents } answers { contents }
every { inventory.setItem(any<Int>(), anyNullable<ItemStack?>()) } answers
{
contents[firstArg()] = secondArg()
}
every { inventory.storageContents } answers { contents }
every { inventory.all(any<Material>()) } answers
{
@@ -191,6 +191,22 @@ class DepositTest {
0,
1,
),
Arguments.of(
"2 renamed Diamond Shards",
"0.2 <aqua>Diamonds",
arrayOf(
Shard.createItemStack(2).apply {
val meta = itemMeta
meta.displayName(Component.text("Renamed Diamond Shard"))
itemMeta = meta
}
),
"0.2",
arrayOf<Long>(2),
0,
0,
0,
),
)
}