public IncrementalDownloadResult(string downloadPath, FilesIndex.DiffList diffList)
 {
     DownloadPath = downloadPath;
     DiffList     = diffList;
 }
 public static DownloadResult FromFilesDiffList(string downloadPath, FilesIndex.DiffList diffList)
 => new IncrementalDownloadResult(downloadPath, diffList);
        public InstallStatus Install(string sourceFolder, string destinationFolder, FilesIndex.DiffList diffList)
        {
            if (!Directory.Exists(destinationFolder))
            {
                _logger.Error($"Install directory is not exist: {destinationFolder}");
                return(InstallStatus.FileError);
            }
            if (diffList.ChangedFiles.Count == 0 && diffList.IsReuseNotChangeFileNames())
            {
                foreach (var removeFile in diffList.RemoveFiles)
                {
                    FileUtils.DeleteFileNoThrow(Path.Combine(destinationFolder, removeFile));
                }
                return(InstallStatus.Success);
            }
            var           movedReusedFiles = new Dictionary <string, string>();
            DirectoryInfo?backupDataDir    = null;
            var           dataPathDir      = new DirectoryInfo(GameConstants.GetDataFolderPath(destinationFolder));

            try
            {
                var  newLibraryPath  = Path.Combine(sourceFolder, GameConstants.PatcherOriginalName);
                bool newLibraryExist = File.Exists(newLibraryPath);
                if (newLibraryExist)
                {
                    using var libraryCertVerifier = new FileCertVerifier(Resources.CoreSigning);
                    if (!libraryCertVerifier.VerifyFile(newLibraryPath))
                    {
                        _logger.Error("Core certificate is invalid. Abort installation");
                        return(InstallStatus.VerifyError);
                    }
                }
                foreach (var reusePair in diffList.ReuseFiles)
                {
                    if (!reusePair.Key.Equals(GameConstants.PatcherOriginalName, StringComparison.OrdinalIgnoreCase))
                    {
                        var sourceReusePath = Path.Combine(destinationFolder, reusePair.Key);
                        var destReusePath   = Path.Combine(sourceFolder, reusePair.Value);
                        Directory.CreateDirectory(Path.GetDirectoryName(destReusePath));
                        File.Move(sourceReusePath, destReusePath);
                        movedReusedFiles.Add(destReusePath, sourceReusePath);
                    }
                }
                if (dataPathDir.Exists)
                {
                    var backupDataDirPath = Path.Combine(destinationFolder, "backup_" + Path.GetRandomFileName());
                    Directory.Move(dataPathDir.FullName, backupDataDirPath);
                    backupDataDir = new DirectoryInfo(backupDataDirPath);
                }
                Directory.Move(GameConstants.GetDataFolderPath(sourceFolder), dataPathDir.FullName);
                if (backupDataDir != null)
                {
                    FileUtils.DeleteDirectoryNoThrow(backupDataDir, true);
                    backupDataDir = null;
                }
                if (newLibraryExist)
                {
                    InstallCore(newLibraryPath, destinationFolder);
                }
                movedReusedFiles.Clear();
            }
            catch (CryptographicException e)
            {
                _logger.Error(e, "Exception during verify core");
                return(InstallStatus.VerifyError);
            }
            catch (IOException e)
            {
                _logger.Error(e, "I/O exception during install");
                return(InstallStatus.FileError);
            }
            catch (Exception e)
            {
                _logger.Error(e, "Unexpected exception during install");
                return(InstallStatus.UnknownError);
            }
            finally
            {
                if (backupDataDir != null)
                {
                    RestoreDirectory(backupDataDir, dataPathDir);
                }
                foreach (var pair in movedReusedFiles)
                {
                    FileUtils.MoveFileNoThrow(pair.Key, pair.Value);
                }
            }
            return(InstallStatus.Success);
        }