mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
61 lines
3.0 KiB
GDScript
61 lines
3.0 KiB
GDScript
class_name AssignmentState
|
|
extends RefCounted
|
|
|
|
# Verified assignment-ready manifest returned by the control plane. The join
|
|
# authorisation is retained in memory only and is never written to the restart
|
|
# snapshot; transport installation belongs to the explicit ENet/Steam layer.
|
|
|
|
var available := false
|
|
var match_id := ""
|
|
var server_id := ""
|
|
var slot := -1
|
|
var expires_at := ""
|
|
var protocol_version := 0
|
|
var transport := ""
|
|
var endpoint := ""
|
|
var join_authorisation := ""
|
|
var error_message := ""
|
|
|
|
|
|
func apply(payload: Dictionary, expected_player_id: String = "") -> bool:
|
|
for key in ["match_id", "server_id", "player_id", "slot", "expires_at", "protocol_version", "transport", "endpoint", "join_authorisation"]:
|
|
if not payload.has(key):
|
|
return _reject("Assignment response is missing " + key)
|
|
if not payload["match_id"] is String or not payload["server_id"] is String or not payload["player_id"] is String or not (payload["slot"] is int or payload["slot"] is float) or not payload["expires_at"] is String or not (payload["protocol_version"] is int or payload["protocol_version"] is float) or not payload["transport"] is String or not payload["endpoint"] is String or not payload["join_authorisation"] is String:
|
|
return _reject("Assignment response contains invalid types")
|
|
var next_match_id := String(payload["match_id"])
|
|
var next_server_id := String(payload["server_id"])
|
|
var next_transport := String(payload["transport"])
|
|
var next_endpoint := String(payload["endpoint"])
|
|
var next_player_id := String(payload["player_id"])
|
|
var expiry_unix := Time.get_unix_time_from_datetime_string(String(payload["expires_at"]))
|
|
if next_match_id.is_empty() or next_server_id.is_empty() or next_player_id.is_empty() or (not expected_player_id.is_empty() and next_player_id != expected_player_id) or int(payload["slot"]) < 0 or int(payload["slot"]) > 5 or int(payload["protocol_version"]) < 1 or (next_transport != "enet" and next_transport != "steam_sdr") or not _valid_endpoint(next_endpoint) or String(payload["expires_at"]).is_empty() or expiry_unix <= Time.get_unix_time_from_system() or String(payload["join_authorisation"]).is_empty():
|
|
return _reject("Assignment response contains invalid values")
|
|
match_id = next_match_id
|
|
server_id = next_server_id
|
|
slot = int(payload["slot"])
|
|
expires_at = String(payload["expires_at"])
|
|
protocol_version = int(payload["protocol_version"])
|
|
transport = next_transport
|
|
endpoint = next_endpoint
|
|
join_authorisation = String(payload["join_authorisation"])
|
|
available = true
|
|
error_message = ""
|
|
return true
|
|
|
|
|
|
static func _valid_endpoint(value: String) -> bool:
|
|
if value.is_empty() or value.contains("/") or value.contains("?") or value.contains("#"):
|
|
return false
|
|
var separator := value.rfind(":")
|
|
if separator <= 0 or separator >= value.length() - 1:
|
|
return false
|
|
var port := value.substr(separator + 1)
|
|
return port.is_valid_int() and int(port) >= 1 and int(port) <= 65535
|
|
|
|
|
|
func _reject(reason: String) -> bool:
|
|
available = false
|
|
error_message = reason
|
|
return false
|