예제 #1
0
        public JuryEditModel(IContestInformation cont)
        {
            var startTime = cont.StartTime?.ToString("yyyy-MM-dd HH:mm:ss zzz") ?? "";
            var stopTime  = cont.EndTime?.ToDeltaString() ?? "";
            var unfTime   = cont.UnfreezeTime?.ToDeltaString() ?? "";
            var freTime   = cont.FreezeTime?.ToDeltaString() ?? "";

            ContestId           = cont.Id;
            FreezeTime          = freTime;
            Name                = cont.Name;
            ShortName           = cont.ShortName;
            RankingStrategy     = cont.RankingStrategy;
            StartTime           = startTime;
            StopTime            = stopTime;
            UnfreezeTime        = unfTime;
            IsPublic            = cont.IsPublic;
            UsePrintings        = cont.Settings.PrintingAvailable;
            UseBalloon          = cont.Settings.BalloonAvailable;
            UseEvents           = cont.Settings.EventAvailable;
            PreferGymUI         = cont.Settings.PreferGymUI ?? false;
            StatusAvailable     = cont.Settings.StatusAvailable;
            Languages           = cont.Settings.Languages;
            PenaltyTime         = cont.Settings.PenaltyTime ?? 20;
            RegisterCategory    = cont.Settings.RegisterCategory ?? new Dictionary <string, int>();
            UseScoreboardPaging = !cont.Settings.ScoreboardPaging.HasValue ? 0 : cont.Settings.ScoreboardPaging.Value ? 1 : 2;

            if (cont.Settings.RestrictIp.HasValue)
            {
                IpRanges              = string.Join(';', cont.Settings.IpRanges ?? Array.Empty <string>());
                RestrictToIpRanges    = (cont.Settings.RestrictIp.Value & 1) == 1;
                RestrictToMinimalSite = (cont.Settings.RestrictIp.Value & 2) == 2;
                RestrictToLastLoginIp = (cont.Settings.RestrictIp.Value & 4) == 4;
            }
        }
예제 #2
0
        protected override async Task RollbackRatingChangesAsync(IContestInformation contest)
        {
            int cid = contest.Id;
            var concurrencyStamp = Guid.NewGuid().ToString();

            var rollbackQuery =
                from t in _context.Set <Team>()
                where t.ContestId == cid && t.CategoryId == _eligibleCategory
                join m in _context.Set <Member>() on new { t.ContestId, t.TeamId } equals new { m.ContestId, m.TeamId }
            where m.RatingDelta != null
            select new { m.UserId, m.PreviousRating };

            await _context.Set <TUser>()
            .BatchUpdateJoinAsync(
                inner: rollbackQuery,
                outerKeySelector: u => u.Id,
                innerKeySelector: u => u.UserId,
                updateSelector: (u, u2) => new TUser
            {
                Rating           = u2.PreviousRating,
                ConcurrencyStamp = concurrencyStamp,
            });

            // revert the calculated rating delta
            await _context.Set <Member>()
            .Where(m => m.ContestId == cid)
            .BatchUpdateAsync(m => new Member {
                RatingDelta = null
            });
        }
예제 #3
0
        /// <inheritdoc />
        public async Task ApplyAsync(IContestInformation contest)
        {
            await ValidateAsync(contest, shouldHaveBeen : false);

            var participants = await GetPreviousRatingsAsync(contest);

            _ratingCalculator.ComputeRatingChanges(participants);
            await ApplyRatingChangesAsync(contest, participants);
        }
예제 #4
0
 /// <summary>
 /// Choose the strategy for contest.
 /// </summary>
 /// <param name="contest">The contest entity.</param>
 /// <returns>The ranking strategy.</returns>
 public static IRankingStrategy Select(IContestInformation contest)
 {
     if (contest == null ||
         contest.RankingStrategy > Strategies.Count ||
         contest.RankingStrategy < 0)
     {
         throw new ArgumentOutOfRangeException(nameof(contest));
     }
     return(Strategies[contest.RankingStrategy]);
 }
예제 #5
0
        public ContestSettings CreateSettings(IContestInformation contest)
        {
            var defaultCat = RegisterCategory?
                             .Where(k => k.Value != 0)
                             .ToDictionary(k => k.Key, v => v.Value);

            if (defaultCat?.Count == 0)
            {
                defaultCat = null;
            }

            if (RestrictToIpRanges)
            {
                IpRanges ??= string.Empty;
            }
            else
            {
                IpRanges = null;
            }
            int restriction =
                (RestrictToIpRanges ? 1 : 0)
                | (RestrictToMinimalSite ? 2 : 0)
                | (RestrictToLastLoginIp ? 4 : 0);

            var penaltyTime =
                contest.RankingStrategy == CcsDefaults.RuleXCPC &&
                PenaltyTime != 20
                ? PenaltyTime : default(int?);

            var scoreboardPagingEnabled =
                UseScoreboardPaging switch
            {
                1 => true,
                2 => false,
                _ => default(bool?),
            };

            var settings = contest.Settings.Clone();

            settings.BalloonAvailable  = contest.Kind == CcsDefaults.KindDom && UseBalloon;
            settings.EventAvailable    = contest.Kind == CcsDefaults.KindDom && UseEvents;
            settings.Languages         = Languages;
            settings.PrintingAvailable = contest.Kind == CcsDefaults.KindDom && UsePrintings;
            settings.RegisterCategory  = defaultCat;
            settings.StatusAvailable   = StatusAvailable;
            settings.PenaltyTime       = penaltyTime;
            settings.ScoreboardPaging  = scoreboardPagingEnabled;
            settings.PreferGymUI       = contest.Kind == CcsDefaults.KindDom && PreferGymUI ? true : default(bool?);
            settings.RestrictIp        = contest.Kind != CcsDefaults.KindDom || restriction == 0 ? default(int?) : restriction;
            settings.IpRanges          = IpRanges?.Split(';', StringSplitOptions.RemoveEmptyEntries);
            return(settings);
        }
예제 #6
0
        /// <summary>
        /// Validates whether the contest rating has been applied.
        /// </summary>
        /// <param name="contest">The contest information.</param>
        /// <param name="shouldHaveBeen">Whether the contest should have been applied or not.</param>
        /// <returns>The task for validating. If validation is failed, throws an exception.</returns>
        /// <exception cref="InvalidOperationException" />
        protected virtual Task ValidateAsync(IContestInformation contest, bool shouldHaveBeen)
        {
            if (contest.RankingStrategy != CcsDefaults.RuleCodeforces)
            {
                throw new InvalidOperationException("The ranking strategy must be codeforces.");
            }

            if (contest.GetState() != Entities.ContestState.Finalized)
            {
                throw new InvalidOperationException("The contest hasn't been finalized.");
            }

            return(Task.CompletedTask);
        }
예제 #7
0
파일: Contest.cs 프로젝트: namofun/ccs
        /// <summary>
        /// Construct a <see cref="Contest"/>.
        /// </summary>
        /// <param name="c">The contest entity.</param>
        public Contest(IContestInformation c)
        {
            FormalName  = c.Name ?? "(unnamed)";
            Name        = c.Name ?? "(unnamed)";
            ShortName   = c.ShortName ?? "DOMjudge";
            Id          = $"{c.Id}";
            PenaltyTime = c.Settings.PenaltyTime ?? 20;
            StartTime   = c.StartTime;
            EndTime     = c.StartTime + c.EndTime;
            Duration    = c.EndTime ?? TimeSpan.FromHours(5);
            ScoreboardFreezeDuration = c.EndTime - c.FreezeTime;

            ScoreboardType = c.RankingStrategy switch
            {
                CcsDefaults.RuleXCPC => "pass-fail",
                CcsDefaults.RuleIOI => "score",
                _ => null,
            };
        }
예제 #8
0
        protected override Task <List <ParticipantRating> > GetPreviousRatingsAsync(IContestInformation contest)
        {
            int cid       = contest.Id;
            var startTime = contest.StartTime !.Value;
            var endTime   = startTime + contest.EndTime !.Value;

            var teamsQuery =
                from t in _context.Set <Team>()
                where t.ContestId == cid && t.CategoryId == _eligibleCategory
                where (from s in _context.Set <Submission>()
                       where s.ContestId == t.ContestId && s.TeamId == t.TeamId
                       where s.Time <= endTime && s.Time >= startTime && !s.Ignored
                       select s).Any()
                join r in _context.Set <RankCache>() on new { t.ContestId, t.TeamId } equals new { r.ContestId, r.TeamId }
            into rcc from r in rcc.DefaultIfEmpty()
            join m in _context.Set <Member>() on new { t.ContestId, t.TeamId } equals new { m.ContestId, m.TeamId }
            select new ParticipantRating(m.UserId, m.PreviousRating, r != null ? r.PointsPublic : 0);

            return(teamsQuery.ToListAsync());
        }
예제 #9
0
        protected override async Task ApplyRatingChangesAsync(IContestInformation contest, IReadOnlyList <ParticipantRating> results)
        {
            int cid           = contest.Id;
            int initialRating = _ratingCalculator.InitialRating;

            // revert the calculated rating delta
            await _context.Set <Member>()
            .Where(m => m.ContestId == cid)
            .BatchUpdateAsync(m => new Member {
                RatingDelta = null
            });

            // save the rating delta
            await _context.Set <Member>()
            .BatchUpdateJoinAsync(
                inner: results.Select(a => new { a.Delta, a.UserId, ContestId = cid }).ToList(),
                outerKeySelector: m => new { m.ContestId, m.UserId },
                innerKeySelector: r => new { r.ContestId, r.UserId },
                updateSelector: (m, r) => new Member {
                RatingDelta = r.Delta
            });

            var newRating =
                from r in _context.Set <Member>()
                where r.ContestId == cid && r.RatingDelta != null
                join u in _context.Set <TUser>() on r.UserId equals u.Id
                select new { u.Id, Rating = (u.Rating ?? initialRating) + r.RatingDelta };

            // don't upload data from local
            await _context.Set <TUser>()
            .BatchUpdateJoinAsync(
                inner: newRating,
                outerKeySelector: u => u.Id,
                innerKeySelector: r => r.Id,
                updateSelector: (u, r) => new TUser {
                Rating = r.Rating
            });
        }
예제 #10
0
 /// <summary>
 /// Applies the rating changes for participants, both on the user entity and team member entity.
 /// </summary>
 /// <param name="contest">The contest information.</param>
 /// <param name="results">The rating results.</param>
 /// <returns>The task for setting the rating.</returns>
 protected abstract Task ApplyRatingChangesAsync(IContestInformation contest, IReadOnlyList <ParticipantRating> results);
예제 #11
0
 /// <summary>
 /// Gets the previous ratings for participants.
 /// </summary>
 /// <param name="contest">The contest information.</param>
 /// <returns>The task for getting the rating.</returns>
 protected abstract Task <List <ParticipantRating> > GetPreviousRatingsAsync(IContestInformation contest);
예제 #12
0
 /// <inheritdoc />
 public Task RollbackAsync(IContestInformation contest)
 => Task.CompletedTask;
예제 #13
0
 /// <inheritdoc />
 public Task ApplyAsync(IContestInformation contest)
 => Task.CompletedTask;
예제 #14
0
 public ContestUpdateEvent(IContestInformation old, IContestInformation @new, IContestContext context)
 {
     OldContest = old;
     NewContest = @new;
     Context    = context;
 }
예제 #15
0
 /// <inheritdoc />
 protected abstract Task RollbackRatingChangesAsync(IContestInformation contest);
예제 #16
0
 /// <inheritdoc />
 public async Task RollbackAsync(IContestInformation contest)
 {
     await ValidateAsync(contest, shouldHaveBeen : true);
     await RollbackRatingChangesAsync(contest);
 }
예제 #17
0
 /// <summary>
 /// Warning: The call <paramref name="funcName"/> to current <paramref name="contest"/> is not proper.
 /// </summary>
 public static void ImproperCall(this ILogger logger, string funcName, IContestInformation contest)
 => _improperCall(logger, funcName, contest.Feature, null);