Skip to content

Commit 23dddf2

Browse files
committed
feat: ✨ added zip_name and zip_path to ModData
1 parent 773ea27 commit 23dddf2

File tree

5 files changed

+72
-40
lines changed

5 files changed

+72
-40
lines changed

addons/mod_loader/internal/file.gd

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,20 @@ static func _get_json_string_as_dict(string: String) -> Dictionary:
4444

4545

4646
# Load the mod ZIP from the provided directory
47-
static func load_zips_in_folder(folder_path: String) -> int:
48-
var temp_zipped_mods_count := 0
47+
static func load_zips_in_folder(folder_path: String) -> Dictionary:
48+
var zip_data := {}
4949

5050
var mod_dir := Directory.new()
5151
var mod_dir_open_error := mod_dir.open(folder_path)
5252
if not mod_dir_open_error == OK:
5353
ModLoaderLog.error("Can't open mod folder %s (Error: %s)" % [folder_path, mod_dir_open_error], LOG_NAME)
54-
return -1
54+
return {}
5555
var mod_dir_listdir_error := mod_dir.list_dir_begin()
5656
if not mod_dir_listdir_error == OK:
5757
ModLoaderLog.error("Can't read mod folder %s (Error: %s)" % [folder_path, mod_dir_listdir_error], LOG_NAME)
58-
return -1
58+
return {}
59+
60+
5961

6062
# Get all zip folders inside the game mod folder
6163
while true:
@@ -76,9 +78,25 @@ static func load_zips_in_folder(folder_path: String) -> int:
7678
# Go to the next file
7779
continue
7880

79-
var mod_folder_path := folder_path.plus_file(mod_zip_file_name)
80-
var mod_folder_global_path := ProjectSettings.globalize_path(mod_folder_path)
81-
var is_mod_loaded_successfully := ProjectSettings.load_resource_pack(mod_folder_global_path, false)
81+
var mod_zip_path := folder_path.plus_file(mod_zip_file_name)
82+
var mod_zip_global_path := ProjectSettings.globalize_path(mod_zip_path)
83+
var is_mod_loaded_successfully := ProjectSettings.load_resource_pack(mod_zip_global_path, false)
84+
85+
# Get the current directories inside UNPACKED_DIR
86+
# This array is used to determine which directory is new
87+
var current_mod_dirs := _ModLoaderPath.get_dir_paths_in_dir(_ModLoaderPath.get_unpacked_mods_dir_path())
88+
# Create a backup to reference when the next mod is loaded
89+
var current_mod_dirs_backup := current_mod_dirs.duplicate()
90+
91+
# Remove all directory paths that existed before, leaving only the one added last
92+
for previous_mod_dir in ModLoaderStore.previous_mod_dirs:
93+
current_mod_dirs.erase(previous_mod_dir)
94+
95+
# The key is the mod_id of the latest loaded mod, and the value is the path to the zip file
96+
zip_data[current_mod_dirs[0].get_slice("/", 3)] = mod_zip_global_path
97+
98+
# Update previous_mod_dirs in ModLoaderStore to use for the next mod
99+
ModLoaderStore.previous_mod_dirs = current_mod_dirs_backup
82100

83101
# Notifies developer of an issue with Godot, where using `load_resource_pack`
84102
# in the editor WIPES the entire virtual res:// directory the first time you
@@ -94,7 +112,7 @@ static func load_zips_in_folder(folder_path: String) -> int:
94112
"Please unpack your mod ZIPs instead, and add them to ", _ModLoaderPath.get_unpacked_mods_dir_path()), LOG_NAME)
95113
ModLoaderStore.has_shown_editor_zips_warning = true
96114

97-
ModLoaderLog.debug("Found mod ZIP: %s" % mod_folder_global_path, LOG_NAME)
115+
ModLoaderLog.debug("Found mod ZIP: %s" % mod_zip_global_path, LOG_NAME)
98116

99117
# If there was an error loading the mod zip file
100118
if not is_mod_loaded_successfully:
@@ -104,11 +122,10 @@ static func load_zips_in_folder(folder_path: String) -> int:
104122

105123
# Mod successfully loaded!
106124
ModLoaderLog.success("%s loaded." % mod_zip_file_name, LOG_NAME)
107-
temp_zipped_mods_count += 1
108125

109126
mod_dir.list_dir_end()
110127

111-
return temp_zipped_mods_count
128+
return zip_data
112129

113130

114131
# Save Data

addons/mod_loader/internal/third_party/steam.gd

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ const LOG_NAME := "ModLoader:ThirdParty:Steam"
99
# Load mod ZIPs from Steam workshop folders. Uses 2 loops: One for each
1010
# workshop item's folder, with another inside that which loops over the ZIPs
1111
# inside each workshop item's folder
12-
static func load_steam_workshop_zips() -> int:
13-
var temp_zipped_mods_count := 0
12+
static func load_steam_workshop_zips() -> Dictionary:
13+
var zip_data := {}
1414
var workshop_folder_path := _get_path_to_workshop()
1515

1616
ModLoaderLog.info("Checking workshop items, with path: \"%s\"" % workshop_folder_path, LOG_NAME)
@@ -19,11 +19,11 @@ static func load_steam_workshop_zips() -> int:
1919
var workshop_dir_open_error := workshop_dir.open(workshop_folder_path)
2020
if not workshop_dir_open_error == OK:
2121
ModLoaderLog.error("Can't open workshop folder %s (Error: %s)" % [workshop_folder_path, workshop_dir_open_error], LOG_NAME)
22-
return -1
22+
return {}
2323
var workshop_dir_listdir_error := workshop_dir.list_dir_begin()
2424
if not workshop_dir_listdir_error == OK:
2525
ModLoaderLog.error("Can't read workshop folder %s (Error: %s)" % [workshop_folder_path, workshop_dir_listdir_error], LOG_NAME)
26-
return -1
26+
return {}
2727

2828
# Loop 1: Workshop folders
2929
while true:
@@ -42,11 +42,11 @@ static func load_steam_workshop_zips() -> int:
4242
continue
4343

4444
# Loop 2: ZIPs inside the workshop folders
45-
temp_zipped_mods_count += _ModLoaderFile.load_zips_in_folder(ProjectSettings.globalize_path(item_path))
45+
zip_data.merge(_ModLoaderFile.load_zips_in_folder(ProjectSettings.globalize_path(item_path)))
4646

4747
workshop_dir.list_dir_end()
4848

49-
return temp_zipped_mods_count
49+
return zip_data
5050

5151

5252
# Get the path to the Steam workshop folder. Only works for Steam games, as it

addons/mod_loader/mod_loader.gd

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,20 @@ func _exit_tree() -> void:
8787
func _load_mods() -> void:
8888
# Loop over "res://mods" and add any mod zips to the unpacked virtual
8989
# directory (UNPACKED_DIR)
90-
var unzipped_mods := _load_mod_zips()
91-
if unzipped_mods > 0:
92-
ModLoaderLog.success("DONE: Loaded %s mod files into the virtual filesystem" % unzipped_mods, LOG_NAME)
93-
else:
90+
var zip_data := _load_mod_zips()
91+
92+
if zip_data.empty():
9493
ModLoaderLog.info("No zipped mods found", LOG_NAME)
94+
else:
95+
ModLoaderLog.success("DONE: Loaded %s mod files into the virtual filesystem" % zip_data.size(), LOG_NAME)
96+
97+
# Initializes the mod_data dictionary if zipped mods are loaded.
98+
# If mods are unpacked in the "mods-unpacked" directory,
99+
# mod_data is initialized in the _setup_mods() function.
100+
for mod_id in zip_data.keys():
101+
var zip_path: String = zip_data[mod_id]
102+
_init_mod_data(mod_id, zip_path)
103+
95104

96105
# Loop over UNPACKED_DIR. This triggers _init_mod_data for each mod
97106
# directory, which adds their data to mod_data.
@@ -213,19 +222,21 @@ func _check_autoload_positions() -> void:
213222

214223
# Loop over "res://mods" and add any mod zips to the unpacked virtual directory
215224
# (UNPACKED_DIR)
216-
func _load_mod_zips() -> int:
217-
var zipped_mods_count := 0
225+
func _load_mod_zips() -> Dictionary:
226+
var zip_data := {}
218227

219228
if not ModLoaderStore.ml_options.steam_workshop_enabled:
220229
var mods_folder_path := _ModLoaderPath.get_path_to_mods()
221230

222231
# If we're not using Steam workshop, just loop over the mod ZIPs.
223-
zipped_mods_count += _ModLoaderFile.load_zips_in_folder(mods_folder_path)
232+
var loaded_zip_data := _ModLoaderFile.load_zips_in_folder(mods_folder_path)
233+
zip_data.merge(loaded_zip_data)
224234
else:
225235
# If we're using Steam workshop, loop over the workshop item directories
226-
zipped_mods_count += _ModLoaderSteam.load_steam_workshop_zips()
236+
var loaded_workshop_zip_data := _ModLoaderSteam.load_steam_workshop_zips()
237+
zip_data.merge(loaded_workshop_zip_data)
227238

228-
return zipped_mods_count
239+
return zip_data
229240

230241

231242
# Loop over UNPACKED_DIR and triggers `_init_mod_data` for each mod directory,
@@ -276,19 +287,20 @@ func _setup_mods() -> int:
276287
# Add a mod's data to mod_data.
277288
# The mod_folder_path is just the folder name that was added to UNPACKED_DIR,
278289
# which depends on the name used in a given mod ZIP (eg "mods-unpacked/Folder-Name")
279-
func _init_mod_data(mod_folder_path: String) -> void:
280-
# The file name should be a valid mod id
281-
var dir_name := _ModLoaderPath.get_file_name_from_path(mod_folder_path, false, true)
282-
283-
# Path to the mod in UNPACKED_DIR (eg "res://mods-unpacked/My-Mod")
284-
var local_mod_path := _ModLoaderPath.get_unpacked_mods_dir_path().plus_file(dir_name)
285-
286-
var mod := ModData.new(local_mod_path)
287-
mod.dir_name = dir_name
290+
func _init_mod_data(mod_id: String, zip_path := "") -> void:
291+
# Path to the mod in UNPACKED_DIR (eg "res://mods-unpacked/My-Mod")
292+
var local_mod_path := _ModLoaderPath.get_unpacked_mods_dir_path().plus_file(mod_id)
293+
294+
var mod := ModData.new()
295+
if not zip_path.empty():
296+
mod.zip_name = _ModLoaderPath.get_file_name_from_path(zip_path)
297+
mod.zip_path = zip_path
298+
mod.dir_path = local_mod_path
299+
mod.dir_name = mod_id
288300
var mod_overwrites_path := mod.get_optional_mod_file_path(ModData.optional_mod_files.OVERWRITES)
289301
mod.is_overwrite = _ModLoaderFile.file_exists(mod_overwrites_path)
290-
mod.is_locked = true if dir_name in ModLoaderStore.ml_options.locked_mods else false
291-
ModLoaderStore.mod_data[dir_name] = mod
302+
mod.is_locked = true if mod_id in ModLoaderStore.ml_options.locked_mods else false
303+
ModLoaderStore.mod_data[mod_id] = mod
292304

293305
# Get the mod file paths
294306
# Note: This was needed in the original version of this script, but it's

addons/mod_loader/mod_loader_store.gd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ var mod_missing_dependencies := {}
4444
# Helps to decide whether a script extension should go through the _ModLoaderScriptExtension.handle_script_extensions() process
4545
var is_initializing := true
4646

47+
# Used when loading mod zips to determine which mod zip corresponds to which mod directory in the UNPACKED_DIR.
48+
var previous_mod_dirs := []
49+
4750
# Store all extenders paths
4851
var script_extensions := []
4952

addons/mod_loader/resources/mod_data.gd

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ enum optional_mod_files {
2323
OVERWRITES
2424
}
2525

26+
# Name of the Mod's zip file
27+
var zip_name := ""
28+
# Path to the Mod's zip file
29+
var zip_path := ""
2630
# Directory of the mod. Has to be identical to [method ModManifest.get_mod_id]
2731
var dir_name := ""
2832
# Path to the Mod's Directory
@@ -45,10 +49,6 @@ var current_config: ModConfig setget _set_current_config
4549
var file_paths: PoolStringArray = []
4650

4751

48-
func _init(_dir_path: String) -> void:
49-
dir_path = _dir_path
50-
51-
5252
# Load meta data from a mod's manifest.json file
5353
func load_manifest() -> void:
5454
if not _has_required_files():

0 commit comments

Comments
 (0)