Allow Mod Loader to automatically add hooks on export (#405)

* Update Mod Loader and Tool addons

* Mod tool checks if script exists before reloading

* Change script export mode to Text for hook export

* Change return type of load_image_from_path to Texture2D
This commit is contained in:
BarrierFalki
2025-09-26 13:30:40 -05:00
committed by GitHub
parent 1c309ce731
commit 78f68b3be1
59 changed files with 104 additions and 69 deletions

View File

@@ -306,7 +306,7 @@ func clear_cache() -> void:
cache.clear() cache.clear()
property_cache.clear() property_cache.clear()
func load_image_from_path(path := "") -> ImageTexture: func load_image_from_path(path := "") -> Texture2D:
if path.contains("res://"): if path.contains("res://"):
if path.contains("NULL"): if path.contains("NULL"):
return null return null

View File

@@ -1 +1 @@
uid://b0csnkkiudklo uid://bmpsawwiyy20a

View File

@@ -1 +1 @@
uid://l36n5fcc565s uid://b6a02y62bm16j

View File

@@ -1 +1 @@
uid://byhbvq7il70cy uid://cepqw3ldumchb

View File

@@ -1 +1 @@
uid://2sifoxblubxv uid://b503egkdydcbv

View File

@@ -1 +1 @@
uid://nyep44jvp7yc uid://2wreigxn0epq

View File

@@ -43,8 +43,13 @@ static var verbosity: VERBOSITY_LEVEL = VERBOSITY_LEVEL.DEBUG
## Array of mods that should be ignored when logging messages (contains mod IDs as strings) ## Array of mods that should be ignored when logging messages (contains mod IDs as strings)
static var ignored_mods: Array[String] = [] static var ignored_mods: Array[String] = []
## Highlighting color for hint type log messages # NOTE: default values which get replaced later by `_configure_logger`
static var hint_color := Color("#70bafa") static var warning_color := Color("#ffde66")
static var success_color := Color("#5d8c3f")
static var info_color := Color("#70bafa")
static var hint_color := Color("#b293fa")
static var debug_color := Color("#d4d4d4")
static var debug_bold := true
## This Sub-Class represents a log entry in ModLoader. ## This Sub-Class represents a log entry in ModLoader.
class ModLoaderLogEntry: class ModLoaderLogEntry:
@@ -99,9 +104,15 @@ class ModLoaderLogEntry:
## Get the prefix string for the log entry, including the log type and mod name.[br] ## Get the prefix string for the log entry, including the log type and mod name.[br]
## [br] ## [br]
## [b]Parameters:[/b][br]
## [param exclude_type] ([bool]): (Optional) If true, the log type (e.g., DEBUG, WARN) will be excluded from the prefix. Default is false.[br]
## [br]
## [b]Returns:[/b] [String] ## [b]Returns:[/b] [String]
func get_prefix() -> String: func get_prefix(exclude_type := false) -> String:
return "%s %s: " % [type.to_upper(), mod_name] return "%s%s: " % [
"" if exclude_type else "%s " % type.to_upper(),
mod_name
]
## Generate an MD5 hash of the log entry (prefix + message).[br] ## Generate an MD5 hash of the log entry (prefix + message).[br]
@@ -391,6 +402,17 @@ static func get_all_entries_as_string(log_entries: Array) -> Array:
# Internal log functions # Internal log functions
# ============================================================================= # =============================================================================
static func _print_rich(prefix: String, message: String, color: Color, bold := true) -> void:
if OS.has_feature("editor"):
var prefix_text := "[b]%s[/b]" % prefix if bold else prefix
print_rich("[color=%s]%s[/color]%s" % [
color.to_html(false),
prefix_text,
message
])
else:
print(prefix + message)
static func _log(message: String, mod_name: String, log_type: String = "info", only_once := false) -> void: static func _log(message: String, mod_name: String, log_type: String = "info", only_once := false) -> void:
if _is_mod_name_ignored(mod_name): if _is_mod_name_ignored(mod_name):
return return
@@ -422,25 +444,35 @@ static func _log(message: String, mod_name: String, log_type: String = "info", o
_write_to_log_file(JSON.stringify(get_stack(), " ")) _write_to_log_file(JSON.stringify(get_stack(), " "))
assert(false, message) assert(false, message)
"error": "error":
printerr(log_entry.get_prefix() + message) if ModLoaderStore.has_feature.editor:
printerr(log_entry.get_prefix(true) + message)
else:
printerr(log_entry.get_prefix() + message)
push_error(message) push_error(message)
_write_to_log_file(log_entry.get_entry()) _write_to_log_file(log_entry.get_entry())
"warning": "warning":
if verbosity >= VERBOSITY_LEVEL.WARNING: if verbosity >= VERBOSITY_LEVEL.WARNING:
print(log_entry.get_prefix() + message) _print_rich(log_entry.get_prefix(), message, warning_color)
push_warning(message) push_warning(message)
_write_to_log_file(log_entry.get_entry()) _write_to_log_file(log_entry.get_entry())
"info", "success": "success":
if verbosity >= VERBOSITY_LEVEL.INFO: if verbosity >= VERBOSITY_LEVEL.INFO:
print(log_entry.get_prefix() + message) _print_rich(log_entry.get_prefix(), message, success_color)
_write_to_log_file(log_entry.get_entry())
"info":
if verbosity >= VERBOSITY_LEVEL.INFO:
_print_rich(log_entry.get_prefix(), message, info_color)
_write_to_log_file(log_entry.get_entry()) _write_to_log_file(log_entry.get_entry())
"debug": "debug":
if verbosity >= VERBOSITY_LEVEL.DEBUG: if verbosity >= VERBOSITY_LEVEL.DEBUG:
print(log_entry.get_prefix() + message) _print_rich(log_entry.get_prefix(), message, debug_color, debug_bold)
_write_to_log_file(log_entry.get_entry()) _write_to_log_file(log_entry.get_entry())
"hint": "hint":
if OS.has_feature("editor") and verbosity >= VERBOSITY_LEVEL.DEBUG: if (
print_rich("[color=%s]%s[/color]" % [hint_color.to_html(false), log_entry.get_prefix() + message]) ModLoaderStore.has_feature.editor and
verbosity >= VERBOSITY_LEVEL.DEBUG
):
_print_rich(log_entry.get_prefix(), message, hint_color)
static func _is_mod_name_ignored(mod_name: String) -> bool: static func _is_mod_name_ignored(mod_name: String) -> bool:

View File

@@ -1 +1 @@
uid://dfoleo2pforxu uid://ca6jko6awb8i3

View File

@@ -1 +1 @@
uid://d2hugw88f3q4e uid://b3khrstensh0

View File

@@ -1 +1 @@
uid://c0u28df0ffhan uid://caiv672leoq2u

View File

@@ -1 +1 @@
uid://b73enisoxe0uq uid://5fg2uh7tfmrh

View File

@@ -1 +1 @@
uid://c3rvk5ry6rqyq uid://ctocxfrx7h62y

View File

@@ -49,6 +49,7 @@ static func check_dependencies(mod: ModData, is_required := true, dependency_cha
_handle_missing_dependency(mod_id, dependency_id) _handle_missing_dependency(mod_id, dependency_id)
# Flag the mod so it's not loaded later # Flag the mod so it's not loaded later
mod.is_loadable = false mod.is_loadable = false
mod.is_active = false
else: else:
var dependency: ModData = ModLoaderStore.mod_data[dependency_id] var dependency: ModData = ModLoaderStore.mod_data[dependency_id]

View File

@@ -1 +1 @@
uid://bnmjbsvid8sxk uid://be0ha68kaqhym

View File

@@ -195,10 +195,7 @@ static func file_exists_in_zip(zip_path: String, path: String) -> bool:
if not reader: if not reader:
return false return false
if _ModLoaderGodot.is_version_below(_ModLoaderGodot.ENGINE_VERSION_HEX_4_2_0): return reader.get_files().has(path.trim_prefix("res://"))
return reader.get_files().has(path.trim_prefix("res://"))
else:
return reader.file_exists(path.trim_prefix("res://"))
static func get_mod_dir_name_in_zip(zip_path: String) -> String: static func get_mod_dir_name_in_zip(zip_path: String) -> String:

View File

@@ -1 +1 @@
uid://d34sgvhw73mtb uid://43dqdp55oll

View File

@@ -1 +1 @@
uid://dc86ulvsd1da7 uid://dke5ndugd3pw8

View File

@@ -1 +1 @@
uid://yrog1crr7kxp uid://cbqwg3m61yvwl

View File

@@ -1 +1 @@
uid://dnwq8741pln26 uid://dcm2pyox3kbym

View File

@@ -1 +1 @@
uid://gxlbhvqctoix uid://cjg3y750m35jr

View File

@@ -1 +1 @@
uid://bk8dltcgr6n5d uid://b5k7eocfniqut

View File

@@ -1 +1 @@
uid://dahg6tbvgiy3q uid://b71qi44121xu6

View File

@@ -1 +1 @@
uid://daijyovwv2vnr uid://2sm6ww4bwa35

View File

@@ -1 +1 @@
uid://dinxouhn4hk1d uid://48f4wo7gu7pg

View File

@@ -1 +1 @@
uid://br0xd56w758rg uid://jmbfyn7bw0c4

View File

@@ -1 +1 @@
uid://bd8npc3ai2vv3 uid://dddx78cqvuhg1

View File

@@ -0,0 +1 @@
uid://b0goxb1n0eqvr

View File

@@ -227,4 +227,9 @@ func _update_ml_options_from_cli_args() -> void:
func _configure_logger() -> void: func _configure_logger() -> void:
ModLoaderLog.verbosity = ml_options.log_level ModLoaderLog.verbosity = ml_options.log_level
ModLoaderLog.ignored_mods = ml_options.ignored_mod_names_in_log ModLoaderLog.ignored_mods = ml_options.ignored_mod_names_in_log
ModLoaderLog.warning_color = ml_options.warning_color
ModLoaderLog.success_color = ml_options.success_color
ModLoaderLog.info_color = ml_options.info_color
ModLoaderLog.hint_color = ml_options.hint_color ModLoaderLog.hint_color = ml_options.hint_color
ModLoaderLog.debug_color = ml_options.debug_color
ModLoaderLog.debug_bold = ml_options.debug_bold

View File

@@ -1 +1 @@
uid://jv5kxtsw7sfj uid://c2ajp5nymw8j8

View File

@@ -1,12 +1,8 @@
[gd_resource type="Resource" script_class="ModLoaderCurrentOptions" load_steps=4 format=3 uid="uid://bls83tkysflvg"] [gd_resource type="Resource" script_class="ModLoaderCurrentOptions" load_steps=4 format=3 uid="uid://bls83tkysflvg"]
[ext_resource type="Resource" path="res://addons/mod_loader/options/profiles/default.tres" id="1_yg7p8"] [ext_resource type="Resource" uid="uid://bau85xe7qd6xm" path="res://addons/mod_loader/options/profiles/default.tres" id="1_yg7p8"]
[ext_resource type="Script" path="res://addons/mod_loader/resources/options_current.gd" id="2"] [ext_resource type="Script" uid="uid://cmxtu4snlj1bb" path="res://addons/mod_loader/resources/options_current.gd" id="2"]
[ext_resource type="Resource" path="res://addons/mod_loader/options/profiles/editor.tres" id="3"] [ext_resource type="Resource" path="res://addons/mod_loader/options/profiles/editor.tres" id="3"]
[resource] [resource]
script = ExtResource("2") script = ExtResource("2")
current_options = ExtResource("1_yg7p8")
feature_override_options = {
"editor": ExtResource("3")
}

View File

@@ -1,14 +1,6 @@
[gd_resource type="Resource" load_steps=2 format=2] [gd_resource type="Resource" script_class="ModLoaderOptionsProfile" load_steps=2 format=3 uid="uid://bau85xe7qd6xm"]
[ext_resource path="res://addons/mod_loader/resources/options_profile.gd" type="Script" id=1]
[ext_resource type="Script" uid="uid://f46uvi5y8oqi" path="res://addons/mod_loader/resources/options_profile.gd" id="1"]
[resource] [resource]
script = ExtResource( 1 ) script = ExtResource("1")
enable_mods = true
log_level = 3
disabled_mods = [ ]
steam_workshop_enabled = false
override_path_to_mods = ""
override_path_to_configs = ""
override_path_to_workshop = ""

View File

@@ -1 +1 @@
uid://bjfjju1edaxwv uid://bvxprkn5ij076

View File

@@ -1 +1 @@
uid://bfnhjikkx0g5s uid://dsgr2b68w3ndv

View File

@@ -1 +1 @@
uid://bleh3oamdbmnr uid://s5gnda0rx2s8

View File

@@ -1 +1 @@
uid://ddrlbkscua6n0 uid://diggt80eyfpwi

View File

@@ -1 +1 @@
uid://cmxtu4snlj1bb uid://isimicww6eyn

View File

@@ -55,7 +55,18 @@ enum VERSION_VALIDATION {
## [code]ModLoader:Dependency[/code] - ignore the exact name [br] ## [code]ModLoader:Dependency[/code] - ignore the exact name [br]
## [code]ModLoader:*[/code] - ignore all beginning with this name [br] ## [code]ModLoader:*[/code] - ignore all beginning with this name [br]
@export var ignored_mod_names_in_log: Array[String] = [] @export var ignored_mod_names_in_log: Array[String] = []
@export var hint_color := Color("#70bafa") ## Highlighting color for warning type log messages
@export var warning_color := Color("#ffde66")
## Highlighting color for success type log messages
@export var success_color := Color("#5d8c3f")
## Highlighting color for info type log messages
@export var info_color := Color("#70bafa")
## Highlighting color for hint type log messages
@export var hint_color := Color("#b293fa")
## Highlighting color for debug type log messages
@export var debug_color := Color("#d4d4d4")
## Highlight debug log prefixes with bold formatting
@export var debug_bold := true
@export_group("Game Data") @export_group("Game Data")
## Steam app id, can be found in the steam page url ## Steam app id, can be found in the steam page url

View File

@@ -1 +1 @@
uid://dsbicisgihjet uid://f46uvi5y8oqi

View File

@@ -1 +1 @@
uid://k10oyyxy00y1 uid://c1ryohmi4al0d

View File

@@ -1 +1 @@
uid://djchjoj06bcko uid://vsfxyayum0ww

View File

@@ -1 +1 @@
uid://2tin8kqukljx uid://2f67cuf7q2fr

View File

@@ -10,7 +10,7 @@ class_name ModToolUtils
static func reload_script(script: Script, mod_tool_store: ModToolStore) -> void: static func reload_script(script: Script, mod_tool_store: ModToolStore) -> void:
var pending_reloads := mod_tool_store.pending_reloads var pending_reloads := mod_tool_store.pending_reloads
if script.resource_path in pending_reloads: if script and script.resource_path in pending_reloads:
var source_code_from_disc := FileAccess.open(script.resource_path, FileAccess.READ).get_as_text() var source_code_from_disc := FileAccess.open(script.resource_path, FileAccess.READ).get_as_text()
var script_editor := EditorInterface.get_script_editor() var script_editor := EditorInterface.get_script_editor()

View File

@@ -89,7 +89,7 @@ func add_custom_context_actions(context_menu: PopupMenu, file_paths: Array[Strin
add_hooks_context_action(context_menu, script_paths) add_hooks_context_action(context_menu, script_paths)
if asset_override_paths.size() > 0: if asset_override_paths.size() > 0:
add_asset_override_context_action(context_menu, script_paths) add_asset_override_context_action(context_menu, asset_override_paths)
func create_script_extension(file_path: String) -> String: func create_script_extension(file_path: String) -> String:

View File

@@ -16,7 +16,7 @@ encryption_exclude_filters=""
seed=0 seed=0
encrypt_pck=false encrypt_pck=false
encrypt_directory=false encrypt_directory=false
script_export_mode=2 script_export_mode=0
[preset.0.options] [preset.0.options]