Fixed invalid ownerids crashing bot on startup

Updated changelog, version to 6.1.3
This commit is contained in:
Toastie 2025-04-05 19:56:46 +13:00
parent 682ecb6f08
commit 427a011590
Signed by: toastie_t0ast
GPG key ID: 0861BE54AD481DC7
3 changed files with 61 additions and 45 deletions
CHANGELOG.md
src/EllieBot
EllieBot.csproj
Modules/Administration/Self

View file

@ -2,6 +2,12 @@
*a,c,f,r,o*
## [6.1.3] - 05.04.2025
### Fixed
- Bot will no longer fail to startup if ownerids are wrong
## [6.1.2] - 03.04.2025
### Fixed

View file

@ -4,7 +4,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
<Version>6.1.2</Version>
<Version>6.1.3</Version>
<!-- Output/build -->
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>

View file

@ -81,13 +81,13 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
await using var uow = _db.GetDbContext();
autoCommands = uow.Set<AutoCommand>()
.AsNoTracking()
.Where(x => x.Interval >= 5)
.AsEnumerable()
.GroupBy(x => x.GuildId)
.ToDictionary(x => x.Key,
y => y.ToDictionary(x => x.Id, TimerFromAutoCommand).ToConcurrent())
.ToConcurrent();
.AsNoTracking()
.Where(x => x.Interval >= 5)
.AsEnumerable()
.GroupBy(x => x.GuildId)
.ToDictionary(x => x.Key,
y => y.ToDictionary(x => x.Id, TimerFromAutoCommand).ToConcurrent())
.ToConcurrent();
var startupCommands = uow.Set<AutoCommand>().AsNoTracking().Where(x => x.Interval == 0);
foreach (var cmd in startupCommands)
@ -101,8 +101,10 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
}
}
if (_client.ShardId == 0)
await LoadOwnerChannels();
if (_client.ShardId != 0)
return;
await LoadOwnerChannels();
}
private Timer TimerFromAutoCommand(AutoCommand x)
@ -165,19 +167,27 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
private async Task LoadOwnerChannels()
{
var channels = await _creds.OwnerIds.Select(id =>
{
var user = _client.GetUser(id);
if (user is null)
return Task.FromResult<IDMChannel>(null);
var channels = await _creds.OwnerIds.Select(async id =>
{
var user = _client.GetUser(id);
if (user is null)
return null;
return user.CreateDMChannelAsync();
})
.WhenAll();
try
{
return await user.CreateDMChannelAsync();
}
catch (Exception)
{
Log.Error("Unable to DM Owner {UserId} - please remove that id from the owner list", user.Id);
return null;
}
})
.WhenAll();
ownerChannels = channels.Where(x => x is not null)
.ToDictionary(x => x.Recipient.Id, x => x)
.ToImmutableDictionary();
.ToDictionary(x => x.Recipient.Id, x => x)
.ToImmutableDictionary();
if (!ownerChannels.Any())
{
@ -401,41 +411,41 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
{
await using var ctx = _db.GetDbContext();
var presentDbUsers = await ctx.GetTable<DiscordUser>()
.Select(x => new
{
x.UserId,
x.Username,
})
.Where(x => users.Select(y => y.Id).Contains(x.UserId))
.ToArrayAsyncEF();
.Select(x => new
{
x.UserId,
x.Username,
})
.Where(x => users.Select(y => y.Id).Contains(x.UserId))
.ToArrayAsyncEF();
var usersToAdd = users
.Where(x => !presentDbUsers.Select(x => x.UserId).Contains(x.Id))
.Select(x => new DiscordUser()
{
UserId = x.Id,
AvatarId = x.AvatarId,
Username = x.Username,
});
.Where(x => !presentDbUsers.Select(x => x.UserId).Contains(x.Id))
.Select(x => new DiscordUser()
{
UserId = x.Id,
AvatarId = x.AvatarId,
Username = x.Username,
});
var added = (await ctx.BulkCopyAsync(usersToAdd)).RowsCopied;
var toUpdateUserIds = presentDbUsers
.Where(x => x.Username.StartsWith("??"))
.Select(x => x.UserId)
.ToArray();
.Where(x => x.Username.StartsWith("??"))
.Select(x => x.UserId)
.ToArray();
foreach (var user in users.Where(x => toUpdateUserIds.Contains(x.Id)))
{
await ctx.GetTable<DiscordUser>()
.Where(x => x.UserId == user.Id)
.UpdateAsync(x => new DiscordUser()
{
Username = user.Username,
.Where(x => x.UserId == user.Id)
.UpdateAsync(x => new DiscordUser()
{
Username = user.Username,
// .award tends to set AvatarId and DateAdded to NULL, so account for that.
AvatarId = user.AvatarId,
DateAdded = x.DateAdded ?? DateTime.UtcNow
});
// .award tends to set AvatarId and DateAdded to NULL, so account for that.
AvatarId = user.AvatarId,
DateAdded = x.DateAdded ?? DateTime.UtcNow
});
}
return (added, toUpdateUserIds.Length);