feat(scoreboard): get session coockie and api config file
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -17,3 +17,6 @@ addons/escoria-core/default_bus_layout.tres
|
||||
addons/godot-plugin-refresher/
|
||||
addons/script-ide/
|
||||
build/
|
||||
|
||||
# API credentials
|
||||
api.ini
|
||||
|
||||
@@ -1,45 +1,123 @@
|
||||
class_name RTMIScoreManager
|
||||
extends Node
|
||||
## Score manager to get and submit scores from and to Scoreboard web service.
|
||||
|
||||
const PERFECT = "perfect"
|
||||
const FASTEST = "fastest"
|
||||
const SUBMIT = "submit"
|
||||
|
||||
var url: String
|
||||
var project_id: String
|
||||
var database_id: String
|
||||
var email: String
|
||||
var password: String
|
||||
|
||||
var http_requests: Dictionary = {
|
||||
PERFECT: HTTPRequest.new(),
|
||||
FASTEST: HTTPRequest.new(),
|
||||
SUBMIT: HTTPRequest.new(),
|
||||
}
|
||||
|
||||
# Session cookie used for authentication. Needed for score submitting.
|
||||
var session_cookie: String = ""
|
||||
|
||||
|
||||
func _init(scene) -> void:
|
||||
_load_api_config()
|
||||
scene.add_child(http_requests[PERFECT])
|
||||
scene.add_child(http_requests[FASTEST])
|
||||
scene.add_child(http_requests[SUBMIT])
|
||||
|
||||
|
||||
func _load_api_config() -> void:
|
||||
var config = ConfigFile.new()
|
||||
var error = config.load("res://api.ini")
|
||||
if error != OK:
|
||||
return
|
||||
|
||||
url = config.get_value("api", "url", "")
|
||||
project_id = config.get_value("api", "project_id", "")
|
||||
database_id = config.get_value("api", "database_id", "")
|
||||
email = config.get_value("api", "email", "")
|
||||
password = config.get_value("api", "password", "")
|
||||
|
||||
|
||||
func get_scores(collection: String) -> Array[RTMIScoreRow]:
|
||||
var http_request = http_requests[collection]
|
||||
var data = await _score_http_request(http_request, "%s/databases/%s/collections/%s/documents" % [url, database_id, collection])
|
||||
if collection == FASTEST:
|
||||
submit_score()
|
||||
|
||||
if not data:
|
||||
return []
|
||||
|
||||
# Map DB rows to RTMIScoreRow
|
||||
var scores_untyped = data.get("documents").map(func(document): return RTMIScoreRow.new(document))
|
||||
# Array.map() does not support typing, we need to use Array.assign to set the type.
|
||||
var scores: Array[RTMIScoreRow]
|
||||
scores.assign(scores_untyped)
|
||||
return scores
|
||||
|
||||
|
||||
func submit_score() -> void:
|
||||
var session_cookie = await get_session_cookie(http_requests[SUBMIT])
|
||||
push_error("SESSION COOKIE=%s" % session_cookie)
|
||||
return
|
||||
|
||||
|
||||
func get_session_cookie(http_request: HTTPRequest) -> String:
|
||||
if session_cookie:
|
||||
return session_cookie
|
||||
|
||||
var error = http_request.request(
|
||||
"https://app.fosil.eu/v1/databases/68fff91900295af283bf/collections/%s/documents" % collection,
|
||||
["X-Appwrite-Project: 68fff7ac0029558ca82c", "Content-Type: application/json"]
|
||||
"%s/account/sessions/email" % url,
|
||||
["X-Appwrite-Project: %s" % project_id, "Content-Type: application/json"],
|
||||
HTTPClient.METHOD_POST,
|
||||
'{"email":"%s","password":"%s"}' % [email, password]
|
||||
)
|
||||
if error != OK:
|
||||
push_error("An error occurred creating the HTTP request: error=%s" % error)
|
||||
return ""
|
||||
|
||||
var response: Array = await http_request.request_completed
|
||||
return _http_request_completed.callv(response)
|
||||
var result: int = response[0]
|
||||
var http_status: int = response[1]
|
||||
var response_headers: PackedStringArray = response[2]
|
||||
|
||||
|
||||
func _http_request_completed(result: int, http_status: int, _headers: PackedStringArray, body: PackedByteArray) -> Array[RTMIScoreRow]:
|
||||
if result != HTTPRequest.RESULT_SUCCESS or http_status < 200 or http_status >= 300:
|
||||
push_error("HTTP request returned an error: result=%s http_status=%s" % [result, http_status])
|
||||
return []
|
||||
return ""
|
||||
|
||||
var response = JSON.parse_string(body.get_string_from_utf8())
|
||||
if not response or not response.get("documents"):
|
||||
var cookie_pos = Array(response_headers).find_custom(func(header: String): return header.to_lower().begins_with("set-cookie: "))
|
||||
if cookie_pos < 0:
|
||||
return ""
|
||||
|
||||
session_cookie = response_headers[cookie_pos].substr("set-cookie: ".length()).get_slice(";", 0)
|
||||
return session_cookie
|
||||
|
||||
|
||||
func _score_http_request(
|
||||
http_request: HTTPRequest, url: String, method: int = HTTPClient.METHOD_GET, request_data: String = "", additional_headers: Array = []
|
||||
) -> Variant:
|
||||
var headers = ["X-Appwrite-Project: %s" % project_id, "Content-Type: application/json"]
|
||||
headers.append_array(additional_headers)
|
||||
|
||||
var error = http_request.request(url, headers, method, request_data)
|
||||
if error:
|
||||
push_error("An error occurred creating the HTTP request: error=%s" % error)
|
||||
return null
|
||||
|
||||
var response: Array = await http_request.request_completed
|
||||
var result: int = response[0]
|
||||
var http_status: int = response[1]
|
||||
var body: PackedByteArray = response[3]
|
||||
|
||||
if result != HTTPRequest.RESULT_SUCCESS or http_status < 200 or http_status >= 300:
|
||||
push_error("HTTP request returned an error: result=%s http_status=%s" % [result, http_status])
|
||||
return null
|
||||
|
||||
var response_data = JSON.parse_string(body.get_string_from_utf8())
|
||||
if not response_data:
|
||||
push_error("Error parsing HTTP body.")
|
||||
return []
|
||||
|
||||
var scores: Array[RTMIScoreRow] = []
|
||||
for document in response.get("documents"):
|
||||
scores.append(RTMIScoreRow.new(document))
|
||||
|
||||
return scores
|
||||
return response_data
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
extends ESCItemComponent
|
||||
class_name ESCItemComponentOutline
|
||||
extends ESCItemComponent
|
||||
|
||||
var outline: ItemOutline
|
||||
|
||||
@@ -24,15 +24,15 @@ func highlight(value: bool) -> void:
|
||||
for node in get_parent().collision.get_children():
|
||||
if node is ItemOutline:
|
||||
node.visible = value
|
||||
|
||||
|
||||
func _input(event) -> void:
|
||||
if not event.is_action("ui_show_hints"):
|
||||
return
|
||||
|
||||
|
||||
if escoria.current_state != escoria.GAME_STATE.DEFAULT:
|
||||
return
|
||||
|
||||
if not get_object().interactive:
|
||||
if get_object() and not get_object().interactive:
|
||||
return
|
||||
|
||||
# No tool selected
|
||||
@@ -46,7 +46,7 @@ func _input(event) -> void:
|
||||
# Only with tool selected
|
||||
if escoria.action_manager.action_state != escoria.action_manager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM:
|
||||
return
|
||||
|
||||
|
||||
if not gymkhana.has_combination_with_current_tool(get_global_id()):
|
||||
return
|
||||
|
||||
@@ -54,4 +54,3 @@ func _input(event) -> void:
|
||||
highlight(true)
|
||||
elif not gymkhana.is_item_under_mouse(get_global_id()):
|
||||
highlight(false)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user