aboutsummaryrefslogtreecommitdiff
path: root/client/server_list.gd
diff options
context:
space:
mode:
Diffstat (limited to 'client/server_list.gd')
-rw-r--r--client/server_list.gd106
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)