public void RenameMod(GenericMod mod, string newLocation) { if (mod.IsEnabled) { throw new InformativeException("Can’t rename mod", "Mod should be disabled first."); } _busy.Delay(() => Directory.Move(mod.ModDirectory, newLocation), 300, true); ScanMods(true); }
public void DeleteMod(GenericMod mod) { if (mod.IsEnabled) { throw new InformativeException("Can’t delete mod", "Mod should be disabled first."); } _busy.Delay(() => FileUtils.Recycle(mod.ModDirectory), 300, true); ScanMods(true); }
private IEnumerable <GenericModFile> CheckConflicts([NotNull] GenericMod mod) { if (mod.IsEnabled) { yield break; } var modFiles = mod.Files; foreach (var enabled in Mods.Where(x => x.IsEnabled)) { var enabledFiles = enabled.Files; foreach (var file in modFiles) { var conflict = enabledFiles.FirstOrDefault(x => x.Destination == file.Destination); if (conflict != null) { yield return(conflict); } } } }
public Task DisableAsync([NotNull] GenericMod mod, IProgress <Tuple <string, double?> > progress = null, CancellationToken cancellation = default(CancellationToken)) { if (!mod.IsEnabled) { throw new InformativeException("Can’t disable mod", "Mod is already disabled."); } return(_busy.Delay(() => Task.Run(() => _operationBusy.Do(() => { Debug($"Disabling {mod.DisplayName}…"); // var dependants = Mods.Where(x => x.DependsOn?.Contains(mod.DisplayName) == true).ToList(); if (mod.DependsOn?.Length > 0) { throw new InformativeException("Can’t disable mod", $"“{mod.DisplayName}” cannot be disabled as {mod.DependsOn.Select(x => $"“{x}”").JoinToReadableString()} has overwritten files and must be removed first."); } var iniFile = new IniFile(ConfigFilename, IniFileMode.SquareBracketsWithin); iniFile["MODS"].Remove(mod.DisplayName); var dependancies = iniFile["DEPENDANCIES"]; foreach (var dependant in dependancies.Select(x => new { x.Key, Values = x.Value.Split(new[] { '"' }, StringSplitOptions.RemoveEmptyEntries) }).Where(x => x.Values.ArrayContains(mod.DisplayName)).ToList()) { dependancies.SetGenericModDependancies(dependant.Key, dependant.Values.ApartFrom(mod.DisplayName)); } SaveApplyOrder(iniFile, true); var installationLog = GetInstallationLogFilename(ModsDirectory, mod.DisplayName); Debug($"Installation log: {installationLog}"); if (!File.Exists(installationLog)) { throw new InformativeException("Can’t disable mod", "Mod is already disabled."); } var lines = File.ReadAllLines(installationLog); Debug($"Lines in log: {lines.Length}"); File.Delete(installationLog); for (var i = 0; i < lines.Length; i++) { var line = lines[i]; Debug($"Line #{i + 1}: {line}"); if (cancellation.IsCancellationRequested) { return; } progress?.Report(Tuple.Create(line, (double?)(0.001 + 0.998 * i / lines.Length))); try { var backup = GetBackupFilename(ModsDirectory, mod.DisplayName, line); var destination = Path.Combine(RootDirectory, line); Debug($"Backup: {backup}"); Debug($"Destination: {destination}"); if (File.Exists(destination)) { Debug("Removing existing destination…"); File.Delete(destination); } if (File.Exists(backup)) { Debug("Restoring existing backup…"); FileUtils.EnsureFileDirectoryExists(destination); File.Move(backup, destination); DeleteIfEmpty(Path.GetDirectoryName(backup)); } else { DeleteIfEmpty(Path.GetDirectoryName(destination)); } } catch (Exception e) { Logging.Warning(e); } } })), 300, true)); }
public Task EnableAsync([NotNull] GenericMod mod, IProgress <Tuple <string, double?> > progress = null, CancellationToken cancellation = default) { if (mod.IsEnabled) { throw new InformativeException("Can’t enable mod", "Mod is already enabled."); } return(_busy.Delay(() => Task.Run(() => _operationBusy.Do(() => { Debug($"Enabling {mod.DisplayName}…"); var iniFile = new IniFile(ConfigFilename, IniFileMode.SquareBracketsWithin); iniFile["MODS"].Set(mod.DisplayName, int.MaxValue); var dependancies = iniFile["DEPENDANCIES"]; foreach (var dependant in CheckConflicts(mod).Select(x => x.ModName).Distinct()) { var current = dependancies.GetGenericModDependancies(dependant); if (current?.ArrayContains(mod.DisplayName) == true) { continue; } dependancies.SetGenericModDependancies(dependant, (current ?? new string[0]).Append(mod.DisplayName)); } SaveApplyOrder(iniFile, true); var installationLog = GetInstallationLogFilename(ModsDirectory, mod.DisplayName); Debug($"Installation log: {installationLog}"); if (File.Exists(installationLog)) { throw new InformativeException("Can’t enable mod", "Mod is already enabled."); } using (var writer = new StreamWriter(installationLog, false)) { var files = mod.Files; for (var i = 0; i < files.Length; i++) { var file = files[i]; if (file.RelativeName.EndsWith(".jsgme", StringComparison.OrdinalIgnoreCase)) { Debug($"File, src={file.Source}, ignore as description"); continue; } Debug($"File, src={file.Source}, dst={file.Destination})"); if (cancellation.IsCancellationRequested) { return; } progress?.Report(Tuple.Create(file.RelativeName, (double?)(0.001 + 0.998 * i / files.Length))); try { if (File.Exists(file.Destination)) { Debug($"Already exists, moving to {file.Backup}"); FileUtils.EnsureFileDirectoryExists(file.Backup); File.Move(file.Destination, file.Backup); } if (file.Source != null) { FileUtils.EnsureFileDirectoryExists(file.Destination); Debug($"Copying to {file.Destination}"); if (_useHardLinks) { FileUtils.HardLinkOrCopy(file.Source, file.Destination, true); } else { File.Copy(file.Source, file.Destination, true); } } writer.WriteLine(file.RelativeName); } catch (Exception e) { Logging.Warning(e); } } } })), 300, true)); }
public Task <GenericModFile[]> CheckConflictsAsync([NotNull] GenericMod mod) { return(Task.Run(() => CheckConflicts(mod).ToArray())); }