diff options
Diffstat (limited to 'client/gui/menus/main/play.gd')
-rw-r--r-- | client/gui/menus/main/play.gd | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/client/gui/menus/main/play.gd b/client/gui/menus/main/play.gd new file mode 100644 index 00000000..c9cbee2f --- /dev/null +++ b/client/gui/menus/main/play.gd @@ -0,0 +1,208 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# 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 +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu + +var server_list_item: PackedScene = preload("res://gui/menus/main/server_list_item.tscn") +var url_regex: RegEx = RegEx.new() + +@onready var server_list: VBoxContainer = $side/margin/options/second/ScrollContainerCustom/ServerList +@onready var server_list_loading: Label = $side/margin/options/second/Loading +@onready var server_list_empty: Label = $side/margin/options/second/NoServers +@onready var connect_uri = $side/margin/options/second/connect/uri +@onready var server = $side/margin/options/second/server +@onready var server_control = $side/margin/options/second/server/control +@onready var server_connect = $side/margin/options/second/server/connect +@onready var editor_control = $side/margin/options/second/editor/control +@onready var editor_connect = $side/margin/options/second/editor/connect +@onready var editor_container = $side/margin/options/second/editor + + +func _ready(): + url_regex.compile("^(?:(ws|wss)://)?([^:]+)(?::([0-9]+))?$") + if OS.has_feature("web"): + server.hide() + connect_uri.text = Global.get_profile("last_server_url") + Sound.play_music("MainMenu") + + ServerList.update_server_list.connect(update_server_list) + ServerList.update_loading.connect(update_server_list_loading) + update_server_list(ServerList.current_list) + update_server_list_loading(ServerList.loading) + + super() + if not Global.get_profile("registry_asked"): + var popup_data := MenuPopup.Data.new() + popup_data.text = tr("c.menu.play.allow_query_registry").format([Global.get_setting("online.registry_url")]) + var allow_button := Button.new() + allow_button.text = tr("c.menu.accept") + var deny_button := Button.new() + deny_button.text = tr("c.menu.deny") + allow_button.pressed.connect(func(): Global.set_setting("online.use_registry", true)) + deny_button.pressed.connect(func(): Global.set_setting("online.use_registry", false)) + popup_data.buttons = [allow_button, deny_button] + await submenu("res://gui/menus/popup.tscn", popup_data) + Global.set_profile("registry_asked", true) + Global.save_settings() + Global.save_profile() + + ServerList.start() + +func update_server_list(lists: Array[Array]): + # Find out the index of the currently focused server in the list + var prev_selected_idx := -1 + for i in range(server_list.get_children().size()): + if server_list.get_child(i).button.has_focus(): + prev_selected_idx = i + break + + for c in server_list.get_children(): + c.queue_free() + + var idx := 0 + for l in lists: + for i in l: + var server_item: ServerListItem = server_list_item.instantiate() + server_list.add_child(server_item) + # TODO: Implement fallback address correctly + server_item.setup(i.name, roundi(i.players_online), i.version) + server_item.button.pressed.connect(connect_to.bind(i.address[0])) + # Focus the same server with the same index as the previously focused one + if idx == prev_selected_idx: + server_item.button.grab_focus() + idx += 1 + + if prev_selected_idx > idx: + # Same index cannot be focused, since number of servers decreased + if idx - 1 < 0: + connect_uri.grab_focus() + else: + server_list.get_child(idx - 1).button.grab_focus() + + # Show message if no servers available + server_list_empty.visible = idx == 0 + +func update_server_list_loading(status: bool): + server_list_loading.visible = status + +func _menu_cover(state): + $side.visible = not state + +func _on_connect_pressed(): + var url = connect_uri.text + var result := url_regex.search(url) + if result != null: + if result.get_string(1) == "": + url = "ws://" + url + # only set default port for non-tls websocket connections + if result.get_string(3) == "" and result.get_string(1) != "wss": + url = url + ":27032" + connect_uri.text = url + Global.set_profile("last_server_url", url) + Global.save_profile() + connect_to(url) + +func _on_quick_connect_pressed(): + if OS.has_feature("web"): + connect_to(JavaScriptBridge.eval(""" + window.location.protocol.endsWith("s:") + ? `wss://${window.location.host}/` + : `ws://${window.location.hostname}:27032/` + """)) + else: + connect_to("wss://hurrycurry.metamuffin.org/") + +func connect_to(url: String): + print("Connecting to %s" % url) + get_parent().replace_menu("res://gui/menus/game.tscn", url) + +func _on_server_control_pressed(): + match Server.state: + Service.State.RUNNING: Server.stop() + Service.State.STOPPED: Server.start() + Service.State.FAILED: Server.start() + +func _on_editor_control_pressed(): + match Editor.state: + Service.State.RUNNING: Editor.stop() + Service.State.STOPPED: Editor.start(); Server.start() + Service.State.FAILED: Editor.start() + +func _on_server_connect_pressed(): + connect_to("ws://%s:%d" % [Server.connect_address(), Global.get_setting("server.bind_port")]) + +func _on_editor_connect_pressed(): + connect_to("ws://[::1]:27032/") + +func _process(_delta): + server_control.disabled = false + server_connect.visible = Server.state == Service.State.RUNNING + server_control.modulate = Color.WHITE + match Server.state: + Service.State.RUNNING: + server_control.text = tr("c.menu.play.server_stop") + server_control.modulate = Color.AQUAMARINE + Service.State.TESTING: + server_control.text = tr("c.menu.play.server_testing") + server_control.disabled = true + Service.State.STARTING: + server_control.text = tr("c.menu.play.server_starting") + server_control.disabled = true + Service.State.STOPPED: + server_control.text = tr("c.menu.play.server_start") + Service.State.FAILED: + server_control.text = tr("c.menu.play.server_failed") + server_control.modulate = Color(1, 0.4, 0.5) + server_control.tooltip_text = tr("c.menu.play.server_failed_tooltip") + Service.State.UNAVAILABLE: + server_control.text = tr("c.menu.play.server_unavailable") + server_control.disabled = true + server_control.tooltip_text = tr("c.menu.play.server_binary_not_found") + + editor_control.disabled = false + editor_connect.visible = Editor.state == Service.State.RUNNING + editor_control.modulate = Color.WHITE + editor_container.visible = Editor.state != Service.State.UNAVAILABLE + match Editor.state: + Service.State.RUNNING: + editor_control.text = tr("c.menu.play.editor_stop") + editor_control.modulate = Color.AQUAMARINE + Service.State.TESTING: + editor_control.text = tr("c.menu.play.editor_testing") + editor_control.disabled = true + Service.State.STARTING: + editor_control.text = tr("c.menu.play.editor_starting") + editor_control.disabled = true + Service.State.STOPPED: + editor_control.text = tr("c.menu.play.editor_start") + Service.State.FAILED: + editor_control.text = tr("c.menu.play.editor_failed") + editor_control.modulate = Color(1, 0.4, 0.5) + editor_control.tooltip_text = tr("c.menu.play.server_failed_tooltip") + Service.State.UNAVAILABLE: + editor_control.text = tr("c.menu.play.editor_unavailable") + editor_control.disabled = true + editor_control.tooltip_text = tr("c.menu.play.server_binary_not_found") + + +func _on_uri_text_changed(new_text): + connect_uri.modulate = Color.WHITE if url_regex.search(new_text) else Color.RED + +func _on_back_pressed(): + exit() + +func _menu_exit(): + ServerList.stop() + super() |