From b7a053b83d0cfa69f8591b876a99c6a21fe08351 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Fri, 13 Jan 2023 11:47:01 +0100 Subject: [PATCH] restructure some container closing logic --- .../data/container/ClientContainer.kt | 20 +++++++++++++++++++ .../minosoft/data/container/Container.kt | 18 ++++++++++++----- .../data/container/types/PlayerInventory.kt | 3 ++- .../player/local/LocalPlayerEntity.kt | 2 +- .../gui/screen/container/ContainerScreen.kt | 4 ++-- .../events/container/ContainerCloseEvent.kt | 3 +-- .../events/container/ContainerOpenEvent.kt | 3 +-- .../connection/play/util/ConnectionUtil.kt | 2 +- .../s2c/play/OpenHorseContainerS2CP.kt | 7 +++++-- .../s2c/play/container/CloseContainerS2CP.kt | 9 ++++----- .../s2c/play/container/OpenContainerS2CP.kt | 5 +++-- 11 files changed, 53 insertions(+), 23 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/data/container/ClientContainer.kt diff --git a/src/main/java/de/bixilon/minosoft/data/container/ClientContainer.kt b/src/main/java/de/bixilon/minosoft/data/container/ClientContainer.kt new file mode 100644 index 000000000..5d54391eb --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/container/ClientContainer.kt @@ -0,0 +1,20 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 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 + +/** + * This container is managed by the client and always be present + * Container closing means in this context hiding it + */ +interface ClientContainer diff --git a/src/main/java/de/bixilon/minosoft/data/container/Container.kt b/src/main/java/de/bixilon/minosoft/data/container/Container.kt index e5e45e38d..b2a02d542 100644 --- a/src/main/java/de/bixilon/minosoft/data/container/Container.kt +++ b/src/main/java/de/bixilon/minosoft/data/container/Container.kt @@ -33,6 +33,7 @@ import de.bixilon.minosoft.data.registries.containers.ContainerType import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.modding.event.events.container.ContainerCloseEvent import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.c2s.play.container.CloseContainerC2SP import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap @@ -215,20 +216,27 @@ open class Container( action.revert(connection, id ?: return, this) } - fun onClose() { - floatingItem = null // ToDo: Does not seem correct + fun close(force: Boolean = false) { + connection.events.fire(ContainerCloseEvent(connection, this)) + onClose() + val id = id ?: return - if (id != PlayerInventory.CONTAINER_ID) { + if (id != PlayerInventory.CONTAINER_ID || this is ClientContainer) { connection.player.containers -= id } - // minecraft behavior, when opening the inventory an open packet is never sent, but a close is - if (connection.player.openedContainer == this) { + + if (force && connection.player.openedContainer == this) { + connection.player.openedContainer = null connection.sendPacket(CloseContainerC2SP(id)) } } + protected open fun onClose() { + floatingItem = null // ToDo: Does not seem correct + } + override fun iterator(): Iterator> { return slots.iterator() } diff --git a/src/main/java/de/bixilon/minosoft/data/container/types/PlayerInventory.kt b/src/main/java/de/bixilon/minosoft/data/container/types/PlayerInventory.kt index 477eb5a2f..e047a1241 100644 --- a/src/main/java/de/bixilon/minosoft/data/container/types/PlayerInventory.kt +++ b/src/main/java/de/bixilon/minosoft/data/container/types/PlayerInventory.kt @@ -16,6 +16,7 @@ package de.bixilon.minosoft.data.container.types import de.bixilon.kutil.collections.CollectionUtil.lockMapOf import de.bixilon.kutil.collections.map.LockMap import de.bixilon.kutil.observer.map.MapObserver.Companion.observeMap +import de.bixilon.minosoft.data.container.ClientContainer import de.bixilon.minosoft.data.container.Container import de.bixilon.minosoft.data.container.EquipmentSlots import de.bixilon.minosoft.data.container.click.SlotSwapContainerAction @@ -40,7 +41,7 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.util.KUtil.toResourceLocation // https://c4k3.github.io/wiki.vg/images/1/13/Inventory-slots.png -class PlayerInventory(connection: PlayConnection) : Container(connection = connection, type = TYPE) { +class PlayerInventory(connection: PlayConnection) : Container(connection = connection, type = TYPE), ClientContainer { override val sections: Array get() = SECTIONS val equipment: LockMap = lockMapOf() 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 d84af08f4..563e31229 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 @@ -107,7 +107,7 @@ class LocalPlayerEntity( } } - var openedContainer: Container? = null + var openedContainer: Container? by observed(null) val itemCooldown: MutableMap = synchronizedMapOf() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/screen/container/ContainerScreen.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/screen/container/ContainerScreen.kt index 6f4ca04de..35408407a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/screen/container/ContainerScreen.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/screen/container/ContainerScreen.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 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. * @@ -66,6 +66,6 @@ abstract class ContainerScreen( override fun onClose() { super.onClose() - container.onClose() + container.close() } } diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/container/ContainerCloseEvent.kt b/src/main/java/de/bixilon/minosoft/modding/event/events/container/ContainerCloseEvent.kt index f39cae15b..ca7aa5bff 100644 --- a/src/main/java/de/bixilon/minosoft/modding/event/events/container/ContainerCloseEvent.kt +++ b/src/main/java/de/bixilon/minosoft/modding/event/events/container/ContainerCloseEvent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 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. * @@ -19,6 +19,5 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection class ContainerCloseEvent( connection: PlayConnection, - val containerId: Int, val container: Container, ) : PlayConnectionEvent(connection) diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/container/ContainerOpenEvent.kt b/src/main/java/de/bixilon/minosoft/modding/event/events/container/ContainerOpenEvent.kt index 2eadd91a1..d269308e5 100644 --- a/src/main/java/de/bixilon/minosoft/modding/event/events/container/ContainerOpenEvent.kt +++ b/src/main/java/de/bixilon/minosoft/modding/event/events/container/ContainerOpenEvent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 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. * @@ -19,6 +19,5 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection class ContainerOpenEvent( connection: PlayConnection, - val containerId: Int, val container: Container, ) : PlayConnectionEvent(connection) diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/util/ConnectionUtil.kt b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/util/ConnectionUtil.kt index 4a3686039..f7e6e2ddb 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/util/ConnectionUtil.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/util/ConnectionUtil.kt @@ -120,7 +120,7 @@ class ConnectionUtil( connection.world.particleRenderer?.removeAllParticles() connection.player.openedContainer?.let { connection.player.openedContainer = null - connection.events.fire(ContainerCloseEvent(connection, it.id ?: -1, it)) + connection.events.fire(ContainerCloseEvent(connection, it)) } connection.player.healthCondition = HealthCondition() connection.world.time = WorldTime() diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/OpenHorseContainerS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/OpenHorseContainerS2CP.kt index a551477b1..8209bc8b0 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/OpenHorseContainerS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/OpenHorseContainerS2CP.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 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. * @@ -27,7 +27,10 @@ class OpenHorseContainerS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { val entityId: Int = buffer.readInt() override fun handle(connection: PlayConnection) { - // ToDo + val entity = connection.world.entities[entityId] ?: return + + // TODO + Log.log(LogMessageType.NETWORK_PACKETS_IN, LogLevels.WARN) { "Can not open entity container: $entity" } } override fun log(reducedLog: Boolean) { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/CloseContainerS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/CloseContainerS2CP.kt index ed8784aac..3f55b4bd3 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/CloseContainerS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/container/CloseContainerS2CP.kt @@ -13,7 +13,6 @@ package de.bixilon.minosoft.protocol.packets.s2c.play.container import de.bixilon.minosoft.data.container.types.PlayerInventory -import de.bixilon.minosoft.modding.event.events.container.ContainerCloseEvent 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 @@ -27,13 +26,13 @@ class CloseContainerS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { val containerId: Int = buffer.readUnsignedByte() override fun handle(connection: PlayConnection) { - if (containerId == PlayerInventory.CONTAINER_ID) { + val container = connection.player.containers[containerId] ?: return + + if (container is PlayerInventory || containerId == PlayerInventory.CONTAINER_ID) { // server can not close inventory return } - val container = connection.player.containers[containerId] ?: return - container.onClose() - connection.events.fire(ContainerCloseEvent(connection, containerId, container)) + container.close(force = true) } override fun log(reducedLog: Boolean) { 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 83ea677ca..4f5ebd2e5 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 @@ -79,9 +79,10 @@ class OpenContainerS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { container.floatingItem = it.floating } connection.player.containers[containerId] = container - connection.player.openedContainer = container - connection.events.fire(ContainerOpenEvent(connection, containerId, container)) + + connection.player.openedContainer = container + connection.events.fire(ContainerOpenEvent(connection, container)) } override fun log(reducedLog: Boolean) {