/// <inheritdoc /> public async Task <IReadOnlyCollection <Standing> > GetLongestStandingsAsync( Game game, DateTime?endDate, StandingType standingType, bool?stillOngoing) { var standings = new List <Standing>(); var wrs = await GetWorldRecordsAsync(game, endDate).ConfigureAwait(false); foreach (var stage in game.GetStages()) { foreach (var level in SystemExtensions.Enumerate <Level>()) { var locWrs = wrs .Where(wr => wr.Stage == stage && wr.Level == level) .OrderBy(wr => wr.Date) .ThenByDescending(wr => wr.Time); Standing currentStanding = null; foreach (var locWr in locWrs) { switch (standingType) { case StandingType.Unslayed: standings.AddRange(locWr.Holders.Select(_ => new Standing(locWr.Time) { Slayer = locWr.SlayPlayer, EndDate = locWr.SlayDate, StartDate = _.Item2, Author = _.Item1, Level = level, Stage = stage })); break; case StandingType.UnslayedExceptSelf: var slayer = locWr.SlayPlayer; var holders = locWr.Holders.ToList(); if (currentStanding != null) { currentStanding.AddTime(locWr.Time); holders.RemoveAll(_ => _.Item1.Id == currentStanding.Author.Id); if (slayer == null || slayer.Id != currentStanding.Author.Id) { currentStanding.Slayer = slayer; currentStanding.EndDate = locWr.SlayDate; currentStanding = null; } } foreach (var holder in holders) { var locCurrentStanding = new Standing(locWr.Time) { StartDate = holder.Item2, Author = holder.Item1, Level = level, Stage = stage }; standings.Add(locCurrentStanding); if (slayer == null || slayer.Id != locCurrentStanding.Author.Id) { locCurrentStanding.Slayer = slayer; locCurrentStanding.EndDate = locWr.SlayDate; } else { currentStanding = locCurrentStanding; } } break; case StandingType.Untied: standings.Add(new Standing(locWr.Time) { Slayer = locWr.UntiedSlayPlayer ?? locWr.SlayPlayer, EndDate = locWr.UntiedSlayDate ?? locWr.SlayDate, StartDate = locWr.Date, Author = locWr.Player, Level = level, Stage = stage }); break; case StandingType.UntiedExceptSelf: if (currentStanding == null) { currentStanding = new Standing(locWr.Time) { StartDate = locWr.Date, Author = locWr.Player, Level = level, Stage = stage }; standings.Add(currentStanding); } currentStanding.AddTime(locWr.Time); var untiedSlayer = locWr.UntiedSlayPlayer ?? locWr.SlayPlayer; if (untiedSlayer == null || untiedSlayer.Id != currentStanding.Author.Id) { currentStanding.Slayer = untiedSlayer; currentStanding.EndDate = locWr.UntiedSlayDate ?? locWr.SlayDate; currentStanding = null; } break; case StandingType.BetweenTwoTimes: for (var i = 0; i < locWr.Holders.Count; i++) { var holder = locWr.Holders.ElementAt(i); var isLast = i == locWr.Holders.Count - 1; standings.Add(new Standing(locWr.Time) { Slayer = isLast ? locWr.SlayPlayer : locWr.Holders.ElementAt(i + 1).Item1, EndDate = isLast ? locWr.SlayDate : locWr.Holders.ElementAt(i + 1).Item2, StartDate = holder.Item2, Author = holder.Item1, Level = level, Stage = stage }); } break; } } } } var now = ServiceProviderAccessor.ClockProvider.Now; return(standings .Where(x => stillOngoing == true ? !x.EndDate.HasValue : (stillOngoing == false ? x.EndDate.HasValue : true)) .OrderByDescending(x => x.WithDays(now).Days) .ToList()); }