Harden multiplayer validation for portable homes

This commit is contained in:
Alexander Sellite 2026-08-30 23:52:25 -04:00
parent d2dce7f900
commit b48cb73f3a
5 changed files with 381 additions and 49 deletions

View file

@ -90,11 +90,12 @@ func _run_first_client() -> void:
player.toggle_sitting()
assert(player.is_sitting())
assert(player.bag.add_item(&"crab_net"))
assert(player.hotbar.assign_item(0, &"crab_net"))
assert(player.hotbar.select_slot(0))
for _frame: int in 2:
await process_frame
assert(bool(player.get("_active_item_is_net")))
# Slot zero begins selected with the starter rod. Replacing that slot does
# not emit a selection change, so use the next slot to exercise the same
# equipped-item path a player uses in normal gameplay.
assert(player.hotbar.assign_item(1, &"crab_net"))
assert(player.hotbar.select_slot(1))
assert(await _wait_for_local_net(main, player))
assert(player.begin_animation_action(ACTIVE_ACTION))
await create_timer(0.5).timeout
assert(StringName(str(player.get("_animation_action_id"))) == ACTIVE_ACTION)
@ -185,6 +186,29 @@ func _wait_for_registry_size(session: NetworkSession, expected: int) -> bool:
return false
func _wait_for_local_net(main: Node, player: Player) -> bool:
var deadline: int = Time.get_ticks_msec() + 10000
while Time.get_ticks_msec() < deadline:
# A joined client can finish its world transition one frame after the
# hotbar selection signal. Refresh through the production path until the
# ready fishing state accepts the equipped item.
main.call("_refresh_active_hotbar_item")
await process_frame
if bool(player.get("_active_item_is_net")):
return true
var fishing_spot: Node = main.get_node("%FishingSpot")
print(
"net equip wait timed out: ",
{
"fishing_state": int(fishing_spot.get("state")),
"selected_slot": player.hotbar.get_selected_slot(),
"selected_item": String(player.hotbar.get_selected_item_id()),
"owns_net": player.bag.owns_item(&"crab_net"),
},
)
return false
func _history_contains(service: NetworkChatService, body: String) -> bool:
return service.get_history().any(
func(message: Dictionary) -> bool: