diff options
Diffstat (limited to 'client/server_list.gd')
-rw-r--r-- | client/server_list.gd | 106 |
1 files changed, 92 insertions, 14 deletions
diff --git a/client/server_list.gd b/client/server_list.gd index f509a34e..43cfc15c 100644 --- a/client/server_list.gd +++ b/client/server_list.gd @@ -1,5 +1,6 @@ # Hurry Curry! - a game about cooking # Copyright 2024 tpart +# Copyright 2024 nokoe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by @@ -18,24 +19,78 @@ extends Node signal update_loading(status: bool) signal update_server_list(list: Array) -var current_list := [] +enum Registry { + MDNS = 0, + GLOBAL = 1, +} + +const MDNS_URL: String = "http://127.0.0.1:27033/v1/list" +const HEADERS: Array[String] = [ + "Accept: application/json", + "User-Agent: Hurry Curry! %s" % Global.VERSION + ] + +var current_list: Array[Array] = [[], []] var loading := false +var mdns := HTTPRequest.new() +var reg := HTTPRequest.new() -@onready var req: HTTPRequest = $HTTPRequest +var thread: Thread +var pid: int + +var mdns_timer := Timer.new() +var reg_timer := Timer.new() +# after 30 minutes we stop fetching results to reduce server load +var timeout := Timer.new() + +func _ready() -> void: + add_child(mdns) + add_child(reg) + mdns_timer.wait_time = 5. + mdns_timer.one_shot = false + mdns_timer.timeout.connect(fetch_server_list.bind(Registry.MDNS)) + add_child(mdns_timer) + reg_timer.wait_time = 60. + reg_timer.one_shot = false + reg_timer.timeout.connect(fetch_server_list.bind(Registry.GLOBAL)) + add_child(reg_timer) + timeout.wait_time = 60. * 30. + timeout.timeout.connect(func(): + stop() + ) + add_child(timeout) + mdns.request_completed.connect(_on_request_completed.bind(Registry.MDNS)) + reg.request_completed.connect(_on_request_completed.bind(Registry.GLOBAL)) + if Global.get_setting("online.use_discovery"): + thread = Thread.new() + thread.start(func(): + # SAFETY: reading/writing arrays/dictionaries is allowed as long as + # the size is not changed. + # cf.: https://docs.godotengine.org/en/4.3/tutorials/performance/thread_safe_apis.html#gdscript-arrays-dictionaries + var res = OS.create_process(get_discovery_path(), [], true) + # SAFETY: since this is not read until the thread stops, this should + # probably be safe without synchronisation :) + pid = res + ) + +static func get_discovery_path() -> String: + var path: String = Global.get_setting("online.discovery_binary") + if path != "": + return path + else: + return "hurrycurry-discovery" + +func fetch_server_list(registry: Registry) -> void: + match registry: + Registry.MDNS: + mdns.request(MDNS_URL, HEADERS) + Registry.GLOBAL: + reg.request(Global.get_setting("online.registry_url") + "/v1/list", HEADERS) -func fetch_server_list(): - if loading: - push_warning("Server list is already loading") - return loading = true update_loading.emit(true) - req.request_completed.connect(_on_request_completed) - req.request("https://hurrycurry-registry.metamuffin.org/v1/list", [ - "Accept: application/json", - "User-Agent: Hurry Curry! %s" % Global.VERSION - ]) -func _on_request_completed(result: int, _response_code: int, _headers: PackedStringArray, body: PackedByteArray): +func _on_request_completed(result: int, _response_code: int, _headers: PackedStringArray, body: PackedByteArray, registry: Registry): loading = false update_loading.emit(false) if result != 0: @@ -45,5 +100,28 @@ func _on_request_completed(result: int, _response_code: int, _headers: PackedStr if json == null: push_error("Server list response invalid") return - current_list = json - update_server_list.emit(json) + current_list[registry] = json + update_server_list.emit(current_list) + +func start() -> void: + timeout.stop() + timeout.start() + if Global.get_setting("online.use_discovery"): + mdns_timer.start() + fetch_server_list(Registry.MDNS) + if Global.get_setting("online.use_registry"): + reg_timer.start() + fetch_server_list(Registry.GLOBAL) + +func stop() -> void: + timeout.stop() + mdns_timer.stop() + reg_timer.stop() + +func one_shot() -> void: + start() + stop() + +func _exit_tree(): + if thread != null: thread.wait_to_finish() + if pid != null: OS.kill(pid) |