feat: add Godot Steam session login

This commit is contained in:
Josh Creek
2026-08-31 22:49:05 +01:00
parent e1807d2492
commit 585056ccc3
3 changed files with 44 additions and 5 deletions
+37 -4
View File
@@ -7,6 +7,7 @@ extends Node
signal request_succeeded(operation: String, payload: Dictionary)
signal request_failed(operation: String, http_code: int, detail: String)
signal session_expired()
signal session_changed(player_id: String)
const DEFAULT_BASE_URL := "http://127.0.0.1:8080"
const PERSIST_PATH := "user://matchmaking_state.cfg"
@@ -14,6 +15,8 @@ const PERSIST_PATH := "user://matchmaking_state.cfg"
var base_url := DEFAULT_BASE_URL
var access_token := ""
var auth_expired := false
var player_id := ""
var session_expires_at := ""
var state: MatchmakingState
var ranked_profile: RankedProfileState
@@ -36,7 +39,7 @@ func _ready() -> void:
func configure(url: String, token: String) -> bool:
var normalized := url.strip_edges().trim_suffix("/")
var normalized_token := token.strip_edges()
if not is_valid_base_url(normalized) or normalized_token.is_empty() or normalized_token.contains("\r") or normalized_token.contains("\n"):
if not is_valid_base_url(normalized) or not is_valid_access_token(normalized_token):
return false
base_url = normalized
access_token = normalized_token
@@ -57,6 +60,12 @@ func queue_create(ticket_id: String, playlist: String, client_build: String, pro
return err
func login_steam(web_api_ticket: String) -> Error:
if not is_valid_web_api_ticket(web_api_ticket):
return ERR_INVALID_PARAMETER
return _start_request("steam_session", HTTPClient.METHOD_POST, "/v1/session/steam", {"web_api_ticket": web_api_ticket}, "")
func retry_queue_create() -> Error:
if _last_queue_create.is_empty() or not _last_queue_create.has("ticket_id"):
return ERR_INVALID_DATA
@@ -115,6 +124,15 @@ static func is_valid_base_url(url: String) -> bool:
return url.begins_with("http://") or url.begins_with("https://")
static func is_valid_web_api_ticket(ticket: String) -> bool:
return not ticket.is_empty() and ticket.length() <= 4096 and not ticket.contains("\r") and not ticket.contains("\n")
static func is_valid_access_token(token: String) -> bool:
var separator := token.find(":")
return separator > 0 and separator < token.length() - 1 and token.length() <= 4096 and not token.contains("\r") and not token.contains("\n")
static func normalize_ticket(payload: Dictionary) -> Dictionary:
var result := payload.duplicate(true)
if result.has("expires_at") and result["expires_at"] is String:
@@ -123,9 +141,13 @@ static func normalize_ticket(payload: Dictionary) -> Dictionary:
func _start_request(operation: String, method: HTTPClient.Method, path: String, payload: Dictionary, idempotency_key: String, expected_revision: int = -1) -> Error:
if _request == null or not _operation.is_empty() or access_token.is_empty() or not is_valid_base_url(base_url):
if _request == null or not _operation.is_empty() or not is_valid_base_url(base_url):
return ERR_BUSY if not _operation.is_empty() else ERR_UNAUTHORIZED
var headers := PackedStringArray(["Authorization: Bearer " + access_token, "Accept: application/json"])
if operation != "steam_session" and access_token.is_empty():
return ERR_UNAUTHORIZED
var headers := PackedStringArray(["Accept: application/json"])
if operation != "steam_session":
headers.append("Authorization: Bearer " + access_token)
if not idempotency_key.is_empty():
headers.append("Idempotency-Key: " + idempotency_key)
if expected_revision >= 0:
@@ -184,7 +206,18 @@ func _on_request_completed(result: HTTPRequest.Result, response_code: int, _head
request_failed.emit(operation, response_code, detail)
return
var payload: Dictionary = parsed
if operation == "queue_create":
if operation == "steam_session":
var returned_token := String(payload.get("access_token", ""))
var returned_player_id := String(payload.get("player_id", ""))
if returned_player_id.is_empty() or not is_valid_access_token(returned_token):
request_failed.emit(operation, response_code, "invalid session response")
return
player_id = returned_player_id
access_token = returned_token
auth_expired = false
session_expires_at = String(payload.get("expires_at", ""))
session_changed.emit(player_id)
elif operation == "queue_create":
state.begin_queue(String(payload.get("ticket_id", "")), String(payload.get("playlist", "")))
if operation.begins_with("queue_"):
state.apply_ticket_update(normalize_ticket(payload))