Skip to content

Commit 3d906d8

Browse files
committed
feat: 🚧 wip: configs loading
1 parent bf590d8 commit 3d906d8

File tree

4 files changed

+60
-57
lines changed

4 files changed

+60
-57
lines changed

addons/mod_loader/api/config.gd

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ static func get_mod_config(mod_id: String) -> Dictionary:
2323
return config_data
2424

2525

26-
static func is_mod_config_data_valid(config_data: ModConfig):
27-
var json_schema := JSONSchema.new()
28-
var error := json_schema.validate(config_data.get_data_as_string(), config_data.get_schema_as_string())
29-
30-
3126
static func update_mod_config(mod_id: String, data: Dictionary) -> void:
3227
# Update the config held in memory
3328
ModLoaderStore.mod_data[mod_id].config.merge(data, true)

addons/mod_loader/classes/mod_config.gd

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ class_name ModConfig
22
extends Resource
33

44

5+
const LOG_NAME := "ModLoader:ModConfig"
6+
57
var mod_id: String
68
var schema: Dictionary
79
var data: Dictionary
@@ -14,3 +16,14 @@ func get_data_as_string() -> String:
1416

1517
func get_schema_as_string() -> String:
1618
return JSON.print(schema)
19+
20+
21+
func is_valid() -> bool:
22+
var json_schema := JSONSchema.new()
23+
var error := json_schema.validate(get_data_as_string(), get_schema_as_string())
24+
25+
if not error == "":
26+
ModLoaderLog.fatal(error, LOG_NAME)
27+
return false
28+
29+
return true

addons/mod_loader/classes/mod_manifest.gd

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,52 @@ func to_json() -> String:
195195
}, "\t")
196196

197197

198-
func is_config_valid(config_data: String, config_schema: String) -> bool:
199-
var json_schema := JSONSchema.new()
200-
var error := json_schema.validate(config_data, config_schema)
201-
202-
if not error == "":
203-
ModLoaderLog.fatal(error, LOG_NAME)
204-
return false
205-
206-
return true
198+
func load_mod_config_defaults() -> void:
199+
var config := ModConfig.new()
200+
config.save_path = _ModLoaderPath.get_path_to_configs().plus_file("%s.json" % get_mod_id())
201+
config.schema = config_schema
202+
config.mod_id = get_mod_id()
203+
204+
# Check if there is no default.json file in the mods config directory
205+
if not _ModLoaderFile.file_exists(config.save_path):
206+
# Generate config_default based on the default values in config_schema
207+
config.data = _generate_default_config_from_schema(config.schema.properties)
208+
# Save the default config to disk
209+
_ModLoaderFile.save_dictionary_to_json_file(config.data, config.save_path)
210+
else:
211+
# If there is a default.json just load that
212+
config.data = _ModLoaderFile.get_json_as_dict(config.save_path)
213+
214+
# Validate the config defaults
215+
config.is_valid()
216+
217+
218+
# Recursively searches for default values
219+
func _generate_default_config_from_schema(property: Dictionary, current_prop := {}) -> Dictionary:
220+
# Exit function if property is empty
221+
if property.empty():
222+
return current_prop
223+
224+
for property_key in property.keys():
225+
var prop = property[property_key]
226+
227+
# If this property contains nested properties, we recursively call this function
228+
if "properties" in prop:
229+
current_prop[property_key] = {}
230+
_generate_default_config_from_schema(prop.properties, current_prop[property_key])
231+
# Return early here because a object will not have a "default" key
232+
return current_prop
233+
234+
# If this property contains a default value, add it to the global config_defaults dictionary
235+
if "default" in prop:
236+
# Initialize the current_key if it is missing in config_defaults
237+
if not current_prop.has(property_key):
238+
current_prop[property_key] = {}
239+
240+
# Add the default value to the config_defaults
241+
current_prop[property_key] = prop.default
242+
243+
return current_prop
207244

208245

209246
# Handles deprecation of the single string value in the compatible_mod_loader_version.

addons/mod_loader/mod_loader.gd

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func _load_mods() -> void:
9999
var mod: ModData = ModLoaderStore.mod_data[dir_name]
100100
mod.load_manifest()
101101
if mod.manifest.get("config_schema") and not mod.manifest.config_schema.empty():
102-
mod.load_mod_config()
102+
mod.load_configs()
103103

104104
ModLoaderLog.success("DONE: Loaded all meta data", LOG_NAME)
105105

@@ -360,48 +360,6 @@ func _setup_mods() -> int:
360360
return unpacked_mods_count
361361

362362

363-
# Load mod config JSONs from res://configs
364-
func _load_mod_configs() -> void:
365-
var found_configs_count := 0
366-
var configs_path := _ModLoaderPath.get_path_to_configs()
367-
368-
for dir_name in ModLoaderStore.mod_data:
369-
var json_path := configs_path.plus_file(dir_name + ".json")
370-
var mod_config := _ModLoaderFile.get_json_as_dict(json_path)
371-
372-
ModLoaderLog.debug("Config JSON: Looking for config at path: %s" % json_path, LOG_NAME)
373-
374-
if mod_config.size() > 0:
375-
found_configs_count += 1
376-
377-
ModLoaderLog.info("Config JSON: Found a config file: '%s'" % json_path, LOG_NAME)
378-
ModLoaderLog.debug_json_print("Config JSON: File data: ", mod_config, LOG_NAME)
379-
380-
# Check `load_from` option. This lets you specify the name of a
381-
# different JSON file to load your config from. Must be in the same
382-
# dir. Means you can have multiple config files for a single mod
383-
# and switch between them quickly. Should include ".json" extension.
384-
# Ignored if the filename matches the mod ID, or is empty
385-
if mod_config.has("load_from"):
386-
var new_path: String = mod_config.load_from
387-
if not new_path == "" and not new_path == str(dir_name, ".json"):
388-
ModLoaderLog.info("Config JSON: Following load_from path: %s" % new_path, LOG_NAME)
389-
var new_config := _ModLoaderFile.get_json_as_dict(configs_path + new_path)
390-
if new_config.size() > 0:
391-
mod_config = new_config
392-
ModLoaderLog.info("Config JSON: Loaded from custom json: %s" % new_path, LOG_NAME)
393-
ModLoaderLog.debug_json_print("Config JSON: File data:", mod_config, LOG_NAME)
394-
else:
395-
ModLoaderLog.error("Config JSON: ERROR - Could not load data via `load_from` for %s, at path: %s" % [dir_name, new_path], LOG_NAME)
396-
397-
ModLoaderStore.mod_data[dir_name].config = mod_config
398-
399-
if found_configs_count > 0:
400-
ModLoaderLog.success("Config JSON: Loaded %s config(s)" % found_configs_count, LOG_NAME)
401-
else:
402-
ModLoaderLog.info("Config JSON: No mod configs were found", LOG_NAME)
403-
404-
405363
# Add a mod's data to mod_data.
406364
# The mod_folder_path is just the folder name that was added to UNPACKED_DIR,
407365
# which depends on the name used in a given mod ZIP (eg "mods-unpacked/Folder-Name")

0 commit comments

Comments
 (0)