124 lines
3.1 KiB
GDScript
124 lines
3.1 KiB
GDScript
extends Node
|
|
|
|
|
|
signal _response_received
|
|
|
|
|
|
const CHECK_INTERVAL: float = 60.0
|
|
const POLL_INTERVAL: float = 0.5
|
|
|
|
|
|
var server_host: String = ""
|
|
var http: HTTPRequest = null
|
|
## True if there is currently a request processing.
|
|
var waiting_for_response: bool = false
|
|
## True if the last request failed and the result is not valid.
|
|
var errored: bool = false
|
|
|
|
var _response_code: int = -1
|
|
var _response_body: String = ""
|
|
|
|
|
|
class ScoreEntry:
|
|
var score: int
|
|
var time: int
|
|
var difficulty: int
|
|
|
|
func _init(score: int, time: int, difficulty: int) -> void:
|
|
self.score = score
|
|
self.time = time
|
|
self.difficulty = difficulty
|
|
|
|
static func from_dict(dict: Dictionary) -> ScoreEntry:
|
|
return ScoreEntry.new(dict.score, dict.time, dict.difficulty)
|
|
|
|
|
|
func _ready() -> void:
|
|
var file = File.new()
|
|
var result = file.open("res://scoreboard_host.txt", File.READ)
|
|
if result == OK:
|
|
server_host = file.get_line()
|
|
file.close()
|
|
|
|
http = HTTPRequest.new()
|
|
http.download_chunk_size = 4096
|
|
http.timeout = 30.0
|
|
http.use_threads = OS.get_name() != "HTML5"
|
|
http.connect("request_completed", self, "_on_request_completed")
|
|
add_child(http)
|
|
|
|
func _on_request_completed(result: int, response_code: int, headers: PoolStringArray, body: PoolByteArray) -> void:
|
|
if result != OK:
|
|
errored = true
|
|
else:
|
|
errored = false
|
|
_response_code = response_code
|
|
_response_body = body.get_string_from_utf8()
|
|
waiting_for_response = false
|
|
emit_signal("_response_received")
|
|
|
|
|
|
func is_name_free(player_name: String, id: int) -> bool:
|
|
if waiting_for_response:
|
|
yield(self, "_response_received")
|
|
var err = http.request(server_host + "/api/players/" + player_name)
|
|
if err != OK:
|
|
errored = true
|
|
return false
|
|
waiting_for_response = true
|
|
|
|
yield(self, "_response_received")
|
|
if _response_code == HTTPClient.RESPONSE_NOT_FOUND or _response_body.to_int() == id:
|
|
return true
|
|
return false
|
|
|
|
|
|
func touch_name(player_name: String, id: int) -> void:
|
|
if waiting_for_response:
|
|
yield(self, "_response_received")
|
|
var err = http.request(
|
|
server_host + "/api/players/%s/%d" % [player_name, id],
|
|
[], true, HTTPClient.METHOD_POST
|
|
)
|
|
if err != OK:
|
|
errored = true
|
|
return
|
|
waiting_for_response = true
|
|
|
|
|
|
func submit_score(level: String, entry: ScoreEntry) -> bool:
|
|
if waiting_for_response:
|
|
yield(self, "_response_received")
|
|
var err = http.request(
|
|
server_host + "/api/scores/%s/%s/%d/%d/%d" % [
|
|
level, Options.scoreboard_name,
|
|
entry.score, entry.time, entry.difficulty
|
|
],
|
|
[], true, HTTPClient.METHOD_POST
|
|
)
|
|
if err != OK:
|
|
errored = true
|
|
return false
|
|
waiting_for_response = true
|
|
yield(self, "_response_received")
|
|
if errored or _response_code != HTTPClient.RESPONSE_OK:
|
|
return false
|
|
return true
|
|
|
|
|
|
func get_scores(level: String) -> Dictionary:
|
|
if waiting_for_response:
|
|
yield(self, "_response_received")
|
|
var err = http.request(server_host + "/api/scores/%s" % level)
|
|
if err != OK:
|
|
errored = true
|
|
return {}
|
|
waiting_for_response = true
|
|
yield(self, "_response_received")
|
|
if not errored and _response_code == HTTPClient.RESPONSE_OK:
|
|
var dict = parse_json(_response_body)
|
|
var scores = {}
|
|
for player in dict.keys():
|
|
scores[player] = ScoreEntry.from_dict(dict[player])
|
|
return scores
|
|
return {}
|