/// <summary> /// Injects the Reloaded bootstrapper into an active process. /// </summary> /// <exception cref="ArgumentException">DLL Injection failed, likely due to bad DLL or application.</exception> public void Inject() { long handle = _injector.Inject(GetBootstrapperPath(_process)); if (handle == 0) { throw new ArgumentException(Errors.DllInjectionFailed()); } // Wait until mod loader loads. // If debugging, ignore timeout. bool WhileCondition() { if (CheckRemoteDebuggerPresent(_process.Handle, out var isDebuggerPresent)) { return(isDebuggerPresent); } return(false); } ActionWrappers.TryGetValueWhile(() => { // Exit if application crashes while loading Reloaded.. if (_process.HasExited) { return(0); } return(Client.GetPort((int)_process.Id)); }, WhileCondition, _xamlModLoaderSetupTimeout.Get(), _xamlModLoaderSetupSleepTime.Get()); }
public async void Execute(object parameter) { _canExecute = false; RaiseCanExecute(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); var updates = await Task.Run(Update.CheckForModUpdatesAsync); var dependencies = Update.CheckMissingDependencies(out var missingDependencies); if ((!updates) && (!dependencies)) { var box = new MessageBox(_noUpdateDialogTitle.Get(), _noUpdateDialogMessage.Get()); box.WindowStartupLocation = WindowStartupLocation.CenterScreen; box.ShowDialog(); } else if (dependencies) { try { await Update.DownloadPackagesAsync(missingDependencies, false, false); } catch (Exception) { // ignored } } _canExecute = true; RaiseCanExecute(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); }
private void Button_Click(object sender, RoutedEventArgs e) { this.Dispatcher.Invoke(() => { void Update() { ViewModel.Updater .Update(ViewModel.Summary, new Progress <double>(d => { ViewModel.Progress = (int)(d * 100); })) .ContinueWith(x => this.Dispatcher.Invoke(this.Close)); } if (ApplicationInstanceTracker.GetAllProcesses(out _)) { var messageBox = new MessageBoxOkCancel(_xamlUpdateModConfirmTitle.Get(), _xamlUpdateModConfirmMessage.Get()); messageBox.WindowStartupLocation = WindowStartupLocation.CenterScreen; messageBox.ShowDialog(); if (messageBox.DialogResult.HasValue && messageBox.DialogResult.Value) { Update(); } } else { Update(); } }); }
public ReloadedAppViewModel(ApplicationViewModel applicationViewModel) { ApplicationViewModel = applicationViewModel; ApplicationViewModel.SelectedProcess.EnableRaisingEvents = true; ApplicationViewModel.SelectedProcess.Exited += SelectedProcessOnExited; /* Try establish connection. */ int port = 0; try { port = ActionWrappers.TryGetValue(GetPort, _xamlModLoaderSetupTimeout.Get(), _xamlModLoaderSetupSleepTime.Get()); } catch (Exception ex) { Errors.HandleException(new Exception(Errors.ErrorFailedToObtainPort(), ex)); return; } Client = new Client(port); Client.OnReceiveException += ClientOnReceiveException; Refresh(); _refreshTimer = new System.Timers.Timer(_xamlModLoaderRefreshInterval.Get()); _refreshTimer.AutoReset = true; _refreshTimer.Elapsed += (sender, args) => Refresh(); _refreshTimer.Enabled = true; }
public async Task Update() { if (ApplicationInstanceTracker.GetAllProcesses(out var processes)) { ActionWrappers.ExecuteWithApplicationDispatcher(() => { // Accumulate list of processes. string allProcessString = $"\n{_xamlUpdateLoaderProcessList.Get()}:"; foreach (var process in processes) { allProcessString += $"\n({process.Id}) {process.ProcessName}"; } var box = new MessageBox(_xamlUpdateLoaderRunningTitle.Get(), _xamlUpdateLoaderRunningMessage.Get() + allProcessString); box.WindowStartupLocation = WindowStartupLocation.CenterScreen; box.ShowDialog(); }); } else { await _manager.PrepareUpdateAsync(_targetVersion, new Progress <double>(d => { Progress = (int)(d * 100); })); _manager.LaunchUpdater(_targetVersion, true); Environment.Exit(0); } }
/// <summary> /// Checks if there are any updates for the mod loader. /// </summary> public static async Task CheckForLoaderUpdatesAsync() { // Check for loader updates. try { using (var manager = new UpdateManager( new GithubPackageResolver("Reloaded-Project", "Reloaded-II", "Release.zip"), new ArchiveExtractor())) { // Check for new version and, if available, perform full update and restart var result = await manager.CheckForUpdatesAsync(); if (result.CanUpdate) { ActionWrappers.ExecuteWithApplicationDispatcher(() => { var dialog = new ModLoaderUpdateDialog(manager, result.LastVersion); dialog.ShowDialog(); }); } } } catch (Exception) { MessageBox.Show(_xamlCheckUpdatesFailed.Get()); } }
/// <summary> /// Checks if there are any updates for the mod loader. /// </summary> public static async Task CheckForLoaderUpdatesAsync() { if (!_hasInternetConnection) { return; } // Check for loader updates. try { using (var manager = new UpdateManager( new GithubPackageResolver(Misc.Constants.GitRepositoryAccount, Misc.Constants.GitRepositoryName, Constants.GitRepositoryReleaseName), new ArchiveExtractor())) { // Check for new version and, if available, perform full update and restart var result = await manager.CheckForUpdatesAsync(); if (result.CanUpdate) { ActionWrappers.ExecuteWithApplicationDispatcher(() => { var dialog = new ModLoaderUpdateDialog(manager, result.LastVersion); dialog.ShowDialog(); }); } } } catch (Exception) { MessageBox.Show(_xamlCheckUpdatesFailed.Get()); } }
/// <summary> /// Creates instances of the animations that are ran on exiting the page. /// Note: Override this to modify animations used by page. /// </summary> protected override Animation[] MakeExitAnimations() { return(new Animation[] { new RenderTransformAnimation(this.ActualWidth, RenderTransformDirection.Horizontal, RenderTransformTarget.Away, null, XamlExitSlideAnimationDuration.Get()), new OpacityAnimation(XamlExitFadeAnimationDuration.Get(), 1, XamlExitFadeOpacityEnd.Get()) }); }
/// <summary> /// Creates instances of the animations that are ran on entering the page. /// Note: Override this to modify animations used by page. /// </summary> protected override Animation[] MakeEntryAnimations() { return(new Animation[] { new RenderTransformAnimation(-this.ActualWidth, RenderTransformDirection.Horizontal, RenderTransformTarget.Towards, null, XamlEntrySlideAnimationDuration.Get()), new OpacityAnimation(XamlEntryFadeAnimationDuration.Get(), XamlEntryFadeOpacityStart.Get(), 1) }); }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is DownloadModStatus status) { switch (status) { case DownloadModStatus.Default: return(_downloadModDefaultText.Get()); case DownloadModStatus.Downloading: return(_downloadModDownloading.Get()); default: return(_downloadModAlreadyDownloaded.Get()); } } return(_downloadModDefaultText.Get()); }
/// <summary> /// Allows the user to save a mod set. /// </summary> public void SaveModSet() { var dialog = new VistaSaveFileDialog { Title = _xamlSaveModSetTitle.Get(), Filter = Constants.WpfJsonFormat, AddExtension = true, DefaultExt = ".json" }; if ((bool)dialog.ShowDialog()) { new ModSet(ApplicationTuple.Config).Save(dialog.FileName); } }
/* Check if not duplicate. */ public bool IsUnique() { if (ModConfigService.Mods.Any(x => x.Config.ModId.Equals(RealViewModel.Config.ModId))) { var messageBoxDialog = new MessageBox(_xamlTitleCreateModNonUniqueId.Get(), _xamlMessageCreateModNonUniqueId.Get()); messageBoxDialog.Owner = this; messageBoxDialog.ShowDialog(); return(false); } return(true); }
/// <summary> /// Opens up a file selection dialog allowing for the selection of a custom image to associate with the profile. /// </summary> private string SelectImageFile() { var dialog = new VistaOpenFileDialog(); dialog.Title = _xamlCreateModDialogSelectorTitle.Get(); dialog.Filter = $"{_xamlCreateModDialogSelectorFilter.Get()} {Constants.WpfSupportedFormatsFilter}"; if ((bool)dialog.ShowDialog()) { return(dialog.FileName); } return(""); }
public void Execute(object parameter) { var deployConfirm = new MessageBoxOkCancel(_xamlAsiLoaderDialogTitle.Get(), _xamlAsiLoaderDialogDescription.Get()); if (deployConfirm.ShowDialog() == true) { Deployer.DeployAsiLoader(out string loaderPath, out string bootstrapperPath); string deployedBootstrapper = $"{_xamlAsiLoaderDialogBootstrapperDeployed.Get()} {bootstrapperPath}"; if (loaderPath == null) { // Installed Bootstrapper but not loader. var box = new MessageBox(_xamlAsiLoaderDialogTitle.Get(), deployedBootstrapper); box.ShowDialog(); } else { string deployedLoader = $"{_xamlAsiLoaderDialogLoaderDeployed.Get()} {loaderPath}"; var box = new MessageBox(_xamlAsiLoaderDialogTitle.Get(), $"{deployedLoader}\n{deployedBootstrapper}"); box.ShowDialog(); } } }
public void Execute(object parameter) { var applicationTuple = _addAppViewModel.MainPageViewModel.Applications.FirstOrDefault(x => x.Config.Equals(_lastConfig)); var loaderConfig = IoC.Get <LoaderConfig>(); var shell = (IShellLink) new ShellLink(); shell.SetDescription($"Launch {applicationTuple?.Config.AppName} via Reloaded II"); shell.SetPath($"\"{loaderConfig.LauncherPath}\""); shell.SetArguments($"{Constants.ParameterLaunch} \"{_lastConfig.AppLocation}\""); shell.SetWorkingDirectory(Path.GetDirectoryName(loaderConfig.LauncherPath)); if (applicationTuple != null) { var hasIcon = ApplicationConfig.TryGetApplicationIcon(applicationTuple.ConfigPath, applicationTuple.Config, out var logoPath); if (hasIcon) { // Make path for icon. string newPath = Path.ChangeExtension(logoPath, ".ico"); // Convert to ICO and save. var bitmapImage = Imaging.BitmapFromUri(new Uri(logoPath, UriKind.Absolute)); var bitmap = Imaging.BitmapImageToBitmap(bitmapImage); var resizedBitmap = Imaging.ResizeImage(bitmap, Constants.IcoMaxWidth, Constants.IcoMaxHeight); using (var newIcon = Icon.FromHandle(resizedBitmap.GetHicon())) using (Stream newIconStream = new FileStream(newPath, FileMode.Create)) { newIcon.Save(newIconStream); } shell.SetIconLocation(newPath, 0); } else { shell.SetIconLocation(_lastConfig.AppLocation, 0); } } // Save the shortcut. var file = (IPersistFile)shell; var link = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), $"{applicationTuple?.Config.AppName} via Reloaded II.lnk"); file.Save(link, false); var messageBox = new MessageBox(_xamlShortcutCreatedTitle.Get(), $"{_xamlShortcutCreatedMessage.Get()} {link}"); messageBox.WindowStartupLocation = WindowStartupLocation.CenterScreen; messageBox.ShowDialog(); }
private async void Load() { try { await _setupApplicationTask; ChangeToMainPage(); DisplayFirstLaunchWarningIfNeeded(); } catch (Exception ex) { var messageBox = new MessageBox(_xamlFailedToLaunchTitle.Get(), _xamlFailedToLaunchMessage.Get() + $" {ex.Message}\n{ex.StackTrace}"); messageBox.ShowDialog(); } }
/// <summary> /// Opens up a file selection dialog allowing for the selection of an executable to associate with the profile. /// </summary> private string SelectEXEFile() { var dialog = new VistaOpenFileDialog(); dialog.Title = _xamlAddAppExecutableTitle.Get(); dialog.Filter = $"{_xamlAddAppExecutableFilter.Get()} (*.exe)|*.exe"; if ((bool)dialog.ShowDialog()) { return(dialog.FileName); } return(""); }
/* Check if not duplicate. */ public bool IsUnique() { var modsViewModel = IoC.Get <ManageModsViewModel>(); if (modsViewModel.Mods.Count(x => x.ModConfig.ModId.Equals(RealViewModel.Config.ModId)) > 0) { var messageBoxDialog = new MessageBox(_xamlTitleCreateModNonUniqueId.Get(), _xamlMessageCreateModNonUniqueId.Get()); messageBoxDialog.Owner = this; messageBoxDialog.ShowDialog(); return(false); } return(true); }
/// <summary> /// Sets up the overall application state for either running or testing. /// Note: This method uses Task.Delay for waiting the minimum splash delay without blocking the thread, it is synchronous. /// </summary> /// <param name="updateText">A function that updates the visible text onscreen.</param> /// <param name="minimumSplashDelay">Minimum amount of time to wait to complete the loading process.</param> public static async Task SetupApplicationAsync(Action <string> updateText, int minimumSplashDelay) { if (!_loadExecuted) { // Benchmark load time. _loadExecuted = true; Stopwatch watch = new Stopwatch(); watch.Start(); // Allow for debugging before crashing. AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; RegisterReloadedProtocol(); updateText(_xamlSplashCreatingDefaultConfig.Get()); await UpdateDefaultConfig(); CheckForMissingDependencies(); updateText(_xamlSplashPreparingResources.Get()); await Task.Run(SetupServices); await Task.Run(SetupViewModels); updateText(_xamlCheckingForUpdates.Get()); #pragma warning disable 4014 CheckForUpdatesAsync(); // Fire and forget, we don't want to delay startup time. #pragma warning restore 4014 updateText(_xamlRunningSanityChecks.Get()); DoSanityTests(); CleanupAfterOldVersions(); var _ = Task.Run(CompressOldLogs); // Wait until splash screen time. updateText($"{_xamlSplashLoadCompleteIn.Get()} {watch.ElapsedMilliseconds}ms"); while (watch.ElapsedMilliseconds < minimumSplashDelay) { await Task.Delay(100); } } }
public void Execute(object parameter) { var loaderConfig = IoC.Get <LoaderConfig>(); var shell = (IShellLink) new ShellLink(); shell.SetDescription($"Launch {_config?.Config.AppName} via Reloaded II"); shell.SetPath($"\"{loaderConfig.LauncherPath}\""); shell.SetArguments($"{Constants.ParameterLaunch} \"{_config.Config.AppLocation}\""); shell.SetWorkingDirectory(Path.GetDirectoryName(loaderConfig.LauncherPath)); if (_config != null) { var hasIcon = _config.Config.TryGetApplicationIcon(_config.Path, out var logoPath); if (hasIcon) { // Make path for icon. string newPath = Path.ChangeExtension(logoPath, ".ico"); // Convert to ICO. Imaging.TryConvertToIcon(logoPath, newPath); shell.SetIconLocation(newPath, 0); } else { shell.SetIconLocation(_config.Config.AppLocation, 0); } } // Save the shortcut. var file = (IPersistFile)shell; var link = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), $"{_config?.Config.AppName} (Reloaded).lnk"); file.Save(link, false); var messageBox = new MessageBox(_xamlShortcutCreatedTitle.Get(), $"{_xamlShortcutCreatedMessage.Get()} {link}"); messageBox.WindowStartupLocation = WindowStartupLocation.CenterScreen; messageBox.ShowDialog(); }
/// <summary> /// Allows a user to load a new mod set. /// </summary> public async void LoadModSet() { var dialog = new VistaOpenFileDialog { Title = _xamlLoadModSetTitle.Get(), Filter = Constants.WpfJsonFormat, AddExtension = true, DefaultExt = ".json" }; if ((bool)dialog.ShowDialog()) { ModSet.FromFile(dialog.FileName).ToApplicationConfig(ApplicationTuple.Config); ApplicationTuple.SaveAsync(); // Check for mod updates/dependencies. if (Update.CheckMissingDependencies(out var missingDependencies)) { try { await Update.DownloadNuGetPackagesAsync(missingDependencies, false, false); } catch (Exception) { } } CheckModCompatibility(); OnLoadModSet(); } }
private async void AfterLoading(object sender, RoutedEventArgs e) { // Start preparing everything on Splash Screen! if (!_loaded) { _loaded = true; try { await Task.Run(async() => { await Setup.SetupApplicationAsync(UpdateText, _xamlSplashMinimumTime.Get()); ChangeToMainPage(); DisplayFirstLaunchWarningIfNeeded(); }); } catch (Exception ex) { var messageBox = new MessageBox(_xamlFailedToLaunchTitle.Get(), _xamlFailedToLaunchMessage.Get() + $" {ex.Message}\n{ex.StackTrace}"); messageBox.ShowDialog(); } } }
private async void Load() { try { await _setupApplicationTask; ChangeToMainPage(); _backgroundTasks.Add(Task.Run(ControllerSupport.Init)); // Post init cleanup. _ = Task.WhenAll(_backgroundTasks).ContinueWith(task => { App.StopProfileOptimization(); GC.Collect(int.MaxValue, GCCollectionMode.Optimized, true, true); App.EmptyWorkingSet(); }); DisplayFirstLaunchWarningIfNeeded(); } catch (Exception ex) { var messageBox = new MessageBox(_xamlFailedToLaunchTitle.Get(), _xamlFailedToLaunchMessage.Get() + $" {ex.Message}\n{ex.StackTrace}"); messageBox.ShowDialog(); } }
public ApplicationViewModel(ImageApplicationPathTuple tuple, ManageModsViewModel modsViewModel) { ApplicationTuple = tuple; ManageModsViewModel = modsViewModel; IoC.Kernel.Rebind <ApplicationViewModel>().ToConstant(this); InstanceTracker = new ApplicationInstanceTracker(tuple.Config.AppLocation); ManageModsViewModel.OnGetModifications += OnGetModifications; InstanceTracker.OnProcessesChanged += OnProcessesChanged; UpdateReloadedProcesses(); GetModsForThisApp(); RefreshProcessesWithLoaderTimer = new Timer(RefreshTimerCallback, null, 500, _xamlProcessRefreshInterval.Get()); Page = ApplicationSubPage.ApplicationSummary; }
public ApplicationViewModel(PathTuple <ApplicationConfig> tuple, ModConfigService modConfigService) { ApplicationTuple = tuple; ModConfigService = modConfigService; MakeShortcutCommand = new MakeShortcutCommand(tuple); IoC.Kernel.Rebind <ApplicationViewModel>().ToConstant(this); InstanceTracker = new ApplicationInstanceTracker(tuple.Config.AppLocation); ModConfigService.Mods.CollectionChanged += OnGetModifications; InstanceTracker.OnProcessesChanged += OnProcessesChanged; UpdateReloadedProcesses(); GetModsForThisApp(); RefreshProcessesWithLoaderTimer = new Timer(RefreshTimerCallback, null, 500, _xamlProcessRefreshInterval.Get()); Page = ApplicationSubPage.ApplicationSummary; }
public SplashPage() : base() { InitializeComponent(); // Setup ViewModel _splashViewModel = new SplashViewModel(); this.DataContext = _splashViewModel; _setupApplicationTask = Task.Run(() => Setup.SetupApplicationAsync(UpdateText, _xamlSplashMinimumTime.Get())); ActionWrappers.ExecuteWithApplicationDispatcherAsync(Load); }