/// <summary> /// Processes the contract bids. /// </summary> private void OnContractBidsUpdated(EsiResult <EsiAPIContractBids> result, object apiMethod) { var methodEnum = (apiMethod as Enum) ?? ESIAPICharacterMethods.ContractBids; var target = Character; m_bidsResponse = result.Response; // Notify if an error occured if (target.ShouldNotifyError(result, methodEnum)) { EveMonClient.Notifications.NotifyContractBidsError(Character, result); } if (!result.HasError) { EveMonClient.Notifications.InvalidateCharacterAPIError(target); Import(result.Result); // Fire correct event type if (methodEnum is ESIAPICharacterMethods) { EveMonClient.OnCharacterContractBidsDownloaded(target); } else { EveMonClient.OnCorporationContractBidsDownloaded(target); } } m_bidsPending = false; }
private async Task <ResponseParams> CreateMessageWithThemesSearch(long chatId, int pageNum) { var pageSize = 10; var pageIndex = pageNum - 1; var themes = await _dbContext.Themes .Where(x => x.ParentId == null) .OrderBy(x => x.Name) .Skip(pageSize * pageIndex) .Take(pageSize) .ToListAsync(); var sb = new StringBuilder(); for (int i = 0; i < themes.Count; i++) { sb.Append($"{i + 1 + pageSize * pageIndex}. <b>{themes[i].Name}</b>{Environment.NewLine}") .Append($" Наборы по этой теме: /tid_{themes[i].ThemeId}{Environment.NewLine}"); } var totalCount = await _dbContext.Themes.Where(x => x.ParentId == null).CountAsync(); var hasRemaining = totalCount % pageSize != 0; var pagesCount = totalCount / pageSize + (hasRemaining ? 1 : 0); var pagingButtons = PagingButtonCreator.CreatePagingButtons(pagesCount, pageNum, ThemeSourceName); var response = new ResponseParams(chatId, sb.ToString()) { ResponseMarkup = pagingButtons }; return(response); }
/// <summary> /// Processes the faction war list. /// </summary> private static void OnFactionWarsUpdated(EsiResult <EsiAPIEveFactionWars> result, object ignore) { s_warsResponse = result.Response; if (result.HasError) { // Was there an error ? s_queryPending = false; EveMonClient.Notifications.NotifyEveFactionWarsError(result); } if (EsiErrors.IsErrorCountExceeded) { s_queryPending = false; // If error count is exceeded (success or fail), retry when it resets s_nextCheckTime = EsiErrors.ErrorCountResetTime; } else if (!result.HasError) { // Stage two request for factional warfare stats EveMonClient.Notifications.InvalidateAPIError(); EveMonClient.APIProviders.CurrentProvider.QueryEsi <EsiAPIEveFactionalWarfareStats>(ESIAPIGenericMethods. EVEFactionalWarfareStats, OnWarStatsUpdated, new ESIParams( s_statsResponse), result.HasData ? result.Result : null); } }
private async Task <ResponseParams> CreateMessageWithSetsForYear(long chatId, int pageNum, int year) { var pageSize = 10; var pageIndex = pageNum - 1; var sets = await _dbContext.Sets .Where(x => x.Year == year) .OrderBy(x => x.Name) .Skip(pageSize * pageIndex) .Take(pageSize) .ToListAsync(); var sb = new StringBuilder(); for (int i = 0; i < sets.Count; i++) { sb.Append($"{i + 1 + pageSize * pageIndex}. <b>{sets[i].Name}</b>{Environment.NewLine}") .Append($" Подробнее про этот набор: {LinkPrefix}{sets[i].SetNumber}{Environment.NewLine}"); } var totalCount = await _dbContext.Sets.Where(x => x.Year == year).CountAsync(); var hasRemaining = totalCount % pageSize != 0; var pagesCount = totalCount / pageSize + (hasRemaining ? 1 : 0); var pagingButtons = PagingButtonCreator.CreatePagingButtons(pagesCount, pageNum, Years_Sets_SourceName, year); var response = new ResponseParams(chatId, sb.ToString()) { ResponseMarkup = pagingButtons }; return(response); }
private async Task <ResponseParams> CreateMessageWithYearsSearch(long chatId, int pageNum) { var pageSize = 10; var pageIndex = pageNum - 1; var years = await _dbContext.Sets .Select(x => x.Year) .Distinct() .OrderBy(x => x) .Skip(pageSize * pageIndex) .Take(pageSize) .ToListAsync(); var sb = new StringBuilder(); for (int i = 0; i < years.Count; i++) { sb.Append($"{i + 1 + pageSize * pageIndex}. <b>{years[i]}</b>{Environment.NewLine}") .Append($" Наборы в этом году: /yid_{years[i]}{Environment.NewLine}"); } var totalCount = await _dbContext.Sets.Select(x => x.Year).Distinct().CountAsync(); var hasRemaining = totalCount % pageSize != 0; var pagesCount = totalCount / pageSize + (hasRemaining ? 1 : 0); var pagingButtons = PagingButtonCreator.CreatePagingButtons(pagesCount, pageNum, YearsSourceName); var response = new ResponseParams(chatId, sb.ToString()) { ResponseMarkup = pagingButtons }; return(response); }
/// <summary> /// Processes the faction war statistics list. /// </summary> private static void OnWarStatsUpdated(EsiResult <EsiAPIEveFactionalWarfareStats> result, object wars) { var factionWars = wars as EsiAPIEveFactionWars; s_statsResponse = result.Response; // Was there an error ? if (result.HasError) { s_queryPending = false; EveMonClient.Notifications.NotifyEveFactionalWarfareStatsError(result); } else { // Set the next update to be after downtime s_nextCheckTime = DateTime.Today.AddHours(EveConstants.DowntimeHour). AddMinutes(EveConstants.DowntimeDuration); s_queryPending = false; EveMonClient.Notifications.InvalidateAPIError(); if (result.HasData) { var fwStats = result.Result.ToXMLItem(factionWars); Import(fwStats); EveMonClient.OnEveFactionalWarfareStatsUpdated(); // Save the file to our cache LocalXmlCache.SaveAsync(Filename, Util.SerializeToXmlDocument(fwStats)). ConfigureAwait(false); } } }
/// <summary> /// Calculates the cached until time based on the response parameters. Uses the expires /// date if provided and in the future; otherwise calculates a default expiration to /// avoid spamming the server. /// </summary> /// <param name="response">The server response.</param> private static DateTime GetCacheTimerFromResponse(ResponseParams response) { DateTime cachedUntil; DateTimeOffset?expires = response.Expires; // If there was an error or no cache timer provided, retry after error cache time if (expires == null) { cachedUntil = GetErrorCacheTime(); } else { DateTimeOffset ccpCacheTime = ((DateTimeOffset)expires), serverTime = response.Time ?? DateTimeOffset.UtcNow; // Ensure that cache date is not in the past if (ccpCacheTime < serverTime) { ccpCacheTime = serverTime.AddSeconds(CACHE_JITTER); } else { ccpCacheTime = ccpCacheTime.AddSeconds(CACHE_JITTER); } cachedUntil = ccpCacheTime.UtcDateTime; } return(cachedUntil); }
/// <summary> /// Gets the contract items or bids. /// </summary> private void GetContractData <T, U>(APIProvider.ESIRequestCallback <T> callback, ESIAPICorporationMethods methodCorp, ESIAPICharacterMethods methodPersonal, ResponseParams response) where T : List <U> where U : class { var cid = Character.Identity; ESIKey key; Enum method; long owner; // Special condition to identify corporation contracts in character query if (IssuedFor == IssuedFor.Corporation && ESIAPICorporationMethods. CorporationContracts.Equals(m_method)) { key = cid.FindAPIKeyWithAccess(methodCorp); method = methodCorp; owner = Character.CorporationID; } else { key = cid.FindAPIKeyWithAccess(methodPersonal); method = methodPersonal; owner = Character.CharacterID; } // Only query if the error count has not been exceeded if (key != null && !EsiErrors.IsErrorCountExceeded) { EveMonClient.APIProviders.CurrentProvider.QueryPagedEsi <T, U>(method, callback, new ESIParams(response, key.AccessToken) { ParamOne = owner, ParamTwo = ID }, method); } }
/// <summary> /// Initializes a new instance of the <see cref="CCPAPIResult{T}" /> class. /// </summary> /// <param name="exception">The exception.</param> /// <exception cref="System.ArgumentNullException">exception</exception> protected JsonResult(Exception exception) { exception.ThrowIfNull(nameof(exception)); Exception = exception; ErrorMessage = exception?.Message ?? string.Empty; Response = new ResponseParams(0); Result = default(T); }
/// <summary> /// Constructor from a CCP API internal error /// </summary> /// <param name="response">The response parameters including the error code.</param> /// <param name="message">The CCP error message.</param> public JsonResult(ResponseParams response, string message) { m_error = APIErrorType.CCP; m_exception = null; m_message = message ?? string.Empty; m_response = response; Result = default(T); }
/// <summary> /// Creates a JSON result wrapped from another JSON result. /// </summary> /// <param name="wrapped">The JSON result to wrap.</param> protected JsonResult(JsonResult <T> wrapped) { m_exception = wrapped.Exception; m_message = wrapped.ErrorMessage; m_error = wrapped.ErrorType; m_response = wrapped.m_response; Result = wrapped.Result; }
/// <summary> /// Default constructor. /// </summary> public JsonResult(ResponseParams response, T result = default(T)) { ErrorType = APIErrorType.None; Exception = null; ErrorMessage = string.Empty; Response = response; Result = result; }
/// <summary> /// Constructor from a CCP API internal error /// </summary> /// <param name="response">The response parameters including the error code.</param> /// <param name="message">The CCP error message.</param> public JsonResult(ResponseParams response, string message) { ErrorType = APIErrorType.CCP; Exception = null; ErrorMessage = message ?? string.Empty; Response = response; Result = default(T); }
/// <summary> /// Default constructor. /// </summary> public JsonResult(ResponseParams response, T result = default(T)) { m_error = APIErrorType.None; m_exception = null; m_message = string.Empty; m_response = response; Result = result; }
public ESIParams(ResponseParams lastResponse, string token = null) { ParamOne = 0L; ParamTwo = 0L; GetData = null; LastResponse = lastResponse ?? new ResponseParams(0); PostData = null; Token = token; }
/// <summary> /// Constructor from the API. /// </summary> /// <param name="ccpCharacter">The CCP character.</param> /// <param name="src">The source.</param> /// <exception cref="System.ArgumentNullException">src</exception> internal Contract(CCPCharacter ccpCharacter, EsiContractListItem src) { src.ThrowIfNull(nameof(src)); m_bidsResponse = m_itemsResponse = null; Character = ccpCharacter; PopulateContractInfo(src); m_state = GetState(src); m_bids = new LinkedList <ContractBid>(); }
/// <summary> /// Constructor from an object deserialized from the settings file. /// </summary> /// <param name="ccpCharacter">The CCP character.</param> /// <param name="src">The source.</param> internal Contract(CCPCharacter ccpCharacter, SerializableContract src) { src.ThrowIfNull(nameof(src)); m_bidsResponse = m_itemsResponse = null; Character = ccpCharacter; ID = src.ContractID; IssuedFor = src.IssuedFor; if (IssuedFor == IssuedFor.Corporation) { IssuerID = Character.CharacterID; } m_state = src.ContractState; m_bids = new LinkedList <ContractBid>(); }
/// <summary> /// Initializes a new instance of the <see cref="PlanetaryColony"/> class. /// </summary> /// <param name="ccpCharacter">The CCP character.</param> /// <param name="src">The source.</param> internal PlanetaryColony(CCPCharacter ccpCharacter, EsiPlanetaryColonyListItem src) { Character = ccpCharacter; SolarSystem = StaticGeography.GetSolarSystemByID(src.SolarSystemID); PlanetID = src.PlanetID; PlanetTypeID = src.PlanetType; PlanetTypeName = StaticItems.GetItemName(PlanetTypeID); PlanetName = SolarSystem.FindPlanetByID(PlanetID)?.Name ?? EveMonConstants. UnknownText; LastUpdate = src.LastUpdate; UpgradeLevel = src.UpgradeLevel; NumberOfPins = src.NumberOfPins; m_layoutResponse = null; GetColonyLayout(); }
/// <summary> /// Initializes a new instance of the <see cref="PlanetaryColony"/> class. /// </summary> /// <param name="ccpCharacter">The CCP character.</param> /// <param name="src">The source.</param> internal PlanetaryColony(CCPCharacter ccpCharacter, SerializablePlanetaryColony src) { Character = ccpCharacter; SolarSystem = StaticGeography.GetSolarSystemByID(src.SolarSystemID); PlanetID = src.PlanetID; PlanetTypeID = src.PlanetTypeID; PlanetTypeName = src.PlanetTypeName; PlanetName = EveMonConstants.UnknownText; LastUpdate = src.LastUpdate; UpgradeLevel = src.UpgradeLevel; NumberOfPins = src.NumberOfPins; m_layoutResponse = m_planetResponse = null; GetColonyLayout(); GetPlanetName(); }
/// <summary> /// Constructor from the API. /// </summary> /// <param name="ccpCharacter">The CCP character.</param> /// <param name="src">The source.</param> internal UpcomingCalendarEvent(CCPCharacter ccpCharacter, EsiAPICalendarEvent src) { m_ccpCharacter = ccpCharacter; m_attendResponse = null; m_eventID = src.EventID; OwnerID = src.OwnerID; m_ownerName = EveIDToName.GetIDToName(OwnerID); EventTitle = src.EventTitle; EventText = src.EventText; Duration = src.Duration; Importance = src.Importance != 0; Response = src.Response; EventDate = src.EventDate; m_eventAttendees = new List <CalendarEventAttendee>(); }
/// <summary> /// Constructor. /// </summary> /// <param name="method">The method.</param> /// <param name="callback">The callback.</param> /// <exception cref="System.ArgumentNullException">callback;@The callback cannot be null.</exception> internal QueryMonitor(Enum method, Action <EsiResult <T> > callback) { // Check callback not null callback.ThrowIfNull(nameof(callback), "The callback cannot be null."); LastUpdate = DateTime.MinValue; m_forceUpdate = true; m_lastResponse = null; m_onUpdated = callback; Method = method; Enabled = false; QueryOnStartup = false; NetworkMonitor.Register(this); EveMonClient.TimerTick += EveMonClient_TimerTick; }
/// <summary> /// Processes the queried EVE mail message mail body. /// </summary> /// <param name="result">The result.</param> private void OnEVEMailBodyDownloaded(EsiResult <EsiAPIMailBody> result, object forMessage) { long messageID = (forMessage as long?) ?? 0L; m_queryPending = false; m_bodyResponse = result.Response; // Notify if an error occured if (m_ccpCharacter.ShouldNotifyError(result, ESIAPICharacterMethods.MailBodies)) { EveMonClient.Notifications.NotifyEVEMailBodiesError(m_ccpCharacter, result); } if (result.HasData && !result.HasError && messageID != 0L && !string.IsNullOrEmpty( result.Result.Body)) { EVEMailBody = new EveMailBody(messageID, result.Result); EveMonClient.OnCharacterEVEMailBodyDownloaded(m_ccpCharacter); } }
/// <summary> /// Occurs when a new result has been queried. /// </summary> /// <param name="result">The downloaded result</param> private void OnQueried(EsiResult <T> result, object state) { IsUpdating = false; Status = QueryStatus.Pending; // Do we need to retry the force update ? m_forceUpdate = m_retryOnForceUpdateError && result.HasError; if (!m_isCanceled) { // Updates the stored data m_retryOnForceUpdateError = false; LastUpdate = DateTime.UtcNow; LastResult = result; m_lastResponse = result.Response; // Notify subscribers m_onUpdated?.Invoke(result); } }
/// <summary> /// Processes the queried character's attributes. /// </summary> /// <param name="result"></param> /// <param name="ignore"></param> private void OnCharacterAttributesUpdated(EsiResult <EsiAPIAttributes> result, object ignore) { var target = m_ccpCharacter; m_attrResponse = result.Response; // Character may have been deleted since we queried if (target != null && target.Monitored) { if (target.ShouldNotifyError(result, ESIAPICharacterMethods.Attributes)) { EveMonClient.Notifications.NotifyCharacterAttributesError(target, result); } if (!result.HasError && result.HasData) { target.Import(result.Result); } } }
/// <summary> /// Constructor from the API. /// </summary> /// <param name="ccpCharacter"></param> /// <param name="src"></param> internal EveMailMessage(CCPCharacter ccpCharacter, SerializableMailMessagesListItem src) { if (ccpCharacter == null) { throw new ArgumentNullException("ccpCharacter"); } m_ccpCharacter = ccpCharacter; m_source = src; m_bodyResponse = null; long senderID = src.SenderID; State = (senderID != ccpCharacter.CharacterID) ? EveMailState.Inbox : EveMailState.SentItem; MessageID = src.MessageID; SentDate = src.SentDate; Title = src.Title.HtmlDecode(); // Was it sent from a mailing list? if (src.ToListID.Contains(senderID)) { m_senderName = ccpCharacter.EVEMailingLists.FirstOrDefault(x => x.ID == senderID)?.Name ?? EveMonConstants.UnknownText; } else if (senderID == 0L) { m_senderName = EveMonConstants.UnknownText; } else { m_senderName = EveIDToName.GetIDToName(senderID); } m_toCharacters = GetIDsToNames(src.ToCharacterIDs); m_toMailingLists = GetMailingListIDsToNames(src.ToListID); m_toCorpOrAlliance = EveIDToName.GetIDToName(src.ToCorpOrAllianceID); EVEMailBody = new EveMailBody(0L, new EsiAPIMailBody() { Body = "" }); }
/// <summary> /// Processes the faction war list. /// </summary> private static void OnFactionWarsUpdated(EsiResult <EsiAPIEveFactionWars> result, object ignore) { s_warsResponse = result.Response; // Was there an error ? if (result.HasError) { s_queryPending = false; EveMonClient.Notifications.NotifyEveFactionWarsError(result); } else { // Stage two request for factional warfare stats EveMonClient.Notifications.InvalidateAPIError(); EveMonClient.APIProviders.CurrentProvider.QueryEsi <EsiAPIEveFactionalWarfareStats>(ESIAPIGenericMethods. EVEFactionalWarfareStats, OnWarStatsUpdated, new ESIParams( s_statsResponse), result.HasData ? result.Result : null); } }
/// <summary> /// Processes the queried character's market orders. Called from the history fetch on /// success or failure, but merges the original orders too. /// </summary> /// <param name="result"></param> /// <remarks>This method is sensitive to which "issued for" orders gets queried first</remarks> private void OnMarketOrdersCompleted(EsiResult <EsiAPIMarketOrders> result, object regularOrders) { var target = m_ccpCharacter; // Character may have been deleted since we queried if (target != null && regularOrders is EsiAPIMarketOrders orders) { var endedOrders = new LinkedList <MarketOrder>(); var allOrders = new EsiAPIMarketOrders(); m_orderHistoryResponse = result.Response; // Ignore the If-Modified-Since and cache timer on order history to ensure // that old orders are not wiped out if (m_orderHistoryResponse != null) { m_orderHistoryResponse.Expires = null; m_orderHistoryResponse.ETag = null; } // Add normal orders first if (orders != null) { allOrders.AddRange(orders); } // Add result second if (result != null && !result.HasError && result.Result != null) { allOrders.AddRange(result.Result); } allOrders.SetAllIssuedBy(target.CharacterID); target.CharacterMarketOrders.Import(allOrders, IssuedFor.Character, endedOrders); EveMonClient.OnCharacterMarketOrdersUpdated(target, endedOrders); allOrders.Clear(); // Notify if either one failed if (result != null && result.HasError) { EveMonClient.Notifications.NotifyCharacterMarketOrdersError(target, result); } } }
/// <summary> /// Called when planetary pins updated. /// </summary> /// <param name="result">The result.</param> private void OnPlanetaryPinsUpdated(EsiResult <EsiAPIPlanetaryColony> result, object ignore) { m_queryPinsPending = false; m_layoutResponse = result.Response; // Notify if an error occured if (Character.ShouldNotifyError(result, ESIAPICharacterMethods.PlanetaryLayout)) { EveMonClient.Notifications.NotifyCharacterPlanetaryLayoutError(Character, result); } if (!result.HasError) { EveMonClient.Notifications.InvalidateCharacterAPIError(Character); if (result.HasData) { Import(result.Result); EveMonClient.OnCharacterPlanetaryLayoutUpdated(Character); } } }
/// <summary> /// Called when planetary information is updated. /// </summary> /// <param name="result">The result.</param> private void OnPlanetNameUpdated(EsiResult <EsiAPIPlanet> result, object ignore) { m_queryNamePending = false; m_planetResponse = result.Response; // Notify if an error occured if (Character.ShouldNotifyError(result, ESIAPIGenericMethods.PlanetInfo)) { EveMonClient.Notifications.NotifyPlanetInfoError(result); } if (!result.HasError) { EveMonClient.Notifications.InvalidateAPIError(); if (result.HasData) { // Gross overkill for only the planet name, but until the XMLGenerator is // updated to output planet details... PlanetName = result.Result.Name; EveMonClient.OnCharacterPlanetaryLayoutUpdated(Character); } } }
/// <summary> /// Processes the queried calendar event attendees. /// </summary> /// <param name="result">The result.</param> private void OnCalendarEventAttendeesDownloaded(EsiResult <EsiAPICalendarEventAttendees> result, object ignore) { m_queryPending = false; m_attendResponse = result.Response; // Notify if an error occured if (m_ccpCharacter.ShouldNotifyError(result, ESIAPICharacterMethods. CalendarEventAttendees)) { EveMonClient.Notifications.NotifyCharacterCalendarEventAttendeesError( m_ccpCharacter, result); } if (result.HasData && !result.HasError && result.Result.Count > 0) { var attendees = result.Result.Select(attendee => new CalendarEventAttendee( attendee)); m_eventAttendees.Clear(); m_eventAttendees.AddRange(attendees); EveMonClient.OnCharacterCalendarEventAttendeesDownloaded(m_ccpCharacter); } }