Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3.22.1 #507

Merged
merged 5 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public void ResolveCaptain_WhenMultiplePlayersFromSameTeam_ResolvesExpected()
var sut = new TeamService
(
A.Fake<IActingUserService>(),
A.Fake<ICacheService>(),
A.Fake<IGameEngineService>(),
A.Fake<IMapper>(),
A.Fake<IMediator>(),
Expand Down
32 changes: 19 additions & 13 deletions src/Gameboard.Api/Features/Challenge/Services/ChallengeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@
using Gameboard.Api.Features.GameEngine;
using Gameboard.Api.Features.Teams;
using Gameboard.Api.Features.Scores;
using Gameboard.Api.Features.Users;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using ServiceStack;
using Gameboard.Api.Features.Users;

namespace Gameboard.Api.Services;

public partial class ChallengeService(
public partial class ChallengeService
(
IActingUserService actingUserService,
ConsoleActorMap actorMap,
CoreOptions coreOptions,
Expand All @@ -42,7 +43,7 @@ public partial class ChallengeService(
IUserRolePermissionsService permissionsService,
IStore store,
ITeamService teamService
) : _Service(logger, mapper, coreOptions)
) : _Service(logger, mapper, coreOptions)
{
private readonly IActingUserService _actingUserService = actingUserService;
private readonly ConsoleActorMap _actorMap = actorMap;
Expand Down Expand Up @@ -177,16 +178,16 @@ public async Task Delete(string id)
await _gameEngine.DeleteGamespace(entity);
}

public async Task<bool> UserIsPlayingChallenge(string id, string subjectId)
public async Task<bool> UserIsPlayingChallenge(string challengeId, string userId)
{
var challengeTeamId = await _store
.WithNoTracking<Data.Challenge>()
.Where(c => c.Id == id)
.Where(c => c.Id == challengeId)
.Select(c => c.TeamId)
.Distinct()
.SingleOrDefaultAsync();

var userTeamIds = await _teamService.GetUserTeamIds(subjectId);
var userTeamIds = await _teamService.GetUserTeamIds(userId);
return userTeamIds.Any(tId => tId == challengeTeamId);
}

Expand Down Expand Up @@ -735,14 +736,19 @@ int variant
challenge.StartTime = state.StartTime;
challenge.LastSyncTime = _now.Get();

// even if a specific end time isn't set, use the expiration time instead
if (state.EndTime.IsNotEmpty())
{
challenge.EndTime = state.EndTime;
}
else if (state.ExpirationTime.IsNotEmpty())
// if we haven't already resolved the endtime
if (challenge.EndTime.IsEmpty())
{
challenge.EndTime = state.ExpirationTime;
// prefer the state's end time
if (state.EndTime.IsNotEmpty())
{
challenge.EndTime = state.EndTime;
}
// but fall back on the expiration time
else if (state.ExpirationTime.IsNotEmpty())
{
challenge.EndTime = state.ExpirationTime;
}
}

challenge.Events.Add(new ChallengeEvent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ await _store
(
up => up
.SetProperty(c => c.LastSyncTime, now)
.SetProperty(c => c.EndTime, c => playerSessionEnds.ContainsKey(challenge.PlayerId) ? playerSessionEnds[challenge.PlayerId] : c.EndTime)
.SetProperty(c => c.EndTime, c => playerSessionEnds.ContainsKey(challenge.PlayerId) ? playerSessionEnds[challenge.PlayerId] : c.EndTime),
cancellationToken
);
}
catch (Exception ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,12 @@ public async Task<ConsoleSummary> GetConsole(Data.Challenge entity, ConsoleReque
}

public IEnumerable<GameEngineGamespaceVm> GetGamespaceVms(GameEngineGameState state)
{
return state.Vms.Select(vm => new GameEngineGamespaceVm
=> state.Vms.Select(vm => new GameEngineGamespaceVm
{
Id = vm.Id,
Name = vm.Name,
Url = _vmUrlResolver.ResolveUrl(vm)
});
}
}).ToArray();

public async Task<IEnumerable<GameEngineSectionSubmission>> AuditChallenge(Data.Challenge entity)
{
Expand Down
82 changes: 26 additions & 56 deletions src/Gameboard.Api/Features/Teams/Services/TeamService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,44 +42,26 @@ public interface ITeamService
Task SetSessionWindow(IEnumerable<string> teamIds, CalculatedSessionWindow sessionWindow, CancellationToken cancellationToken);
}

internal class TeamService : ITeamService, INotificationHandler<UserJoinedTeamNotification>
internal class TeamService
(
IActingUserService actingUserService,
IGameEngineService gameEngine,
IMapper mapper,
IMediator mediator,
INowService now,
IInternalHubBus teamHubService,
IPracticeService practiceService,
IStore store
) : ITeamService
{
private readonly IActingUserService _actingUserService;
private readonly ICacheService _cacheService;
private readonly IGameEngineService _gameEngine;
private readonly IMapper _mapper;
private readonly IMediator _mediator;
private readonly INowService _now;
private readonly IInternalHubBus _hubBus;
private readonly IPracticeService _practiceService;
private readonly IStore _store;

public TeamService
(
IActingUserService actingUserService,
ICacheService cacheService,
IGameEngineService gameEngine,
IMapper mapper,
IMediator mediator,
INowService now,
IInternalHubBus teamHubService,
IPracticeService practiceService,
IStore store
)
{
_actingUserService = actingUserService;
_cacheService = cacheService;
_gameEngine = gameEngine;
_mapper = mapper;
_mediator = mediator;
_now = now;
_practiceService = practiceService;
_store = store;
_hubBus = teamHubService;
}

public Task Handle(UserJoinedTeamNotification notification, CancellationToken cancellationToken)
=> Task.Run(() => _cacheService.Invalidate(GetUserTeamIdsCacheKey(notification.UserId)), cancellationToken);
private readonly IActingUserService _actingUserService = actingUserService;
private readonly IGameEngineService _gameEngine = gameEngine;
private readonly IMapper _mapper = mapper;
private readonly IMediator _mediator = mediator;
private readonly INowService _now = now;
private readonly IInternalHubBus _hubBus = teamHubService;
private readonly IPracticeService _practiceService = practiceService;
private readonly IStore _store = store;

public async Task<IEnumerable<Api.Player>> AddPlayers(string teamId, CancellationToken cancellationToken, params string[] playerIds)
{
Expand Down Expand Up @@ -399,22 +381,13 @@ public async Task<IEnumerable<Team>> GetTeams(IEnumerable<string> ids)
}

public Task<string[]> GetUserTeamIds(string userId)
=> _cacheService.GetOrCreateAsync
(
GetUserTeamIdsCacheKey(userId),
async entry =>
{
var userTeamIds = await _store
.WithNoTracking<Data.Player>()
.Where(p => p.UserId == userId)
.Select(p => p.TeamId)
.Distinct()
.ToArrayAsync();

entry.Value = userTeamIds;
return userTeamIds;
}
);
=> _store
.WithNoTracking<Data.Player>()
.Where(p => p.UserId == userId)
.Select(p => p.TeamId)
.Distinct()
.ToArrayAsync();


public async Task<bool> IsAtGamespaceLimit(string teamId, Data.Game game, CancellationToken cancellationToken)
{
Expand Down Expand Up @@ -583,7 +556,4 @@ private async Task<TeamState> GetTeamState(string teamId, SimpleEntity actor, Ca
Actor = actor
};
}

private string GetUserTeamIdsCacheKey(string userId)
=> $"UserTeamIds:{userId}";
}
18 changes: 9 additions & 9 deletions src/Gameboard.Api/Features/User/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ public class UserSettings

public class UserOnly
{
public string Id { get; set; }
public string Name { get; set; }
public string NameStatus { get; set; }
public string ApprovedName { get; set; }
public SponsorWithParentSponsor Sponsor { get; set; }
public DateTimeOffset CreatedOn { get; set; }
public DateTimeOffset? LastLoginDate { get; set; }
public int LoginCount { get; set; }
public UserRoleKey Role { get; set; }
public required string Id { get; set; }
public required string Name { get; set; }
public required string NameStatus { get; set; }
public required string ApprovedName { get; set; }
public required SponsorWithParentSponsor Sponsor { get; set; }
public required DateTimeOffset CreatedOn { get; set; }
public required DateTimeOffset? LastLoginDate { get; set; }
public required int LoginCount { get; set; }
public required UserRoleKey Role { get; set; }
}

public class TryCreateUserResult
Expand Down
4 changes: 4 additions & 0 deletions src/Gameboard.Api/Features/User/UserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ public async Task<IEnumerable<UserOnly>> List<TProject>(UserSearch model) where
Name = u.Name,
NameStatus = u.NameStatus,
ApprovedName = u.ApprovedName,
CreatedOn = u.CreatedOn,
LastLoginDate = u.LastLoginDate,
LoginCount = u.LoginCount,
Role = u.Role,
Sponsor = new SponsorWithParentSponsor
{
Id = u.SponsorId,
Expand Down