From 63cdc8abf04b5ab66df024b4eee247bcf223ba59 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sat, 26 Feb 2022 16:11:02 +0100 Subject: [PATCH] fix some inventory actions, make ItemStack::copy is non locking --- .../click/FastMoveContainerAction.kt | 4 ++- .../container/click/SimpleContainerAction.kt | 35 +++++++++++++------ .../stack/property/DisplayProperty.kt | 6 ++-- .../stack/property/DurabilityProperty.kt | 4 +-- .../stack/property/EnchantingProperty.kt | 2 +- .../container/stack/property/HideProperty.kt | 2 +- .../types/generic/GenericContainer.kt | 29 ++++++++++++++- .../minosoft/data/entities/entities/Entity.kt | 2 +- 8 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/container/click/FastMoveContainerAction.kt b/src/main/java/de/bixilon/minosoft/data/container/click/FastMoveContainerAction.kt index fe90d99a1..c56aa3b04 100644 --- a/src/main/java/de/bixilon/minosoft/data/container/click/FastMoveContainerAction.kt +++ b/src/main/java/de/bixilon/minosoft/data/container/click/FastMoveContainerAction.kt @@ -53,11 +53,12 @@ class FastMoveContainerAction( } } val changes: Int2ObjectOpenHashMap = Int2ObjectOpenHashMap() - for ((slot, content) in targets) { + for ((slot, content) in targets.toSortedMap()) { if (content == null) { changes[slot] = source changes[this.slot] = null container._set(slot, source) + container._set(this.slot, null) break } val countToPut = source.item._count - (source.item.item.maxStackSize - content.item._count) @@ -73,6 +74,7 @@ class FastMoveContainerAction( connection.sendPacket(ContainerClickC2SP(containerId, container.serverRevision, this.slot, 1, 0, container.createAction(this), changes, previous)) } finally { container.commit() + container._validate() } } } diff --git a/src/main/java/de/bixilon/minosoft/data/container/click/SimpleContainerAction.kt b/src/main/java/de/bixilon/minosoft/data/container/click/SimpleContainerAction.kt index a0d64d874..03dbf3f88 100644 --- a/src/main/java/de/bixilon/minosoft/data/container/click/SimpleContainerAction.kt +++ b/src/main/java/de/bixilon/minosoft/data/container/click/SimpleContainerAction.kt @@ -36,7 +36,7 @@ class SimpleContainerAction( floatingItem = item } else { // half - val stayCount = maxOf(item.item.count / 2, 1) + val stayCount = item.item.count / 2 item.item.count = stayCount floatingItem = previous.copy(count = previous.item.count - stayCount) } @@ -59,14 +59,24 @@ class SimpleContainerAction( val slotType = container.getSlotType(slot) if (target != null && floatingItem.matches(target)) { - if (slotType?.canPut(container, slot, floatingItem) != true) { - // is this check needed? - return + if (slotType?.canPut(container, slot, floatingItem) == true) { + // merge + val subtract = if (count == ContainerCounts.ALL) minOf(target.item.item.maxStackSize - target.item._count, floatingItem.item._count) else 1 + if (subtract == 0) { + return + } + target.item._count += subtract + floatingItem.item._count -= subtract + } else if (slotType?.canRemove(container, slot, floatingItem) == true) { + // remove only (e.g. crafting result) + // ToDo: respect count + val subtract = minOf(floatingItem.item.item.maxStackSize - floatingItem.item._count, target.item._count) + if (subtract == 0) { + return + } + target.item._count -= subtract + floatingItem.item._count += subtract } - // merge - val subtract = minOf(target.item.item.maxStackSize - target.item._count, floatingItem.item._count) - target.item._count += subtract - floatingItem.item._count -= subtract connection.sendPacket(ContainerClickC2SP(containerId, container.serverRevision, slot, 0, count.ordinal, container.createAction(this), mapOf(slot to target), target)) return @@ -78,8 +88,13 @@ class SimpleContainerAction( return } // swap - container.floatingItem = target - container._set(slot, floatingItem) + if (count == ContainerCounts.ALL) { + container.floatingItem = target + container._set(slot, floatingItem) + } else { + floatingItem.item._count-- + container._set(slot, floatingItem.copy(count = 1)) + } connection.sendPacket(ContainerClickC2SP(containerId, container.serverRevision, slot, 0, count.ordinal, container.createAction(this), mapOf(slot to target), target)) } finally { floatingItem.commit() diff --git a/src/main/java/de/bixilon/minosoft/data/container/stack/property/DisplayProperty.kt b/src/main/java/de/bixilon/minosoft/data/container/stack/property/DisplayProperty.kt index ea5c337eb..2b546eae6 100644 --- a/src/main/java/de/bixilon/minosoft/data/container/stack/property/DisplayProperty.kt +++ b/src/main/java/de/bixilon/minosoft/data/container/stack/property/DisplayProperty.kt @@ -37,7 +37,7 @@ class DisplayProperty( var _customDisplayName = customDisplayName var customDisplayName by InventoryDelegate(stack, this::_customDisplayName) var _dyeColor = dyedColor - var dyedColor by InventoryDelegate(stack, this::_dyeColor) + var dyeColor by InventoryDelegate(stack, this::_dyeColor) init { @@ -80,8 +80,8 @@ class DisplayProperty( fun copy( stack: ItemStack, lore: MutableList = this.lore.toMutableList(), - customDisplayName: ChatComponent? = this.customDisplayName, - dyedColor: RGBColor? = this.dyedColor, + customDisplayName: ChatComponent? = this._customDisplayName, + dyedColor: RGBColor? = this._dyeColor, ): DisplayProperty { return DisplayProperty(stack, lore, customDisplayName, dyedColor) } diff --git a/src/main/java/de/bixilon/minosoft/data/container/stack/property/DurabilityProperty.kt b/src/main/java/de/bixilon/minosoft/data/container/stack/property/DurabilityProperty.kt index d9294531a..15466661d 100644 --- a/src/main/java/de/bixilon/minosoft/data/container/stack/property/DurabilityProperty.kt +++ b/src/main/java/de/bixilon/minosoft/data/container/stack/property/DurabilityProperty.kt @@ -81,8 +81,8 @@ class DurabilityProperty( fun copy( stack: ItemStack, - unbreakable: Boolean = this.unbreakable, - durability: Int = this.durability, + unbreakable: Boolean = this._unbreakable, + durability: Int = this._durability, ): DurabilityProperty { return DurabilityProperty(stack, unbreakable, durability) } diff --git a/src/main/java/de/bixilon/minosoft/data/container/stack/property/EnchantingProperty.kt b/src/main/java/de/bixilon/minosoft/data/container/stack/property/EnchantingProperty.kt index 6e6fbf738..d7a82edd3 100644 --- a/src/main/java/de/bixilon/minosoft/data/container/stack/property/EnchantingProperty.kt +++ b/src/main/java/de/bixilon/minosoft/data/container/stack/property/EnchantingProperty.kt @@ -95,7 +95,7 @@ class EnchantingProperty( fun copy( stack: ItemStack, enchantments: MutableMap = this.enchantments.toMutableMap(), - repairCost: Int = this.repairCost, + repairCost: Int = this._repairCost, ): EnchantingProperty { return EnchantingProperty(stack, enchantments, repairCost) } diff --git a/src/main/java/de/bixilon/minosoft/data/container/stack/property/HideProperty.kt b/src/main/java/de/bixilon/minosoft/data/container/stack/property/HideProperty.kt index 4f591950b..8f464c42c 100644 --- a/src/main/java/de/bixilon/minosoft/data/container/stack/property/HideProperty.kt +++ b/src/main/java/de/bixilon/minosoft/data/container/stack/property/HideProperty.kt @@ -90,7 +90,7 @@ class HideProperty( fun copy( stack: ItemStack, - hideFlags: Int = this.hideFlags, + hideFlags: Int = this._hideFlags, ): HideProperty { return HideProperty(stack, hideFlags) } diff --git a/src/main/java/de/bixilon/minosoft/data/container/types/generic/GenericContainer.kt b/src/main/java/de/bixilon/minosoft/data/container/types/generic/GenericContainer.kt index 03d884d21..d8b17ed4f 100644 --- a/src/main/java/de/bixilon/minosoft/data/container/types/generic/GenericContainer.kt +++ b/src/main/java/de/bixilon/minosoft/data/container/types/generic/GenericContainer.kt @@ -14,6 +14,8 @@ package de.bixilon.minosoft.data.container.types.generic import de.bixilon.minosoft.data.container.Container +import de.bixilon.minosoft.data.container.slots.DefaultSlotType +import de.bixilon.minosoft.data.container.slots.SlotType import de.bixilon.minosoft.data.registries.other.containers.ContainerType import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection @@ -23,4 +25,29 @@ abstract class GenericContainer( connection: PlayConnection, type: ContainerType, title: ChatComponent?, -) : Container(connection, type, title) +) : Container(connection, type, title) { + override val sections: Array = arrayOf(0 until rows * SLOTS_PER_ROW, rows * SLOTS_PER_ROW until rows * SLOTS_PER_ROW + INVENTORY_SLOTS) + + override fun getSlotType(slotId: Int): SlotType? { + if (slotId in 0 until rows * SLOTS_PER_ROW + INVENTORY_SLOTS) { + return DefaultSlotType + } + return null + } + + override fun getSection(slotId: Int): Int? { + if (slotId in 0 until rows * SLOTS_PER_ROW) { + return 0 + } + if (slotId in rows * SLOTS_PER_ROW until rows * SLOTS_PER_ROW + INVENTORY_SLOTS) { + return 1 + } + return null + } + + + companion object { + const val SLOTS_PER_ROW = 9 + const val INVENTORY_SLOTS = 4 * SLOTS_PER_ROW + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt index 01edeb19b..b9a80c85f 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt @@ -332,7 +332,7 @@ abstract class Entity( this is PlayerEntity -> { val chestPlate = equipment[EquipmentSlots.CHEST] if (chestPlate != null && chestPlate.item.item is DyeableArmorItem) { - chestPlate._display?.dyedColor?.let { return it } + chestPlate._display?.dyeColor?.let { return it } } val formattingCode = tabListItem.team?.formattingCode if (formattingCode is RGBColor) {