//public static bool EnsureStaticAssets() //{ // // This is not really used anymore. Just kept around in case new static assets are necessary. // // Used to download objectt infos. These are embedded into ME3ExplorerCore. // (string filename, string md5)[] objectInfoFiles = { }; // string localBaseDir = Utilities.GetObjectInfoFolder(); // try // { // bool downloadOK = false; // foreach (var info in objectInfoFiles) // { // var localPath = Path.Combine(localBaseDir, info.filename); // bool download = !File.Exists(localPath); // if (!download) // { // var calcedMd5 = Utilities.CalculateMD5(localPath); // download = calcedMd5 != info.md5; // if (download) Log.Warning($@"Invalid hash for local asset {info.filename}: got {calcedMd5}, expected {info.md5}. Redownloading"); // } // else // { // Log.Information($@"Local asset missing: {info.filename}, downloading"); // } // if (download) // { // foreach (var staticurl in StaticFilesBaseEndpoints) // { // var fullURL = staticurl + @"objectinfos/" + info.filename; // try // { // using var wc = new ShortTimeoutWebClient(); // Log.Information("Downloading static asset: " + fullURL); // wc.DownloadFile(fullURL, localPath); // downloadOK = true; // break; // } // catch (Exception e) // { // Log.Error($"Could not download {info} from endpoint {fullURL} {e.Message}"); // } // } // } // else downloadOK = true; //say we're OK // } // if (!downloadOK) // { // throw new Exception("At least one static asset failed to download. Mod Manager will not properly function without these assets. See logs for more information"); // } // } // catch (Exception e) // { // Log.Error("Exception trying to ensure static assets: " + e.Message); // Crashes.TrackError(new Exception(@"Could not download static supporting files: " + e.Message)); // return false; // } // return true; //} public static (MemoryStream result, string errorMessage) FetchString(string url) { using var wc = new ShortTimeoutWebClient(); string downloadError = null; MemoryStream responseStream = null; wc.DownloadDataCompleted += (a, args) => { downloadError = args.Error?.Message; if (downloadError == null) { responseStream = new MemoryStream(args.Result); } lock (args.UserState) { //releases blocked thread Monitor.Pulse(args.UserState); } }; var syncObject = new Object(); lock (syncObject) { Debug.WriteLine(@"Download file to memory: " + url); wc.DownloadDataAsync(new Uri(url), syncObject); //This will block the thread until download completes Monitor.Wait(syncObject); } return(responseStream, downloadError); }
/// <summary> /// Downloads from a URL to memory. This is a blocking call and should be done on a background thread. /// </summary> /// <param name="url">URL to download from</param> /// <param name="progressCallback">Progress information clalback</param> /// <param name="hash">Hash check value (md5). Leave null if no hash check</param> /// <returns></returns> public static (MemoryStream result, string errorMessage) DownloadToMemory(string url, Action <long, long> progressCallback = null, string hash = null) { using var wc = new ShortTimeoutWebClient(); string downloadError = null; MemoryStream responseStream = null; wc.DownloadProgressChanged += (a, args) => { progressCallback?.Invoke(args.BytesReceived, args.TotalBytesToReceive); }; wc.DownloadDataCompleted += (a, args) => { downloadError = args.Error?.Message; if (downloadError == null) { responseStream = new MemoryStream(args.Result); if (hash != null) { var md5 = Utilities.CalculateMD5(responseStream); responseStream.Position = 0; if (md5 != hash) { responseStream = null; downloadError = $"Hash of downloaded item ({url}) does not match expected hash. Expected: {hash}, got: {md5}"; //needs localized } } } lock (args.UserState) { //releases blocked thread Monitor.Pulse(args.UserState); } }; var syncObject = new Object(); lock (syncObject) { Debug.WriteLine("Download file to memory: " + url); wc.DownloadDataAsync(new Uri(url), syncObject); //This will block the thread until download completes Monitor.Wait(syncObject); } return(responseStream, downloadError); }