// Delete a mod by its index. The event is invoked before the mod is removed from the list. // Deletes from filesystem as well as from internal data. // Updates indices of later mods. public void DeleteMod(int idx) { var mod = this[idx]; if (Directory.Exists(mod.ModPath.FullName)) { try { Directory.Delete(mod.ModPath.FullName, true); PluginLog.Debug("Deleted directory {Directory:l} for {Name:l}.", mod.ModPath.FullName, mod.Name); } catch (Exception e) { PluginLog.Error($"Could not delete the mod {mod.ModPath.Name}:\n{e}"); } } ModPathChanged.Invoke(ModPathChangeType.Deleted, mod, mod.ModPath, null); _mods.RemoveAt(idx); foreach (var remainingMod in _mods.Skip(idx)) { --remainingMod.Index; } PluginLog.Debug("Deleted mod {Name:l}.", mod.Name); }
// Rename/Move a mod directory. // Updates all collection settings and sort order settings. public void MoveModDirectory(int idx, string newName) { var mod = this[idx]; var oldName = mod.Name; var oldDirectory = mod.ModPath; switch (NewDirectoryValid(oldDirectory.Name, newName, out var dir)) { case NewDirectoryState.NonExisting: // Nothing to do break; case NewDirectoryState.ExistsEmpty: try { Directory.Delete(dir !.FullName); } catch (Exception e) { PluginLog.Error($"Could not delete empty directory {dir!.FullName} to move {mod.Name} to it:\n{e}"); return; } break; // Should be caught beforehand. case NewDirectoryState.ExistsNonEmpty: case NewDirectoryState.ExistsAsFile: case NewDirectoryState.ContainsInvalidSymbols: // Nothing to do at all. case NewDirectoryState.Identical: default: return; } try { Directory.Move(oldDirectory.FullName, dir !.FullName); } catch (Exception e) { PluginLog.Error($"Could not move {mod.Name} from {oldDirectory.Name} to {dir!.Name}:\n{e}"); return; } dir.Refresh(); mod.ModPath = dir; if (!mod.Reload(out var metaChange)) { PluginLog.Error($"Error reloading moved mod {mod.Name}."); return; } ModPathChanged.Invoke(ModPathChangeType.Moved, mod, oldDirectory, BasePath); if (metaChange != MetaChangeType.None) { ModMetaChanged?.Invoke(metaChange, mod, oldName); } }
// Load a new mod and add it to the manager if successful. public void AddMod(DirectoryInfo modFolder) { if (_mods.Any(m => m.ModPath.Name == modFolder.Name)) { return; } var mod = LoadMod(modFolder); if (mod == null) { return; } mod.Index = _mods.Count; _mods.Add(mod); ModPathChanged.Invoke(ModPathChangeType.Added, mod, null, mod.ModPath); PluginLog.Debug("Added new mod {Name:l} from {Directory:l}.", mod.Name, modFolder.FullName); }
// Reload a mod without changing its base directory. // If the base directory does not exist anymore, the mod will be deleted. public void ReloadMod(int idx) { var mod = this[idx]; var oldName = mod.Name; ModPathChanged.Invoke(ModPathChangeType.StartingReload, mod, mod.ModPath, mod.ModPath); if (!mod.Reload(out var metaChange)) { PluginLog.Warning(mod.Name.Length == 0 ? $"Reloading mod {oldName} has failed, new name is empty. Deleting instead." : $"Reloading mod {oldName} failed, {mod.ModPath.FullName} does not exist anymore or it ha. Deleting instead."); DeleteMod(idx); return; } ModPathChanged.Invoke(ModPathChangeType.Reloaded, mod, mod.ModPath, mod.ModPath); if (metaChange != MetaChangeType.None) { ModMetaChanged?.Invoke(metaChange, mod, oldName); } }