Skip to content

Commit

Permalink
Fix KeyNotFoundException for scheduled free game collection (#70)
Browse files Browse the repository at this point in the history
This commit resolves the `KeyNotFoundException` encountered during the scheduled free game collection process. The issue was caused by an attempt to access a non-existent key in the bot dictionary, as reported in issue #70.

Changes include:
- Added a check in `ASFFreeGamesPlugin.cs` to ensure there are viable bots before proceeding with the free game collection command.
- Modified `FreeGamesCommand.cs` to handle bot collections more robustly, trimming bot names to prevent whitespace issues and using `GetValueOrDefault` to avoid exceptions when a bot name is not found.
- Updated the `HandleInternalCollectCommand` method to return a more informative response, indicating the number of collected games and the bots involved in the operation.

These updates aim to enhance the stability and reliability of the free game collection feature in ASF.
  • Loading branch information
maxisoft committed May 11, 2024
1 parent 0348c31 commit 217f5ed
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
6 changes: 6 additions & 0 deletions ASFFreeGames/ASFFreeGamesPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ public async void CollectGamesOnClock(object? source) {
Array.Sort(reorderedBots, comparison);
}

if (reorderedBots.Length == 0) {
ArchiLogger.LogGenericDebug("no viable bot found for freegame scheduled operation");

return;
}

if (!cts.IsCancellationRequested) {
string cmd = $"FREEGAMES {FreeGamesCommand.CollectInternalCommandString} " + string.Join(' ', reorderedBots.Select(static bot => bot.BotName));
await OnBotCommand(null!, EAccess.None, cmd, cmd.Split()).ConfigureAwait(false);
Expand Down
19 changes: 15 additions & 4 deletions ASFFreeGames/Commands/FreeGamesCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ internal sealed class FreeGamesCommand : IBotCommand, IDisposable {
}

private async Task<string?> HandleCollectCommand(Bot? bot) {
int collected = await CollectGames(bot is not null ? new[] { bot } : Context.Bots, ECollectGameRequestSource.RequestedByUser, Context.CancellationToken).ConfigureAwait(false);
int collected = await CollectGames(bot is not null ? [bot] : Context.Bots.ToArray(), ECollectGameRequestSource.RequestedByUser, Context.CancellationToken).ConfigureAwait(false);

return FormatBotResponse(bot, $"Collected a total of {collected} free game(s)");
}
Expand All @@ -134,10 +134,21 @@ internal sealed class FreeGamesCommand : IBotCommand, IDisposable {
}

private async ValueTask<string?> HandleInternalCollectCommand(Bot? bot, string[] args, CancellationToken cancellationToken) {
Dictionary<string, Bot> botMap = Context.Bots.ToDictionary(static b => b.BotName, static b => b, StringComparer.InvariantCultureIgnoreCase);
int collected = await CollectGames(args.Skip(2).Select(botName => botMap[botName]), ECollectGameRequestSource.Scheduled, cancellationToken).ConfigureAwait(false);
Dictionary<string, Bot> botMap = Context.Bots.ToDictionary(static b => b.BotName.Trim(), static b => b, StringComparer.InvariantCultureIgnoreCase);

return FormatBotResponse(bot, $"Collected a total of {collected} free game(s)");
Bot[] bots = args.Skip(2).Select(botName => botMap.GetValueOrDefault(botName.Trim())).Where(static b => b is not null).ToArray()!;

if (bots.Length == 0) {
if (bot is null) {
return null;
}

bots = [bot];
}

int collected = await CollectGames(bots, ECollectGameRequestSource.Scheduled, cancellationToken).ConfigureAwait(false);

return FormatBotResponse(bot, $"Collected a total of {collected} free game(s)" + (bots.Length > 1 ? $" on {bots.Length} bots" : $" on {bots.FirstOrDefault()?.BotName}"));
}

private async Task SaveOptions(CancellationToken cancellationToken) {
Expand Down

0 comments on commit 217f5ed

Please sign in to comment.