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); }