Skip to content

Commit

Permalink
Merge pull request #70 from cmu-sei/next
Browse files Browse the repository at this point in the history
3.6.5
  • Loading branch information
sei-mkaar authored Nov 15, 2022
2 parents 8d8813b + 823377e commit a54215d
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 49 deletions.
7 changes: 3 additions & 4 deletions src/Gameboard.Api/Features/UnityGames/IUnityGameService.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Gameboard.Api.Data;

namespace Gameboard.Api.Features.UnityGames;

public interface IUnityGameService
{
Task<ChallengeEvent> AddChallengeEvent(NewUnityChallengeEvent model, string userId);
Task<Data.Challenge> AddChallenge(NewUnityChallenge newChallenge, User actor);
Task CreateMissionEvent(UnityMissionUpdate model, Api.User actor);
Task<Data.ChallengeEvent> CreateMissionEvent(UnityMissionUpdate model, Api.User actor);
Task DeleteChallengeData(string gameId);
bool IsUnityGame(Game game);
bool IsUnityGame(Data.Game game);
}
32 changes: 11 additions & 21 deletions src/Gameboard.Api/Features/UnityGames/UnityGameController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,35 +162,25 @@ await _hub.Clients
return result;
}

/// <summary>
/// Log a challenge event for all members of the specified team.
/// </summary>
/// <param name="model">NewChallengeEvent</param>
/// <returns>ChallengeEvent</returns>
[HttpPost("api/unity/challengeEvent")]
[Authorize]
public async Task<Data.ChallengeEvent> CreateChallengeEvent([FromBody] NewUnityChallengeEvent model)
{
AuthorizeAny(
() => Actor.IsDirector,
() => Actor.IsAdmin,
() => Actor.IsDesigner
);

await Validate(model);
return await _unityGameService.AddChallengeEvent(model, Actor.Id);
}

[HttpPost("api/unity/mission-update")]
[Authorize]
public async Task CreateMissionEvent([FromBody] UnityMissionUpdate model)
public async Task<IActionResult> CreateMissionEvent([FromBody] UnityMissionUpdate model)
{
AuthorizeAny(
() => Actor.IsAdmin
);

await Validate(model);
await _unityGameService.CreateMissionEvent(model, Actor);
var challengeEvent = await _unityGameService.CreateMissionEvent(model, Actor);

if (challengeEvent == null)
{
// this means that everything went fine, but that we've already been told the team completed this challenge
return Accepted();
}

// this means we actually created an event
return Ok(challengeEvent);
}

[Authorize]
Expand Down
56 changes: 32 additions & 24 deletions src/Gameboard.Api/Features/UnityGames/UnityGameService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ ConsoleActorMap actorMap
UserId = actor.Id,
TeamId = newChallenge.TeamId,
Timestamp = DateTimeOffset.UtcNow,
Text = $"{teamCaptain.ApprovedName}'s journey into CubeSpace has begun...",
Text = $"{teamCaptain.ApprovedName}'s has gathered their team and departed into CubeSpace...",
Type = ChallengeEventType.Started
}
},
Expand All @@ -157,21 +157,6 @@ ConsoleActorMap actorMap
return newChallengeEntity;
}

public async Task<ChallengeEvent> AddChallengeEvent(NewUnityChallengeEvent model, string userId)
{
var challengeEvent = new Data.ChallengeEvent
{
ChallengeId = model.ChallengeId,
UserId = userId,
TeamId = model.TeamId,
Text = model.Text,
Type = model.Type,
Timestamp = model.Timestamp
};

return await Store.AddUnityChallengeEvent(challengeEvent);
}

public async Task DeleteChallengeData(string gameId)
{
var challenges = await Store
Expand All @@ -192,40 +177,63 @@ public async Task DeleteChallengeData(string gameId)
await Store.DbContext.SaveChangesAsync();
}

public async Task CreateMissionEvent(UnityMissionUpdate model, Api.User actor)
public async Task<Data.ChallengeEvent> CreateMissionEvent(UnityMissionUpdate model, Api.User actor)
{
var challenge = await Store.DbContext
var unityMode = GetUnityModeString();
var challengeCandidates = await Store.DbContext
.Challenges
.Include(c => c.Game)
.Include(c => c.Events)
.Include(c => c.Player)
.Where(c => c.TeamId == model.TeamId && c.Game.Mode.ToLower() == "unity")
.FirstOrDefaultAsync();
.Where(c => c.TeamId == model.TeamId && c.Game.Mode == unityMode)
.ToListAsync();

if (challenge == null)
if (challengeCandidates.Count() != 1)
{
throw new ChallengeResolutionFailure(model.TeamId);
}

// if we return null to the controller above, it interprets this as an "ok cool, we already have this one"
// kind of thing
var challenge = challengeCandidates.First();
if (IsMissionComplete(challenge.Events, model.MissionId))
{
return null;
}

// record an event for this challenge
challenge.Events.Add(new Data.ChallengeEvent
var challengeEvent = new Data.ChallengeEvent
{
Id = Guid.NewGuid().ToString("n"),
ChallengeId = challenge.Id,
UserId = actor.Id,
TeamId = model.TeamId,
Text = $"{challenge.Player} has found the codex for {model.MissionName}!",
Text = $"{challenge.Player.ApprovedName}'s team has found the codex for {model.MissionName}! {GetMissionCompleteDefinitionString(model.MissionId)}",
Type = ChallengeEventType.Submission,
Timestamp = DateTimeOffset.UtcNow
});
};
challenge.Events.Add(challengeEvent);

// also update the score of the challenge
challenge.Score += model.PointsScored;

// save it up
await Store.DbContext.SaveChangesAsync();

// return (used to determine HTTP status code in an above controller)
return challengeEvent;
}

public bool IsUnityGame(Data.Game game) => game.Mode == GetUnityModeString();
public bool IsUnityGame(Game game) => game.Mode == GetUnityModeString();
private string GetUnityModeString() => "unity";

private string GetMissionCompleteDefinitionString(string missionId)
=> $"[complete:{missionId}]";

private bool IsMissionComplete(IEnumerable<Data.ChallengeEvent> events, string missionId)
=> events.Any(e => e.Text.Contains(GetMissionCompleteDefinitionString(missionId)));

private Data.Player ResolveTeamCaptain(IEnumerable<Data.Player> players, NewUnityChallenge newChallenge)
{
if (players.Count() == 0)
Expand Down

0 comments on commit a54215d

Please sign in to comment.