private void SendWarAnnouncements(CachedWar cachedWar, List <CachedClanWar>?cachedClanWars) { try { if (cachedWar.Data == null) { return; } if (cachedWar.Announcements.HasFlag(Announcements.WarStartingSoon) == false && DateTime.UtcNow > cachedWar.Data.StartTime.AddHours(-1) && DateTime.UtcNow < cachedWar.Data.StartTime) { cachedWar.Announcements |= Announcements.WarStartingSoon; _clansClient.OnClanWarStartingSoon(cachedWar.Data); } if (cachedWar.Announcements.HasFlag(Announcements.WarEndingSoon) == false && DateTime.UtcNow > cachedWar.Data.EndTime.AddHours(-1) && DateTime.UtcNow < cachedWar.Data.EndTime) { cachedWar.Announcements |= Announcements.WarEndingSoon; _clansClient.OnClanWarEndingSoon(cachedWar.Data); } if (cachedWar.Announcements.HasFlag(Announcements.WarEndNotSeen) == false && cachedWar.State != WarState.WarEnded && DateTime.UtcNow > cachedWar.EndTime && DateTime.UtcNow < cachedWar.EndTime.AddHours(24) && cachedWar.Data.AllAttacksAreUsed() == false && cachedClanWars != null && cachedClanWars.All(w => w.Data != null && w.Data.PreparationStartTime != cachedWar.Data.PreparationStartTime)) { cachedWar.Announcements |= Announcements.WarEndNotSeen; _clansClient.OnClanWarEndNotSeen(cachedWar.Data); } if (cachedWar.Announcements.HasFlag(Announcements.WarEnded) == false && cachedWar.EndTime < DateTime.UtcNow && cachedWar.EndTime.Day == DateTime.UtcNow.Day) { cachedWar.Announcements |= Announcements.WarEnded; _clansClient.OnClanWarEnded(cachedWar.Data); } } catch (Exception e) { _clansClient.OnLog(this, new ExceptionEventArgs(nameof(SendWarAnnouncements), e)); throw; } }
internal bool HasUpdated(CachedWar stored, CachedClanWar fetched) { if (stored.ServerExpiration > fetched.ServerExpiration) { return(false); } if (stored.Data == null || fetched.Data == null || ClanWar.IsSameWar(stored.Data, fetched.Data) == false) { throw new ArgumentException(); } return(HasUpdated(stored.Data, fetched.Data)); }
public async Task <CachedWar> GetLeagueWarAsync(string warTag, DateTime season, CancellationToken?cancellationToken = default) { string formattedTag = Clash.FormatTag(warTag); using var scope = Services.CreateScope(); CacheContext dbContext = scope.ServiceProvider.GetRequiredService <CacheContext>(); CachedWar war = await dbContext.Wars .AsNoTracking() .FirstAsync(w => w.WarTag == formattedTag && w.Season == season, cancellationToken.GetValueOrDefault()) .ConfigureAwait(false); war.Data.Initialize(war.ServerExpiration, formattedTag); return(war); }
internal async Task InsertNewWarAsync(CachedWar fetched) { if (fetched.Data == null) { throw new ArgumentException("Data should not be null."); } if (UpdatingWar.TryAdd(fetched, new byte()) == false) { return; } try { using var scope = Services.CreateScope(); CacheContext dbContext = scope.ServiceProvider.GetRequiredService <CacheContext>(); CachedWar?exists = await dbContext.Wars .Where(w => w.PreparationStartTime == fetched.Data.PreparationStartTime && w.ClanTag == fetched.Data.Clans.First().Value.Tag) .FirstOrDefaultAsync(_stopRequestedTokenSource.Token); if (exists != null) { return; } dbContext.Wars.Add(fetched); await dbContext.SaveChangesAsync(_stopRequestedTokenSource.Token); OnClanWarAdded(fetched.Data); } finally { UpdatingWar.TryRemove(fetched, out var _); } }
private async Task <CachedWar?> ReturnNewWarOrDefaultAsync(string tag, DateTime season, string warTag) { if (_stopRequestedTokenSource.IsCancellationRequested) { return(null); } try { using var scope = Services.CreateScope(); CacheContext dbContext = scope.ServiceProvider.GetRequiredService <CacheContext>(); CachedWar?cachedWar = await dbContext.Wars .FirstOrDefaultAsync(w => w.WarTag == warTag && w.Season == season) .ConfigureAwait(false); if (cachedWar != null) { return(null); } CachedWar fetched = await CachedWar .FromClanWarLeagueWarResponseAsync(warTag, season, _clansClient, _clansApi, _stopRequestedTokenSource.Token) .ConfigureAwait(false); if (fetched.ClanTags.Any(c => c == tag) == false) { return(null); } return(fetched); } catch (Exception e) { _clansClient.OnLog(this, new LogEventArgs(nameof(ReturnNewWarOrDefaultAsync), LogLevel.Debug, $"Error updating cwl war:{tag}\n{e.Message}\n{e.InnerException?.Message}")); return(null); } }
private async Task MonitorWarAsync(CachedWar cached) { if (_stopRequestedTokenSource.IsCancellationRequested || _clansClient.UpdatingWar.TryAdd(cached, new byte()) == false) { return; } try { using var scope = Services.CreateScope(); CacheContext dbContext = scope.ServiceProvider.GetRequiredService <CacheContext>(); List <CachedClanWar>?cachedClanWars = null; if (cached.WarTag == null) { cachedClanWars = await dbContext.ClanWars .AsNoTracking() .Where(c => cached.ClanTags.Contains(c.Tag)) .OrderByDescending(c => c.ServerExpiration) .ToListAsync(_stopRequestedTokenSource.Token) .ConfigureAwait(false); if (cachedClanWars.Count == 2 && cachedClanWars.All(c => c.PreparationStartTime > cached.PreparationStartTime) || cached.EndTime.AddDays(8) < DateTime.UtcNow) { cached.IsFinal = true; return; } CachedClanWar?cachedClanWar = cachedClanWars .OrderByDescending(c => c.ServerExpiration) .FirstOrDefault(c => c.PreparationStartTime == cached.PreparationStartTime); if (cached.Data != null && cachedClanWar?.Data != null && _clansClient.HasUpdated(cached, cachedClanWar)) { _clansClient.OnClanWarUpdated(cached.Data, cachedClanWar.Data); } if (cachedClanWar != null) { cached.UpdateFrom(cachedClanWar); } } else { CachedWar?fetched = await CachedWar .FromClanWarLeagueWarResponseAsync( cached.WarTag, cached.Season.Value, _clansClient, _clansApi, _stopRequestedTokenSource.Token) .ConfigureAwait(false); if (cached.Data != null && fetched.Data != null && cached.Season == fetched.Season && _clansClient.HasUpdated(cached, fetched)) { _clansClient.OnClanWarUpdated(cached.Data, fetched.Data); } cached.UpdateFrom(fetched); } cached.IsFinal = cached.State == WarState.WarEnded; SendWarAnnouncements(cached, cachedClanWars); } finally { _clansClient.UpdatingWar.TryRemove(cached, out _); } }