When items are picked up via right-click, middle-click, or mouse wheel
(none of which change GUI focus), clicking outside the formspec closes
it instead of dropping the held item. This happens because
remapClickOutside() only delegates to GUIInventoryList when it has
focus, but focus is only set on left mouse down.
Add a virtual hasModalInteraction() hook so GUIFormSpecMenu can signal
that it has an ongoing interaction (held item). When true,
remapClickOutside() backs off and lets the normal event dispatch route
the click to the formspec's inventory drop handling code.
fixes#16952
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit ensures that the death formspec is re-shown in case another formspec force-closed it.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TOSERVER_INIT2 is registered as TOSERVER_STATE_NOT_CONNECTED, so it
bypasses all client state checks in ProcessData. When received from a
client already in CS_Active (or any state other than CS_AwaitingInit2),
the CSE_GotInit2 event triggers an invalid state transition that can
crash the server.
Add an explicit state check to early-return if the client is not in
CS_AwaitingInit2.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
IDropAction::apply() accessed list_from->getItem(from_i) without
validating that from_i is within the inventory list bounds. In
release builds, InventoryList::getItem() only guards this with an
assert, so an out-of-bounds index causes undefined behavior.
A malicious client can exploit this by sending a crafted
TOSERVER_INVENTORY_ACTION packet with a Drop action containing an
arbitrary from_i value, crashing the server via segfault:
This was reproduced using a custom network packet fuzzer I made
a long time ago.
IMoveAction::apply() already had the equivalent bounds check (lines
325-330). This adds the same check to IDropAction::apply().
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>