public static async void BeginFlow(MainWindow window) { // PRE LIBRARY LOAD RegistryHandler.RegistrySettingsPath = @"HKEY_CURRENT_USER\Software\MassEffect2Randomizer"; RegistryHandler.CurrentUserRegistrySubpath = @"Software\MassEffect2Randomizer"; LegendaryExplorerCoreLib.SetSynchronizationContext(TaskScheduler.FromCurrentSynchronizationContext()); try { // This is in a try catch because this is a critical no-crash zone that is before launch window.Title = $"Mass Effect 2 Randomizer {App.AppVersion}"; } catch { } if (Utilities.GetExecutablePath().StartsWith(Path.GetTempPath(), StringComparison.InvariantCultureIgnoreCase)) { // Running from temp! This is not allowed await window.ShowMessageAsync("Cannot run from temp directory", $"Mass Effect 2 Randomizer cannot be run from the system's Temp directory. If this executable was run from within an archive, it needs to be extracted first."); Environment.Exit(1); } var pd = await window.ShowProgressAsync("Starting up", $"Mass Effect 2 Randomizer is starting up. Please wait."); pd.SetIndeterminate(); NamedBackgroundWorker bw = new NamedBackgroundWorker("StartupThread"); bw.DoWork += (a, b) => { ALOTInstallerCoreLib.Startup(SetWrapperLogger, RunOnUIThread, startTelemetry, stopTelemetry, $"Mass Effect 2 Randomizer {App.AppVersion} starting up", false); // Logger is now available // Setup telemetry handlers CoreAnalytics.TrackEvent = TelemetryController.TrackEvent; CoreCrashes.TrackError = TelemetryController.TrackError; CoreCrashes.TrackError2 = TelemetryController.TrackError2; CoreCrashes.TrackError3 = TelemetryController.TrackError3; // Setup the InteropPackage for the update check #region Update interop CancellationTokenSource ct = new CancellationTokenSource(); AppUpdateInteropPackage interopPackage = new AppUpdateInteropPackage() { GithubOwner = "Mgamerz", GithubReponame = "MassEffect2Randomizer", UpdateAssetPrefix = "ME2Randomizer", UpdateFilenameInArchive = "ME2Randomizer.exe", ShowUpdatePromptCallback = (title, text, updateButtonText, declineButtonText) => { bool response = false; object syncObj = new object(); Application.Current.Dispatcher.Invoke(async() => { if (Application.Current.MainWindow is MainWindow mw) { var result = await mw.ShowMessageAsync(title, text, MessageDialogStyle.AffirmativeAndNegative, new MetroDialogSettings() { AffirmativeButtonText = updateButtonText, NegativeButtonText = declineButtonText, DefaultButtonFocus = MessageDialogResult.Affirmative }, 75); response = result == MessageDialogResult.Affirmative; lock (syncObj) { Monitor.Pulse(syncObj); } } }); lock (syncObj) { Monitor.Wait(syncObj); } return(response); }, ShowUpdateProgressDialogCallback = (title, initialmessage, canCancel) => { // We don't use this as we are already in a progress dialog pd.SetCancelable(canCancel); pd.SetMessage(initialmessage); pd.SetTitle(title); }, SetUpdateDialogTextCallback = s => { pd.SetMessage(s); }, ProgressCallback = (done, total) => { pd.SetProgress(done * 1d / total); pd.SetMessage($"Downloading update {FileSize.FormatSize(done)} / {FileSize.FormatSize(total)}"); }, ProgressIndeterminateCallback = () => { pd.SetIndeterminate(); }, ShowMessageCallback = (title, message) => { object syncObj = new object(); Application.Current.Dispatcher.Invoke(async() => { if (Application.Current.MainWindow is MainWindow mw) { await mw.ShowMessageAsync(title, message); lock (syncObj) { Monitor.Pulse(syncObj); } } }); lock (syncObj) { Monitor.Wait(syncObj); } }, NotifyBetaAvailable = () => { App.BetaAvailable = true; }, DownloadCompleted = () => { pd.SetCancelable(false); }, cancellationTokenSource = ct, ApplicationName = "Mass Effect 2 Randomizer", RequestHeader = "ME2Randomizer", ForcedUpgradeMaxReleaseAge = 3 }; #endregion pd.SetMessage("Checking for application updates"); pd.Canceled += (sender, args) => { ct.Cancel(); }; AppUpdater.PerformGithubAppUpdateCheck(interopPackage); // If user aborts download pd.SetCancelable(false); pd.SetIndeterminate(); pd.SetTitle("Starting up"); void setStatus(string message) { pd.SetIndeterminate(); pd.SetMessage(message); } GameTarget target = null; try { pd.SetMessage("Loading Mass Effect 2 Randomizer framework"); ToolTipService.ShowOnDisabledProperty.OverrideMetadata(typeof(Control), new FrameworkPropertyMetadata(true)); ToolTipService.ShowDurationProperty.OverrideMetadata(typeof(DependencyObject), new FrameworkPropertyMetadata(int.MaxValue)); ALOTInstallerCoreLib.PostCriticalStartup(x => pd.SetMessage(x), RunOnUIThread, false); #if __LE2__ LE2Directory.ReloadDefaultGamePath(true); if (LE2Directory.DefaultGamePath != null) { GameTarget gt = new GameTarget(MEGame.LE2, LE2Directory.DefaultGamePath, true); if (gt.ValidateTarget() == null) { Locations.SetTarget(gt, false); } } #endif MEPackageHandler.GlobalSharedCacheEnabled = false; // ME2R does not use the global shared cache. handleM3Passthrough(); target = Locations.GetTarget(MERFileSystem.Game); if (target == null) { var gamePath = MEDirectories.GetDefaultGamePath(MERFileSystem.Game); if (Directory.Exists(gamePath)) { target = new GameTarget(MERFileSystem.Game, gamePath, true); var validationFailedReason = target.ValidateTarget(); if (validationFailedReason == null) { // CHECK NOT TEXTURE MODIFIED if (target.TextureModded) { MERLog.Error($@"Game target is texture modded: {target.TargetPath}. This game target is not targetable by ME2R"); object o = new object(); Application.Current.Dispatcher.Invoke(async() => { if (Application.Current.MainWindow is MainWindow mw) { await mw.ShowMessageAsync("Mass Effect 2 target is texture modded", $"The game located at {target.TargetPath} has had textures modified. Mass Effect 2 Randomizer cannot randomize texture modified games, as it adds package files. If you want to texture mod your game, it must be done after randomization.", ContentWidthPercent: 75); lock (o) { Monitor.Pulse(o); } } }); lock (o) { Monitor.Wait(o); } } // We still set target so we can restore game if necessary Locations.SetTarget(target, false); } } } pd.SetMessage("Performing startup checks"); MERStartupCheck.PerformStartupCheck((title, message) => { object o = new object(); Application.Current.Dispatcher.Invoke(async() => { if (Application.Current.MainWindow is MainWindow mw) { await mw.ShowMessageAsync(title, message, ContentWidthPercent: 75); lock (o) { Monitor.Pulse(o); } } }); lock (o) { Monitor.Wait(o); } }, x => pd.SetMessage(x)); // force initial refresh MERPeriodicRefresh(null, null); } catch (Exception e) { MERLog.Exception(e, @"There was an error starting up the framework!"); } pd.SetMessage("Preparing interface"); Thread.Sleep(250); // This will allow this message to show up for moment so user can see it. Application.Current.Dispatcher.Invoke(async() => { if (Application.Current.MainWindow is MainWindow mw) { mw.SetupTargetDescriptionText(); var backupStatus = BackupService.GetBackupStatus(MERFileSystem.Game); mw.BackupRestoreText = backupStatus?.BackupActionText; mw.BackupRestore_Button.ToolTip = backupStatus != null && backupStatus.BackedUp ? "Click to restore game/uninstall randomizer mod" : "Click to backup game"; mw.FinalizeInterfaceLoad(); /* * if (!hasWorkingMEM) * { * await mw.ShowMessageAsync("Required components are not available", * "Some components for installation are not available, likely due to network issues (blocking, no internet, etc). To install these components, folow the 'How to install the Installer Support Package' directions on any of the ALOT pages on NexusMods. The installer will not work without these files installed.", * ContentWidthPercent: 75); * }*/ PeriodicRefresh.OnPeriodicRefresh += MERPeriodicRefresh; } }); }; bw.RunWorkerCompleted += async(a, b) => { // Post critical startup Random random = new Random(); var preseed = random.Next(); window.ImageCredits.ReplaceAll(ImageCredit.LoadImageCredits("imagecredits.txt", false)); window.ContributorCredits.ReplaceAll(window.GetContributorCredits()); window.LibraryCredits.ReplaceAll(LibraryCredit.LoadLibraryCredits("librarycredits.txt")); #if DEBUG window.SeedTextBox.Text = 529572808.ToString(); #else window.SeedTextBox.Text = preseed.ToString(); #endif window.TextBlock_AssemblyVersion.Text = $"Version {App.AppVersion}"; window.SelectedRandomizeMode = MainWindow.RandomizationMode.ERandomizationMode_SelectAny; var hasFirstRun = RegistryHandler.GetRegistrySettingBool(MainWindow.SETTING_FIRSTRUN); if (hasFirstRun == null || !hasFirstRun.Value) { window.FirstRunFlyoutOpen = true; } await pd.CloseAsync(); }; bw.RunWorkerAsync(); }