From 9d1a5bf104beee5ad5ec78e420833680cec9b266 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sun, 20 Nov 2022 21:36:29 +0100 Subject: [PATCH] network: allow setting floating item --- .../data/container/IncompleteContainer.kt | 23 +++++++++++++++++++ .../player/local/LocalPlayerEntity.kt | 3 ++- .../s2c/play/container/ContainerItemS2CP.kt | 21 +++++++++++------ .../s2c/play/container/ContainerItemsS2CP.kt | 19 +++++++-------- .../s2c/play/container/OpenContainerS2CP.kt | 3 ++- 5 files changed, 51 insertions(+), 18 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/data/container/IncompleteContainer.kt diff --git a/src/main/java/de/bixilon/minosoft/data/container/IncompleteContainer.kt b/src/main/java/de/bixilon/minosoft/data/container/IncompleteContainer.kt new file mode 100644 index 000000000..40c91e4aa --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/container/IncompleteContainer.kt @@ -0,0 +1,23 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.container + +import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf +import de.bixilon.kutil.collections.map.SynchronizedMap +import de.bixilon.minosoft.data.container.stack.ItemStack + +class IncompleteContainer() { + val slots: SynchronizedMap = synchronizedMapOf() + var floating: ItemStack? = null +} diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/player/local/LocalPlayerEntity.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/player/local/LocalPlayerEntity.kt index 322f66326..9745b3579 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/player/local/LocalPlayerEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/player/local/LocalPlayerEntity.kt @@ -37,6 +37,7 @@ import de.bixilon.minosoft.data.abilities.Gamemodes import de.bixilon.minosoft.data.abilities.ItemCooldown import de.bixilon.minosoft.data.accounts.Account import de.bixilon.minosoft.data.container.Container +import de.bixilon.minosoft.data.container.IncompleteContainer import de.bixilon.minosoft.data.container.InventorySlots import de.bixilon.minosoft.data.container.stack.ItemStack import de.bixilon.minosoft.data.container.types.PlayerInventory @@ -92,7 +93,7 @@ class LocalPlayerEntity( val baseAbilities = Abilities() val inventory = PlayerInventory(connection) - val incompleteContainers: SynchronizedMap> = synchronizedMapOf() + val incompleteContainers: SynchronizedMap = synchronizedMapOf() val containers: SynchronizedBiMap = synchronizedBiMapOf( ProtocolDefinition.PLAYER_CONTAINER_ID to inventory, ) diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/ContainerItemS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/ContainerItemS2CP.kt index 447e197a4..03074f275 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/ContainerItemS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/ContainerItemS2CP.kt @@ -12,7 +12,7 @@ */ package de.bixilon.minosoft.protocol.packets.s2c.play.container -import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf +import de.bixilon.minosoft.data.container.IncompleteContainer import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.factory.LoadPacket import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket @@ -30,22 +30,29 @@ class ContainerItemS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { } else { -1 } - val slot = buffer.readUnsignedShort() + val slot = buffer.readShort().toInt() val itemStack = buffer.readItemStack() override fun handle(connection: PlayConnection) { val container = connection.player.containers[containerId] if (container == null) { - val slots = connection.player.incompleteContainers.synchronizedGetOrPut(containerId) { synchronizedMapOf() } - if (itemStack == null) { - slots -= slot + val incomplete = connection.player.incompleteContainers.synchronizedGetOrPut(containerId) { IncompleteContainer() } + if (slot < 0) { + incomplete.floating = itemStack + } else if (itemStack == null) { + incomplete.slots -= slot } else { - slots[slot] = itemStack + incomplete.slots[slot] = itemStack } + return } - container[slot] = itemStack + if (slot < 0) { + container.floatingItem = itemStack + } else { + container[slot] = itemStack + } container.serverRevision = revision } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/ContainerItemsS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/ContainerItemsS2CP.kt index 205faf71a..e04ea4ef2 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/ContainerItemsS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/ContainerItemsS2CP.kt @@ -12,10 +12,8 @@ */ package de.bixilon.minosoft.protocol.packets.s2c.play.container -import de.bixilon.kutil.cast.CastUtil.unsafeCast -import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf -import de.bixilon.kutil.collections.map.SynchronizedMap import de.bixilon.minosoft.data.container.Container +import de.bixilon.minosoft.data.container.IncompleteContainer import de.bixilon.minosoft.data.container.stack.ItemStack import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.factory.LoadPacket @@ -25,6 +23,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_1_17_1_PRE1 import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogMessageType +import java.util.* @LoadPacket class ContainerItemsS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { @@ -41,24 +40,25 @@ class ContainerItemsS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { buffer.readUnsignedShort() } ) { buffer.readItemStack() } - val cursor = if (buffer.versionId >= V_1_17_1_PRE1) { - buffer.readItemStack() + val floatingItem = if (buffer.versionId >= V_1_17_1_PRE1) { + buffer.readItemStack()?.let { Optional.of(it) } ?: Optional.empty() } else { null } private fun pushIncompleteContainer(connection: PlayConnection) { - val slots: SynchronizedMap = synchronizedMapOf() + val container = IncompleteContainer() for ((slotId, stack) in this.items.withIndex()) { if (stack == null) { continue } - slots[slotId] = stack + container.slots[slotId] = stack } + container.floating = floatingItem?.let { if (it.isEmpty) null else it.get() } - connection.player.incompleteContainers[containerId] = slots.unsafeCast() + connection.player.incompleteContainers[containerId] = container } private fun updateContainer(container: Container) { @@ -72,6 +72,7 @@ class ContainerItemsS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { container._set(slotId, stack) } container.serverRevision = revision + this.floatingItem?.let { container.floatingItem = if (it.isEmpty) null else it.get() } container.lock.unlock() container.revision++ } @@ -86,6 +87,6 @@ class ContainerItemsS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { } override fun log(reducedLog: Boolean) { - Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Container items (containerId=$containerId, items=${items.contentToString()}" } + Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Container items (containerId=$containerId, items=${items.contentToString()}, floating=$floatingItem)" } } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/OpenContainerS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/OpenContainerS2CP.kt index 23826aab5..d5e13a1e8 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/OpenContainerS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/OpenContainerS2CP.kt @@ -73,9 +73,10 @@ class OpenContainerS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { val container = containerType.factory.build(connection, containerType, title) connection.player.incompleteContainers.remove(containerId)?.let { - for ((slot, stack) in it) { + for ((slot, stack) in it.slots) { container[slot] = stack } + container.floatingItem = it.floating } connection.player.containers[containerId] = container connection.player.openedContainer = container