From 44ffd1c41b22354c554ae3abdb642618e164f14a Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sat, 26 Feb 2022 17:28:27 +0100 Subject: [PATCH] more container and gui fixes --- .../minosoft/data/container/Container.kt | 13 ++-- .../container/click/SimpleContainerAction.kt | 8 +- .../data/container/types/PlayerInventory.kt | 8 +- .../minosoft/gui/rendering/gui/GUIRenderer.kt | 4 +- .../elements/items/ContainerItemsElement.kt | 6 +- .../gui/elements/items/RawItemElement.kt | 5 +- .../gui/rendering/gui/gui/GUIManager.kt | 2 +- .../gui/rendering/gui/gui/GUIMeshElement.kt | 12 +-- .../gui/gui/dragged/DraggedGUIElement.kt | 2 +- .../gui/gui/dragged/DraggedManager.kt | 14 ++-- .../gui/hud/elements/chat/ChatElement.kt | 2 +- .../interaction/InteractInteractionHandler.kt | 76 ++++++++++--------- .../s2c/play/container/ContainerItemsS2CP.kt | 37 ++++++--- 13 files changed, 104 insertions(+), 85 deletions(-) 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 23188e182..f65ecc761 100644 --- a/src/main/java/de/bixilon/minosoft/data/container/Container.kt +++ b/src/main/java/de/bixilon/minosoft/data/container/Container.kt @@ -166,17 +166,16 @@ open class Container( } } - fun clear() { - lock.lock() - val size = slots.size - if (size == 0) { - lock.unlock() - return - } + fun _clear() { for (stack in slots.values) { stack.holder?.container = null } slots.clear() + } + + fun clear() { + lock.lock() + _clear() lock.unlock() revision++ } 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 03dbf3f88..1885a4917 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 @@ -57,12 +57,14 @@ class SimpleContainerAction( return connection.sendPacket(ContainerClickC2SP(containerId, container.serverRevision, null, 0, count.ordinal, container.createAction(this), mapOf(), null)) } val slotType = container.getSlotType(slot) + val matches = floatingItem.matches(target) - if (target != null && floatingItem.matches(target)) { + if (target != null && matches) { 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) { + // ToDo: Check stack size + if (subtract == 0 || target.item._count + subtract > target.item.item.maxStackSize) { return } target.item._count += subtract @@ -88,7 +90,7 @@ class SimpleContainerAction( return } // swap - if (count == ContainerCounts.ALL) { + if (count == ContainerCounts.ALL || !matches) { container.floatingItem = target container._set(slot, floatingItem) } else { 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 51387d57a..965c15867 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 @@ -42,7 +42,7 @@ class PlayerInventory(connection: PlayConnection) : Container(connection = conne fun getHotbarSlot(hotbarSlot: Int = connection.player.selectedHotbarSlot): ItemStack? { check(hotbarSlot in 0..HOTBAR_SLOTS) { "Hotbar slot out of bounds!" } - return slots[hotbarSlot + HOTBAR_OFFSET] + return this[hotbarSlot + HOTBAR_OFFSET] } operator fun get(slot: InventorySlots.EquipmentSlots): ItemStack? { @@ -54,10 +54,10 @@ class PlayerInventory(connection: PlayConnection) : Container(connection = conne } operator fun get(hand: Hands): ItemStack? { - return get(when (hand) { + return this[(when (hand) { Hands.MAIN -> InventorySlots.EquipmentSlots.MAIN_HAND Hands.OFF -> InventorySlots.EquipmentSlots.OFF_HAND - }) + })] } @JvmName("setEquipment") @@ -68,7 +68,7 @@ class PlayerInventory(connection: PlayConnection) : Container(connection = conne realSlots += Pair(slot.slot, itemStack) } - super.set(*realSlots.toTypedArray()) + set(*realSlots.toTypedArray()) } override fun getSlotType(slotId: Int): SlotType? { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/GUIRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/GUIRenderer.kt index d17d2d579..57c8297a5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/GUIRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/GUIRenderer.kt @@ -63,7 +63,7 @@ class GUIRenderer( val shader = renderWindow.renderSystem.createShader("minosoft:hud".toResourceLocation()) val atlasManager = AtlasManager(renderWindow) - var currentCursorPosition: Vec2i by watched(Vec2i.EMPTY) + var currentMousePosition: Vec2i by watched(Vec2i.EMPTY) private set override fun init(latch: CountUpAndDownLatch) { @@ -114,7 +114,7 @@ class GUIRenderer( override fun onMouseMove(position: Vec2i): Boolean { val scaledPosition = position.scale() - currentCursorPosition = scaledPosition + currentMousePosition = scaledPosition if (dragged.onMouseMove(scaledPosition)) { return true } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ContainerItemsElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ContainerItemsElement.kt index 1d09a2b0e..07560e1f2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ContainerItemsElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ContainerItemsElement.kt @@ -40,13 +40,13 @@ class ContainerItemsElement( override var activeDragElement: ItemElement? = null private var update = true set(value) { + if (value) { + cacheUpToDate = false + } if (field == value) { return } field = value - if (value) { - cacheUpToDate = false - } } init { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt index 4aea93fa0..c56d2a1d5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt @@ -50,10 +50,7 @@ class RawItemElement( return } if (value != null) { - value::revision.observe(this) { forceSilentApply() } - } - if (field == value) { - return + value::revision.observe(this) { if (value === field) forceSilentApply() } // ToDo: check if watcher is still up-to-date } field = value forceSilentApply() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIManager.kt index 86ca9af9d..d09b29609 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIManager.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIManager.kt @@ -231,7 +231,7 @@ class GUIManager( } elementOrder.add(0, element) element.onOpen() - onMouseMove(guiRenderer.currentCursorPosition) + onMouseMove(guiRenderer.currentMousePosition) } @Deprecated("Only use for dynamic gui (e.g. dialogs, ...)") diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIMeshElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIMeshElement.kt index a3c0a2ef0..34a1f5052 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIMeshElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIMeshElement.kt @@ -110,9 +110,6 @@ open class GUIMeshElement( } override fun onCharPress(char: Int): Boolean { - if (lastPosition == null) { - return false - } return element.onCharPress(char) } @@ -122,8 +119,8 @@ open class GUIMeshElement( } override fun onKey(type: KeyChangeTypes, key: KeyCodes): Boolean { - val position = lastPosition ?: return false val mouseButton = MouseButtons[key] ?: return element.onKey(key, type) + val position = lastPosition ?: return false val mouseAction = MouseActions[type] ?: return false return element.onMouseAction(position, mouseButton, mouseAction) @@ -144,8 +141,8 @@ open class GUIMeshElement( } override fun onDragKey(type: KeyChangeTypes, key: KeyCodes, dragged: Dragged): Element? { - val position = lastDragPosition ?: return null val mouseButton = MouseButtons[key] ?: return element.onDragKey(key, type, dragged) + val position = lastDragPosition ?: return null val mouseAction = MouseActions[type] ?: return null return element.onDragMouseAction(position, mouseButton, mouseAction, dragged) @@ -156,9 +153,6 @@ open class GUIMeshElement( } override fun onDragChar(char: Int, dragged: Dragged): Element? { - if (lastDragPosition == null) { - return null - } return element.onDragChar(char.toChar(), dragged) } @@ -171,7 +165,7 @@ open class GUIMeshElement( override fun onOpen() { element.onOpen() - onMouseMove(guiRenderer.currentCursorPosition) + onMouseMove(guiRenderer.currentMousePosition) } override fun onHide() { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/DraggedGUIElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/DraggedGUIElement.kt index 429e73f4d..5f52e5a25 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/DraggedGUIElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/DraggedGUIElement.kt @@ -19,7 +19,7 @@ import glm_.vec2.Vec2i class DraggedGUIElement(element: T) : GUIMeshElement(element) { override fun prepare() { - prepare(guiRenderer.currentCursorPosition - (element.size / 2)) + prepare(guiRenderer.currentMousePosition - (element.size / 2)) } override fun onMouseMove(position: Vec2i): Boolean { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/DraggedManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/DraggedManager.kt index e6ad10db1..e0e7664dd 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/DraggedManager.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/DraggedManager.kt @@ -35,13 +35,17 @@ class DraggedManager( if (field == value || field?.element == value?.element) { return } - val position = guiRenderer.currentCursorPosition + val position = guiRenderer.currentMousePosition val previous = field previous?.element?.onDragEnd(position, guiRenderer.gui.onDragMove(Vec2i(-1, -1), previous.element)) field = value - guiRenderer.gui.onMouseMove(Vec2i(-1, -1)) // move mouse ot - value?.element?.onDragStart(position, guiRenderer.gui.onDragMove(position, value.element)) + if (value == null) { + guiRenderer.gui.onMouseMove(position) + } else { + guiRenderer.gui.onMouseMove(Vec2i(-1, -1)) // move mouse out + value.element.onDragStart(position, guiRenderer.gui.onDragMove(position, value.element)) + } applyCursor() } override var lastTickTime: Long = -1L @@ -114,14 +118,14 @@ class DraggedManager( } val mouseAction = MouseActions[type] ?: return false - element.element.onDragMouseAction(guiRenderer.currentCursorPosition, mouseButton, mouseAction, target) + element.element.onDragMouseAction(guiRenderer.currentMousePosition, mouseButton, mouseAction, target) return true } override fun onScroll(scrollOffset: Vec2d): Boolean { val element = element ?: return false val target = guiRenderer.gui.onDragScroll(scrollOffset, element.element) - element.element.onDragScroll(guiRenderer.currentCursorPosition, scrollOffset, target) + element.element.onDragScroll(guiRenderer.currentMousePosition, scrollOffset, target) return true } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/ChatElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/ChatElement.kt index 8e28b265f..19798a9b3 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/ChatElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/ChatElement.kt @@ -46,7 +46,7 @@ class ChatElement(guiRenderer: GUIRenderer) : AbstractChatElement(guiRenderer) { field = value messages._active = value messages.forceSilentApply() - historyIndex = -1 + historyIndex = history.size + 1 forceApply() } override var skipDraw: Boolean diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractInteractionHandler.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractInteractionHandler.kt index c46f4e2b5..2628db34f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractInteractionHandler.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractInteractionHandler.kt @@ -77,32 +77,34 @@ class InteractInteractionHandler( } // if out of world (border): return CONSUME - connection.sendPacket(BlockInteractC2SP( - position = target.blockPosition, - direction = target.direction, - cursorPosition = Vec3(target.hitPosition), - item = stack, - hand = hand, - insideBlock = false, // ToDo: insideBlock - )) + try { + if (connection.player.gamemode == Gamemodes.SPECTATOR) { + return InteractionResults.SUCCESS + } - if (connection.player.gamemode == Gamemodes.SPECTATOR) { - return InteractionResults.SUCCESS - } + val result = target.blockState.block.onUse(connection, target, hand, stack) + if (result == InteractionResults.SUCCESS) { + return InteractionResults.SUCCESS + } - val result = target.blockState.block.onUse(connection, target, hand, stack) - if (result == InteractionResults.SUCCESS) { - return InteractionResults.SUCCESS - } + if (stack == null) { + return InteractionResults.PASS + } + if (interactionManager.isCoolingDown(stack.item.item)) { + return InteractionResults.PASS // ToDo: Check + } - if (stack == null) { - return InteractionResults.PASS + return stack.item.item.interactBlock(connection, target, hand, stack) + } finally { + connection.sendPacket(BlockInteractC2SP( + position = target.blockPosition, + direction = target.direction, + cursorPosition = Vec3(target.hitPosition), + item = stack, + hand = hand, + insideBlock = false, // ToDo: insideBlock + )) } - if (interactionManager.isCoolingDown(stack.item.item)) { - return InteractionResults.PASS // ToDo: Check - } - - return stack.item.item.interactBlock(connection, target, hand, stack) } fun interactEntityAt(target: EntityTarget, hand: Hands): InteractionResults { @@ -119,14 +121,17 @@ class InteractInteractionHandler( fun interactEntity(target: EntityTarget, hand: Hands): InteractionResults { val player = connection.player - connection.sendPacket(EntityEmptyInteractC2SP(connection, target.entity, hand, player.isSneaking)) + try { - if (player.gamemode == Gamemodes.SPECTATOR) { + if (player.gamemode == Gamemodes.SPECTATOR) { + return InteractionResults.PASS + } + + // ToDo: return hit.entity.interact(hand) (e.g. equipping saddle) return InteractionResults.PASS + } finally { + connection.sendPacket(EntityEmptyInteractC2SP(connection, target.entity, hand, player.isSneaking)) } - - // ToDo: return hit.entity.interact(hand) (e.g. equipping saddle) - return InteractionResults.PASS } fun interactItem(item: ItemStack, hand: Hands): InteractionResults { @@ -136,15 +141,18 @@ class InteractInteractionHandler( val player = connection.player connection.sendPacket(PositionRotationC2SP(player.position, player.rotation, player.onGround)) - // ToDo: Before 1.9 - connection.sendPacket(UseItemC2SP(hand)) + try { - if (interactionManager.isCoolingDown(item.item.item)) { - return InteractionResults.PASS + if (interactionManager.isCoolingDown(item.item.item)) { + return InteractionResults.PASS + } + + + return item.item.item.interactItem(connection, hand, item) + } finally { + // ToDo: Before 1.9 + connection.sendPacket(UseItemC2SP(hand)) } - - - return item.item.item.interactItem(connection, hand, item) } fun useItem() { 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 efd4c953b..f1eb907a3 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 @@ -14,6 +14,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.stack.ItemStack import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.factory.LoadPacket @@ -43,15 +45,9 @@ class ContainerItemsS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { null } - override fun handle(connection: PlayConnection) { - val container = connection.player.containers[containerId] - val slots = if (container == null) { - synchronizedMapOf() - } else { - container.lock.lock() - container.slots.clear() - container.slots - } + private fun pushIncompleteContainer(connection: PlayConnection) { + val slots: SynchronizedMap = synchronizedMapOf() + for ((slotId, stack) in this.items.withIndex()) { if (stack == null) { @@ -60,10 +56,29 @@ class ContainerItemsS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { slots[slotId] = stack } + connection.player.incompleteContainers[containerId] = slots.unsafeCast() + } + + private fun updateContainer(container: Container) { + container.lock.lock() + container._clear() + + for ((slotId, stack) in this.items.withIndex()) { + if (stack == null) { + continue + } + container._set(slotId, stack) + } + container.lock.unlock() + container.revision++ + } + + override fun handle(connection: PlayConnection) { + val container = connection.player.containers[containerId] if (container == null) { - connection.player.incompleteContainers[containerId] = slots.unsafeCast() + pushIncompleteContainer(connection) } else { - container.lock.unlock() + updateContainer(container) } }