Skip to content

Commit

Permalink
v3.23.3 (#515)
Browse files Browse the repository at this point in the history
* Fixed an issue that caused user roles and login info to fail to appear on the user list page in admin.

* Fixed an issue that could cause Gameboard to fail to align challenge end time with engine expiration.

* WIP

* Minor cleanup

* Fixed a bug that could cause incorrect resolution of user team membership

* Update topo package version

* Bug fixes and new tags filter for the challenges report

* Add unstarted teams/no launched challenge teams to enrollment report summary

* Game center teams sort fix, score progress widget fix, cleanup

* Fixed bugs: game level feedback, add tags to practice area report, hide invisible tags

* Fix compile error

* Improve regex efficiency and fix tag bugs

* Correct rendering of enrollment report
  • Loading branch information
sei-bstein authored Oct 16, 2024
1 parent 4772a4f commit 550b840
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 24 deletions.
11 changes: 11 additions & 0 deletions src/Gameboard.Api/Common/CommonRegexes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Text.RegularExpressions;

namespace Gameboard.Api.Common;

public static partial class CommonRegexes
{
public static readonly Regex WhitespaceGreedy = _WhitespaceGreedy();

[GeneratedRegex(@"\s+", RegexOptions.Multiline)]
private static partial Regex _WhitespaceGreedy();
}
13 changes: 13 additions & 0 deletions src/Gameboard.Api/Features/Challenge/Services/ChallengeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,19 @@ public async Task<Challenge> GetOrCreate(NewChallenge model, string actorId, str
return await Create(model, actorId, graderUrl, CancellationToken.None);
}

public IEnumerable<string> GetTags(Data.ChallengeSpec spec)
{
if (spec.Tags.IsEmpty())
return [];

return CommonRegexes
.WhitespaceGreedy
.Split(spec.Tags)
.Select(m => m.Trim().ToLower())
.Where(m => m.IsNotEmpty())
.ToArray();
}

public async Task<Challenge> Create(NewChallenge model, string actorId, string graderUrl, CancellationToken cancellationToken)
{
var now = _now.Get();
Expand Down
5 changes: 3 additions & 2 deletions src/Gameboard.Api/Features/Practice/PracticeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ public IEnumerable<string> UnescapeSuggestedSearches(string input)
if (input.IsEmpty())
return [];

return Regex
.Split(input, @"/s+", RegexOptions.Multiline)
return CommonRegexes
.WhitespaceGreedy
.Split(input)
.Select(m => m.Trim().ToLower())
.Where(m => m.IsNotEmpty())
.ToArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public async Task<IOrderedEnumerable<EnrollmentReportRecord>> GetRawResults(Enro
PlayTime = new EnrollmentReportPlayTimeViewModel
{
Start = p.SessionBegin.HasValue() ? p.SessionBegin : null,
DurationMs = p.Time > 0 ? p.Time : null,
DurationMs = p.SessionBegin.HasValue() ? p.Time : null,
End = (p.SessionBegin.HasValue() && p.Time > 0) ? p.SessionBegin.AddMilliseconds(p.Time) : null
},
Challenges = challenges,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
using Gameboard.Api.Data;
using Gameboard.Api.Features.Games;
using Gameboard.Api.Features.Practice;
using Gameboard.Api.Services;
using Microsoft.EntityFrameworkCore;
using ServiceStack;

namespace Gameboard.Api.Features.Reports;

Expand All @@ -22,14 +22,18 @@ public interface IPracticeModeReportService
Task<PracticeModeReportPlayerModeSummary> GetPlayerModePerformanceSummary(string userId, bool isPractice, CancellationToken cancellationToken);
}

internal partial class PracticeModeReportService : IPracticeModeReportService
internal class PracticeModeReportService
(
ChallengeService challengeService,
IPracticeService practiceService,
IReportsService reportsService,
IStore store
) : IPracticeModeReportService
{
private readonly IPracticeService _practiceService;
private readonly IReportsService _reportsService;
private readonly IStore _store;

public PracticeModeReportService(IPracticeService practiceService, IReportsService reportsService, IStore store)
=> (_practiceService, _reportsService, _store) = (practiceService, reportsService, store);
private readonly ChallengeService _challengeService = challengeService;
private readonly IPracticeService _practiceService = practiceService;
private readonly IReportsService _reportsService = reportsService;
private readonly IStore _store = store;

private sealed class PracticeModeReportUngroupedResults
{
Expand Down Expand Up @@ -203,6 +207,7 @@ public async Task<PracticeModeReportResults> GetResultsByChallenge(PracticeModeR
{
var attempts = g.ToList();
var spec = ungroupedResults.Specs[g.Key];
var specTags = _challengeService.GetTags(spec);
var sponsorIdsPlayed = attempts.Select(a => a.Player.Sponsor.Id).Distinct();
var sponsorsPlayed = ungroupedResults
Expand All @@ -219,16 +224,6 @@ public async Task<PracticeModeReportResults> GetResultsByChallenge(PracticeModeR
Performance = BuildChallengePerformance(attempts, s)
});
var tags = Array.Empty<string>();
if (spec.Tags.IsNotEmpty())
{
var specTags = Regex
.Split(spec.Tags, @"\s+", RegexOptions.Multiline)
.Select(m => m.Trim().ToLower())
.ToArray();
tags = visibleTags.Intersect(specTags).ToArray();
}
return new PracticeModeByChallengeReportRecord
{
Id = spec.Id,
Expand All @@ -245,7 +240,7 @@ public async Task<PracticeModeReportResults> GetResultsByChallenge(PracticeModeR
MaxPossibleScore = spec.Points,
AvgScore = attempts.Select(a => a.Score).Average(),
Description = spec.Description,
Tags = tags,
Tags = specTags.Intersect(visibleTags).ToArray(),
Text = spec.Text,
SponsorsPlayed = sponsorsPlayed,
OverallPerformance = performanceOverall,
Expand Down
4 changes: 2 additions & 2 deletions src/Gameboard.Api/Features/Reports/ReportService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ internal async Task<SponsorReport> GetSponsorStats()

internal Task<GameSponsorReport> GetGameSponsorsStats(string gameId)
{
List<GameSponsorStat> gameSponsorStats = new List<GameSponsorStat>();
var gameSponsorStats = new List<GameSponsorStat>();

if (string.IsNullOrWhiteSpace(gameId))
if (gameId.IsEmpty())
throw new ArgumentNullException("Invalid game id");

var game = _store
Expand Down

0 comments on commit 550b840

Please sign in to comment.