using Godot; using System.Collections.Generic; using System.Collections.ObjectModel; public class GlobalModManager(string modPath = "user://mods") { public static GlobalModManager Instance { get; } = new(); private readonly Dictionary _mods = []; public ReadOnlyDictionary Mods => new(_mods); private readonly Dictionary _modList = []; public ReadOnlyDictionary ModList => new(_modList); private readonly string modPath = modPath; private static readonly Logging.Logger logger = Logging.GetLogger("GlobalMod"); public void SearchAllMods(bool isFlush = false) { if (isFlush) { _modList.Clear(); } if (!DirAccess.DirExistsAbsolute(modPath)) return; using var dir = DirAccess.Open(modPath); if (dir == null) return; dir.ListDirBegin(); string fileName = dir.GetNext(); while (!string.IsNullOrEmpty(fileName)) { string fullPath = $"{modPath}/{fileName}"; const string entryFileName = "main.lua"; if (dir.CurrentIsDir() && !fileName.StartsWith('.') && FileAccess.FileExists($"{fullPath}/{entryFileName}")) { _modList.Add($"{fullPath}/{entryFileName}", fullPath); } fileName = dir.GetNext(); } } public void LoadAllMods(bool isFlush = false) { if (isFlush) { _mods.Clear(); } foreach (var mod in _modList) { try { LoadMod(mod.Key, mod.Value); } catch (System.Exception e) { logger.Exception("Failed to load mod {0}", e, mod.Key); } } } public void ClearAllMods() { _mods.Clear(); } private void LoadMod(string filePath, string modPath) { string _filePath = ProjectSettings.GlobalizePath(filePath); string _modPath = ProjectSettings.GlobalizePath(modPath); _mods.Add(filePath, new LuaModManager(_filePath, _modPath)); } private static void SaveFile(string path, string content) { using var file = FileAccess.Open(path, FileAccess.ModeFlags.Write); file.StoreString(content); } private static string LoadFile(string path) { using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read); string content = file.GetAsText(); return content; } }