/// <summary> /// Imports data from the given character sheet informations. /// </summary> /// <param name="serial">The serialized character sheet</param> internal void Import(CCPAPIResult <SerializableAPICharacterSheet> serial) { Import(serial.Result); EveMonClient.OnCharacterUpdated(this); }
protected override void TriggerEvent() { EveMonClient.OnEveIDToNameUpdated(); s_savePending = true; }
/// <summary> /// Checks the query status. /// </summary> /// <param name="result">The result.</param> /// <returns></returns> private bool CheckQueryStatus(DownloadResult <SerializableECItemPrices> result) { s_queryCounter--; if (result == null || result.Error != null) { if (result?.Error != null) { EveMonClient.Trace(result.Error.Message); // Abort further attempts if (result.Error.Status == HttpWebClientServiceExceptionStatus.Timeout || result.Error.Status == HttpWebClientServiceExceptionStatus.ServerError) { s_queue.Clear(); // Set a retry Loaded = true; CachedUntil = DateTime.UtcNow.AddHours(1); // Reset query pending flag s_queryPending = false; EveMonClient.OnPricesDownloaded(null, string.Empty); // We return 'true' to avoid saving a file return(true); } // If it's a 'Bad Request' just return // We'll check those items later on a lower query step if (result.Error.Status == HttpWebClientServiceExceptionStatus.Exception && result.Error.Message.Contains("400 (Bad Request)") && s_queue.Count != 0) { return(true); } // If we are done set the proper flags if (!s_queryMonitorList.Any() || s_queryStep <= 1) { Loaded = true; EveMonClient.Trace("ECItemPricer.Import - done", printMethod: false); return(false); } } } // When the query succeeds import the data and remove the ids from the monitoring list if (result?.Result != null) { foreach (SerializableECItemPriceListItem item in result.Result.ItemPrices) { s_queryMonitorList.Remove(item.ID); } Import(result.Result.ItemPrices); } // If all items where queried we are done if (s_queryCounter == 0 && s_queue.Count == 0 && s_queryStep <= 1) { return(false); } // If there are still items in queue just continue if (s_queryCounter != 0 || !s_queryMonitorList.Any() || s_queue.Count != 0) { return(true); } // if there are ids still to query repeat the query on a lower query step s_queryStep = s_queryStep / 2; s_queue = new Queue <int>(s_queryMonitorList); Task.WhenAll(QueryIDs()); return(true); }
/// <summary> /// Adds an API key to this collection. /// </summary> /// <param name="apiKey"></param> internal void Add(ESIKey apiKey) { Items.Add(apiKey.ID, apiKey); EveMonClient.OnESIKeyCollectionChanged(); }
protected override void TriggerEvent() { EveMonClient.OnConquerableStationListUpdated(); }
/// <summary> /// Removes the given set. /// </summary> /// <param name="set"></param> public void Remove(ImplantSet set) { m_customSets.Remove(set); EveMonClient.OnCharacterUpdated(m_character); }
protected override void TriggerEvent() { EveMonClient.OnEveIDToNameUpdated(); }
/// <summary> /// Called when the check fails. /// </summary> /// <param name="exc">The exc.</param> private static void CheckFailure(Exception exc) { EveMonClient.Trace(exc.Message); ScheduleCheck(TimeSpan.FromMinutes(1)); }
/// <summary> /// Check for time synchronization, /// or reschedule it for later if no connection is available. /// </summary> public static void ScheduleCheck(TimeSpan time) { Dispatcher.Schedule(time, () => BeginCheckAsync().ConfigureAwait(false)); EveMonClient.Trace($"in {time}"); }
/// <summary> /// Occurs when we downloaded a loadout from the provider. /// </summary> /// <param name="result">The result.</param> private static void OnLoadoutDownloaded(DownloadResult <String> result) { s_queryPending = false; EveMonClient.OnLoadoutDownloaded(result.Result, result.Error?.Message); }
/// <summary> /// When the collection changed, the global event is fired. /// </summary> protected override void OnChanged() { EveMonClient.OnCharacterPlanCollectionChanged(m_owner); }
/// <summary> /// Occurs when we downloaded a loadouts feed from the provider. /// </summary> /// <param name="loadoutFeed">The loadout feed.</param> /// <param name="errorMessage">The error message.</param> private static void OnLoadoutsFeedDownloaded(object loadoutFeed, string errorMessage) { s_queryFeedPending = false; EveMonClient.OnLoadoutsFeedDownloaded(loadoutFeed, errorMessage); }
/// <summary> /// Method to determine if the user's clock is syncrhonised to NIST time. /// </summary> private static async Task BeginCheckAsync() { if (!NetworkMonitor.IsNetworkAvailable) { // Reschedule later otherwise ScheduleCheck(TimeSpan.FromMinutes(1)); return; } EveMonClient.Trace(); Uri url = new Uri(NetworkConstants.NISTTimeServer); DateTime serverTimeToLocalTime; bool isSynchronised; await Dns.GetHostAddressesAsync(url.Host) .ContinueWith(async task => { IPAddress[] ipAddresses = task.Result; if (!ipAddresses.Any()) { return; } try { DateTime dateTimeNowUtc; DateTime localTime = DateTime.Now; using (TcpClient tcpClient = new TcpClient()) { await tcpClient.ConnectAsync(ipAddresses.First(), url.Port); using (NetworkStream netStream = tcpClient.GetStream()) { // Set a three seconds timeout netStream.ReadTimeout = (int)TimeSpan.FromSeconds(3).TotalMilliseconds; byte[] data = new byte[24]; await netStream.ReadAsync(data, 0, data.Length); data = data.Skip(7).Take(17).ToArray(); string dateTimeText = Encoding.ASCII.GetString(data); dateTimeNowUtc = DateTime.ParseExact(dateTimeText, "yy-MM-dd HH:mm:ss", CultureInfo.CurrentCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal); } } serverTimeToLocalTime = dateTimeNowUtc.ToLocalTime(); TimeSpan timediff = TimeSpan.FromSeconds(Math.Abs(serverTimeToLocalTime.Subtract(localTime).TotalSeconds)); isSynchronised = timediff < TimeSpan.FromSeconds(60); OnCheckCompleted(isSynchronised, serverTimeToLocalTime, localTime); } catch (Exception exc) { CheckFailure(exc); } }, EveMonClient.CurrentSynchronizationContext).ConfigureAwait(false); }
protected override void TriggerEvent() { EveMonClient.OnConquerableStationListUpdated(); s_savePending = true; }
/// <summary> /// Starts up the application asynchronously. /// </summary> /// <returns></returns> private static async Task StartupAsync() { // Quits if another instance already exists if (!IsInstanceUnique) { return; } // Check if we are in DEBUG mode EveMonClient.CheckIsDebug(); // Check if we are in SNAPSHOT mode EveMonClient.CheckIsSnapshot(); // Subscribe application's events (especially the unhandled exceptions management for the crash box) AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; Application.ThreadException += Application_ThreadException; Application.ApplicationExit += ApplicationExitCallback; Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // Find our files EveMonClient.InitializeFileSystemPaths(); // Creates a trace file EveMonClient.StartTraceLogging(); EveMonClient.Trace("Starting up", false); // Make our windows nice MakeWindowsJuicy(); // Ensures the installation file downloaded through the autoupdate is correctly deleted UpdateManager.DeleteInstallationFiles(); // Upgrades the Cloud Storage Service Provider settings CloudStorageServiceProvider.UpgradeSettings(); // Initialization EveMonClient.Initialize(); Settings.Initialize(); // Did something requested an exit before we entered Run() ? if (s_exitRequested) { return; } try { // Fires the main window EveMonClient.Trace("Main loop - start", printMethod: false); s_mainWindow = new MainWindow(); Application.Run(s_mainWindow); EveMonClient.Trace("Main loop - done", printMethod: false); // Save before we quit await Task.WhenAll(Settings.SaveImmediateAsync(), EveIDToName.SaveImmediateAsync()); } finally { // Stop the one-second timer right now EveMonClient.Shutdown(); EveMonClient.Trace("Closed", printMethod: false); EveMonClient.StopTraceLogging(); } }
/// <summary> /// Method to determine if the user's clock is syncrhonised to NTP time pool. /// Updated to move to NTP (global NTP pool) rather than NIST port 13 time check, which is being deprecated /// </summary> private static async Task BeginCheckAsync() { if (!NetworkMonitor.IsNetworkAvailable) { // Reschedule later otherwise ScheduleCheck(TimeSpan.FromMinutes(1)); return; } EveMonClient.Trace(); string ntpServer = NetworkConstants.GlobalNTPPool;// "pool.ntp.org"; DateTime serverTimeToLocalTime; bool isSynchronised; await Dns.GetHostAddressesAsync(ntpServer) .ContinueWith(task => { IPAddress[] ipAddresses = task.Result; if (!ipAddresses.Any()) { return; } try { DateTime dateTimeNowUtc; DateTime localTime = DateTime.Now; var ntpData = new byte[48]; ntpData[0] = 0x1B; //LeapIndicator = 0 (no warning), VersionNum = 3 (IPv4 only), Mode = 3 (Client Mode) var ipEndPoint = new IPEndPoint(task.Result.First(), 123); using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { socket.ReceiveTimeout = 5000; socket.SendTimeout = 5000; socket.Connect(ipEndPoint); socket.Send(ntpData); socket.Receive(ntpData); socket.Close(); } ulong intPart = (ulong)ntpData[40] << 24 | (ulong)ntpData[41] << 16 | (ulong)ntpData[42] << 8 | (ulong)ntpData[43]; ulong fractPart = (ulong)ntpData[44] << 24 | (ulong)ntpData[45] << 16 | (ulong)ntpData[46] << 8 | (ulong)ntpData[47]; var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L); var networkDateTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long)milliseconds); dateTimeNowUtc = networkDateTime; serverTimeToLocalTime = dateTimeNowUtc.ToLocalTime(); TimeSpan timediff = TimeSpan.FromSeconds(Math.Abs(serverTimeToLocalTime.Subtract(localTime).TotalSeconds)); isSynchronised = timediff < TimeSpan.FromSeconds(60); OnCheckCompleted(isSynchronised, serverTimeToLocalTime, localTime); } catch (Exception exc) { CheckFailure(exc); } }, EveMonClient.CurrentSynchronizationContext).ConfigureAwait(false); }
/// <summary> /// Notifies for industry jobs related events. /// </summary> private void NotifyForIndustryJobsRelatedEvents() { // Fires the event regarding industry jobs update EveMonClient.OnIndustryJobsUpdated(this); }
/// <summary> /// Called when character's skill in training gets updated. /// </summary> /// <param name="result">The result.</param> /// <param name="characterName">The character's name.</param> private void OnSkillInTrainingUpdated(CCPAPIResult <SerializableAPISkillInTraining> result, string characterName) { // Quit if the API key was deleted while it was updating if (!EveMonClient.APIKeys.Contains(this)) { return; } CCPCharacter ccpCharacter = EveMonClient.Characters.OfType <CCPCharacter>().FirstOrDefault(x => x.Name == characterName); // Checks if EVE database is out of service if (result.EVEDatabaseError) { return; } // Return on error if (result.HasError) { if (ccpCharacter != null && ccpCharacter.ShouldNotifyError(result, CCPAPICharacterMethods.SkillInTraining)) { EveMonClient.Notifications.NotifySkillInTrainingError(ccpCharacter, result); } m_skillInTrainingCache[characterName].State = ResponseState.InError; return; } m_skillInTrainingCache[characterName].State = result.Result.SkillInTraining == 1 ? ResponseState.Training : ResponseState.NotTraining; // In the event this becomes a very long running process because of latency // and characters have been removed from the API key since they were queried // remove those characters from the cache IEnumerable <KeyValuePair <string, SkillInTrainingResponse> > toRemove = m_skillInTrainingCache.Where(x => CharacterIdentities.All(y => y.CharacterName != x.Key)); foreach (KeyValuePair <string, SkillInTrainingResponse> charToRemove in toRemove) { m_skillInTrainingCache.Remove(charToRemove.Key); } // If we did not get response from a character in API key yet // or there was an error in any responce, // we are not sure so wait until next time if (m_skillInTrainingCache.Any(x => x.Value.State == ResponseState.Unknown || x.Value.State == ResponseState.InError)) { return; } // We have successful responces from all characters in API key, // so we notify the user and fire the event NotifyAccountNotInTraining(); // Fires the event regarding the API key characters skill in training update EveMonClient.OnCharactersSkillInTrainingUpdated(this); // Reset update pending flag m_updatePending = false; }