class_name ABGEntryBootService extends RefCounted const DEFAULT_REQUIRED_RESOURCES: Array[String] = [ "res://main.tscn", "res://entry/entry_shell.gd", "res://assets/backgrounds/p9_3_guild_hall.png", "res://assets/fonts/NotoSansSC.ttf", ] const DEFAULT_PREFERENCES_PATH := "user://aetherbound_guild_settings.json" const DEFAULT_SAVE_PATH := "user://aetherbound_guild_p10_3.json" var required_resources: Array = DEFAULT_REQUIRED_RESOURCES.duplicate() var preferences_path := DEFAULT_PREFERENCES_PATH var save_path := DEFAULT_SAVE_PATH var checks: Array[Dictionary] = [] var index := 0 var result: Dictionary = {} func begin() -> Dictionary: checks = [] for path in required_resources: checks.append({"kind": "resource", "path": path}) checks.append({"kind": "storage"}) checks.append({"kind": "preferences", "path": preferences_path}) checks.append({"kind": "save", "path": save_path}) index = 0 result = { "state": "running", "completed": 0, "total": checks.size(), "step": "resources", "code": "", } return result.duplicate(true) func verify_next() -> Dictionary: if checks.is_empty(): begin() if String(result.get("state", "")) != "running": return result.duplicate(true) if index >= checks.size(): result["state"] = "complete" result["step"] = "complete" return result.duplicate(true) var check: Dictionary = checks[index] var check_result := _run_check(check) if not check_result.ok: result = { "state": "error", "completed": index, "total": checks.size(), "step": String(check_result.step), "code": String(check_result.code), } return result.duplicate(true) index += 1 result["completed"] = index result["step"] = _next_step() if index >= checks.size(): result["state"] = "complete" result["step"] = "complete" return result.duplicate(true) func _run_check(check: Dictionary) -> Dictionary: match String(check.kind): "resource": var path := String(check.path) if not ResourceLoader.exists(path) or ResourceLoader.load(path) == null: return {"ok": false, "step": "resources", "code": "REQUIRED_RESOURCE_UNAVAILABLE"} "storage": var user_root := ProjectSettings.globalize_path("user://") if DirAccess.open(user_root) == null: return {"ok": false, "step": "storage", "code": "LOCAL_STORAGE_UNAVAILABLE"} "preferences": if FileAccess.file_exists(String(check.path)): var preferences_parser := JSON.new() var preferences_error := preferences_parser.parse(FileAccess.get_file_as_string(String(check.path))) if preferences_error != OK or not preferences_parser.data is Dictionary: return {"ok": false, "step": "preferences", "code": "SETTINGS_FILE_INVALID"} "save": if FileAccess.file_exists(String(check.path)): var save_parser := JSON.new() var save_error := save_parser.parse(FileAccess.get_file_as_string(String(check.path))) var parsed = save_parser.data if save_error != OK or not parsed is Dictionary or not parsed.has("save_kind") or not parsed.has("save_version"): return {"ok": false, "step": "save", "code": "SAVE_REVIEW_REQUIRED"} return {"ok": true, "step": String(check.kind), "code": ""} func _next_step() -> String: if index >= checks.size(): return "complete" return String(checks[index].kind)