private void OnShown(object sender, EventArgs e)
        {
            DialogResult = DialogResult.OK;

            int modCount = mods.Count;
            int modIndex = 0;

            SetTaskCount(modCount);

            CancellationToken token = tokenSource.Token;
            var generator           = new ModManifestGenerator();

            void hashStart(object o, FileHashEventArgs args)
            {
                args.Cancel = token.IsCancellationRequested;
                SetStep($"Checking file {args.FileIndex}/{args.FileCount}: {args.FileName}");
                SetProgress(args.FileIndex / (double)args.FileCount);
            }

            void hashEnd(object o, FileHashEventArgs args)
            {
                args.Cancel = token.IsCancellationRequested;
            }

            generator.FileHashStart += hashStart;
            generator.FileHashEnd   += hashEnd;

            using (var task = new Task(() =>
            {
                foreach (Tuple <string, ModInfo> i in mods)
                {
                    string path = Path.Combine("mods", i.Item1);
                    ModInfo info = i.Item2;

                    SetTaskAndStep($"Verifying mod {++modIndex}/{modCount}: {info.Name}",
                                   "Loading local manifest...");

                    List <ModManifest> local = ModManifest.FromFile(Path.Combine(path, "mod.manifest"));
                    List <ModManifestDiff> diff = generator.Verify(path, local);

                    if (diff?.Any(x => x.State != ModManifestState.Unchanged) == true)
                    {
                        Failed.Add(new Tuple <string, ModInfo, List <ModManifestDiff> >(i.Item1, info, diff));
                    }

                    NextTask();
                }
            }))
            {
                task.Start();

                while (!task.IsCompleted && !task.IsCanceled)
                {
                    Application.DoEvents();
                }

                task.Wait(token);
            }
        }
        private void OnShown(object sender, EventArgs eventArgs)
        {
            DialogResult = DialogResult.OK;

            SetTaskCount(1);
            SetProgress(1);

            CancellationToken token = tokenSource.Token;

            DialogResult result;

            do
            {
                result = DialogResult.Cancel;

                try
                {
                    // poor man's await Task.Run (not available in .net 4.0)
                    using (var task = new Task(() =>
                    {
                        string newManPath = Path.Combine(updatePath, "loader.manifest");
                        string oldManPath = "loader.manifest";

                        SetTaskAndStep("Parsing manifest...");
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }

                        List <ModManifestEntry> newManifest = ModManifest.FromFile(newManPath);

                        SetTaskAndStep("Applying manifest...");
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }

                        if (File.Exists(oldManPath))
                        {
                            List <ModManifestEntry> oldManifest = ModManifest.FromFile(oldManPath);
                            List <string> oldFiles = oldManifest.Except(newManifest)
                                                     .Select(x => x.FilePath)
                                                     .ToList();

                            foreach (string file in oldFiles)
                            {
                                if (File.Exists(file))
                                {
                                    File.Delete(file);
                                }
                            }

                            RemoveEmptyDirectories(oldManifest, newManifest);
                        }

                        foreach (ModManifestEntry file in newManifest)
                        {
                            string dir = Path.GetDirectoryName(file.FilePath);
                            if (!string.IsNullOrEmpty(dir))
                            {
                                string newDir = dir;
                                if (!Directory.Exists(newDir))
                                {
                                    Directory.CreateDirectory(newDir);
                                }
                            }

                            string dest = file.FilePath;

                            if (File.Exists(dest))
                            {
                                File.Delete(dest);
                            }

                            File.Copy(Path.Combine(updatePath, file.FilePath), dest);
                        }

                        File.Copy(newManPath, oldManPath, true);

                        Process.Start(Path.GetFileName(Application.ExecutablePath), $"cleanupdate \"{updatePath}\"");
                    }, token))
                    {
                        task.Start();

                        while (!task.IsCompleted && !task.IsCanceled)
                        {
                            Application.DoEvents();
                        }

                        task.Wait(token);
                    }
                }
                catch (AggregateException ae)
                {
                    ae.Handle(ex =>
                    {
                        result = MessageBox.Show(this, $"Failed to update:\r\n{ex.Message}",
                                                 "Update Failed", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
                        return(true);
                    });
                }
            } while (result == DialogResult.Retry);

            Close();
        }
Esempio n. 3
0
        private void uninstallToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show(this, "This will uninstall all selected mods."
                                                  + "\n\nAre you sure you wish to continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

            if (result != DialogResult.Yes)
            {
                return;
            }

            result = MessageBox.Show(this, "Would you like to keep mod user data where possible? (Save files, config files, etc)",
                                     "User Data", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

            if (result == DialogResult.Cancel)
            {
                return;
            }

            foreach (ListViewItem item in modListView.SelectedItems)
            {
                var dir     = (string)item.Tag;
                var modDir  = Path.Combine("mods", dir);
                var manpath = Path.Combine(modDir, "mod.manifest");

                try
                {
                    if (result == DialogResult.Yes && File.Exists(manpath))
                    {
                        List <ModManifest> manifest = ModManifest.FromFile(manpath);
                        foreach (var entry in manifest)
                        {
                            var path = Path.Combine(modDir, entry.FilePath);
                            if (File.Exists(path))
                            {
                                File.Delete(path);
                            }
                        }

                        File.Delete(manpath);
                        var version = Path.Combine(modDir, "mod.version");
                        if (File.Exists(version))
                        {
                            File.Delete(version);
                        }
                    }
                    else
                    {
                        if (result == DialogResult.Yes)
                        {
                            var retain = MessageBox.Show(this, $"The mod \"{ mods[dir].Name }\" (\"mods\\{ dir }\") does not have a manifest, so mod user data cannot be retained."
                                                         + " Do you want to uninstall it anyway?", "Cannot Retain User Data", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

                            if (retain == DialogResult.No)
                            {
                                continue;
                            }
                        }

                        Directory.Delete(modDir, true);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, $"Failed to uninstall mod \"{ mods[dir].Name }\" from \"{ dir }\": { ex.Message }", "Failed",
                                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

            LoadModList();
        }
Esempio n. 4
0
        private void OnShown(object sender, EventArgs e)
        {
            CancellationToken token = tokenSource.Token;
            var generator           = new ModManifestGenerator();

            generator.FilesIndexed += (o, args) =>
            {
                SetTask("Manifest generation complete!");
                SetTaskCount(args.FileCount);
            };

            generator.FileHashStart += (o, args) =>
            {
                args.Cancel = token.IsCancellationRequested;
                SetTaskAndStep($"Hashing file: {args.FileIndex}/{args.FileCount}", args.FileName);
                SetProgress(args.FileIndex / (double)args.FileCount);
            };

            generator.FileHashEnd += (o, args) =>
            {
                args.Cancel = token.IsCancellationRequested;
                NextTask();
            };

            using (var task = new Task(() =>
            {
                manifest = generator.Generate(modPath);

                if (!token.IsCancellationRequested)
                {
                    Diff = ModManifestGenerator.Diff(manifest, File.Exists(manifestPath) ? ModManifest.FromFile(manifestPath) : null);
                }
            }))
            {
                task.Start();

                while (!task.IsCompleted && !task.IsCanceled)
                {
                    Application.DoEvents();
                }

                task.Wait(token);
            }

            DialogResult = DialogResult.OK;
        }
Esempio n. 5
0
        private List <LoadData> PrepareLoadData()
        {
            var modDirectories  = Directory.GetDirectories(SourceDirectory);
            var modLoadDataList = new List <LoadData>();

            foreach (var rootPath in modDirectories)
            {
                Log.Debug(rootPath);

                var directoryName = Path.GetFileName(rootPath);

                Log.Info($"Found directory '{directoryName}'");
                var manifestPath = Path.Combine(rootPath, Defaults.ManifestFileName);

                if (!File.Exists(manifestPath))
                {
                    Log.Warning($"Skipping directory without manifest.");
                    continue;
                }

                ModManifest manifest;
                try
                {
                    manifest = ModManifest.FromFile(manifestPath);

                    var validationErrors = manifest.Validate();
                    if (validationErrors != 0)
                    {
                        var sb = new StringBuilder();

                        if (validationErrors.HasFlag(ManifestValidationFlags.MissingFriendlyName))
                        {
                            sb.AppendLine(" * Missing 'FriendlyName' property.");
                        }

                        if (validationErrors.HasFlag(ManifestValidationFlags.MissingModuleFileName))
                        {
                            sb.AppendLine(" * Missing 'ModuleFileName' property.");
                        }

                        Log.Error($"Refusing to load the mod. Manifest has the following issues:\n{sb.ToString()}");
                        continue;
                    }

                    if (manifest.SkipLoad)
                    {
                        Log.Warning("Skipping due to 'SkipLoad' property set to true.");
                        continue;
                    }

                    modLoadDataList.Add(
                        new LoadData
                    {
                        RootDirectory = rootPath,
                        Manifest      = manifest
                    }
                        );
                }
                catch (ManifestReadException mre)
                {
                    Log.Error($"Manifest is invalid: {mre.Message}");
                    continue;
                }
            }

            modLoadDataList = modLoadDataList.OrderByDescending(x => x.Manifest.Priority).ToList();
            return(modLoadDataList);
        }