Defekte Sitzung gibt Mitspieler frei, nur echte Gäste beenden die Pause
Hält der Kern mit einem internen Fehler an, schließt ein Host seine Welt für Gäste, und ein Gast kehrt ins Menü zurück, statt dass die anderen ohne Nachricht warten. Eine Pause endet erst, wenn der Host einen Gast angenommen hat, nicht schon bei einer bloßen Verbindung. So kann ein Gast nicht mehr in einer pausierten Welt festhängen, wenn der Host zwischen Verbindung und Gruß pausiert. Eine Pause lässt sich immer beenden. Meldungen, die nach dem Ende einer Sitzung im selben Stapel folgen, bleiben unbeachtet. Vier neue Tests decken das ab. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
+33
-5
@@ -57,6 +57,9 @@ var _save_blocked := false
|
||||
var _figure_wait := 0.0
|
||||
## The address a guest is joining, for messages.
|
||||
var _joining := ""
|
||||
## The host's accepted guests when _process last looked. A new one ends a
|
||||
## pause.
|
||||
var _known_guests := 0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -233,12 +236,37 @@ func _leave(message: String) -> void:
|
||||
_show_menu(message)
|
||||
|
||||
|
||||
## A broken session runs no more ticks. Instead of leaving the others
|
||||
## waiting, a host closes its world to guests and a guest leaves.
|
||||
func _stop_sharing() -> void:
|
||||
if not session.is_host():
|
||||
_leave(tr("SIMULATION_STOPPED"))
|
||||
return
|
||||
link.link.close()
|
||||
link = null
|
||||
figures.clear()
|
||||
_update_status()
|
||||
|
||||
|
||||
## Ends a pause once the host accepted a guest: the guest joins in the next
|
||||
## tick, and a paused world would keep it waiting. A connection that has not
|
||||
## greeted yet is no guest.
|
||||
func _end_pause_for_new_guests() -> void:
|
||||
var guests := session.guest_count()
|
||||
if guests > _known_guests and clock.paused:
|
||||
_set_paused(false)
|
||||
_known_guests = guests
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if link != null:
|
||||
for notice in link.pump(delta):
|
||||
_on_notice(notice)
|
||||
if session != null and session.is_broken() and link != null:
|
||||
_stop_sharing()
|
||||
if session == null or not session.is_running() or session.is_broken():
|
||||
return
|
||||
_end_pause_for_new_guests()
|
||||
_update_marker()
|
||||
if Input.is_action_pressed("dig") and not clock.paused:
|
||||
_try_dig()
|
||||
@@ -257,11 +285,10 @@ func _process(delta: float) -> void:
|
||||
|
||||
|
||||
func _on_notice(notice: Dictionary) -> void:
|
||||
# An earlier notice of the same batch may have ended the session.
|
||||
if session == null:
|
||||
return
|
||||
match notice["type"]:
|
||||
"guest_arrived":
|
||||
# Pausing is for playing alone; a guest ends the pause.
|
||||
if clock.paused:
|
||||
_set_paused(false)
|
||||
"world_received":
|
||||
if notice["resync"]:
|
||||
resyncs += 1
|
||||
@@ -304,7 +331,8 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||
elif event.is_action_pressed("load_game"):
|
||||
_reload()
|
||||
elif event.is_action_pressed("toggle_pause"):
|
||||
if session.is_host() and session.guest_count() == 0:
|
||||
# Ending a pause is always allowed, starting one only alone.
|
||||
if clock.paused or (session.is_host() and session.guest_count() == 0):
|
||||
_set_paused(not clock.paused)
|
||||
else:
|
||||
hud.flash("PAUSE_ONLY_ALONE")
|
||||
|
||||
Reference in New Issue
Block a user