示例#1
0
        private async Task Create(RegistrationContext ctx, User actor)
        {
            var ts = DateTimeOffset.UtcNow;

            int duration = actor.GamespaceMaxMinutes > 0
                ? actor.GamespaceMaxMinutes
                : ctx.Workspace.DurationMinutes > 0
                    ? ctx.Workspace.DurationMinutes
                    : _options.DefaultGamespaceMinutes
            ;

            if (string.IsNullOrEmpty(ctx.Request.GraderKey))
            {
                ctx.Request.GraderKey = Guid.NewGuid().ToString("n");
            }

            ctx.Gamespace = new Data.Gamespace
            {
                Id                  = Guid.NewGuid().ToString("n"),
                Name                = ctx.Workspace.Name,
                Workspace           = ctx.Workspace,
                ManagerId           = actor.Id,
                ManagerName         = actor.Name,
                AllowReset          = ctx.Request.AllowReset,
                CleanupGraceMinutes = actor.GamespaceCleanupGraceMinutes,
                WhenCreated         = ts,
                ExpirationTime      = ctx.Request.ResolveExpiration(ts, duration),
                PlayerCount         = ctx.Request.PlayerCount > 0 ? ctx.Request.PlayerCount : ctx.Request.Players.Count(),
                GraderKey           = ctx.Request.GraderKey.ToSha256()
            };

            var gamespace = ctx.Gamespace;

            foreach (var player in ctx.Request.Players)
            {
                gamespace.Players.Add(
                    new Data.Player
                {
                    SubjectId   = player.SubjectId,
                    SubjectName = player.SubjectName
                }
                    );
            }

            if (gamespace.Players.Any())
            {
                gamespace.Players.First().Permission = Permission.Manager;
            }

            // clone challenge
            var spec = JsonSerializer.Deserialize <ChallengeSpec>(ctx.Workspace.Challenge ?? "{}", jsonOptions);

            //resolve transforms
            ResolveTransforms(spec, ctx);

            // TODO: if customize-script, run and update transforms

            // select variant, adjusting from 1-based to 0-based index
            gamespace.Variant = ctx.Request.Variant > 0
                ? Math.Min(ctx.Request.Variant, spec.Variants.Count) - 1
                : _random.Next(spec.Variants.Count)
            ;

            spec.Challenge = spec.Variants
                             .Skip(gamespace.Variant).Take(1)
                             .FirstOrDefault();

            // initialize selected challenge
            spec.Challenge.SetQuestionWeights();

            spec.MaxPoints = ctx.Request.Points;

            spec.MaxAttempts = ctx.Request.MaxAttempts;

            spec.Variants = null;

            gamespace.Challenge = JsonSerializer.Serialize(spec, jsonOptions);

            // apply transforms
            foreach (var kvp in spec.Transforms)
            {
                gamespace.Challenge = gamespace.Challenge.Replace($"##{kvp.Key}##", kvp.Value);
            }

            await _store.Create(gamespace);
        }