public async Task <GameState> Launch(GamespaceSpec spec) { var game = await _gamespaceStore.Load(spec.IsolationId); if (game == null) { var workspace = await _workspaceStore.Load(spec.WorkspaceId); if (workspace == null || !workspace.HasScope(Client.Scope)) { _logger.LogInformation($"No audience match for workspace {spec?.WorkspaceId}: [{workspace?.Audience}] [{Client?.Scope}]"); throw new InvalidOperationException(); } game = new Data.Gamespace { GlobalId = spec.IsolationId, Name = workspace.Name, Workspace = workspace, Audience = Client.Id.Untagged() // ShareCode = Guid.NewGuid().ToString("N") }; await _gamespaceStore.Add(game); } return(await Deploy(await _gamespaceStore.Load(game.Id), spec)); }
public async Task <GameState> Launch(int workspaceId) { var gamespaces = await _gamespaceStore .ListByProfile(User.Id) .ToArrayAsync(); var game = gamespaces .Where(m => m.WorkspaceId == workspaceId) .SingleOrDefault(); if (game == null) { var workspace = await _workspaceStore.Load(workspaceId); if (workspace == null) { throw new InvalidOperationException(); } if (gamespaces.Length >= _options.GamespaceLimit) { throw new GamespaceLimitReachedException(); } game = new Data.Gamespace { Name = workspace.Name, Workspace = workspace, LastActivity = DateTime.UtcNow, ShareCode = Guid.NewGuid().ToString("N"), Audience = "topomojo" }; game.Players.Add( new Data.Player { PersonId = User.Id, Permission = Data.Permission.Manager // LastSeen = DateTime.UtcNow } ); await _gamespaceStore.Add(game); } return(await Deploy(await _gamespaceStore.Load(game.Id))); }
private async Task <Data.Gamespace> Create( Data.Workspace workspace, string client, string isolationId ) { var gamespace = new Data.Gamespace { GlobalId = isolationId, Name = workspace.Name, Workspace = workspace, ShareCode = Guid.NewGuid().ToString("n"), Audience = client }; gamespace.Players.Add( new Data.Player { PersonId = User.Id, Permission = Data.Permission.Manager // LastSeen = DateTime.UtcNow } ); // glean randomize targets var regex = new Regex("##[^#]*##"); var map = new Dictionary <string, string>(); foreach (var t in gamespace.Workspace.Templates) { foreach (Match match in regex.Matches(t.Guestinfo ?? "")) { map.TryAdd(match.Value, ""); } foreach (Match match in regex.Matches(t.Detail ?? t.Parent?.Detail ?? "")) { map.TryAdd(match.Value, ""); } } // clone challenge var spec = new ChallengeSpec(); if (!string.IsNullOrEmpty(workspace.Challenge)) { spec = JsonSerializer.Deserialize <ChallengeSpec>(workspace.Challenge ?? "{}", jsonOptions); foreach (var question in spec.Questions) { foreach (Match match in regex.Matches(question.Answer)) { string key = match.Value; string val = ""; if (key.Contains(":list##")) { string[] list = question.Answer .Split(' ', StringSplitOptions.RemoveEmptyEntries) .Skip(1) .ToArray(); if (list.Length > 0) { val = list[_random.Next(list.Length)]; question.Answer = key; if (map.ContainsKey(key)) { map[key] = val; } } } map.TryAdd(key, val); } } } // resolve macros foreach (string key in map.Keys.ToArray()) { if (string.IsNullOrEmpty(map[key])) { map[key] = ResolveRandom(key); } } // apply macros to spec answers foreach (var q in spec.Questions) { foreach (string key in map.Keys) { q.Answer = q.Answer.Replace(key, map[key]); } } spec.Randoms = map; gamespace.Challenge = JsonSerializer.Serialize(spec, jsonOptions); await _gamespaceStore.Add(gamespace); return(gamespace); }