/// <summary> /// Initilisation /// </summary> /// <remarks>LOUIS Yoann 18/07/2016 création</remarks> private void Initialisation() { // yl - De base en selectionne le module de selection des ecriture this.ModuleEnCours = EModule.SelectionEcriture; // yl - Gestion des abonnement this.GestionAbonnement(); }
/// <summary> /// Determines whether or not the local copy of the manifest for the specifed module is outdated. /// </summary> /// <exception cref="ArgumentOutOfRangeException"> /// Will be thrown if the <see cref="EModule"/> passed to the function is not a valid value. /// </exception> protected virtual bool IsModuleManifestOutdated(EModule module) { string manifestPath; switch (module) { case EModule.Launcher: case EModule.Game: { manifestPath = this.FileManifestHandler.GetManifestPath((EManifestType)module, false); break; } default: { throw new ArgumentOutOfRangeException(nameof(module), module, "An invalid module value was passed to RefreshModuleManifest."); } } if (File.Exists(manifestPath)) { string remoteHash = GetRemoteModuleManifestChecksum(module); using (Stream file = File.OpenRead(manifestPath)) { string localHash = MD5Handler.GetStreamHash(file); return(remoteHash != localHash); } } return(true); }
/// <summary> /// Gets the checksum of the manifest for the specified module. /// </summary> protected virtual string GetRemoteModuleManifestChecksum(EModule Module) { string checksum; switch (Module) { case EModule.Launcher: { checksum = ReadRemoteFile(Manifest.GetLaunchpadManifestChecksumURL()); break; } case EModule.Game: { checksum = ReadRemoteFile(Manifest.GetGameManifestChecksumURL()); break; } default: { throw new ArgumentOutOfRangeException(nameof(Module), Module, null); } } return(Utilities.SanitizeString(checksum)); }
/// <summary> /// Gets the checksum of the manifest for the specified module. /// </summary> /// <param name="module">The module.</param> /// <returns>The checksum.</returns> /// <exception cref="ArgumentOutOfRangeException"> /// Will be thrown if the <see cref="EModule"/> passed to the function is not a valid value. /// </exception> protected virtual string GetRemoteModuleManifestChecksum(EModule module) { string checksum; switch (module) { case EModule.Launcher: case EModule.Game: { checksum = ReadRemoteFile(this.FileManifestHandler.GetManifestChecksumURL((EManifestType)module)).RemoveLineSeparatorsAndNulls(); break; } default: { throw new ArgumentOutOfRangeException ( nameof(module), module, "An invalid module value was passed to GetRemoteModuleManifestChecksum." ); } } return(checksum.RemoveLineSeparatorsAndNulls()); }
/// <summary> /// Refreshes the current manifest by redownloading it, if required; /// </summary> /// <exception cref="ArgumentOutOfRangeException"> /// Will be thrown if the <see cref="EModule"/> passed to the function is not a valid value. /// </exception> protected virtual void RefreshModuleManifest(EModule module) { bool manifestExists; switch (module) { case EModule.Launcher: case EModule.Game: { manifestExists = File.Exists(this.FileManifestHandler.GetManifestPath((EManifestType)module, false)); break; } default: { throw new ArgumentOutOfRangeException(nameof(module), module, "An invalid module value was passed to RefreshModuleManifest"); } } if (manifestExists) { if (IsModuleManifestOutdated(module)) { DownloadModuleManifest(module); } } else { DownloadModuleManifest(module); } // Now update the handler instance this.FileManifestHandler.ReloadManifests((EManifestType)module); }
/// <summary> /// Verifies and repairs the files of the specified module. /// </summary> public override void VerifyModule(EModule module) { List <ManifestEntry> manifest = this.FileManifestHandler.GetManifest((EManifestType)module, false); List <ManifestEntry> brokenFiles = new List <ManifestEntry>(); try { int verifiedFiles = 0; foreach (ManifestEntry fileEntry in manifest) { ++verifiedFiles; // Prepare the progress event contents this.ModuleVerifyProgressArgs.IndicatorLabelMessage = GetVerifyIndicatorLabelMessage(Path.GetFileName(fileEntry.RelativePath), verifiedFiles, manifest.Count); OnModuleVerifyProgressChanged(); if (!fileEntry.IsFileIntegrityIntact()) { brokenFiles.Add(fileEntry); Log.Info($"File \"{Path.GetFileName(fileEntry.RelativePath)}\" failed its integrity check and was queued for redownload."); } } int downloadedFiles = 0; foreach (ManifestEntry fileEntry in brokenFiles) { ++downloadedFiles; // Prepare the progress event contents this.ModuleDownloadProgressArgs.IndicatorLabelMessage = GetDownloadIndicatorLabelMessage(Path.GetFileName(fileEntry.RelativePath), downloadedFiles, brokenFiles.Count); OnModuleDownloadProgressChanged(); for (int i = 0; i < this.Config.GetFileRetries(); ++i) { if (!fileEntry.IsFileIntegrityIntact()) { DownloadManifestEntry(fileEntry, module); Log.Info($"File \"{Path.GetFileName(fileEntry.RelativePath)}\" failed its integrity check again after redownloading. ({i} retries)"); } else { break; } } } } catch (IOException ioex) { Log.Warn($"Verification of {module} files failed (IOException): " + ioex.Message); OnModuleInstallationFailed(); } OnModuleInstallationFinished(); }
/// <summary> /// Downloads the manifest for the specified module, and backs up the old copy of the manifest. /// </summary> /// <exception cref="ArgumentOutOfRangeException"> /// Will be thrown if the <see cref="EModule"/> passed to the function is not a valid value. /// </exception> protected virtual void DownloadModuleManifest(EModule module) { string remoteURL; string localPath; string oldLocalPath; switch (module) { case EModule.Launcher: { remoteURL = ManifestHandler.GetLaunchpadManifestURL(); localPath = ManifestHandler.GetLaunchpadManifestPath(); oldLocalPath = ManifestHandler.GetOldLaunchpadManifestPath(); break; } case EModule.Game: { remoteURL = FileManifestHandler.GetGameManifestURL(); localPath = ManifestHandler.GetGameManifestPath(); oldLocalPath = ManifestHandler.GetOldGameManifestPath(); break; } default: { throw new ArgumentOutOfRangeException(nameof(module), module, "An invalid module value was passed to DownloadModuleManifest"); } } try { // Delete the old backup (if there is one) if (File.Exists(oldLocalPath)) { File.Delete(oldLocalPath); } // Create a backup of the old manifest so that we can compare them when updating the game File.Move(localPath, oldLocalPath); } catch (IOException ioex) { Log.Warn("Failed to back up the old launcher manifest (IOException): " + ioex.Message); } DownloadRemoteFile(remoteURL, localPath); }
/// <inheritdoc /> public override bool IsModuleOutdated(EModule module) { try { Version local; Version remote; switch (module) { case EModule.Launcher: { local = this.LocalVersionService.GetLocalLauncherVersion(); remote = GetRemoteLauncherVersion(); break; } case EModule.Game: { local = this.LocalVersionService.GetLocalGameVersion(); remote = GetRemoteGameVersion(); break; } default: { throw new ArgumentOutOfRangeException ( nameof(module), module, "An invalid module value was passed to IsModuleOutdated." ); } } return(local < remote); } catch (WebException wex) { Log.Warn("Unable to determine whether or not the launcher was outdated (WebException): " + wex.Message); return(false); } }
/// <summary> /// Determines whether or not the local copy of the manifest for the specifed module is outdated. /// </summary> protected virtual bool IsModuleManifestOutdated(EModule Module) { string manifestPath; switch (Module) { case EModule.Launcher: { manifestPath = ManifestHandler.GetLaunchpadManifestPath(); break; } case EModule.Game: { manifestPath = ManifestHandler.GetGameManifestPath(); break; } default: { throw new ArgumentOutOfRangeException(nameof(Module), Module, "The module passed to RefreshModuleManifest was invalid."); } } if (File.Exists(manifestPath)) { string remoteHash = GetRemoteModuleManifestChecksum(Module); using (Stream file = File.OpenRead(manifestPath)) { string localHash = MD5Handler.GetStreamHash(file); return(remoteHash != localHash); } } return(true); }
public override bool IsModuleOutdated(EModule Module) { try { Version local; Version remote; switch (Module) { case EModule.Launcher: { local = Config.GetLocalLauncherVersion(); remote = GetRemoteLauncherVersion(); break; } case EModule.Game: { local = Config.GetLocalGameVersion(); remote = GetRemoteGameVersion(); break; } default: { throw new ArgumentOutOfRangeException(nameof(Module), Module, null); } } return(local < remote); } catch (WebException wex) { Log.Warn("Unable to determine whether or not the launcher was outdated (WebException): " + wex.Message); return(false); } }
/// <summary> /// Refreshes the current manifest by redownloading it, if required; /// </summary> /// <exception cref="ArgumentOutOfRangeException"> /// Will be thrown if the <see cref="EModule"/> passed to the function is not a valid value. /// </exception> protected virtual void RefreshModuleManifest(EModule module) { bool doesManifestExist; switch (module) { case EModule.Launcher: { doesManifestExist = File.Exists(ManifestHandler.GetLaunchpadManifestPath()); break; } case EModule.Game: { doesManifestExist = File.Exists(ManifestHandler.GetGameManifestPath()); break; } default: { throw new ArgumentOutOfRangeException(nameof(module), module, "An invalid module value was passed to RefreshModuleManifest"); } } if (doesManifestExist) { if (IsModuleManifestOutdated(module)) { DownloadModuleManifest(module); } } else { DownloadModuleManifest(module); } }
protected virtual void DownloadManifestEntry(ManifestEntry Entry, EModule Module) { ModuleDownloadProgressArgs.Module = Module; string baseRemoteURL; string baseLocalPath; switch (Module) { case EModule.Launcher: { baseRemoteURL = Config.GetLauncherBinariesURL(); baseLocalPath = ConfigHandler.GetTempLauncherDownloadPath(); break; } case EModule.Game: { baseRemoteURL = Config.GetGameURL(); baseLocalPath = Config.GetGamePath(); break; } default: { throw new ArgumentOutOfRangeException(nameof(Module), Module, "The module passed to DownloadManifestEntry was invalid."); } } // Build the access strings string remoteURL = $"{baseRemoteURL}{Entry.RelativePath}"; string localPath = $"{baseLocalPath}{Path.DirectorySeparatorChar}{Entry.RelativePath}"; // Make sure we have a directory to put the file in if (Path.GetDirectoryName(localPath) != null) { Directory.CreateDirectory(Path.GetDirectoryName(localPath)); } else { throw new ArgumentNullException(nameof(localPath), "The local path was null."); } // Reset the cookie File.WriteAllText(ConfigHandler.GetInstallCookiePath(), string.Empty); // Write the current file progress to the install cookie using (TextWriter textWriterProgress = new StreamWriter(ConfigHandler.GetInstallCookiePath())) { textWriterProgress.WriteLine(Entry); textWriterProgress.Flush(); } if (File.Exists(localPath)) { FileInfo fileInfo = new FileInfo(localPath); if (fileInfo.Length != Entry.Size) { // If the file is partial, resume the download. if (fileInfo.Length < Entry.Size) { Log.Info($"Resuming interrupted file \"{Path.GetFileNameWithoutExtension(Entry.RelativePath)}\" at byte {fileInfo.Length}."); DownloadRemoteFile(remoteURL, localPath, Entry.Size, fileInfo.Length); } else { // If it's larger than expected, toss it in the bin and try again. Log.Info($"Restarting interrupted file \"{Path.GetFileNameWithoutExtension(Entry.RelativePath)}\": File bigger than expected."); File.Delete(localPath); DownloadRemoteFile(remoteURL, localPath, Entry.Size); } } else { string localHash; using (FileStream fs = File.OpenRead(localPath)) { localHash = MD5Handler.GetStreamHash(fs); } if (localHash != Entry.Hash) { // If the hash doesn't match, toss it in the bin and try again. Log.Info($"Redownloading file \"{Path.GetFileNameWithoutExtension(Entry.RelativePath)}\": " + $"Hash sum mismatch. Local: {localHash}, Expected: {Entry.Hash}"); File.Delete(localPath); DownloadRemoteFile(remoteURL, localPath, Entry.Size); } } } else { // No file, download it DownloadRemoteFile(remoteURL, localPath, Entry.Size); } if (ChecksHandler.IsRunningOnUnix()) { // If we're dealing with a file that should be executable, string gameName = Config.GetGameName(); bool bFileIsGameExecutable = (Path.GetFileName(localPath).EndsWith(".exe")) || (Path.GetFileName(localPath) == gameName); if (bFileIsGameExecutable) { // Set the execute bits UnixHandler.MakeExecutable(localPath); } } // We've finished the download, so empty the cookie File.WriteAllText(ConfigHandler.GetInstallCookiePath(), string.Empty); }
protected override void DownloadModule(EModule module) { throw new NotImplementedException(); }
/// <summary> /// Downloads the latest version of the specified module. /// </summary> /// <exception cref="ArgumentOutOfRangeException"> /// Will be thrown if the <see cref="EModule"/> passed to the function is not a valid value. /// </exception> protected override void DownloadModule(EModule module) { IReadOnlyList <ManifestEntry> moduleManifest; switch (module) { case EModule.Launcher: { RefreshModuleManifest(EModule.Launcher); this.ModuleInstallFinishedArgs.Module = EModule.Launcher; this.ModuleInstallFailedArgs.Module = EModule.Launcher; moduleManifest = this.FileManifestHandler.GetManifest(EManifestType.Launchpad, false); break; } case EModule.Game: { RefreshModuleManifest(EModule.Game); this.ModuleInstallFinishedArgs.Module = EModule.Game; this.ModuleInstallFailedArgs.Module = EModule.Game; moduleManifest = this.FileManifestHandler.GetManifest(EManifestType.Game, false); break; } default: { throw new ArgumentOutOfRangeException(nameof(module), module, "An invalid module value was passed to DownloadModule."); } } if (moduleManifest == null) { Log.Error($"No manifest was found when installing the module \"{module}\". The server files may be inaccessible or missing."); OnModuleInstallationFailed(); return; } // In order to be able to resume downloading, we check if there is an entry // stored in the install cookie. // Attempt to parse whatever is inside the install cookie ManifestEntry lastDownloadedFile; if (ManifestEntry.TryParse(File.ReadAllText(ConfigHandler.GetGameCookiePath()), out lastDownloadedFile)) { // Loop through all the entries in the manifest until we encounter // an entry which matches the one in the install cookie foreach (ManifestEntry fileEntry in moduleManifest) { if (lastDownloadedFile.Equals(fileEntry)) { // Skip all entries before the one we were last at. moduleManifest = moduleManifest.Skip(moduleManifest.ToList().IndexOf(fileEntry)).ToList(); } } } int downloadedFiles = 0; foreach (ManifestEntry fileEntry in moduleManifest) { ++downloadedFiles; // Prepare the progress event contents this.ModuleDownloadProgressArgs.IndicatorLabelMessage = GetDownloadIndicatorLabelMessage(Path.GetFileName(fileEntry.RelativePath), downloadedFiles, moduleManifest.Count); OnModuleDownloadProgressChanged(); DownloadManifestEntry(fileEntry, module); } }
/// <summary> /// Downloads the file referred to by the specifed manifest entry. /// </summary> /// <param name="fileEntry">The entry to download.</param> /// <param name="module">The module that the entry belongs to.</param> /// <param name="oldFileEntry">The old entry, if one exists.</param> /// <exception cref="ArgumentOutOfRangeException"> /// Will be thrown if the <see cref="EModule"/> passed to the function is not a valid value. /// </exception> /// <exception cref="ArgumentNullException"> /// Will be thrown if the local path set in the <paramref name="fileEntry"/> passed to the function is not a valid value. /// </exception> protected virtual void DownloadManifestEntry(ManifestEntry fileEntry, EModule module, ManifestEntry oldFileEntry = null) { this.ModuleDownloadProgressArgs.Module = module; string baseRemoteURL; string baseLocalPath; switch (module) { case EModule.Launcher: { baseRemoteURL = this.Config.GetLauncherBinariesURL(); baseLocalPath = ConfigHandler.GetTempLauncherDownloadPath(); break; } case EModule.Game: { baseRemoteURL = this.Config.GetGameURL(); baseLocalPath = this.Config.GetGamePath(); break; } default: { throw new ArgumentOutOfRangeException(nameof(module), module, "An invalid module value was passed to DownloadManifestEntry."); } } // Build the access strings string remoteURL = $"{baseRemoteURL}{fileEntry.RelativePath}"; string localPath = $"{baseLocalPath}{fileEntry.RelativePath}"; // Make sure we have a directory to put the file in if (!string.IsNullOrEmpty(localPath)) { string localPathParentDir = Path.GetDirectoryName(localPath); if (!Directory.Exists(localPathParentDir)) { Directory.CreateDirectory(Path.GetDirectoryName(localPath)); } } else { throw new ArgumentNullException(nameof(localPath), "The local path was null or empty."); } // Reset the cookie File.WriteAllText(ConfigHandler.GetGameCookiePath(), string.Empty); // Write the current file progress to the install cookie using (TextWriter textWriterProgress = new StreamWriter(ConfigHandler.GetGameCookiePath())) { textWriterProgress.WriteLine(fileEntry); textWriterProgress.Flush(); } // First, let's see if an old file exists, and is valid. if (oldFileEntry != null) { // Check if the file is present, the correct size, and the correct hash if (oldFileEntry.IsFileIntegrityIntact()) { // If it is, delete it. File.Delete(localPath); } } if (File.Exists(localPath)) { FileInfo fileInfo = new FileInfo(localPath); if (fileInfo.Length != fileEntry.Size) { // If the file is partial, resume the download. if (fileInfo.Length < fileEntry.Size) { Log.Info($"Resuming interrupted file \"{Path.GetFileNameWithoutExtension(fileEntry.RelativePath)}\" at byte {fileInfo.Length}."); DownloadRemoteFile(remoteURL, localPath, fileEntry.Size, fileInfo.Length); } else { // If it's larger than expected, toss it in the bin and try again. Log.Info($"Restarting interrupted file \"{Path.GetFileNameWithoutExtension(fileEntry.RelativePath)}\": File bigger than expected."); File.Delete(localPath); DownloadRemoteFile(remoteURL, localPath, fileEntry.Size); } } else { string localHash; using (FileStream fs = File.OpenRead(localPath)) { localHash = MD5Handler.GetStreamHash(fs); } if (localHash != fileEntry.Hash) { // If the hash doesn't match, toss it in the bin and try again. Log.Info($"Redownloading file \"{Path.GetFileNameWithoutExtension(fileEntry.RelativePath)}\": " + $"Hash sum mismatch. Local: {localHash}, Expected: {fileEntry.Hash}"); File.Delete(localPath); DownloadRemoteFile(remoteURL, localPath, fileEntry.Size); } } } else { // No file, download it DownloadRemoteFile(remoteURL, localPath, fileEntry.Size); } // We've finished the download, so empty the cookie File.WriteAllText(ConfigHandler.GetGameCookiePath(), string.Empty); }
/// <summary> /// Passes the internal event in the protocol handler to the outward-facing /// event. /// </summary> /// <param name="sender">Sender.</param> /// <param name="e">E.</param> private void OnModuleInstallationFailed(object sender, EModule e) { this.DownloadFailed?.Invoke(sender, EventArgs.Empty); }
/// <summary> /// Updates the specified module to the latest version. /// </summary> /// <param name="module">The module to update.</param> /// <exception cref="ArgumentOutOfRangeException"> /// Will be thrown if the <see cref="EModule"/> passed to the function is not a valid value. /// </exception> public override void UpdateModule(EModule module) { IReadOnlyList <ManifestEntry> manifest; IReadOnlyList <ManifestEntry> oldManifest; switch (module) { case EModule.Launcher: { RefreshModuleManifest(EModule.Launcher); this.ModuleInstallFinishedArgs.Module = EModule.Launcher; this.ModuleInstallFailedArgs.Module = EModule.Launcher; manifest = this.FileManifestHandler.GetManifest(EManifestType.Launchpad, false); oldManifest = this.FileManifestHandler.GetManifest(EManifestType.Launchpad, true); break; } case EModule.Game: { RefreshModuleManifest(EModule.Game); this.ModuleInstallFinishedArgs.Module = EModule.Game; this.ModuleInstallFailedArgs.Module = EModule.Game; manifest = this.FileManifestHandler.GetManifest(EManifestType.Game, false); oldManifest = this.FileManifestHandler.GetManifest(EManifestType.Game, true); break; } default: { throw new ArgumentOutOfRangeException(nameof(module), module, "An invalid module value was passed to UpdateModule."); } } // Check to see if we have valid manifests if (manifest == null) { Log.Error($"No manifest was found when updating the module \"{module}\". The server files may be inaccessible or missing."); OnModuleInstallationFailed(); return; } // This dictionary holds a list of new entries and their equivalents from the old manifest. It is used // to determine whether or not a file is partial, or merely old yet smaller. Dictionary <ManifestEntry, ManifestEntry> oldEntriesBeingReplaced = new Dictionary <ManifestEntry, ManifestEntry>(); List <ManifestEntry> filesRequiringUpdate = new List <ManifestEntry>(); foreach (ManifestEntry fileEntry in manifest) { filesRequiringUpdate.Add(fileEntry); if (oldManifest != null) { if (!oldManifest.Contains(fileEntry)) { // See if there is an old entry which matches the new one. ManifestEntry matchingOldEntry = oldManifest.FirstOrDefault(oldEntry => oldEntry.RelativePath == fileEntry.RelativePath); if (matchingOldEntry != null) { oldEntriesBeingReplaced.Add(fileEntry, matchingOldEntry); } } } } try { int updatedFiles = 0; foreach (ManifestEntry fileEntry in filesRequiringUpdate) { ++updatedFiles; this.ModuleUpdateProgressArgs.IndicatorLabelMessage = GetUpdateIndicatorLabelMessage(Path.GetFileName(fileEntry.RelativePath), updatedFiles, filesRequiringUpdate.Count); OnModuleUpdateProgressChanged(); // If we're updating an existing file, make sure to let the downloader know if (oldEntriesBeingReplaced.ContainsKey(fileEntry)) { DownloadManifestEntry(fileEntry, module, oldEntriesBeingReplaced[fileEntry]); } else { DownloadManifestEntry(fileEntry, module); } } } catch (IOException ioex) { Log.Warn($"Updating of {module} files failed (IOException): " + ioex.Message); OnModuleInstallationFailed(); return; } OnModuleInstallationFinished(); }
/// <summary> /// Changeemnt de module /// </summary> /// <param name="pModule">Module appeler</param> /// <remarks>LOUIS Yoann 06/09/2016</remarks> private void ChangeModule(EModule pModule) { // yl - Affectation du module this.ModuleEnCours = pModule; }
/// <summary> /// Invoke the <see cref="ModuleInstallationFailed"/> event. /// </summary> /// <param name="module">The module that failed.</param> protected void OnModuleInstallationFailed(EModule module) { this.ModuleInstallationFailed?.Invoke(this, module); }
private void OnLauncherDownloadFinished(object sender, EModule e) { this.LauncherDownloadFinished?.Invoke(sender, EventArgs.Empty); }
public override void UpdateModule(EModule Module) { List <ManifestEntry> Manifest; List <ManifestEntry> OldManifest; switch (Module) { case EModule.Launcher: { RefreshModuleManifest(EModule.Launcher); ModuleInstallFinishedArgs.Module = EModule.Launcher; ModuleInstallFailedArgs.Module = EModule.Launcher; Manifest = this.Manifest.LaunchpadManifest; OldManifest = this.Manifest.OldLaunchpadManifest; break; } case EModule.Game: { RefreshModuleManifest(EModule.Game); ModuleInstallFinishedArgs.Module = EModule.Game; ModuleInstallFailedArgs.Module = EModule.Game; Manifest = this.Manifest.GameManifest; OldManifest = this.Manifest.OldGameManifest; break; } default: { throw new ArgumentOutOfRangeException(nameof(Module), Module, null); } } List <ManifestEntry> FilesRequiringUpdate = new List <ManifestEntry>(); foreach (ManifestEntry Entry in Manifest) { if (!OldManifest.Contains(Entry)) { FilesRequiringUpdate.Add(Entry); } } try { int updatedFiles = 0; foreach (ManifestEntry Entry in FilesRequiringUpdate) { ++updatedFiles; ModuleUpdateProgressArgs.IndicatorLabelMessage = GetUpdateIndicatorLabelMessage(Path.GetFileName(Entry.RelativePath), updatedFiles, FilesRequiringUpdate.Count); OnModuleUpdateProgressChanged(); DownloadManifestEntry(Entry, Module); } } catch (IOException ioex) { Log.Warn($"Updating of {Module} files failed (IOException): " + ioex.Message); OnModuleInstallationFailed(); } OnModuleInstallationFinished(); }
/// <inheritdoc /> public override void VerifyModule(EModule module) { var manifest = this.FileManifestHandler.GetManifest((EManifestType)module, false); var brokenFiles = new List <ManifestEntry>(); if (manifest == null) { Log.Error($"No manifest was found when verifying the module \"{module}\". The server files may be inaccessible or missing."); OnModuleInstallationFailed(module); return; } try { var verifiedFiles = 0; foreach (var fileEntry in manifest) { ++verifiedFiles; // Prepare the progress event contents this.ModuleVerifyProgressArgs.IndicatorLabelMessage = GetVerifyIndicatorLabelMessage ( Path.GetFileName(fileEntry.RelativePath), verifiedFiles, manifest.Count ); OnModuleVerifyProgressChanged(); if (fileEntry.IsFileIntegrityIntact()) { continue; } brokenFiles.Add(fileEntry); Log.Info($"File \"{Path.GetFileName(fileEntry.RelativePath)}\" failed its integrity check and was queued for redownload."); } var downloadedFiles = 0; foreach (var fileEntry in brokenFiles) { ++downloadedFiles; // Prepare the progress event contents this.ModuleDownloadProgressArgs.IndicatorLabelMessage = GetDownloadIndicatorLabelMessage ( Path.GetFileName(fileEntry.RelativePath), downloadedFiles, brokenFiles.Count ); OnModuleDownloadProgressChanged(); for (int i = 0; i < this.Configuration.RemoteFileDownloadRetries; ++i) { if (!fileEntry.IsFileIntegrityIntact()) { DownloadManifestEntry(fileEntry, module); Log.Info($"File \"{Path.GetFileName(fileEntry.RelativePath)}\" failed its integrity check again after redownloading. ({i} retries)"); } else { break; } } } } catch (IOException ioex) { Log.Warn($"Verification of {module} files failed (IOException): " + ioex.Message); OnModuleInstallationFailed(module); } OnModuleInstallationFinished(module); }
/// <summary> /// Updates the specified module to the latest version. /// </summary> /// <param name="module">The module to update.</param> public abstract void UpdateModule(EModule module);
/// <summary> /// Determines whether or not the specified module is outdated. /// </summary> /// <param name="module">The module.</param> /// <returns>true if the module is outdated; otherwise, false.</returns> public abstract bool IsModuleOutdated(EModule module);
public override bool IsModuleOutdated(EModule module) { throw new NotImplementedException(); }
/// <summary> /// Downloads the provided manifest entry. /// This function resumes incomplete files, verifies downloaded files and /// downloads missing files. /// </summary> /// <param name="Entry">The entry to download.</param> /// <param name="Module">The module to download the file for. Determines download location.</param> private void DownloadEntry(ManifestEntry Entry, EModule Module) { ModuleDownloadProgressArgs.Module = Module; string baseRemotePath; string baseLocalPath; if (Module == EModule.Game) { baseRemotePath = Config.GetGameURL(); baseLocalPath = Config.GetGamePath(); } else { baseRemotePath = Config.GetLauncherBinariesURL(); baseLocalPath = ConfigHandler.GetTempLauncherDownloadPath(); } string RemotePath = String.Format("{0}{1}", baseRemotePath, Entry.RelativePath); string LocalPath = String.Format("{0}{1}{2}", baseLocalPath, Path.DirectorySeparatorChar, Entry.RelativePath); // Make sure we have a directory to put the file in Directory.CreateDirectory(Path.GetDirectoryName(LocalPath)); // Reset the cookie File.WriteAllText(ConfigHandler.GetInstallCookiePath(), String.Empty); // Write the current file progress to the install cookie using (TextWriter textWriterProgress = new StreamWriter(ConfigHandler.GetInstallCookiePath())) { textWriterProgress.WriteLine(Entry); textWriterProgress.Flush(); } if (File.Exists(LocalPath)) { FileInfo fileInfo = new FileInfo(LocalPath); if (fileInfo.Length != Entry.Size) { // If the file is partial, resume the download. if (fileInfo.Length < Entry.Size) { DownloadRemoteFile(RemotePath, LocalPath, fileInfo.Length); } else { // If it's larger than expected, toss it in the bin and try again. File.Delete(LocalPath); DownloadRemoteFile(RemotePath, LocalPath); } } else { string LocalHash; using (FileStream fs = File.OpenRead(LocalPath)) { LocalHash = MD5Handler.GetStreamHash(fs); } if (LocalHash != Entry.Hash) { File.Delete(LocalPath); DownloadRemoteFile(RemotePath, LocalPath); } } } else { //no file, download it DownloadRemoteFile(RemotePath, LocalPath); } if (ChecksHandler.IsRunningOnUnix()) { //if we're dealing with a file that should be executable, string gameName = Config.GetGameName(); bool bFileIsGameExecutable = (Path.GetFileName(LocalPath).EndsWith(".exe")) || (Path.GetFileName(LocalPath) == gameName); if (bFileIsGameExecutable) { //set the execute bits UnixHandler.MakeExecutable(LocalPath); } } // We've finished the download, so empty the cookie File.WriteAllText(ConfigHandler.GetInstallCookiePath(), String.Empty); }
/// <summary> /// Downloads the latest version of the specified module. /// </summary> /// <param name="module">The module.</param> protected abstract void DownloadModule(EModule module);
public override void UpdateModule(EModule module) { throw new NotImplementedException(); }
/// <summary> /// Verifies and repairs the files of the specified module. /// </summary> /// <param name="module">The module.</param> public abstract void VerifyModule(EModule module);
public override void VerifyModule(EModule module) { throw new NotImplementedException(); }