예제 #1
0
 private static void MERPeriodicRefresh(object?sender, EventArgs e)
 {
     Application.Current.Dispatcher.Invoke(() =>
     {
         if (Application.Current.MainWindow is MainWindow mw)
         {
             // Is DLC component installed?
             var dlcModPath           = MERFileSystem.GetDLCModPath();
             mw.DLCComponentInstalled = dlcModPath != null ? Directory.Exists(dlcModPath) : false;
         }
     });
 }
        private async void UninstallDLCComponent()
        {
            var dlcModPath = MERFileSystem.GetDLCModPath();

            if (Directory.Exists(dlcModPath))
            {
                var pd = await this.ShowProgressAsync("Deleting DLC component", "Please wait while the DLC mod component of your current randomization is deleted.");

                pd.SetIndeterminate();
                Task.Run(() =>
                {
                    Utilities.DeleteFilesAndFoldersRecursively(dlcModPath);
                    DLCComponentInstalled = false;
                    Thread.Sleep(2000);
                })
                .ContinueWithOnUIThread(async x =>
                {
                    await pd.CloseAsync();
                    await this.ShowMessageAsync("DLC component uninstalled", "The DLC component of the randomization has been uninstalled. A few files that cannot be placed into DLC may remain, you will need to repair your game to remove them.\n\nFor faster restores in the future, make a backup with an ME3Tweaks program. Mass Effect 2 randomization uninstallation only takes a few seconds when an ME3Tweaks backup is available.");
                    CommandManager.InvalidateRequerySuggested();
                });
            }
        }
        private async void StartRandomization()
        {
            var modPath      = MERFileSystem.GetDLCModPath();
            var backupStatus = BackupService.GetBackupStatus(MERFileSystem.Game);

            if (!backupStatus.BackedUp && !Directory.Exists(modPath))
            {
                var settings = new MetroDialogSettings()
                {
                    AffirmativeButtonText = "Continue anyways",
                    NegativeButtonText    = "Cancel"
                };
                var result = await this.ShowMessageAsync("No ME3Tweaks-based backup availbale", "It is recommended that you create an ME3Tweaks-based backup before randomization, as this allows much faster re-rolls. You can take a backup using the button on the bottom left of the interface.", MessageDialogStyle.AffirmativeAndNegative, settings);

                if (result == MessageDialogResult.Negative)
                {
                    // Do nothing. User canceled
                    return;
                }
            }


            if (Directory.Exists(modPath) && PerformReroll)
            {
                var isControllerInstalled = SFXGame.IsControllerBasedInstall();
                if (!isControllerInstalled)
                {
                    if (backupStatus.BackedUp)
                    {
                        var settings = new MetroDialogSettings()
                        {
                            AffirmativeButtonText    = "Quick restore",
                            NegativeButtonText       = "No restore",
                            FirstAuxiliaryButtonText = "Cancel",
                            DefaultButtonFocus       = MessageDialogResult.Affirmative
                        };
                        var result = await this.ShowMessageAsync("Existing randomization already installed", "An existing randomization is already installed. It is highly recommended that you perform a quick restore before re-rolling so that basegame changes do not stack or are left installed if your new options do not include these changes.\n\nPerform a quick restore before randomization?", MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary, settings);

                        if (result == MessageDialogResult.FirstAuxiliary)
                        {
                            // Do nothing. User canceled
                            return;
                        }

                        if (result == MessageDialogResult.Affirmative)
                        {
                            // Perform quick restore first
                            RestoreController.StartRestore(this, true, InternalStartRandomization);
                            return; // Return, we will run randomization after this
                        }

                        // User did not want to restore, just run
                    }
                    else
                    {
                        var settings = new MetroDialogSettings()
                        {
                            AffirmativeButtonText = "Continue anyways",
                            NegativeButtonText    = "Cancel",
                        };
                        var result = await this.ShowMessageAsync("Existing randomization already installed", "An existing randomization is already installed. Some basegame only randomized files may remain after the DLC component is removed, and if options that modify these files are selected, the effects will stack. It is recommended you 'Remove Randomization' in the bottom left window, then repair your game to ensure you have a fresh installation for a re-roll.\n\nAn ME3Tweaks-based backup is recommended to avoid this procedure, which can be created in the bottom left of the application. It enables the quick restore feature, which only takes a few seconds.", MessageDialogStyle.AffirmativeAndNegative, settings);

                        if (result == MessageDialogResult.Negative)
                        {
                            // Do nothing. User canceled
                            return;
                        }
                    }
                }
                else
                {
                    if (backupStatus.BackedUp)
                    {
                        var settings = new MetroDialogSettings()
                        {
                            AffirmativeButtonText     = "Perform quick restore + randomize",
                            NegativeButtonText        = "Perform only quick restore",
                            FirstAuxiliaryButtonText  = "Install anyways",
                            SecondAuxiliaryButtonText = "Cancel",

                            DefaultButtonFocus = MessageDialogResult.Negative
                        };
                        var result = await this.ShowMessageAsync("Controller mod detected", "Performing a quick restore will undo changes made by the ME2Controller mod. After performing a quick restore, but before randomization, you should reinstall ME2Controller.", MessageDialogStyle.AffirmativeAndNegativeAndDoubleAuxiliary, settings);

                        if (result == MessageDialogResult.SecondAuxiliary)
                        {
                            // Do nothing. User canceled
                            return;
                        }

                        if (result == MessageDialogResult.Affirmative)
                        {
                            // Perform quick restore first
                            RestoreController.StartRestore(this, true, InternalStartRandomization);
                            return; // Return, we will run randomization after this
                        }

                        if (result == MessageDialogResult.Negative)
                        {
                            RestoreController.StartRestore(this, true);
                            return; // Return, we will run randomization after this
                        }
                        // User did not want to restore, just run
                    }
                    else
                    {
                        // no backup, can't quick restore
                        var settings = new MetroDialogSettings()
                        {
                            AffirmativeButtonText = "Continue anyways",
                            NegativeButtonText    = "Cancel",
                        };
                        var result = await this.ShowMessageAsync("Existing randomization already installed", "An existing randomization is already installed. Some basegame only randomized files may remain after the DLC component is removed, and if options that modify these files are selected, the effects will stack. It is recommended you 'Remove Randomization' in the bottom left window, then repair your game to ensure you have a fresh installation for a re-roll.\n\nAn ME3Tweaks-based backup is recommended to avoid this procedure, which can be created in the bottom left of the application. It enables the quick restore feature, which only takes a few seconds.", MessageDialogStyle.AffirmativeAndNegative, settings);

                        if (result == MessageDialogResult.Negative)
                        {
                            // Do nothing. User canceled
                            return;
                        }
                    }
                }
            }

            InternalStartRandomization();
        }
예제 #4
0
        public static async void StartRestore(MainWindow mw, bool isQuick, Action postRestoreDelegate = null)
        {
            var pd = await mw.ShowProgressAsync("Restoring game", "Preparing to restore game");

            pd.SetIndeterminate();
            await Task.Run(() =>
            {
                if (isQuick)
                {
                    // Nuke the DLC
                    MERLog.Information(@"Quick restore started");
                    pd.SetMessage("Removing randomize DLC component");
                    var dlcModPath = MERFileSystem.GetDLCModPath();
                    if (Directory.Exists(dlcModPath))
                    {
                        MERLog.Information($@"Deleting {dlcModPath}");
                        Utilities.DeleteFilesAndFoldersRecursively(dlcModPath);
                    }

                    mw.DLCComponentInstalled = false;


                    // Restore basegame only files
                    pd.SetMessage("Restoring randomized basegame files");
                    var isControllerModInstalled = SFXGame.IsControllerBasedInstall();

                    var backupPath       = BackupService.GetGameBackupPath(MERFileSystem.Game, out _, false);
                    var gameCookedPath   = M3Directories.GetCookedPath(Locations.GetTarget(MERFileSystem.Game));
                    var backupCookedPath = MEDirectories.GetCookedPath(MERFileSystem.Game, backupPath);
                    foreach (var bgf in MERFileSystem.alwaysBasegameFiles)
                    {
                        var srcPath  = Path.Combine(backupCookedPath, bgf);
                        var destPath = Path.Combine(gameCookedPath, bgf);
                        MERLog.Information($@"Restoring {bgf}");
                        File.Copy(srcPath, destPath, true);
                    }

                    if (isControllerModInstalled)
                    {
                        // We must also restore Coalesced.ini or it will reference a UI that is no longer available and game will not boot
                        MERLog.Information(@"Controller based install detected, also restoring Coalesced.ini to prevent startup crash");
                        File.Copy(Path.Combine(backupPath, "BioGame", "Config", "PC", "Cooked", "Coalesced.ini"), Path.Combine(Locations.GetTarget(MERFileSystem.Game).TargetPath, "BioGame", "Config", "PC", "Cooked", "Coalesced.ini"), true);
                    }

                    // Delete basegame TFC
                    var baseTFC = MERFileSystem.GetTFCPath(false);
                    if (File.Exists(baseTFC))
                    {
                        File.Delete(baseTFC);
                    }

                    // Done!
                }
                else
                {
                    // Full restore
                    var target = Locations.GetTarget(MERFileSystem.Game);
                    MERLog.Information($@"Performing full game restore on {target.TargetPath} target after restore");

                    object syncObj = new object();
                    BackupHandler.GameRestore gr = new BackupHandler.GameRestore(MERFileSystem.Game)
                    {
                        ConfirmationCallback = (title, message) =>
                        {
                            bool response = false;
                            Application.Current.Dispatcher.Invoke(async() =>
                            {
                                response = await mw.ShowMessageAsync(title, message,
                                                                     MessageDialogStyle.AffirmativeAndNegative,
                                                                     new MetroDialogSettings()
                                {
                                    AffirmativeButtonText = "OK",
                                    NegativeButtonText    = "Cancel",
                                }) == MessageDialogResult.Affirmative;
                                lock (syncObj)
                                {
                                    Monitor.Pulse(syncObj);
                                }
                            });
                            lock (syncObj)
                            {
                                Monitor.Wait(syncObj);
                            }

                            return(response);
                        },
                        BlockingErrorCallback = (title, message) => { Application.Current.Dispatcher.Invoke(async() => { await mw.ShowMessageAsync(title, message); }); },
                        RestoreErrorCallback  = (title, message) => { Application.Current.Dispatcher.Invoke(async() => { await mw.ShowMessageAsync(title, message); }); },
                        UpdateStatusCallback  = message =>
                                                Application.Current.Dispatcher.Invoke(() => pd.SetMessage(message)),
                        UpdateProgressCallback = (done, total) =>
                                                 Application.Current.Dispatcher.Invoke(() =>
                        {
                            pd.SetProgress(done * 1d / total);
                            if (total != 0)
                            {
                                TaskbarHelper.SetProgressState(TaskbarProgressBarState.Normal);
                                TaskbarHelper.SetProgress(done * 1.0 / total);
                            }
                        }),
                        SetProgressIndeterminateCallback = indeterminate => Application.Current.Dispatcher.Invoke(() =>
                        {
                            if (indeterminate)
                            {
                                pd.SetIndeterminate();
                            }
                            TaskbarHelper.SetProgressState(indeterminate ? TaskbarProgressBarState.Indeterminate : TaskbarProgressBarState.Normal);
                        }),
                        SelectDestinationDirectoryCallback = (title, message) =>
                        {
                            string selectedPath = null;
                            Application.Current.Dispatcher.Invoke(() =>
                            {
                                // Not sure if this has to be synced
                                CommonOpenFileDialog ofd = new CommonOpenFileDialog()
                                {
                                    Title            = "Select restore destination directory",
                                    IsFolderPicker   = true,
                                    EnsurePathExists = true
                                };
                                if (ofd.ShowDialog() == CommonFileDialogResult.Ok)
                                {
                                    selectedPath = ofd.FileName;
                                }
                            });
                            return(selectedPath);
                        }
                    };
                    gr.PerformRestore(target.TargetPath);
                    mw.DLCComponentInstalled = false;
                    MERLog.Information(@"Reloading target after restore");
                    target.ReloadGameTarget(false, false);
                    mw.SetupTargetDescriptionText();
                }
            }).ContinueWithOnUIThread(async x =>
            {
                TaskbarHelper.SetProgressState(TaskbarProgressBarState.NoProgress);
                await pd.CloseAsync();
                postRestoreDelegate?.Invoke();
            });
        }