internal ChallengePreview(ICtfChallenge challenge, TimeSpan elapsed, EnumDisplayConverter enumCv, int?score, bool?solved) { this.Id = challenge.Id; this.Title = challenge.Title; this.CategoryId = challenge.Category.Id; this.Difficulty = enumCv.Convert(challenge.Difficulty); this.Description = challenge.Description; if (challenge.Hints != null) { this.Hints = challenge.Hints .Where(x => x.ReleaseTime <= elapsed) .Select(x => x.Contents) .ToList(); } if (challenge.Attachments != null) { this.Attachments = challenge.Attachments .Select(x => new ChallengeAttachmentPreview(x)) .ToList(); } if (challenge.Endpoint != null) { this.Endpoint = EndpointToString(challenge.Endpoint); } this.Score = score ?? challenge.BaseScore; this.IsSolved = solved; }
public async Task <ScoreInfo> ComputeCurrentScoreAsync(ICtfChallenge challenge, CancellationToken cancellationToken = default) { using var _ = await this.ScoreLockService.AcquireLockAsync(challenge.Id, cancellationToken); var solves = await this.ChallengeCacheRepository.IncrementSolveCountAsync(challenge.Id, cancellationToken); var baseline = await this.ChallengeCacheRepository.GetBaselineSolveCountAsync(cancellationToken); var rate = solves / (double)baseline; var postRate = (solves + 1.0) / baseline; var cscore = this.ScoringModel.ComputeScore(challenge.BaseScore, rate); var pscore = this.ScoringModel.ComputeScore(challenge.BaseScore, postRate); await this.ChallengeCacheRepository.UpdateScoreAsync(challenge.Id, pscore, cancellationToken); return(new ScoreInfo(cscore, pscore)); }
internal ChallengePreview(ICtfChallenge challenge, TimeSpan elapsed, EnumDisplayConverter enumCv) : this(challenge, elapsed, enumCv, null) { }
/// <summary> /// Converts a <see cref="ICtfChallenge"/> to its abridged variant. /// </summary> /// <param name="challenge">Challenge to convert.</param> /// <param name="elapsed">Time elapsed since the beginning of the event.</param> /// <param name="score">Current score for this challenge.</param> /// <param name="solved">Whether the currently-logged in user's team solved the challenge.</param> /// <returns>An abridged challenge.</returns> public ChallengePreview GetChallenge(ICtfChallenge challenge, TimeSpan elapsed, int?score, bool?solved) => new ChallengePreview(challenge, elapsed, this.EnumDisplayConverter, score, solved);
/// <summary> /// Converts a <see cref="ICtfChallenge"/> to its abridged variant. /// </summary> /// <param name="challenge">Challenge to convert.</param> /// <param name="elapsed">Time elapsed since the beginning of the event.</param> /// <param name="score">Current score for this challenge.</param> /// <returns>An abridged challenge.</returns> public ChallengePreview GetChallenge(ICtfChallenge challenge, TimeSpan elapsed, int?score) => this.GetChallenge(challenge, elapsed, score, null);
/// <summary> /// Converts a <see cref="ICtfChallenge"/> to its abridged variant. /// </summary> /// <param name="challenge">Challenge to convert.</param> /// <param name="elapsed">Time elapsed since the beginning of the event.</param> /// <returns>An abridged challenge.</returns> public ChallengePreview GetChallenge(ICtfChallenge challenge, TimeSpan elapsed) => this.GetChallenge(challenge, elapsed, null);