コード例 #1
0
        private string ResolveRandom(string key, RegistrationContext ctx)
        {
            byte[] buffer;

            string result = "";

            string[] seg = key.Split(':');

            int count = 8;

            switch (seg[0])
            {
            case "id":
                result = ctx.Gamespace.Id;
                break;

            case "grader_key":
                result = ctx.Request.GraderKey;
                break;

            case "grader_url":
                result = ctx.Request.GraderUrl;
                break;

            case "uid":
                result = Guid.NewGuid().ToString("n");
                break;

            case "hex":
                if (seg.Length < 2 || !int.TryParse(seg[1], out count))
                {
                    count = 8;
                }

                count = Math.Min(count, 256) / 2;

                buffer = new byte[count];

                _random.NextBytes(buffer);

                result = BitConverter.ToString(buffer).Replace("-", "").ToLower();

                break;

            case "b64":
                if (seg.Length < 2 || !int.TryParse(seg[1], out count))
                {
                    count = 16;
                }

                count = Math.Min(count, 256);

                buffer = new byte[count];

                _random.NextBytes(buffer);

                result = Convert.ToBase64String(buffer);

                break;

            case "list":
                if (seg.Length < 3 || !int.TryParse(seg[1], out count))
                {
                    count = 1;
                }

                var options = seg.Last()
                              .Split(' ', StringSplitOptions.RemoveEmptyEntries)
                              .ToList();

                while (count > 0 && options.Count > 0)
                {
                    string val = options[_random.Next(options.Count)];
                    result += val + " ";
                    options.Remove(val);
                    count -= 1;
                }

                result = result.Trim();
                break;

            case "int":
            default:
                int min = 0;
                int max = int.MaxValue;
                if (seg.Length > 1)
                {
                    string[] range = seg[1].Split('-');
                    if (range.Length > 1)
                    {
                        int.TryParse(range[0], out min);
                        int.TryParse(range[1], out max);
                    }
                    else
                    {
                        int.TryParse(range[0], out max);
                    }
                }
                result = _random.Next(min, max).ToString();
                break;
            }

            return(result);
        }
コード例 #2
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);
        }