Example #1
0
 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);
 }
Example #2
0
 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);
 }
Example #3
0
        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);
                    }
                }
            }
        }
Example #4
0
        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));
        }
Example #5
0
        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));
        }
Example #6
0
 public Task <GenericModFile[]> CheckConflictsAsync([NotNull] GenericMod mod)
 {
     return(Task.Run(() => CheckConflicts(mod).ToArray()));
 }