mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 08:23:45 +00:00
feat: connect clients from validated assignments
This commit is contained in:
@@ -9,6 +9,8 @@ signal session_expired()
|
||||
signal session_changed(player_id: String)
|
||||
signal websocket_event(event: Dictionary)
|
||||
signal websocket_status_changed(status: String)
|
||||
signal assignment_connection_started(assignment: AssignmentState)
|
||||
signal assignment_connection_failed(detail: String)
|
||||
|
||||
const DEFAULT_BASE_URL := "http://127.0.0.1:8080"
|
||||
const PERSIST_PATH := "user://matchmaking_state.cfg"
|
||||
@@ -178,6 +180,47 @@ func fetch_assignment(match_id: String) -> Error:
|
||||
return _start_request("assignment", HTTPClient.METHOD_GET, "/v1/assignments/" + match_id, {}, "")
|
||||
|
||||
|
||||
# Starts the assigned game transport only after AssignmentState has validated
|
||||
# the complete player-scoped manifest. The signed authorisation is passed to
|
||||
# MatchNet's hello RPC, never appended to the endpoint URL or logged. Server
|
||||
# admission remains authoritative; this method only owns the client-side
|
||||
# readiness/transport boundary.
|
||||
func connect_to_assignment() -> Error:
|
||||
if assignment == null or not assignment.available or not _assignment_is_fresh(assignment):
|
||||
var unavailable_detail := "Match assignment is unavailable or expired"
|
||||
assignment_connection_failed.emit(unavailable_detail)
|
||||
return ERR_UNAUTHORIZED
|
||||
var endpoint := _split_assignment_endpoint(assignment.endpoint)
|
||||
if endpoint.is_empty():
|
||||
var invalid_detail := "Match assignment endpoint is invalid"
|
||||
assignment_connection_failed.emit(invalid_detail)
|
||||
return ERR_INVALID_PARAMETER
|
||||
var transport := NetworkManager.TRANSPORT_ENET if assignment.transport == "enet" else NetworkManager.TRANSPORT_STEAM
|
||||
MatchNet.join_authorisation = assignment.join_authorisation
|
||||
state.mark_connecting()
|
||||
var err := NetworkManager.join(String(endpoint["host"]), int(endpoint["port"]), transport)
|
||||
if err != OK:
|
||||
MatchNet.join_authorisation = ""
|
||||
assignment_connection_failed.emit("Unable to connect to match server")
|
||||
return err
|
||||
assignment_connection_started.emit(assignment)
|
||||
return OK
|
||||
|
||||
|
||||
static func _assignment_is_fresh(value: AssignmentState) -> bool:
|
||||
if value == null or value.expires_at.is_empty():
|
||||
return false
|
||||
var expiry := Time.get_unix_time_from_datetime_string(value.expires_at)
|
||||
return expiry > Time.get_unix_time_from_system()
|
||||
|
||||
|
||||
static func _split_assignment_endpoint(value: String) -> Dictionary:
|
||||
if not AssignmentState._valid_endpoint(value):
|
||||
return {}
|
||||
var separator := value.rfind(":")
|
||||
return {"host": value.substr(0, separator), "port": int(value.substr(separator + 1))}
|
||||
|
||||
|
||||
func heartbeat(ticket_id: String, expected_revision: int) -> Error:
|
||||
if ticket_id.is_empty() or expected_revision < 0:
|
||||
return ERR_INVALID_PARAMETER
|
||||
|
||||
Reference in New Issue
Block a user