/// <summary> /// Alternative to Form.ShowDialog() that will not stall out unit tests. /// </summary> /// <param name="frmForm"></param> /// <param name="owner"></param> /// <returns></returns> public static Task <DialogResult> ShowDialogSafeAsync(this Form frmForm, IWin32Window owner = null) { // Unit tests cannot use ShowDialog because that will stall them out return(!Utils.IsUnitTest ? Task.FromResult(frmForm.ShowDialog(owner)) : ShowDialogSafeUnitTestAsync()); async Task <DialogResult> ShowDialogSafeUnitTestAsync() { bool blnDoClose = false; void FormOnShown(object sender, EventArgs args) => blnDoClose = true; frmForm.Shown += FormOnShown; frmForm.Show(owner); while (!blnDoClose) { await Utils.SafeSleepAsync(); } frmForm.Close(); return(frmForm.DialogResult); } }
private async ValueTask LoadConnection() { while (_clientChangelogDownloader.IsBusy) { await Utils.SafeSleepAsync(); } _blnIsConnected = false; if (_objConnectionLoaderCancellationTokenSource.IsCancellationRequested) { return; } bool blnChummerVersionGotten = true; string strError = (await LanguageManager.GetStringAsync("String_Error")).Trim(); _strExceptionString = string.Empty; LatestVersion = strError; Uri uriUpdateLocation = new Uri(_blnPreferNightly ? "https://api.github.com/repos/chummer5a/chummer5a/releases" : "https://api.github.com/repos/chummer5a/chummer5a/releases/latest"); HttpWebRequest request = null; try { WebRequest objTemp = WebRequest.Create(uriUpdateLocation); request = objTemp as HttpWebRequest; } catch (System.Security.SecurityException) { blnChummerVersionGotten = false; } if (request == null) { blnChummerVersionGotten = false; } if (blnChummerVersionGotten) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; request.UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)"; request.Accept = "application/json"; request.Timeout = 5000; // Get the response. HttpWebResponse response = null; try { response = await request.GetResponseAsync() as HttpWebResponse; if (_objConnectionLoaderCancellationTokenSource.IsCancellationRequested) { return; } // Get the stream containing content returned by the server. using (Stream dataStream = response?.GetResponseStream()) { if (dataStream == null) { blnChummerVersionGotten = false; } if (blnChummerVersionGotten) { if (_objConnectionLoaderCancellationTokenSource.IsCancellationRequested) { return; } // Open the stream using a StreamReader for easy access. string responseFromServer; using (StreamReader reader = new StreamReader(dataStream, Encoding.UTF8, true)) responseFromServer = await reader.ReadToEndAsync(); if (_objConnectionLoaderCancellationTokenSource.IsCancellationRequested) { return; } bool blnFoundTag = false; bool blnFoundArchive = false; foreach (string line in responseFromServer.SplitNoAlloc(',', StringSplitOptions.RemoveEmptyEntries)) { if (_objConnectionLoaderCancellationTokenSource.IsCancellationRequested) { return; } if (!blnFoundTag && line.Contains("tag_name")) { _strLatestVersion = line.SplitNoAlloc(':').ElementAtOrDefault(1); LatestVersion = _strLatestVersion.SplitNoAlloc('}').FirstOrDefault().FastEscape('\"').Trim(); blnFoundTag = true; if (blnFoundArchive) { break; } } if (!blnFoundArchive && line.Contains("browser_download_url")) { _strDownloadFile = line.SplitNoAlloc(':').ElementAtOrDefault(2) ?? string.Empty; _strDownloadFile = _strDownloadFile.Substring(2); _strDownloadFile = _strDownloadFile.SplitNoAlloc('}').FirstOrDefault().FastEscape('\"'); _strDownloadFile = "https://" + _strDownloadFile; blnFoundArchive = true; if (blnFoundTag) { break; } } } if (!blnFoundArchive || !blnFoundTag) { blnChummerVersionGotten = false; } } } } catch (WebException ex) { blnChummerVersionGotten = false; string strException = ex.ToString(); int intNewLineLocation = strException.IndexOf(Environment.NewLine, StringComparison.Ordinal); if (intNewLineLocation == -1) { intNewLineLocation = strException.IndexOf('\n'); } if (intNewLineLocation != -1) { strException = strException.Substring(0, intNewLineLocation); } _strExceptionString = strException; } finally { response?.Close(); } } if (!blnChummerVersionGotten || LatestVersion == strError) { if (!SilentMode) { Program.MainForm.ShowMessageBox(this, string.IsNullOrEmpty(_strExceptionString) ? await LanguageManager.GetStringAsync("Warning_Update_CouldNotConnect") : string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync("Warning_Update_CouldNotConnectException"), _strExceptionString), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } return; } if (File.Exists(_strTempLatestVersionChangelogPath)) { if (!await Utils.SafeDeleteFileAsync(_strTempLatestVersionChangelogPath + ".old", !SilentMode)) { return; } File.Move(_strTempLatestVersionChangelogPath, _strTempLatestVersionChangelogPath + ".old"); } string strUrl = "https://raw.githubusercontent.com/chummer5a/chummer5a/" + LatestVersion + "/Chummer/changelog.txt"; try { Uri uriConnectionAddress = new Uri(strUrl); if (!await Utils.SafeDeleteFileAsync(_strTempLatestVersionChangelogPath + ".tmp", !SilentMode)) { return; } await _clientChangelogDownloader.DownloadFileTaskAsync(uriConnectionAddress, _strTempLatestVersionChangelogPath + ".tmp"); if (_objConnectionLoaderCancellationTokenSource.IsCancellationRequested) { return; } File.Move(_strTempLatestVersionChangelogPath + ".tmp", _strTempLatestVersionChangelogPath); } catch (WebException ex) { string strException = ex.ToString(); int intNewLineLocation = strException.IndexOf(Environment.NewLine, StringComparison.Ordinal); if (intNewLineLocation == -1) { intNewLineLocation = strException.IndexOf('\n'); } if (intNewLineLocation != -1) { strException = strException.Substring(0, intNewLineLocation); } _strExceptionString = strException; if (!SilentMode) { Program.MainForm.ShowMessageBox(this, string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync("Warning_Update_CouldNotConnectException"), strException), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } return; } catch (UriFormatException ex) { string strException = ex.ToString(); int intNewLineLocation = strException.IndexOf(Environment.NewLine, StringComparison.Ordinal); if (intNewLineLocation == -1) { intNewLineLocation = strException.IndexOf('\n'); } if (intNewLineLocation != -1) { strException = strException.Substring(0, intNewLineLocation); } _strExceptionString = strException; if (!SilentMode) { Program.MainForm.ShowMessageBox(this, string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync("Warning_Update_CouldNotConnectException"), strException), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } return; } _blnIsConnected = true; }
private async Task <bool> LoadFromFileCoreAsync(bool blnSync, string strFile) { while (IsLoadMethodRunning) { if (blnSync) { Utils.SafeSleep(); } else { await Utils.SafeSleepAsync(); } } IsLoadMethodRunning = true; try { DownLoadRunning = null; string strErrorText = string.Empty; XPathNavigator xmlSourceNode; if (!File.Exists(strFile)) { xmlSourceNode = null; strErrorText = blnSync // ReSharper disable once MethodHasAsyncOverload ? LanguageManager.GetString("MessageTitle_FileNotFound") : await LanguageManager.GetStringAsync("MessageTitle_FileNotFound"); } else { // If we run into any problems loading the character cache, fail out early. try { XPathDocument xmlDoc = blnSync ? LoadXPathDocument() : await Task.Run(LoadXPathDocument); XPathDocument LoadXPathDocument() { using (StreamReader objStreamReader = new StreamReader(strFile, Encoding.UTF8, true)) { using (XmlReader objXmlReader = XmlReader.Create(objStreamReader, GlobalSettings.SafeXmlReaderSettings)) { return(new XPathDocument(objXmlReader)); } } } xmlSourceNode = xmlDoc.CreateNavigator().SelectSingleNodeAndCacheExpression("/character"); } catch (Exception ex) { xmlSourceNode = null; strErrorText = ex.ToString(); } } if (xmlSourceNode != null) { Description = xmlSourceNode.SelectSingleNodeAndCacheExpression("description")?.Value; BuildMethod = xmlSourceNode.SelectSingleNodeAndCacheExpression("buildmethod")?.Value; Background = xmlSourceNode.SelectSingleNodeAndCacheExpression("background")?.Value; CharacterNotes = xmlSourceNode.SelectSingleNodeAndCacheExpression("notes")?.Value; GameNotes = xmlSourceNode.SelectSingleNodeAndCacheExpression("gamenotes")?.Value; Concept = xmlSourceNode.SelectSingleNodeAndCacheExpression("concept")?.Value; Karma = xmlSourceNode.SelectSingleNodeAndCacheExpression("totalkarma")?.Value; Metatype = xmlSourceNode.SelectSingleNodeAndCacheExpression("metatype")?.Value; Metavariant = xmlSourceNode.SelectSingleNodeAndCacheExpression("metavariant")?.Value; PlayerName = xmlSourceNode.SelectSingleNodeAndCacheExpression("playername")?.Value; CharacterName = xmlSourceNode.SelectSingleNodeAndCacheExpression("name")?.Value; CharacterAlias = xmlSourceNode.SelectSingleNodeAndCacheExpression("alias")?.Value; Created = xmlSourceNode.SelectSingleNodeAndCacheExpression("created")?.Value == bool.TrueString; Essence = xmlSourceNode.SelectSingleNodeAndCacheExpression("totaless")?.Value; string strSettings = xmlSourceNode.SelectSingleNodeAndCacheExpression("settings")?.Value ?? string.Empty; if (!string.IsNullOrEmpty(strSettings)) { if (SettingsManager.LoadedCharacterSettings.TryGetValue( strSettings, out CharacterSettings objSettings)) { SettingsFile = objSettings.DisplayName; } else { string strTemp = blnSync // ReSharper disable once MethodHasAsyncOverload ? LanguageManager.GetString("MessageTitle_FileNotFound") + // ReSharper disable once MethodHasAsyncOverload LanguageManager.GetString("String_Space") : await LanguageManager.GetStringAsync("MessageTitle_FileNotFound") + await LanguageManager.GetStringAsync("String_Space"); SettingsFile = strTemp + '[' + strSettings + ']'; } } else { SettingsFile = string.Empty; } string strMugshotBase64 = xmlSourceNode.SelectSingleNodeAndCacheExpression("mugshot")?.Value ?? string.Empty; if (string.IsNullOrEmpty(strMugshotBase64)) { XPathNavigator xmlMainMugshotIndex = xmlSourceNode.SelectSingleNodeAndCacheExpression("mainmugshotindex"); if (xmlMainMugshotIndex != null && int.TryParse(xmlMainMugshotIndex.Value, out int intMainMugshotIndex) && intMainMugshotIndex >= 0) { XPathNodeIterator xmlMugshotList = xmlSourceNode.SelectAndCacheExpression("mugshots/mugshot"); if (xmlMugshotList.Count > intMainMugshotIndex) { int intIndex = 0; foreach (XPathNavigator xmlMugshot in xmlMugshotList) { if (intMainMugshotIndex == intIndex) { strMugshotBase64 = xmlMugshot.Value; break; } ++intIndex; } } } } if (!string.IsNullOrEmpty(strMugshotBase64)) { if (blnSync) { // ReSharper disable once MethodHasAsyncOverload using (Image imgMugshot = strMugshotBase64.ToImage()) // ReSharper disable once MethodHasAsyncOverload Mugshot = imgMugshot.GetCompressedImage(); } else { using (Image imgMugshot = await strMugshotBase64.ToImageAsync()) Mugshot = await imgMugshot.GetCompressedImageAsync(); } } } else { ErrorText = strErrorText; } FilePath = strFile; if (!string.IsNullOrEmpty(strFile)) { int last = strFile.LastIndexOf(Path.DirectorySeparatorChar) + 1; if (strFile.Length > last) { FileName = strFile.Substring(last); } } return(string.IsNullOrEmpty(strErrorText)); } finally { IsLoadMethodRunning = false; } }