fix multiplayer snapshot disconnect race

This commit is contained in:
Josh Creek
2026-08-31 20:05:40 +01:00
parent 8d4a0640e2
commit 835233672f
4 changed files with 32 additions and 3 deletions
+23
View File
@@ -71,6 +71,7 @@ var is_server := false
var is_client := false
var _peer: MultiplayerPeer # keep a strong ref alongside multiplayer.multiplayer_peer
var active_transport := ""
var _invalidated_peer_ids: Dictionary = {}
var rtt_ms := -1.0 # min-RTT sample currently in the window; -1 = no sample yet
var clock_offset_ms := 0.0 # add to a local Time.get_ticks_msec() reading to estimate the server's clock
@@ -127,6 +128,27 @@ func poll() -> void:
multiplayer.poll()
# A peer can be removed from the transport while Godot is still draining the
# same poll batch. During that interval get_peers() may still contain it, but
# an RPC send already fails because ENet has torn down its channels.
func invalidate_peer(peer_id: int) -> void:
_invalidated_peer_ids[peer_id] = true
func can_send_to_peer(peer_id: int) -> bool:
if _invalidated_peer_ids.has(peer_id):
return false
if _peer == null or _peer is OfflineMultiplayerPeer:
return false
# A listening server's peer status is transport/version-specific; the
# authoritative server is valid as soon as it owns a peer and the target
# appears in get_peers(). Clients, however, must not dispatch while their
# connection is still handshaking.
if not is_server and _peer.get_connection_status() != MultiplayerPeer.CONNECTION_CONNECTED:
return false
return peer_id in multiplayer.get_peers()
func available_transports() -> PackedStringArray:
var transports := PackedStringArray([TRANSPORT_ENET])
if SteamTransportScript.new().is_available():
@@ -185,6 +207,7 @@ func shutdown() -> void:
peer.close()
multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new()
_peer = null
_invalidated_peer_ids.clear()
active_transport = ""
is_server = false
is_client = false