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) | 
