Example #1
0
        private bool ExecuteUninstallTask()
        {
            UpdateStatus(TaskExecutionStatus.Uninstall);

            // Get files, affected by install
            UpdateStatus(TaskExecutionStatus.UninstallGetAffectedFiles);
            var affectedFiles = _persistenceService.GetAffectedFiles(Task.ModID);

            if (!affectedFiles.AnySafe())
            {
                return(true);
            }

            // Delete files
            UpdateStatus(TaskExecutionStatus.UninstallDeleteFiles);
            foreach (string file in affectedFiles)
            {
                if (IsAbortPending)
                {
                    TaskAborted?.Invoke(this, new TaskEventArgs(Task));
                    return(false);
                }

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

                UpdateStatus(Progress + 100.0 / affectedFiles.Length);
            }

            // Restore backups
            UpdateStatus(TaskExecutionStatus.UninstallRestoreBackups);
            _backupService.RestoreAll(Task.ModID);

            // Store results
            UpdateStatus(TaskExecutionStatus.UninstallStoreResults);
            _persistenceService.RecordUninstall(Task.ModID);

#if !DEBUG
            // Submit results
            UpdateStatus(TaskExecutionStatus.UninstallSubmitResults);
            _apiService.ReportSuccessfulExecution(Task.ModID, TaskType.Uninstall);
#endif

            return(true);
        }
Example #2
0
        private ModInstallationState ExecuteVerifyTask()
        {
            UpdateStatus(TaskExecutionStatus.Verify);

            // Get files affected by install
            UpdateStatus(TaskExecutionStatus.VerifyGetAffectedFiles);
            var affectedFiles = _persistenceService.GetAffectedFiles(Task.FileId);

            if (!affectedFiles.AnySafe())
            {
                return(ModInstallationState.NotInstalled);
            }

            // Normalize affected files
            if (affectedFiles.Length > 1)
            {
                affectedFiles = affectedFiles.ToArray();
            }
            affectedFiles = affectedFiles.Select(f => f.Replace("\\", "/")).ToArray();

            // Verify files
            UpdateStatus(TaskExecutionStatus.VerifyExecute);
            foreach (var file in affectedFiles)
            {
                if (IsAbortPending)
                {
                    TaskAborted?.Invoke(this, new TaskEventArgs(Task));
                    return(ModInstallationState.Unknown);
                }

                if (file.IsBlank())
                {
                    return(ModInstallationState.Corrupt);
                }

                // Check if exists
                if (!File.Exists(file))
                {
                    return(ModInstallationState.Corrupt);
                }

                UpdateStatus(Progress + 100.0 / affectedFiles.Length);
            }

            // All checks passed => installed
            return(ModInstallationState.Installed);
        }
Example #3
0
        private bool ExecuteInstallTask()
        {
            UpdateStatus(TaskExecutionStatus.Install);

            // Get mod info
            UpdateStatus(TaskExecutionStatus.InstallGetModInfo);
            var modInfo = _apiService.GetModInfo(Task.ModID);

            if (modInfo == null)
            {
                return(false);
            }

            // Reset everything
            _fileChanges.Clear();

            // Download archive
            UpdateStatus(TaskExecutionStatus.InstallDownload);
            var downloadedFile = _webService.Download(modInfo.DownloadURL, FileSystem.CreateTempFile($"Mod_{modInfo.ModID}"));

            if (downloadedFile == null)
            {
                return(false);
            }
            if (IsAbortPending)
            {
                TaskAborted?.Invoke(this, new TaskEventArgs(Task));
                return(false);
            }

            // Unpack archive
            UpdateStatus(TaskExecutionStatus.InstallUnpack);
            string unpackedDir = FileSystem.CreateTempDirectory($"Mod_{modInfo.ModID}");

            _aliasService.Set(new InternalAlias(InternalAliasKeyword.ArchiveExtractedDirectory, unpackedDir));
            _archivingService.ExtractFiles(downloadedFile.FullName, unpackedDir);
            if (!Directory.Exists(unpackedDir))
            {
                return(false);
            }
            if (IsAbortPending)
            {
                TaskAborted?.Invoke(this, new TaskEventArgs(Task));
                return(false);
            }

            // Get commands
            UpdateStatus(TaskExecutionStatus.InstallExecute);
            var    commands         = _apiService.GetInstallationCommands(modInfo.ModID);
            string commandContextID = modInfo.ModID; // can be improved later

            // Execute commands
            foreach (var command in commands)
            {
                if (IsAbortPending)
                {
                    TaskAborted?.Invoke(this, new TaskEventArgs(Task));
                    return(false);
                }

                bool success = _commandExecutionService.ExecuteCommand(command, commandContextID);
                if (!success)
                {
#if !DEBUG
                    _windowService.ShowErrorWindowAsync(Localization.Current.Task_CommandExecutionFailed).GetResult();
                    return(false);
#endif
                }

                UpdateStatus(Progress + 100.0 / commands.Count);
            }

            // Clear local aliases
            _aliasService.Clear(commandContextID);

            // Store results
            UpdateStatus(TaskExecutionStatus.InstallStoreResults);
            _persistenceService.RecordInstall(commandContextID, _fileChanges.ToArray());

#if !DEBUG
            // Submit results
            UpdateStatus(TaskExecutionStatus.InstallSubmitResults);
            _apiService.ReportSuccessfulExecution(Task.ModID, TaskType.Install);
#endif

            return(true);
        }
Example #4
0
        private ModInstallationState ExecuteVerifyTask()
        {
            UpdateStatus(TaskExecutionStatus.Verify);

            // Get files affected by install
            UpdateStatus(TaskExecutionStatus.VerifyGetAffectedFiles);
            var affectedFiles = _persistenceService.GetAffectedFiles(Task.ModID);

            if (!affectedFiles.AnySafe())
            {
                return(ModInstallationState.NotInstalled);
            }

            // Normalize affected files
            if (affectedFiles.Length > 1)
            {
                affectedFiles = affectedFiles.StripCommonStart().ToArray();
            }
            affectedFiles = affectedFiles.Select(f => f.Replace("\\", "/")).ToArray();

            // Get verification pairs
            UpdateStatus(TaskExecutionStatus.VerifyGetVerificationPairs);
            var verificationPairs = _apiService.GetVerificationPairs(Task.ModID);

            // Verify files
            UpdateStatus(TaskExecutionStatus.VerifyExecute);
            foreach (var verificationPair in verificationPairs)
            {
                if (IsAbortPending)
                {
                    TaskAborted?.Invoke(this, new TaskEventArgs(Task));
                    return(ModInstallationState.Unknown);
                }

                // Get file in question
                string file = affectedFiles
                              .Where(f => f.ContainsInvariant(verificationPair.File))
                              .OrderBy(f => f.Length)
                              .FirstOrDefault();
                if (file.IsBlank())
                {
                    return(ModInstallationState.Corrupt);
                }

                // Check if exists
                if (!File.Exists(file))
                {
                    return(ModInstallationState.Corrupt);
                }

                // Compare hashes
                if (!Ext.CompareFileHash(file, verificationPair.Hash))
                {
                    return(ModInstallationState.Corrupt);
                }

                UpdateStatus(Progress + 100.0 / verificationPairs.Count);
            }

            // All checks passed => installed
            return(ModInstallationState.Installed);
        }
Example #5
0
        private bool ExecuteInstallTask()
        {
            UpdateStatus(TaskExecutionStatus.Install);

            // Get mod info
            UpdateStatus(TaskExecutionStatus.InstallGetModInfo);
            var modInfo = _apiService.GetModInfo(Task.Identifier);

            if (modInfo == null)
            {
                return(false);
            }

            // Reset everything
            _fileChanges.Clear();

            // Retrieve file info
            var fileInfo = _apiService.GetFileInfo(modInfo.FileId);

            // Download archive
            UpdateStatus(TaskExecutionStatus.InstallDownload);
            var downloadedFileContainer = _webService.Download(fileInfo.DownloadUrl, FileSystem.CreateTempFile($"Mod_{modInfo.FileId}"));

            if (downloadedFileContainer == null)
            {
                _windowService.ShowErrorWindowAsync(Localization.Current.Task_Install_Download_Failed).GetResult();
                return(false);
            }
            var contentType    = downloadedFileContainer.ResponseHeaders[HttpResponseHeader.ContentType];
            var downloadedFile = downloadedFileContainer.FileInfo;

            if (IsAbortPending)
            {
                TaskAborted?.Invoke(this, new TaskEventArgs(Task));
                return(false);
            }

            // Unpack archive
            UpdateStatus(TaskExecutionStatus.InstallUnpack);
            string unpackedDir = FileSystem.CreateTempDirectory($"Mod_{modInfo.FileId}");

            _aliasService.Set(new InternalAlias(InternalAliasKeyword.ArchiveExtractedDirectory, unpackedDir));
            var extractSuccess = _archivingService.ExtractFiles(downloadedFile.FullName, unpackedDir);

            if (!extractSuccess || !Directory.Exists(unpackedDir))
            {
                // Note: RAR5 supported now, but might be useful for future formats
                //if ("application/x-rar-compressed".Equals(contentType))
                //{
                //    _windowService.ShowErrorWindowAsync(Localization.Current.Task_Install_Unpack_Failed_RAR5).GetResult();
                //}
                //else
                //{
                _windowService.ShowErrorWindowAsync(Localization.Current.Task_Install_Unpack_Failed).GetResult();
                //}
                return(false);
            }
            if (IsAbortPending)
            {
                TaskAborted?.Invoke(this, new TaskEventArgs(Task));
                return(false);
            }

            // Get commands
            UpdateStatus(TaskExecutionStatus.InstallExecute);
            var    commands         = fileInfo.InstallationCommands;
            string commandContextID = modInfo.FileId; // can be improved later

            // If we aren't copying files, we probably don't have an installation scheme for this type of submission
            if (!commands.Any(c => CommandType.Copy.Equals(c.Type)))
            {
                _windowService.ShowErrorWindowAsync(Localization.Current.Task_UnknownInstallationProcess).GetResult();
                return(false);
            }

            // Execute commands
            foreach (var command in commands)
            {
                if (IsAbortPending)
                {
                    TaskAborted?.Invoke(this, new TaskEventArgs(Task));
                    return(false);
                }

                bool success = _commandExecutionService.ExecuteCommand(command, commandContextID);
                if (!success)
                {
#if !DEBUG
                    _windowService.ShowErrorWindowAsync(Localization.Current.Task_CommandExecutionFailed).GetResult();
                    return(false);
#endif
                }

                UpdateStatus(Progress + 100.0 / commands.Count);
            }

            // Clear local aliases
            _aliasService.Clear(commandContextID);

            // Store results
            UpdateStatus(TaskExecutionStatus.InstallStoreResults);
            _persistenceService.RecordInstall(modInfo.Identifier, _fileChanges.ToArray());

            return(true);
        }