예제 #1
0
        /// <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));
        }
예제 #3
0
        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();
                }
            });
        }
예제 #4
0
        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;
        }
예제 #5
0
        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);
            }
        }
예제 #6
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());
            }
        }
예제 #7
0
        /// <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());
            }
        }
예제 #8
0
 /// <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())
     });
 }
예제 #9
0
 /// <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)
     });
 }
예제 #10
0
        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());
        }
예제 #11
0
        /// <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);
            }
        }
예제 #12
0
        /* 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);
        }
예제 #13
0
        /// <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("");
        }
예제 #14
0
        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();
                }
            }
        }
예제 #15
0
        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();
        }
예제 #16
0
 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();
     }
 }
예제 #17
0
        /// <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("");
        }
예제 #18
0
        /* 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);
        }
예제 #19
0
        /// <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);
                }
            }
        }
예제 #20
0
        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();
        }
예제 #21
0
        /// <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();
            }
        }
예제 #22
0
 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();
        }
    }
예제 #24
0
        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;
        }
예제 #25
0
        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;
        }
예제 #26
0
        public SplashPage() : base()
        {
            InitializeComponent();

            // Setup ViewModel
            _splashViewModel      = new SplashViewModel();
            this.DataContext      = _splashViewModel;
            _setupApplicationTask = Task.Run(() => Setup.SetupApplicationAsync(UpdateText, _xamlSplashMinimumTime.Get()));
            ActionWrappers.ExecuteWithApplicationDispatcherAsync(Load);
        }