/// <summary> /// Asynchronously download an XML and deserializes it into the specified type. /// </summary> /// <typeparam name="T">The inner type to deserialize</typeparam> /// <param name="url">The url to query</param> /// <param name="param">The request parameters. If null, defaults will be used.</param> /// <param name="transform">The XSL transform to apply, may be null.</param> internal static async Task <CCPAPIResult <T> > DownloadAPIResultAsync <T>(Uri url, RequestParams param = null, XslCompiledTransform transform = null) { var asyncResult = await HttpWebClientService.DownloadXmlAsync(url, param); CCPAPIResult <T> result; try { // Was there an HTTP error ? result = (asyncResult.Error != null) ? new CCPAPIResult <T>(asyncResult.Error) : DeserializeAPIResultCore <T>(asyncResult.Result, transform); // We got the result return(result); } catch (Exception e) { result = new CCPAPIResult <T>(HttpWebClientServiceException.Exception(url, e)); ExceptionHandler.LogException(e, false); EveMonClient.Trace($"Method: DownloadAPIResultAsync, url: {url.AbsoluteUri}, postdata: {param?.Content}, type: {typeof(T).Name}", false); } return(result); }
/// <summary> /// Synchronously download an XML and deserializes it into the specified type. /// </summary> /// <typeparam name="T">The inner type to deserialize</typeparam> /// <param name="url">The url to query</param> /// <param name="acceptEncoded">if set to <c>true</c> accept encoded response.</param> /// <param name="postData">The post data.</param> /// <param name="transform">The XSL transform to apply, may be null.</param> internal static CCPAPIResult <T> DownloadAPIResult <T>(Uri url, bool acceptEncoded = false, string postData = null, XslCompiledTransform transform = null) { CCPAPIResult <T> result; try { DownloadResult <IXPathNavigable> apiResult = HttpWebClientService.DownloadXmlAsync(url, HttpMethod.Post, acceptEncoded, postData).Result; // Was there an HTTP error ? result = apiResult.Error != null ? new CCPAPIResult <T>(apiResult.Error) : DeserializeAPIResultCore <T>(apiResult.Result, transform); } catch (Exception e) { ExceptionHandler.LogException(e, true); result = new CCPAPIResult <T>(Enumerations.CCPAPI.CCPAPIErrors.Http, e.Message); EveMonClient.Trace( $"Method: DownloadAPIResult, url: {url.AbsoluteUri}, postdata: {postData}, type: {typeof(T).Name}", false); } // Returns return(result); }
/// <summary> /// Asynchronously download an XML and deserializes it into the specified type. /// </summary> /// <typeparam name="T">The inner type to deserialize</typeparam> /// <param name="url">The url to query</param> /// <param name="acceptEncoded">if set to <c>true</c> accept encoded response.</param> /// <param name="postData">The post data.</param> /// <param name="transform">The XSL transform to apply, may be null.</param> internal static async Task <CCPAPIResult <T> > DownloadAPIResultAsync <T>(Uri url, bool acceptEncoded = false, string postData = null, XslCompiledTransform transform = null) { DownloadResult <IXPathNavigable> asyncResult = await HttpWebClientService.DownloadXmlAsync(url, HttpMethod.Post, acceptEncoded, postData); CCPAPIResult <T> result; try { // Was there an HTTP error ? result = asyncResult.Error != null ? new CCPAPIResult <T>(asyncResult.Error) : DeserializeAPIResultCore <T>(asyncResult.Result, transform); // We got the result return(result); } catch (Exception e) { result = new CCPAPIResult <T>(HttpWebClientServiceException.Exception(url, e)); ExceptionHandler.LogException(e, false); EveMonClient.Trace( $"Method: DownloadAPIResultAsync, url: {url.AbsoluteUri}, postdata: {postData}, type: {typeof(T).Name}", false); } return(result); }
/// <summary> /// Try to deserialize the settings from a file, prompting the user for errors. /// </summary> /// <returns><c>Null</c> if we have been unable to load anything from files, the generated settings otherwise</returns> private static SerializableSettings TryDeserializeFromFile() { string settingsFile = EveMonClient.SettingsFileNameFullPath; string backupFile = settingsFile + ".bak"; // If settings file doesn't exists // try to recover from the backup if (!File.Exists(settingsFile)) { return(TryDeserializeFromBackupFile(backupFile)); } EveMonClient.Trace("begin"); // Check settings file length FileInfo settingsInfo = new FileInfo(settingsFile); if (settingsInfo.Length == 0) { return(TryDeserializeFromBackupFile(backupFile)); } // Get the revision number of the assembly which generated this file // Try to load from a file (when no revision found then it's a pre 1.3.0 version file) SerializableSettings settings = Util.GetRevisionNumber(settingsFile) == 0 ? (SerializableSettings)UIHelper.ShowNoSupportMessage() : Util.DeserializeXmlFromFile <SerializableSettings>(settingsFile, SettingsTransform); // If the settings loaded OK, make a backup as 'last good settings' and return if (settings == null) { return(TryDeserializeFromBackupFile(backupFile)); } CheckSettingsVersion(settings); FileHelper.CopyOrWarnTheUser(settingsFile, backupFile); EveMonClient.Trace("done"); return(settings); }
/// <summary> /// Try to deserialize the settings from a storage server file, prompting the user for errors. /// </summary> /// <param name="fileContent">Content of the file.</param> /// <returns> /// <c>Null</c> if we have been unable to deserialize anything, the generated settings otherwise /// </returns> private static SerializableSettings TryDeserializeFromFileContent(string fileContent) { if (String.IsNullOrWhiteSpace(fileContent)) { return(null); } EveMonClient.Trace("begin"); // Gets the revision number of the assembly which generated this file int revision = Util.GetRevisionNumber(fileContent); // Try to load from a file (when no revision found then it's a pre 1.3.0 version file) SerializableSettings settings = revision == 0 ? (SerializableSettings)UIHelper.ShowNoSupportMessage() : Util.DeserializeXmlFromString <SerializableSettings>(fileContent, SettingsTransform); if (settings != null) { EveMonClient.Trace("done"); return(settings); } const string Caption = "Corrupt Settings"; DialogResult dr = MessageBox.Show($"Loading settings from {CloudStorageServiceProvider.ProviderName} failed." + $"{Environment.NewLine}Do you want to use the local settings file?", Caption, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); if (dr != DialogResult.No) { return(TryDeserializeFromFile()); } MessageBox.Show($"A new settings file will be created.{Environment.NewLine}" + @"You may wish then to restore a saved copy of the file.", Caption, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return(null); }
/// <summary> /// Imports the provided serialization object. /// </summary> private static void Import() { EveMonClient.Trace("begin"); // When null, we just reset if (s_settings == null) { s_settings = new SerializableSettings(); } try { // API settings SSOClientID = s_settings.SSOClientID ?? string.Empty; SSOClientSecret = s_settings.SSOClientSecret ?? string.Empty; // User settings UI = s_settings.UI; G15 = s_settings.G15; Proxy = s_settings.Proxy; Updates = s_settings.Updates; Calendar = s_settings.Calendar; Exportation = s_settings.Exportation; MarketPricer = s_settings.MarketPricer; Notifications = s_settings.Notifications; Compatibility = s_settings.Compatibility; LoadoutsProvider = s_settings.LoadoutsProvider; PortableEveInstallations = s_settings.PortableEveInstallations; CloudStorageServiceProvider = s_settings.CloudStorageServiceProvider; // Scheduler Scheduler.Import(s_settings.Scheduler); } finally { EveMonClient.Trace("done"); // Notify the subscribers EveMonClient.OnSettingsChanged(); } }
/// <summary> /// Imports the data. /// </summary> private static void ImportData() { EveMonClient.Trace("begin"); if (s_settings == null) { s_settings = new SerializableSettings(); } EveMonClient.ResetCollections(); EveMonClient.Characters.Import(s_settings.Characters); EveMonClient.ESIKeys.Import(s_settings.ESIKeys); EveMonClient.Characters.ImportPlans(s_settings.Plans); EveMonClient.MonitoredCharacters.Import(s_settings.MonitoredCharacters); OnImportCompleted(); EveMonClient.Trace("done"); // Notify the subscribers EveMonClient.OnSettingsChanged(); }
/// <summary> /// Performs the check asynchronously. /// </summary> /// <remarks> /// Invoked on the UI thread the first time and on some background thread the rest of the time. /// </remarks> private static async Task BeginCheckAsync() { // If update manager has been disabled since the last // update was triggered quit out here if (!s_enabled) { s_checkScheduled = false; return; } // No connection ? Recheck in one minute if (!NetworkMonitor.IsNetworkAvailable) { ScheduleCheck(TimeSpan.FromMinutes(1)); return; } EveMonClient.Trace(); string updateAddress = $"{NetworkConstants.GitHubBase}{NetworkConstants.EVEMonUpdates}"; // Otherwise, query for the patch file // First look up for an emergency patch await Util.DownloadXmlAsync <SerializablePatch>( new Uri($"{updateAddress.Replace(".xml", string.Empty)}-emergency.xml")) .ContinueWith(async task => { DownloadResult <SerializablePatch> result = task.Result; // If no emergency patch found proceed with the regular if (result.Error != null) { result = await Util.DownloadXmlAsync <SerializablePatch>(new Uri(updateAddress)); } // Proccess the result OnCheckCompleted(result); }, EveMonClient.CurrentSynchronizationContext).ConfigureAwait(false); }
/// <summary> /// Called when patch file check completed. /// </summary> /// <param name="result">The result.</param> private static void OnCheckCompleted(DownloadResult <SerializablePatch> result) { // If update manager has been disabled since the last // update was triggered quit out here if (!s_enabled) { s_checkScheduled = false; return; } // Was there an error ? if (result.Error != null) { // Logs the error and reschedule EveMonClient.Trace($"UpdateManager - {result.Error.Message}", printMethod: false); ScheduleCheck(TimeSpan.FromMinutes(1)); return; } try { // No error, let's try to deserialize ScanUpdateFeed(result.Result); } catch (InvalidOperationException exc) { // An error occurred during the deserialization ExceptionHandler.LogException(exc, true); } finally { EveMonClient.Trace(); // Reschedule ScheduleCheck(s_frequency); } }
/// <summary> /// Try to deserialize from the backup file. /// </summary> /// <param name="backupFile">The backup file.</param> /// <param name="recover">if set to <c>true</c> do a settings recover attempt.</param> /// <returns> /// <c>Null</c> if we have been unable to load anything from files, the generated settings otherwise /// </returns> private static SerializableSettings TryDeserializeFromBackupFile(string backupFile, bool recover = true) { // Backup file doesn't exist if (!File.Exists(backupFile)) { return(null); } EveMonClient.Trace("begin"); // Check backup settings file length FileInfo backupInfo = new FileInfo(backupFile); if (backupInfo.Length == 0) { return(null); } string settingsFile = EveMonClient.SettingsFileNameFullPath; const string Caption = "Corrupt Settings"; if (recover) { // Prompts the user to use the backup string fileDate = $"{backupInfo.LastWriteTime.ToLocalTime().ToShortDateString()} " + $"at {backupInfo.LastWriteTime.ToLocalTime().ToShortTimeString()}"; DialogResult dialogResult = MessageBox.Show( $"The settings file is missing or corrupt. There is a backup available from {fileDate}.{Environment.NewLine}" + @"Do you want to use the backup file?", Caption, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); if (dialogResult == DialogResult.No) { MessageBox.Show($"A new settings file will be created.{Environment.NewLine}" + @"You may wish then to restore a saved copy of the file.", Caption, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); // Save a copy of the corrupt file just in case FileHelper.CopyOrWarnTheUser(backupFile, settingsFile + ".corrupt"); return(null); } } // Get the revision number of the assembly which generated this file // Try to load from a file (when no revision found then it's a pre 1.3.0 version file) SerializableSettings settings = Util.GetRevisionNumber(backupFile) == 0 ? (SerializableSettings)UIHelper.ShowNoSupportMessage() : Util.DeserializeXmlFromFile <SerializableSettings>(backupFile, SettingsTransform); // If the settings loaded OK, copy to the main settings file, then copy back to stamp date if (settings != null) { CheckSettingsVersion(settings); FileHelper.CopyOrWarnTheUser(backupFile, settingsFile); FileHelper.CopyOrWarnTheUser(settingsFile, backupFile); EveMonClient.Trace("done"); return(settings); } if (recover) { // Backup failed too, notify the user we have a problem MessageBox.Show($"Loading from backup failed.\nA new settings file will be created.{Environment.NewLine}" + @"You may wish then to restore a saved copy of the file.", Caption, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); // Save a copy of the corrupt file just in case FileHelper.CopyOrWarnTheUser(backupFile, settingsFile + ".corrupt"); } else { // Restoring from file failed MessageBox.Show($"Restoring settings from {backupFile} failed, the file is corrupted.", Caption, MessageBoxButtons.OK, MessageBoxIcon.Warning); } return(null); }
/// <summary> /// Schedules a check a specified time period in the future. /// </summary> /// <param name="time">Time period in the future to start check.</param> private static void ScheduleCheck(TimeSpan time) { s_checkScheduled = true; Dispatcher.Schedule(time, () => BeginCheckAsync().ConfigureAwait(false)); EveMonClient.Trace($"in {time}"); }