fix(multiplayer): enforce proposal transitions

This commit is contained in:
Josh Creek
2026-09-01 22:00:37 +01:00
parent a60c1a097e
commit 0ce2a49419
3 changed files with 38 additions and 0 deletions
+21
View File
@@ -112,15 +112,28 @@ func apply_proposal_update(update: Dictionary) -> bool:
return _request_resync(proposal_id)
var incoming_proposal_state := String(update["state"])
if incoming_proposal_state == "OPEN":
if not _is_legal_proposal_transition(proposal_state, incoming_proposal_state):
return _request_resync(proposal_id)
phase = PROPOSED
elif incoming_proposal_state == "ACCEPTED":
if not _is_legal_proposal_transition(proposal_state, incoming_proposal_state):
return _request_resync(proposal_id)
phase = ALLOCATING
elif incoming_proposal_state == "DECLINED":
if not _is_legal_proposal_transition(proposal_state, incoming_proposal_state):
return _request_resync(proposal_id)
phase = FAILED
message = "A player declined the match proposal"
elif incoming_proposal_state == "EXPIRED":
if not _is_legal_proposal_transition(proposal_state, incoming_proposal_state):
return _request_resync(proposal_id)
phase = EXPIRED
message = "The match proposal expired"
elif incoming_proposal_state == "CANCELLED":
if not _is_legal_proposal_transition(proposal_state, incoming_proposal_state):
return _request_resync(proposal_id)
phase = CANCELLED
message = "The match proposal was cancelled"
else:
return _request_resync(proposal_id)
proposal_revision = incoming_revision
@@ -268,6 +281,14 @@ func _is_legal_ticket_transition(from: String, to: String) -> bool:
return transitions.has(from) and to in transitions[from]
func _is_legal_proposal_transition(from: String, to: String) -> bool:
if from.is_empty():
return to == "OPEN"
if from == to:
return true
return from == "OPEN" and to in ["ACCEPTED", "DECLINED", "EXPIRED", "CANCELLED"]
func _has_string(value: Dictionary, key: String) -> bool:
return value.has(key) and value[key] is String and not String(value[key]).is_empty()