Skip to content

--only-setup cmd arg #92

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 89 additions & 3 deletions addons/mod_loader/mod_loader_setup.gd
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ const new_global_classes := [
# Otherwise, script compilation will break on first load since the class is not defined.
var modloaderutils: Node = load("res://addons/mod_loader/mod_loader_utils.gd").new()

var path := {}
var file_name := {}
var is_only_setup: bool = modloaderutils.is_running_with_command_line_arg("--only-setup")


func _init() -> void:
try_setup_modloader()
Expand All @@ -46,16 +50,24 @@ func try_setup_modloader() -> void:
OS.set_window_title("%s (Modded)" % ProjectSettings.get_setting("application/config/name"))
return

setup_file_data()
setup_modloader()

# If the loader is set up, but the override is not applied yet,
# prompt the user to quit and restart the game.
if is_loader_set_up() and not is_loader_setup_applied():
modloaderutils.log_info("ModLoader is set up, but the game needs to be restarted", LOG_NAME)
OS.alert("The Godot ModLoader has been set up. Restart the game to apply the changes. Confirm to quit.")
ProjectSettings.set_setting(settings.IS_LOADER_SETUP_APPLIED, true)
var _savecustom_error: int = ProjectSettings.save_custom(modloaderutils.get_override_path())
quit()

match true:
# If the --only-setup cli argument is passed, quit with exit code 0
is_only_setup:
quit(0)
# If no cli argument is passed, show message with OS.alert() and user has to restart the game
_:
OS.alert("The Godot ModLoader has been set up. Restart the game to apply the changes. Confirm to quit.")
quit(0)


# Set up the ModLoader as an autoload and register the other global classes.
Expand All @@ -67,7 +79,7 @@ func setup_modloader() -> void:
modloaderutils.register_global_classes_from_array(new_global_classes)

# Add ModLoader autoload (the * marks the path as autoload)
ProjectSettings.set_setting(settings.MOD_LOADER_AUTOLOAD, "*res://addons/mod_loader/mod_loader.gd")
reorder_autoloads()
ProjectSettings.set_setting(settings.IS_LOADER_SET_UP, true)

# The game needs to be restarted first, bofore the loader is truly set up
Expand All @@ -77,6 +89,80 @@ func setup_modloader() -> void:
var _savecustom_error: int = ProjectSettings.save_custom(modloaderutils.get_override_path())
modloaderutils.log_info("ModLoader setup complete", LOG_NAME)

create_project_binary()
inject_project_binary()
clean_up_project_binary_file()


# Reorders the autoloads in the project settings, to get the ModLoader on top.
func reorder_autoloads() -> void:
# remove and re-add autoloads
var original_autoloads := {}
for prop in ProjectSettings.get_property_list():
var name: String = prop.name
if name.begins_with("autoload/"):
var value: String = ProjectSettings.get_setting(name)
original_autoloads[name] = value

for autoload in original_autoloads.keys():
ProjectSettings.set_setting(autoload, null)

# add ModLoader autoload (the * marks the path as autoload)
ProjectSettings.set_setting("autoload/ModLoader", "*" + "res://addons/mod_loader/mod_loader.gd")

# add all previous autoloads back again
for autoload in original_autoloads.keys():
ProjectSettings.set_setting(autoload, original_autoloads[autoload])


# Saves the project settings to a project.binary file inside the addons/mod_loader/ directory.
func create_project_binary() -> void:
var _error_save_custom_project_binary = ProjectSettings.save_custom(path.game_base_dir + "addons/mod_loader/project.binary")


# Add modified binary to the pck
func inject_project_binary() -> void:
var output_add_project_binary := []
var _exit_code_add_project_binary := OS.execute(path.pck_tool, ["--pack", path.pck, "--action", "add", "--file", path.project_binary, "--remove-prefix", path.mod_loader_dir], true, output_add_project_binary)
modloaderutils.log_debug_json_print("Adding custom project.binary to res://", output_add_project_binary, LOG_NAME)


# Removes the project.binary file
func clean_up_project_binary_file() -> void:
var dir = Directory.new()
dir.remove(path.project_binary)


# Initialize the path and file_name dictionary
func setup_file_data() -> void:
# C:/path/to/game/game.exe
path.exe = OS.get_executable_path()
# C:/path/to/game/
path.game_base_dir = modloaderutils.get_local_folder_dir()
# C:/path/to/game/addons/mod_loader
path.mod_loader_dir = path.game_base_dir + "addons/mod_loader/"
# C:/path/to/game/addons/mod_loader/vendor/godotpcktool/godotpcktool.exe
path.pck_tool = path.mod_loader_dir + "vendor/godotpcktool/godotpcktool.exe"
# can be supplied to override the exe_name
file_name.cli_arg_exe = modloaderutils.get_cmd_line_arg_value("--exe-name")
# can be supplied to override the pck_name
file_name.cli_arg_pck = modloaderutils.get_cmd_line_arg_value("--pck-name")
# game - or use the value of cli_arg_exe_name if there is one
file_name.exe = modloaderutils.get_file_name_from_path(path.exe, true, true) if file_name.cli_arg_exe == '' else file_name.cli_arg_exe
# game - or use the value of cli_arg_pck_name if there is one
# using exe_path.get_file() instead of exe_name
# so you don't override the pck_name with the --exe-name cli arg
# the main pack name is the same as the .exe name
# if --main-pack cli arg is not set
file_name.pck = modloaderutils.get_file_name_from_path(path.exe, true, true) if file_name.cli_arg_pck == '' else file_name.cli_arg_pck
# C:/path/to/game/game.pck
path.pck = path.game_base_dir.plus_file(file_name.pck + '.pck')
# C:/path/to/game/addons/mod_loader/project.binary
path.project_binary = path.mod_loader_dir + "project.binary"

modloaderutils.log_debug_json_print("path: ", path, LOG_NAME)
modloaderutils.log_debug_json_print("file_name: ", file_name, LOG_NAME)


func is_loader_set_up() -> bool:
return is_project_setting_true(settings.IS_LOADER_SET_UP)
Expand Down
21 changes: 21 additions & 0 deletions addons/mod_loader/vendor/godotpcktool/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020-2022 Henri Hyyryläinen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Binary file not shown.