diff --git a/scenes/config_field_container.tscn b/scenes/config_field_container.tscn index 14cd63c..886f5c3 100644 --- a/scenes/config_field_container.tscn +++ b/scenes/config_field_container.tscn @@ -8,9 +8,9 @@ line_spacing = -6.0 font_color = Color(0.753984, 0.753984, 0.753984, 1) [node name="ConfigFieldContainer" type="VBoxContainer"] -custom_minimum_size = Vector2(600, 61) -offset_right = 42.0 -offset_bottom = 34.0 +custom_minimum_size = Vector2(600, 69) +offset_right = 600.0 +offset_bottom = 69.0 theme = ExtResource("1_1skrl") script = ExtResource("1_2i062") diff --git a/scenes/mod_manager.tscn b/scenes/mod_manager.tscn index 3c042f4..87ea14e 100644 --- a/scenes/mod_manager.tscn +++ b/scenes/mod_manager.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=7 format=3 uid="uid://c6570n2s1k1wv"] +[gd_scene load_steps=9 format=3 uid="uid://c6570n2s1k1wv"] [ext_resource type="Theme" uid="uid://dged4041swr1" path="res://theme.tres" id="1_1wikn"] [ext_resource type="Script" path="res://scripts/mod_manager.gd" id="2_37t4h"] @@ -6,6 +6,11 @@ [ext_resource type="Script" path="res://scripts/mod_loader_container.gd" id="4_vi72b"] [ext_resource type="Script" path="res://scripts/mod_list_container.gd" id="5_pbjar"] [ext_resource type="StyleBox" uid="uid://dl64sodill7qu" path="res://panel_style_box.tres" id="6_7hd73"] +[ext_resource type="Script" path="res://scripts/mod_manager_config_container.gd" id="7_wuify"] + +[sub_resource type="LabelSettings" id="LabelSettings_g2u8q"] +line_spacing = -6.0 +font_color = Color(0.753984, 0.753984, 0.753984, 1) [node name="ModManager" type="Control"] layout_mode = 3 @@ -136,12 +141,59 @@ layout_mode = 2 visible = false layout_mode = 2 size_flags_vertical = 3 +theme_override_constants/separation = 24 +script = ExtResource("7_wuify") + +[node name="CheckForUpdates" type="VBoxContainer" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer"] +layout_mode = 2 + +[node name="OptionsContainer" type="HBoxContainer" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/CheckForUpdates"] +layout_mode = 2 + +[node name="Label" type="Label" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/CheckForUpdates/OptionsContainer"] +layout_mode = 2 +text = "Check for updates" + +[node name="CheckBox" type="CheckBox" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/CheckForUpdates/OptionsContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +button_pressed = true + +[node name="ResetToDefault" type="Button" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/CheckForUpdates/OptionsContainer"] +layout_mode = 2 +text = "Reset to default" + +[node name="DescriptionLabel" type="Label" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/CheckForUpdates"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.712129, 0.712129, 0.712129, 1) +theme_override_font_sizes/font_size = 16 +text = "Should GSS Mod Manager check for updates when started?" +label_settings = SubResource("LabelSettings_g2u8q") -[node name="NoticeLabel" type="Label" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer"] +[node name="LaunchGSSWithGUIConsole" type="VBoxContainer" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer"] layout_mode = 2 -text = "Nothing to configure here right now! -TODO: Add configuration" +[node name="OptionsContainer" type="HBoxContainer" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/LaunchGSSWithGUIConsole"] +layout_mode = 2 + +[node name="Label" type="Label" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/LaunchGSSWithGUIConsole/OptionsContainer"] +layout_mode = 2 +text = "Launch GSS with GUI console" + +[node name="CheckBox" type="CheckBox" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/LaunchGSSWithGUIConsole/OptionsContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ResetToDefault" type="Button" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/LaunchGSSWithGUIConsole/OptionsContainer"] +layout_mode = 2 +text = "Reset to default" + +[node name="DescriptionLabel" type="Label" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/LaunchGSSWithGUIConsole"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.712129, 0.712129, 0.712129, 1) +theme_override_font_sizes/font_size = 16 +text = "Should Grocery Store Simulator launch with a debugging GUI console?" +label_settings = SubResource("LabelSettings_g2u8q") [node name="ScrollContainer" type="ScrollContainer" parent="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer"] visible = false @@ -190,22 +242,31 @@ theme_override_styles/panel = ExtResource("6_7hd73") [node name="MainContainer" type="VBoxContainer" parent="PopupMarginContainer/PanelContainer"] layout_mode = 2 -theme_override_constants/separation = 20 alignment = 1 [node name="UpdateLabel" type="Label" parent="PopupMarginContainer/PanelContainer/MainContainer"] layout_mode = 2 text = "A new version of GSS Mod Manager is avaliable! -(current: ; latest: )" +(current: ; latest: ) +Update description:" horizontal_alignment = 1 +[node name="DescriptionMargin" type="MarginContainer" parent="PopupMarginContainer/PanelContainer/MainContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 16 +theme_override_constants/margin_right = 16 +theme_override_constants/margin_bottom = 24 + +[node name="UpdateDescriptionLabel" type="Label" parent="PopupMarginContainer/PanelContainer/MainContainer/DescriptionMargin"] +layout_mode = 2 + [node name="ControlsContainer" type="HBoxContainer" parent="PopupMarginContainer/PanelContainer/MainContainer"] layout_mode = 2 alignment = 1 -[node name="OpenLinkButton" type="Button" parent="PopupMarginContainer/PanelContainer/MainContainer/ControlsContainer"] +[node name="OpenUpdateLinkButton" type="Button" parent="PopupMarginContainer/PanelContainer/MainContainer/ControlsContainer"] layout_mode = 2 -text = "Open link" +text = "Open update link" [node name="CloseButton" type="Button" parent="PopupMarginContainer/PanelContainer/MainContainer/ControlsContainer"] layout_mode = 2 @@ -229,10 +290,14 @@ use_native_dialog = true [connection signal="pressed" from="MarginContainer/MainContainer/ModListContainer/RefreshButton" to="MarginContainer/MainContainer/ModListContainer" method="_on_refresh_button_pressed"] [connection signal="pressed" from="MarginContainer/MainContainer/ModListContainer/InstallModButton" to="MarginContainer/MainContainer/ModListContainer" method="_on_install_mod_button_pressed"] [connection signal="pressed" from="MarginContainer/MainContainer/ModManagerContainer/ConfigureButton" to="." method="_on_configure_button_pressed"] +[connection signal="toggled" from="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/CheckForUpdates/OptionsContainer/CheckBox" to="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer" method="_on_check_for_updates_toggled"] +[connection signal="pressed" from="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/CheckForUpdates/OptionsContainer/ResetToDefault" to="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer" method="_on_reset_check_for_updates_pressed"] +[connection signal="toggled" from="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/LaunchGSSWithGUIConsole/OptionsContainer/CheckBox" to="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer" method="_on_launch_gss_with_gui_console_toggled"] +[connection signal="pressed" from="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer/LaunchGSSWithGUIConsole/OptionsContainer/ResetToDefault" to="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ModManagerConfigContainer" method="_on_reset_launch_gss_with_gui_console_pressed"] [connection signal="pressed" from="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ConfigControls/SaveButton" to="." method="_on_save_config_button_pressed"] [connection signal="pressed" from="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ConfigControls/CancelButton" to="." method="_on_cancel_config_button_pressed"] [connection signal="pressed" from="PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ConfigControls/CopyLogButton" to="." method="_on_copy_log_button_pressed"] -[connection signal="pressed" from="PopupMarginContainer/PanelContainer/MainContainer/ControlsContainer/OpenLinkButton" to="." method="_on_open_link_button_pressed"] +[connection signal="pressed" from="PopupMarginContainer/PanelContainer/MainContainer/ControlsContainer/OpenUpdateLinkButton" to="." method="_on_open_update_link_button_pressed"] [connection signal="pressed" from="PopupMarginContainer/PanelContainer/MainContainer/ControlsContainer/CloseButton" to="." method="_on_update_close_button_pressed"] [connection signal="dir_selected" from="FileDialog" to="." method="_on_file_dialog_gss_path_selected"] [connection signal="file_selected" from="FileDialog" to="MarginContainer/MainContainer/ModListContainer" method="_on_file_dialog_mod_selected"] diff --git a/scripts/mod_manager.gd b/scripts/mod_manager.gd index 4f76b01..174bc86 100644 --- a/scripts/mod_manager.gd +++ b/scripts/mod_manager.gd @@ -8,6 +8,7 @@ class_name ModManager extends Control @onready var mod_config_container = $PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ScrollContainer/ModConfigContainer @onready var mod_config_scroll_container = $PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ScrollContainer @onready var copy_log_button = $PanelMarginContainer/PanelContainer/MarginContainer/ConfigContainer/ConfigControls/CopyLogButton +@onready var update_description_label = $PopupMarginContainer/PanelContainer/MainContainer/DescriptionMargin/UpdateDescriptionLabel @onready var update_label = $PopupMarginContainer/PanelContainer/MainContainer/UpdateLabel @onready var popup = $PopupMarginContainer @onready var mod_containers: Control = main.get_node("MarginContainer/ScrollContainer/ModContainers") @@ -40,7 +41,7 @@ const BUILTIN_MODS: Array[String] = [ "CheatManagerEnablerMod", "ConsoleCommandsMod", "ConsoleEnablerMod", "jsbLuaProfilerMod", "Keybinds", "LineTraceMod", "SplitScreenMod" ] -const VERSION: String = "v0.5.0" +const VERSION: String = "v0.6.0" # NOTE: Things like installing the mod loader and installing mods only work in exported. @@ -138,10 +139,11 @@ func _on_configure_mod(mod_name: String) -> void: var fields = ConfigParser.parse(ue_root, mod_name) if fields.is_empty(): var label = Label.new() - label.text = "Couldn't parse config, a new notepad window has been opened.\n" + \ - "The Mod Manager will be unresponsive until you close notepad.\n\n" + \ - "Config parser log (there's a Copy log button below, send to #support on Discord):\n" + \ - ConfigParser.logs + label.text = \ + "Couldn't parse config, a new notepad window has been opened.\n" + \ + "Edit the config in notepad, then save and close notepad.\n\n" + \ + "Config parser log (there's a Copy log button below, send to #support on Discord):\n" + \ + ConfigParser.logs copy_log_button.show() mod_config_container.add_child(label) @@ -149,9 +151,7 @@ func _on_configure_mod(mod_name: String) -> void: mod_config_scroll_container.show() main.hide() - # OS tries to execute notepad faster than the above takes effect - await get_tree().create_timer(0.01).timeout - OS.execute("notepad", [ue_root + "/Mods/%s/Scripts/config.lua" % mod_name]) + OS.execute_with_pipe("notepad", [ue_root + "/Mods/%s/Scripts/config.lua" % mod_name]) else: for field in fields: var container = ConfigFieldContainer.with(field) @@ -210,7 +210,7 @@ func _ready() -> void: var err := config.load("user://config") if err == ERR_FILE_NOT_FOUND: path_container.detect_gss() - else: + elif err != OK: error("Read user config", err) var path: String = config.get_value("main", "gss_path") @@ -219,9 +219,12 @@ func _ready() -> void: else: gss_path = path + error("Read mod manager config", mod_manager_config_container.load_from(ue_root, config)) mod_manager_label.text = "GSS Mod Manager " + VERSION - err = http.request("https://api.github.com/repos/nieboczek/gss-mod-manager/releases/latest") - error("Initiate HTTP request", err) + + if mod_manager_config_container.check_for_updates: + err = http.request("https://api.github.com/repos/nieboczek/gss-mod-manager/releases/latest") + error("Initiate HTTP request", err) ## Returns a boolean that if is true, action didn't complete successfully func error(action: String, err: Error) -> bool: @@ -243,10 +246,12 @@ func _on_save_config_button_pressed() -> void: configured_mod = "" hide_config_ui() else: - # Saving for Mod Manager config here + error("Save mod manager config", mod_manager_config_container.save(ue_root, config)) hide_config_ui() func _on_cancel_config_button_pressed() -> void: + if configured_mod.is_empty(): + mod_manager_config_container.cancel() hide_config_ui() func hide_config_ui() -> void: @@ -260,19 +265,20 @@ func hide_config_ui() -> void: mod_manager_config_container.hide() func _on_copy_log_button_pressed() -> void: - # Does magic Discord formatting and copies to clipboard DisplayServer.clipboard_set("Config parser log:\n```d\n%s```" % ConfigParser.logs) -func _on_http_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) -> void: +func _on_http_request_completed(result: int, _response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void: if !error("Request update data", result): var json = JSON.parse_string(body.get_string_from_utf8()) if json and json["tag_name"] != VERSION: update_label.text = \ "A new version of GSS Mod Manager is avaliable!\n" + \ - "(current: %s; latest: %s)" % [VERSION, json["tag_name"]] + "(current: %s; latest: %s)\n" % [VERSION, json["tag_name"]] + \ + "Update description:" + update_description_label.text = json["body"] popup.show() -func _on_open_link_button_pressed() -> void: +func _on_open_update_link_button_pressed() -> void: OS.shell_open("https://github.com/nieboczek/gss-mod-manager/releases/latest") func _on_update_close_button_pressed() -> void: diff --git a/scripts/mod_manager_config_container.gd b/scripts/mod_manager_config_container.gd new file mode 100644 index 0000000..548a5ba --- /dev/null +++ b/scripts/mod_manager_config_container.gd @@ -0,0 +1,83 @@ +extends VBoxContainer + +@onready var check_for_updates_checkbox = $CheckForUpdates/OptionsContainer/CheckBox +@onready var launch_gss_with_gui_console_checkbox = $LaunchGSSWithGUIConsole/OptionsContainer/CheckBox + +var changed_values: Dictionary = {} +var ue4ss_setting_lines: Array[String] = [] +var check_for_updates: bool + +func save(ue_root: String, config: ConfigFile) -> Error: + for value_name in changed_values: + var value = changed_values[value_name] + match value_name: + "check_for_updates": check_for_updates = value + "launch_gss_with_gui_console": + var err = save_launch_gss_with_gui_console(ue_root, value) + if err: return err + continue + _: + push_error("Unknown value name with no handler: " + value_name) + return ERR_METHOD_NOT_FOUND + + config.set_value("main", value_name, value) + + config.save("user://config") + return OK + +func cancel() -> void: + changed_values = {} + +func load_from(ue_root: String, config: ConfigFile) -> Error: + check_for_updates = config.get_value("main", "check_for_updates", true) + check_for_updates_checkbox.button_pressed = check_for_updates + + var err = load_launch_gss_with_gui_console(ue_root) + if err: return err + + return OK + +func save_launch_gss_with_gui_console(ue_root: String, value: bool) -> Error: + var file = FileAccess.open(ue_root + "/UE4SS-settings.ini", FileAccess.WRITE) + if file: + for i in range(len(ue4ss_setting_lines)): + if ue4ss_setting_lines[i].begins_with("GuiConsoleVisible"): + ue4ss_setting_lines[i] = "GuiConsoleVisible = " + '1' if value else '0' + + file.store_string(ue4ss_setting_lines[i]) + if i < len(ue4ss_setting_lines) - 1: + file.store_string("\n") + + file.close() + return OK + else: + return FileAccess.get_open_error() + +func load_launch_gss_with_gui_console(ue_root: String) -> Error: + var file = FileAccess.open(ue_root + "/UE4SS-settings.ini", FileAccess.READ) + if file: + while not file.eof_reached(): + ue4ss_setting_lines.append(file.get_line()) + file.close() + + for i in range(len(ue4ss_setting_lines)): + if ue4ss_setting_lines[i].begins_with("GuiConsoleVisible"): + launch_gss_with_gui_console_checkbox.button_pressed = \ + ue4ss_setting_lines[i].replace("GuiConsoleVisible = ", "") == '1' + break + + return OK + else: + return FileAccess.get_open_error() + +func _on_check_for_updates_toggled(toggled_on: bool) -> void: + changed_values["check_for_updates"] = toggled_on + +func _on_reset_check_for_updates_pressed() -> void: + changed_values["check_for_updates"] = true + +func _on_launch_gss_with_gui_console_toggled(toggled_on: bool) -> void: + changed_values["launch_gss_with_gui_console"] = toggled_on + +func _on_reset_launch_gss_with_gui_console_pressed() -> void: + changed_values["launch_gss_with_gui_console"] = false