Skip to content

Commit

Permalink
Block runs based on their tags, such as "opener", "checkpoint", "reca…
Browse files Browse the repository at this point in the history
…p", "sleep", and "finale". All existing blocking logic is retained (title, duration, runner IDs).
  • Loading branch information
Aldaviva committed Jan 8, 2025
1 parent 1edffe6 commit cb36c0e
Show file tree
Hide file tree
Showing 9 changed files with 7,303 additions and 178 deletions.
6 changes: 4 additions & 2 deletions GamesDoneQuickCalendarFactory/Data/GDQ/GdqRun.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ namespace GamesDoneQuickCalendarFactory.Data.GDQ;
/// <param name="name">Usually the same as <paramref name="gameName"/>, but if this is a bonus game, <paramref name="name"/> will have a <c>BONUS GAME 1- </c> prefix.</param>
/// <param name="gameName">Usually the same as <paramref name="name"/>, but if this is a bonus game, <paramref name="gameName"/> won't have the <c>BONUS GAME 1- </c> prefix.</param>
/// <param name="category">The type or rule set of the run, such as 100% or Any%.</param>
/// <param name="console">The hardware the game is running on, such as PC or PS5.</param>
/// <param name="console">The hardware the game is running on, such as PC or PS5, or the empty string.</param>
/// <param name="order">The sequence number of this run in its containing event, starting at <c>1</c> for the first run of the even and increasing by <c>1</c> for each run in the event</param>
/// <param name="runTime">Before a run ends, this is the estimated duration, but after a run ends, this changes to the actual duration. To get the original estimated duration even after the run ends, use <paramref name="endTime"/><c>-</c><paramref name="startTime"/>.</param>
/// <param name="tags">Zero or more of <c>awful</c>, <c>bingo</c>, <c>bonus</c>, <c>checkpoint</c>, <c>checkpoint_run</c>, <c>coop</c>, <c>finale</c>, <c>horror</c>, <c>kaizo</c>, <c>new_addition</c>, <c>online</c>, <c>opener</c>, <c>race</c>, <c>randomizer</c>, <c>recap</c>, <c>relay</c>, <c>rhythm</c>, <c>showcase</c>, <c>sleep</c>, <c>tas</c>, or <c>tournament</c> (as of AGDQ2025, there can be more in the future). Can be empty, but never null.</param>
public record GdqRun(
int id,
[property: JsonPropertyName("name")] string name,
Expand All @@ -26,7 +27,8 @@ public record GdqRun(
[property: JsonPropertyName("run_time")] Period runTime,
[property: JsonPropertyName("setup_time")] Period setupTime,
[property: JsonPropertyName("anchor_time")] OffsetDateTime? anchorTime,
[property: JsonPropertyName("video_links")] IReadOnlyList<Video> recordings
[property: JsonPropertyName("video_links")] IReadOnlyList<Video> recordings,
IReadOnlyList<string> tags
);

public record GdqPerson(
Expand Down
11 changes: 6 additions & 5 deletions GamesDoneQuickCalendarFactory/Data/GameRun.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
namespace GamesDoneQuickCalendarFactory.Data;

public record GameRun(
OffsetDateTime start,
Duration duration,
string name,
string description,
OffsetDateTime start,
Duration duration,
string name,
string description,
IEnumerable<Person> runners,
IEnumerable<Person> commentators,
IEnumerable<Person> hosts
IEnumerable<Person> hosts,
IEnumerable<string> tags
);

public record Person(int id, string name);
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifiers>win-x64;win-arm64;linux-x64;linux-arm;linux-arm64</RuntimeIdentifiers>
<Version>2.7.5</Version>
<Version>2.7.6</Version>
<Product>Games Done Quick Calendar Factory</Product>
<AssemblyTitle>Games Done Quick Calendar Factory</AssemblyTitle>
<Company>Ben Hutchison</Company>
Expand Down
20 changes: 16 additions & 4 deletions GamesDoneQuickCalendarFactory/Services/EventDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,18 @@ public class EventDownloader(IGdqClient gdq, IClock clock): IEventDownloader {
1434, // Interview Crew
1884, // Faith (the Frame Fatales saber-toothed tiger mascot)
1885, // Everyone!
2071 // Frame Fatales Interstitial Team
2071, // Frame Fatales Interstitial Team
2171, // Everyone
}.ToFrozenSet();

private static readonly IReadOnlySet<string> TAG_BLACKLIST = new HashSet<string> {
"opener",
"checkpoint",
"recap",
"sleep",
"finale"
}.Select(s => s.ToLowerInvariant()).ToFrozenSet();

/// <summary>
/// If there are no calendar events ending in the last 1 day, and no upcoming events, hide all those old past events.
/// </summary>
Expand All @@ -32,17 +41,20 @@ public class EventDownloader(IGdqClient gdq, IClock clock): IEventDownloader {
GdqEvent currentEvent = await gdq.getCurrentEvent();

IReadOnlyList<GameRun> runs = (await gdq.getEventRuns(currentEvent))
.Where(run => !run.runners.IntersectBy(RUNNER_BLACKLIST, runner => runner.id).Any() && !isSleep(run))
.Where(run =>
!run.runners.IntersectBy(RUNNER_BLACKLIST, runner => runner.id).Any() &&
!run.tags.Intersect(TAG_BLACKLIST).Any() &&
!"Sleep".Equals(run.name, StringComparison.CurrentCultureIgnoreCase) &&
run.duration < MAX_RUN_DURATION)
.ToList().AsReadOnly();

Instant latestRunEndTimeToInclude = clock.GetCurrentInstant() - MAX_EVENT_END_CLEANUP_DELAY;
if (runs.Any(run => (run.start + run.duration).ToInstant() > latestRunEndTimeToInclude)) {
return new Event(currentEvent.longName, currentEvent.shortName, runs);
} else {
// All runs ended too far in the past
return null;
}
}

private static bool isSleep(GameRun run) => run.name == "Sleep" || run.duration >= MAX_RUN_DURATION;

}
3 changes: 2 additions & 1 deletion GamesDoneQuickCalendarFactory/Services/GdqClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ public async Task<IEnumerable<GameRun>> getEventRuns(int eventId) {
description: $"{run.category} \u2014 {run.console}",
runners: run.runners.Select(getPerson),
commentators: run.commentators.Select(getPerson),
hosts: run.hosts.Select(getPerson));
hosts: run.hosts.Select(getPerson),
tags: run.tags.Select(s => s.ToLowerInvariant()));
runs.Add(gameRun);

// The API returns runs sorted in ascending start time order, but guarantee it here so the faster equality check in CalendarPoller is correct
Expand Down
12 changes: 8 additions & 4 deletions Tests/CalendarGeneratorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public async Task generateCalendar() {
"Any% Unrestricted — PC",
[new Person(1, "Radicoon")],
[new Person(2, "kevinregamey"), new Person(3, "silentdestroyer")],
[new Person(4, "AttyJoe")]),
[new Person(4, "AttyJoe")],
[]),

new GameRun(
OffsetDateTimePattern.GeneralIso.Parse("2024-01-14T12:48:00-05:00").GetValueOrThrow(),
Expand All @@ -37,7 +38,8 @@ [new Person(4, "AttyJoe")]),
"Master — Wii",
[new Person(1, "Helix")],
[new Person(2, "limy"), new Person(3, "PeasSMB")],
[new Person(4, "AttyJoe")]),
[new Person(4, "AttyJoe")],
[]),

new GameRun(
OffsetDateTimePattern.GeneralIso.Parse("2024-01-14T13:21:00-05:00").GetValueOrThrow(),
Expand All @@ -46,7 +48,8 @@ [new Person(4, "AttyJoe")]),
"101% — SNES",
[new Person(1, "Tonkotsu")],
[new Person(2, "Glan"), new Person(3, "V0oid")],
[new Person(4, "AttyJoe")]),
[new Person(4, "AttyJoe")],
[]),

new GameRun(
OffsetDateTimePattern.GeneralIso.Parse("2024-01-20T21:04:00-05:00").GetValueOrThrow(),
Expand All @@ -55,7 +58,8 @@ [new Person(4, "AttyJoe")]),
"Any% Cutscene Remover — PC",
[new Person(1, "Zic3")],
[new Person(2, "FoxyJira"), new Person(3, "WoadyB")],
[new Person(4, "Prolix")])
[new Person(4, "Prolix")],
[])
]);

A.CallTo(() => eventDownloader.downloadSchedule()).Returns(@event);
Expand Down
7,077 changes: 7,076 additions & 1 deletion Tests/Data/runs.json

Large diffs are not rendered by default.

Loading

0 comments on commit cb36c0e

Please sign in to comment.