summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornokoe <nokoe@mailbox.org>2024-09-28 23:28:03 +0200
committernokoe <nokoe@mailbox.org>2024-09-28 23:31:00 +0200
commit3df8e2c3167849023c822004b4525bcae7bb3cd1 (patch)
treeada35b64dee43fd540bcc816c6e613f24fb5208c
parentb31b08da8b4d3730040eb9fe73be9ab2452ebfa0 (diff)
downloadhurrycurry-3df8e2c3167849023c822004b4525bcae7bb3cd1.tar
hurrycurry-3df8e2c3167849023c822004b4525bcae7bb3cd1.tar.bz2
hurrycurry-3df8e2c3167849023c822004b4525bcae7bb3cd1.tar.zst
start and use mdns discovery in client; fixes #177
-rw-r--r--client/menu/main.gd2
-rw-r--r--client/menu/play.gd28
-rw-r--r--client/project.godot2
-rw-r--r--client/server_list.gd106
-rw-r--r--client/server_list.tscn8
-rw-r--r--client/settings.gd7
6 files changed, 118 insertions, 35 deletions
diff --git a/client/menu/main.gd b/client/menu/main.gd
index 997653c9..5aa3fbaa 100644
--- a/client/menu/main.gd
+++ b/client/menu/main.gd
@@ -24,7 +24,7 @@ func _ready():
if OS.has_feature("web"):
quit_button.hide()
Sound.play_music("MainMenu")
- ServerList.fetch_server_list()
+ ServerList.one_shot()
func _menu_cover(state):
$side.visible = not state
diff --git a/client/menu/play.gd b/client/menu/play.gd
index b117d6a4..44cd3eb0 100644
--- a/client/menu/play.gd
+++ b/client/menu/play.gd
@@ -37,21 +37,23 @@ func _ready():
ServerList.update_loading.connect(update_server_list_loading)
update_server_list(ServerList.current_list)
update_server_list_loading(ServerList.loading)
-
+
+ ServerList.start()
super()
-func update_server_list(json: Array):
+func update_server_list(lists: Array[Array]):
for c in server_list.get_children():
c.queue_free()
- for i in json:
- var b := Button.new()
- b.text_overrun_behavior = TextServer.OVERRUN_TRIM_WORD_ELLIPSIS
- b.text = "%s (%d players)" % [i.name, i.players_online]
- # TODO: Implement fallback address correctly
- if i.version[0] != Multiplayer.VERSION_MAJOR or i.version[1] > Multiplayer.VERSION_MINOR:
- b.disabled = true
- b.pressed.connect(connect_to.bind(i.address[0]))
- server_list.add_child(b)
+ for l in lists:
+ for i in l:
+ var b := Button.new()
+ b.text_overrun_behavior = TextServer.OVERRUN_TRIM_WORD_ELLIPSIS
+ b.text = "%s (%d players)" % [i.name, i.players_online]
+ # TODO: Implement fallback address correctly
+ if i.version[0] != Multiplayer.VERSION_MAJOR or i.version[1] > Multiplayer.VERSION_MINOR:
+ b.disabled = true
+ b.pressed.connect(connect_to.bind(i.address[0]))
+ server_list.add_child(b)
func update_server_list_loading(status: bool):
server_list_loading.visible = status
@@ -127,3 +129,7 @@ func _on_uri_text_changed(new_text):
func _on_back_pressed():
exit()
+
+func _menu_exit():
+ ServerList.stop()
+ super()
diff --git a/client/project.godot b/client/project.godot
index d1e85f05..d931a1b0 100644
--- a/client/project.godot
+++ b/client/project.godot
@@ -24,7 +24,7 @@ Server="*res://server.gd"
Sound="*res://audio/sound.tscn"
DisableWrongJoypads="*res://disable_wrong_joypads.gd"
InputManager="*res://menu/settings/input/input_manager.gd"
-ServerList="*res://server_list.tscn"
+ServerList="*res://server_list.gd"
[display]
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)
diff --git a/client/server_list.tscn b/client/server_list.tscn
deleted file mode 100644
index f43da77f..00000000
--- a/client/server_list.tscn
+++ /dev/null
@@ -1,8 +0,0 @@
-[gd_scene load_steps=2 format=3 uid="uid://3p61jpqt7acp"]
-
-[ext_resource type="Script" path="res://server_list.gd" id="1_a8xqo"]
-
-[node name="ServerList" type="Node"]
-script = ExtResource("1_a8xqo")
-
-[node name="HTTPRequest" type="HTTPRequest" parent="."]
diff --git a/client/settings.gd b/client/settings.gd
index 667ffa41..eddc5207 100644
--- a/client/settings.gd
+++ b/client/settings.gd
@@ -70,6 +70,13 @@ static func get_root():
ToggleSetting.new("upnp", false),
ToggleSetting.new("mdns", false),
ToggleSetting.new("register", false),
+ ]),
+ SettingsCategory.new("online", [
+ # TODO: make this opt-in
+ ToggleSetting.new("use_registry", true),
+ TextSetting.new("registry_url", "https://hurrycurry-registry.metamuffin.org/"),
+ ToggleSetting.new("use_discovery", true),
+ TextSetting.new("discovery_binary", ""),
])
])