/// <summary> /// Returns an archive download link that returns a game archive for the specified OperatingSystem, game version, bitness and client type. /// </summary> /// <exception cref="ArgumentOutOfRangeException">The value of spec.OperatingSystem wasn't expected.</exception> public Uri GetGameArchiveDownloadUri(GameArchiveSpec spec) { /* uri format: factorio.com/get-download/{version}/{build}/{platform} * * version: 0.0.0 * build: alpha, demo, headless (only linux64 platform) * platform: * - win64: .exe file, win64-manual: .zip file, win32, .exe file, win32-manual: .zip file * - osx: .dmg file * - linux64: .tar.gz file, linux32: .tar.gz file * */ string platform; switch (spec.OperatingSystem) { case OperatingSystem.Windows: platform = "win64-manual"; break; case OperatingSystem.Mac: platform = "osx"; break; case OperatingSystem.Linux: platform = "linux64"; break; default: throw new ArgumentOutOfRangeException(); } var uriTail = string.Format("{0}/{1}/{2}", spec.Version, spec.BuildConfiguration, platform); return(new Uri(_gameArchiveDownloadsUriBase, uriTail)); }
/// <summary> /// Note: the extension component of the destination path in the GameArchive result may be different based on the archive format received. /// </summary> /// <exception cref="SecurityException">The caller does not have the required permission to access the file.</exception> /// <exception cref="ArgumentNullException"><paramref name="spec"/> or <paramref name="destinationPath"/> is <see langword="null" />.</exception> /// <exception cref="FileNotFoundException"></exception> /// <exception cref="HttpRequestException">Recieved an error status code that could not be recovered from.</exception> public async Task <GameArchive> GetGameAsArchive(GameArchiveSpec spec, string destinationPath) { if (spec == null) { throw new ArgumentNullException("spec"); } if (destinationPath == null) { throw new ArgumentNullException("destinationPath"); } // Append the proper extension if it doesn't have it already // So that apps like 7z can properly extract the file in the future var extension = spec.GetFileExtension(); if (!destinationPath.EndsWith(extension)) { destinationPath = destinationPath + extension; } try { using (var outStream = new FileStream(destinationPath, FileMode.OpenOrCreate)) using (var inStream = await GetGameAsArchiveStream(spec)) { await inStream.CopyToAsync(outStream); } } catch (DirectoryNotFoundException ex) { throw new FileNotFoundException(ex.Message, ex); } return(new GameArchive(destinationPath, spec)); }
// ReSharper disable ExceptionNotThrown /// <exception cref="WebException">Request failed due to a bad connection (e.g. no internet).</exception> /// <exception cref="HttpRequestException">Recieved an error status code that could not be recovered from.</exception> // ReSharper restore ExceptionNotThrown public async Task <Stream> GetGameAsArchiveStream(GameArchiveSpec spec) { var uri = _homepageUriFactory.GetGameArchiveDownloadUri(spec); return(await _client.GetStreamAsync(uri)); }