Skip to content

Commit ed77a75

Browse files
authored
chore: backport 4.x to 4.0 (#567)
Loses engine hex version checking, but seeing as we're below version 4.2 anyway the check isn't required anymore
2 parents e75c045 + 07f77a5 commit ed77a75

File tree

16 files changed

+195
-139
lines changed

16 files changed

+195
-139
lines changed

addons/mod_loader/_export_plugin/export_plugin.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
extends EditorExportPlugin
22

33

4-
static var hook_pre_processor: _ModLoaderModHookPreProcessor
4+
var hook_pre_processor: _ModLoaderModHookPreProcessor
55

66
func _get_name() -> String:
77
return "Godot Mod Loader Export Plugin"

addons/mod_loader/api/config.gd

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ static func create_config(mod_id: String, config_name: String, config_data: Dict
5353
)
5454

5555
# Check if the mod_config is valid
56-
if not mod_config.is_valid:
56+
#if not mod_config.is_valid:
57+
if not mod_config.is_valid():
5758
return null
5859

5960
# Store the mod_config in the mod's ModData
@@ -86,7 +87,8 @@ static func update_config(config: ModConfig) -> ModConfig:
8687
return null
8788

8889
# Check if the config passed validation
89-
if not config.is_valid:
90+
#if not config.is_valid:
91+
if not config.is_valid():
9092
ModLoaderLog.error("Update for config \"%s\" failed validation with error message \"%s\"" % [config.name, error_message], LOG_NAME)
9193
return null
9294

addons/mod_loader/api/log.gd

Lines changed: 116 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,15 @@ enum VERBOSITY_LEVEL {
1818
DEBUG, ## For debugging, can get quite verbose
1919
}
2020

21-
## Keeps track of logged messages, to avoid flooding the log with duplicate notices
22-
## Can also be used by mods, eg. to create an in-game developer console that
23-
## shows messages
24-
static var logged_messages := {
25-
"all": {},
26-
"by_mod": {},
27-
"by_type": {
28-
"fatal-error": {},
29-
"error": {},
30-
"warning": {},
31-
"info": {},
32-
"success": {},
33-
"debug": {},
34-
"hint": {},
35-
}
21+
enum VERBOSITY_COLOR {
22+
ERROR, ## For errors and fatal errors
23+
WARNING, ## For warnings
24+
INFO, ## For everything informational
25+
SUCCESS,
26+
DEBUG, ## For debugging, can get quite verbose
27+
hint,
3628
}
3729

38-
## Verbosity/Logging level.
39-
## Used to filter out messages below the set level
40-
## (if the [enum VERBOSITY_LEVEL] int of a new entry is larger than the [member verbosity] it is ignored)
41-
static var verbosity: VERBOSITY_LEVEL = VERBOSITY_LEVEL.DEBUG
42-
43-
## Array of mods that should be ignored when logging messages (contains mod IDs as strings)
44-
static var ignored_mods: Array[String] = []
45-
46-
## Highlighting color for hint type log messages
47-
static var hint_color := Color("#70bafa")
48-
4930
## This Sub-Class represents a log entry in ModLoader.
5031
class ModLoaderLogEntry:
5132
extends Resource
@@ -99,9 +80,15 @@ class ModLoaderLogEntry:
9980

10081
## Get the prefix string for the log entry, including the log type and mod name.[br]
10182
## [br]
83+
## [b]Parameters:[/b][br]
84+
## [param exclude_type] ([bool]): (Optional) If true, the log type (e.g., DEBUG, WARN) will be excluded from the prefix. Default is false.[br]
85+
## [br]
10286
## [b]Returns:[/b] [String]
103-
func get_prefix() -> String:
104-
return "%s %s: " % [type.to_upper(), mod_name]
87+
func get_prefix(exclude_type := false) -> String:
88+
return "%s%s: " % [
89+
"" if exclude_type else "%s " % type.to_upper(),
90+
mod_name
91+
]
10592

10693

10794
## Generate an MD5 hash of the log entry (prefix + message).[br]
@@ -323,8 +310,8 @@ static func get_all() -> Array:
323310
var log_entries := []
324311

325312
# Get all log entries
326-
for entry_key in logged_messages.all.keys():
327-
var entry: ModLoaderLogEntry = logged_messages.all[entry_key]
313+
for entry_key in ModLoaderStore.logged_messages.all.keys():
314+
var entry: ModLoaderLogEntry = ModLoaderStore.logged_messages.all[entry_key]
328315
log_entries.append_array(entry.get_all_entries())
329316

330317
# Sort them by time
@@ -343,12 +330,12 @@ static func get_all() -> Array:
343330
static func get_by_mod(mod_name: String) -> Array:
344331
var log_entries := []
345332

346-
if not logged_messages.by_mod.has(mod_name):
333+
if not ModLoaderStore.logged_messages.by_mod.has(mod_name):
347334
error("\"%s\" not found in logged messages." % mod_name, _LOG_NAME)
348335
return []
349336

350-
for entry_key in logged_messages.by_mod[mod_name].keys():
351-
var entry: ModLoaderLogEntry = logged_messages.by_mod[mod_name][entry_key]
337+
for entry_key in ModLoaderStore.logged_messages.by_mod[mod_name].keys():
338+
var entry: ModLoaderLogEntry = ModLoaderStore.logged_messages.by_mod[mod_name][entry_key]
352339
log_entries.append_array(entry.get_all_entries())
353340

354341
return log_entries
@@ -364,8 +351,8 @@ static func get_by_mod(mod_name: String) -> Array:
364351
static func get_by_type(type: String) -> Array:
365352
var log_entries := []
366353

367-
for entry_key in logged_messages.by_type[type].keys():
368-
var entry: ModLoaderLogEntry = logged_messages.by_type[type][entry_key]
354+
for entry_key in ModLoaderStore.logged_messages.by_type[type].keys():
355+
var entry: ModLoaderLogEntry = ModLoaderStore.logged_messages.by_type[type][entry_key]
369356
log_entries.append_array(entry.get_all_entries())
370357

371358
return log_entries
@@ -391,6 +378,17 @@ static func get_all_entries_as_string(log_entries: Array) -> Array:
391378
# Internal log functions
392379
# =============================================================================
393380

381+
static func _print_rich(prefix: String, message: String, color: Color, bold := true) -> void:
382+
if OS.has_feature("editor"):
383+
var prefix_text := "[b]%s[/b]" % prefix if bold else prefix
384+
print_rich("[color=%s]%s[/color]%s" % [
385+
color.to_html(false),
386+
prefix_text,
387+
message
388+
])
389+
else:
390+
print(prefix + message)
391+
394392
static func _log(message: String, mod_name: String, log_type: String = "info", only_once := false) -> void:
395393
if _is_mod_name_ignored(mod_name):
396394
return
@@ -422,63 +420,125 @@ static func _log(message: String, mod_name: String, log_type: String = "info", o
422420
_write_to_log_file(JSON.stringify(get_stack(), " "))
423421
assert(false, message)
424422
"error":
425-
printerr(log_entry.get_prefix() + message)
423+
if ModLoaderStore.has_feature.editor:
424+
printerr(log_entry.get_prefix(true) + message)
425+
else:
426+
printerr(log_entry.get_prefix() + message)
426427
push_error(message)
427428
_write_to_log_file(log_entry.get_entry())
428429
"warning":
429-
if verbosity >= VERBOSITY_LEVEL.WARNING:
430-
print(log_entry.get_prefix() + message)
430+
if _get_verbosity() >= VERBOSITY_LEVEL.WARNING:
431+
_print_rich(
432+
log_entry.get_prefix(),
433+
message,
434+
_get_color(VERBOSITY_COLOR.WARNING)
435+
)
431436
push_warning(message)
432437
_write_to_log_file(log_entry.get_entry())
433-
"info", "success":
434-
if verbosity >= VERBOSITY_LEVEL.INFO:
435-
print(log_entry.get_prefix() + message)
438+
"success":
439+
if _get_verbosity() >= VERBOSITY_LEVEL.INFO:
440+
_print_rich(
441+
log_entry.get_prefix(),
442+
message,
443+
_get_color(VERBOSITY_COLOR.SUCCESS)
444+
)
445+
_write_to_log_file(log_entry.get_entry())
446+
"info":
447+
if _get_verbosity() >= VERBOSITY_LEVEL.INFO:
448+
_print_rich(
449+
log_entry.get_prefix(),
450+
message,
451+
_get_color(VERBOSITY_COLOR.INFO)
452+
)
436453
_write_to_log_file(log_entry.get_entry())
437454
"debug":
438-
if verbosity >= VERBOSITY_LEVEL.DEBUG:
439-
print(log_entry.get_prefix() + message)
455+
if _get_verbosity() >= VERBOSITY_LEVEL.DEBUG:
456+
_print_rich(
457+
log_entry.get_prefix(),
458+
message,
459+
_get_color(VERBOSITY_COLOR.DEBUG),
460+
true if not ModLoaderStore else ModLoaderStore.ml_options.debug_bold
461+
)
440462
_write_to_log_file(log_entry.get_entry())
441463
"hint":
442-
if OS.has_feature("editor") and verbosity >= VERBOSITY_LEVEL.DEBUG:
443-
print_rich("[color=%s]%s[/color]" % [hint_color.to_html(false), log_entry.get_prefix() + message])
464+
if ModLoaderStore.has_feature.editor:
465+
if _get_verbosity() >= VERBOSITY_LEVEL.DEBUG:
466+
_print_rich(
467+
log_entry.get_prefix(),
468+
message,
469+
_get_color(VERBOSITY_COLOR.hint)
470+
)
471+
472+
473+
static func _is_mod_name_ignored(mod_log_name: String) -> bool:
474+
if not ModLoaderStore:
475+
return false
444476

477+
var ignored_mod_log_names := ModLoaderStore.ml_options.ignored_mod_names_in_log as Array
445478

446-
static func _is_mod_name_ignored(mod_name: String) -> bool:
447-
if ignored_mods.is_empty():
479+
# No ignored mod names
480+
if ignored_mod_log_names.size() == 0:
448481
return false
449482

450-
if mod_name in ignored_mods:
483+
# Directly match a full mod log name. ex: "ModLoader:Deprecated"
484+
if mod_log_name in ignored_mod_log_names:
451485
return true
452486

487+
# Match a mod log name with a wildcard. ex: "ModLoader:*"
488+
for ignored_mod_name in ignored_mod_log_names:
489+
if ignored_mod_name.ends_with("*"):
490+
if mod_log_name.begins_with(ignored_mod_name.trim_suffix("*")):
491+
return true
492+
493+
# No match
453494
return false
454495

496+
static func _get_color(verbosity: VERBOSITY_COLOR) -> Color:
497+
if not ModLoaderStore:
498+
return Color("#d4d4d4")
499+
500+
var color = ModLoaderStore.ml_options.get(
501+
"%s_color" % VERBOSITY_COLOR.keys()[verbosity].to_lower()
502+
)
503+
if color == null:
504+
return Color("#d4d4d4")
505+
506+
return color
507+
508+
static func _get_verbosity() -> int:
509+
if not ModLoaderStore:
510+
return VERBOSITY_LEVEL.DEBUG
511+
return ModLoaderStore.ml_options.log_level
455512

456513
static func _store_log(log_entry: ModLoaderLogEntry) -> void:
514+
# HACK: this makes logs from ModLoaderStore unable to be stored
515+
if not ModLoaderStore:
516+
return
457517
var existing_entry: ModLoaderLogEntry
458518

459519
# Store in all
460520
# If it's a new entry
461-
if not logged_messages.all.has(log_entry.get_md5()):
462-
logged_messages.all[log_entry.get_md5()] = log_entry
521+
if not ModLoaderStore.logged_messages.all.has(log_entry.get_md5()):
522+
ModLoaderStore.logged_messages.all[log_entry.get_md5()] = log_entry
463523
# If it's a existing entry
464524
else:
465-
existing_entry = logged_messages.all[log_entry.get_md5()]
525+
existing_entry = ModLoaderStore.logged_messages.all[log_entry.get_md5()]
466526
existing_entry.time = log_entry.time
467527
existing_entry.stack.push_back(log_entry)
468528

469529
# Store in by_mod
470530
# If the mod is not yet in "by_mod" init the entry
471-
if not logged_messages.by_mod.has(log_entry.mod_name):
472-
logged_messages.by_mod[log_entry.mod_name] = {}
531+
if not ModLoaderStore.logged_messages.by_mod.has(log_entry.mod_name):
532+
ModLoaderStore.logged_messages.by_mod[log_entry.mod_name] = {}
473533

474-
logged_messages.by_mod[log_entry.mod_name][log_entry.get_md5()] = log_entry if not existing_entry else existing_entry
534+
ModLoaderStore.logged_messages.by_mod[log_entry.mod_name][log_entry.get_md5()] = log_entry if not existing_entry else existing_entry
475535

476536
# Store in by_type
477-
logged_messages.by_type[log_entry.type.to_lower()][log_entry.get_md5()] = log_entry if not existing_entry else existing_entry
537+
ModLoaderStore.logged_messages.by_type[log_entry.type.to_lower()][log_entry.get_md5()] = log_entry if not existing_entry else existing_entry
478538

479539

480540
static func _is_logged_before(entry: ModLoaderLogEntry) -> bool:
481-
if not logged_messages.all.has(entry.get_md5()):
541+
if not ModLoaderStore.logged_messages.all.has(entry.get_md5()):
482542
return false
483543

484544
return true

addons/mod_loader/api/mod.gd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ const LOG_NAME := "ModLoader:Mod"
3838
static func install_script_extension(child_script_path: String) -> void:
3939
var mod_id: String = _ModLoaderPath.get_mod_dir(child_script_path)
4040
var mod_data: ModData = get_mod_data(mod_id)
41+
if mod_data == null:
42+
ModLoaderLog.warning('"%s" is not a valid mod id! Please ensure the supplied path is valid!' % mod_id, LOG_NAME)
43+
4144
if not ModLoaderStore.saved_extension_paths.has(mod_data.manifest.get_mod_id()):
4245
ModLoaderStore.saved_extension_paths[mod_data.manifest.get_mod_id()] = []
4346
ModLoaderStore.saved_extension_paths[mod_data.manifest.get_mod_id()].append(child_script_path)

addons/mod_loader/api/profile.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ static func _generate_mod_list_entry(mod_id: String, is_active: bool) -> Diction
350350
# Set the current_config if the mod has a config schema and is active
351351
if is_active and not ModLoaderConfig.get_config_schema(mod_id).is_empty():
352352
var current_config: ModConfig = ModLoaderStore.mod_data[mod_id].current_config
353-
if current_config and current_config.is_valid:
353+
if current_config and current_config.is_valid():
354354
# Set to the current_config name if valid
355355
mod_list_entry.current_config = current_config.name
356356
else:

addons/mod_loader/internal/dependency.gd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ static func check_dependencies(mod: ModData, is_required := true, dependency_cha
4949
_handle_missing_dependency(mod_id, dependency_id)
5050
# Flag the mod so it's not loaded later
5151
mod.is_loadable = false
52+
mod.is_active = false
5253
else:
5354
var dependency: ModData = ModLoaderStore.mod_data[dependency_id]
5455

addons/mod_loader/internal/file.gd

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ static func get_json_as_dict_from_zip(zip_path: String, file_path: String, is_fu
9999
for path in reader.get_files():
100100
if Array(path.rsplit("/", false, 1)).back() == file_path:
101101
full_path = path
102-
if not full_path:
102+
#if not full_path:
103+
if full_path.is_empty():
103104
ModLoaderLog.error("File was not found in zip at path %s" % [file_path], LOG_NAME)
104105
return {}
105106

@@ -194,11 +195,8 @@ static func file_exists_in_zip(zip_path: String, path: String) -> bool:
194195
var reader := zip_reader_open(zip_path)
195196
if not reader:
196197
return false
197-
198-
if _ModLoaderGodot.is_version_below(_ModLoaderGodot.ENGINE_VERSION_HEX_4_2_0):
199-
return reader.get_files().has(path.trim_prefix("res://"))
200-
else:
201-
return reader.file_exists(path.trim_prefix("res://"))
198+
199+
return reader.get_files().has(path.trim_prefix("res://"))
202200

203201

204202
static func get_mod_dir_name_in_zip(zip_path: String) -> String:

addons/mod_loader/internal/godot.gd

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ const AUTOLOAD_CONFIG_HELP_MSG := "To configure your autoloads, go to Project >
1212
const ENGINE_VERSION_HEX_4_2_2 := 0x040202
1313
const ENGINE_VERSION_HEX_4_2_0 := 0x040200
1414

15-
static var engine_version_hex: int = Engine.get_version_info().hex
16-
17-
1815
# Check autoload positions:
1916
# Ensure 1st autoload is `ModLoaderStore`, and 2nd is `ModLoader`.
2017
static func check_autoload_positions() -> void:
@@ -106,11 +103,3 @@ static func get_autoload_index(autoload_name: String) -> int:
106103
var autoload_index := autoloads.find(autoload_name)
107104

108105
return autoload_index
109-
110-
111-
static func is_version_below(version_hex: int) -> bool:
112-
return engine_version_hex < version_hex
113-
114-
115-
static func is_version_above(version_hex: int) -> bool:
116-
return engine_version_hex > version_hex

addons/mod_loader/internal/hooks.gd

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@ extends Object
88

99
const LOG_NAME := "ModLoader:Hooks"
1010

11-
static var any_mod_hooked := false
12-
13-
1411
## Internal ModLoader method. [br]
1512
## To add hooks from a mod use [method ModLoaderMod.add_hook].
1613
static func add_hook(mod_callable: Callable, script_path: String, method_name: String) -> void:
17-
any_mod_hooked = true
14+
ModLoaderStore.any_mod_hooked = true
1815
var hash := get_hook_hash(script_path, method_name)
1916
if not ModLoaderStore.modding_hooks.has(hash):
2017
ModLoaderStore.modding_hooks[hash] = []

0 commit comments

Comments
 (0)