.setgame renamed to .setactivity and now supports custom activities (with no playing in front of the text)

This commit is contained in:
Toastie 2024-08-17 22:46:31 +12:00
parent 05c03248c4
commit 2605351f5c
Signed by: toastie_t0ast
GPG key ID: 27F3B6855AFD40A4
6 changed files with 80 additions and 59 deletions

View file

@ -58,7 +58,7 @@ public sealed class PlayingRotateService : IEService, IReadyExecutor
: rotatingStatuses[index++]; : rotatingStatuses[index++];
var statusText = await _repService.ReplaceAsync(playingStatus.Status, new (client: _client)); var statusText = await _repService.ReplaceAsync(playingStatus.Status, new (client: _client));
await _selfService.SetGameAsync(statusText, (ActivityType)playingStatus.Type); await _selfService.SetActivityAsync(statusText, (ActivityType)playingStatus.Type);
} }
catch (Exception ex) catch (Exception ex)
{ {

View file

@ -491,14 +491,25 @@ public partial class Administration
[Cmd] [Cmd]
[OwnerOnly] [OwnerOnly]
public async Task SetGame(ActivityType type, [Leftover] string game = null) public async Task SetActivity(ActivityType? type, [Leftover] string game = null)
{ {
// var rep = new ReplacementBuilder().WithDefault(Context).Build(); // var rep = new ReplacementBuilder().WithDefault(Context).Build();
var repCtx = new ReplacementContext(ctx); var repCtx = new ReplacementContext(ctx);
await _service.SetGameAsync(game is null ? game : await repSvc.ReplaceAsync(game, repCtx), type); await _service.SetActivityAsync(game is null ? game : await repSvc.ReplaceAsync(game, repCtx), type);
await Response().Confirm(strs.set_game).SendAsync(); await Response().Confirm(strs.set_activity).SendAsync();
}
[Cmd]
[OwnerOnly]
public Task SetActivity([Leftover] string game = null)
=> SetActivity(null, game);
public class SetActivityOptions
{
public ActivityType? Type { get; set; }
public string Game { get; set; }
} }
[Cmd] [Cmd]

View file

@ -85,13 +85,14 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
{ {
await using var uow = _db.GetDbContext(); await using var uow = _db.GetDbContext();
autoCommands = uow.Set<AutoCommand>().AsNoTracking() autoCommands = uow.Set<AutoCommand>()
.Where(x => x.Interval >= 5) .AsNoTracking()
.AsEnumerable() .Where(x => x.Interval >= 5)
.GroupBy(x => x.GuildId) .AsEnumerable()
.ToDictionary(x => x.Key, .GroupBy(x => x.GuildId)
y => y.ToDictionary(x => x.Id, TimerFromAutoCommand).ToConcurrent()) .ToDictionary(x => x.Key,
.ToConcurrent(); y => y.ToDictionary(x => x.Id, TimerFromAutoCommand).ToConcurrent())
.ToConcurrent();
var startupCommands = uow.Set<AutoCommand>().AsNoTracking().Where(x => x.Interval == 0); var startupCommands = uow.Set<AutoCommand>().AsNoTracking().Where(x => x.Interval == 0);
foreach (var cmd in startupCommands) foreach (var cmd in startupCommands)
@ -170,18 +171,18 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
private async Task LoadOwnerChannels() private async Task LoadOwnerChannels()
{ {
var channels = await _creds.OwnerIds.Select(id => var channels = await _creds.OwnerIds.Select(id =>
{ {
var user = _client.GetUser(id); var user = _client.GetUser(id);
if (user is null) if (user is null)
return Task.FromResult<IDMChannel>(null); return Task.FromResult<IDMChannel>(null);
return user.CreateDMChannelAsync(); return user.CreateDMChannelAsync();
}) })
.WhenAll(); .WhenAll();
ownerChannels = channels.Where(x => x is not null) ownerChannels = channels.Where(x => x is not null)
.ToDictionary(x => x.Recipient.Id, x => x) .ToDictionary(x => x.Recipient.Id, x => x)
.ToImmutableDictionary(); .ToImmutableDictionary();
if (!ownerChannels.Any()) if (!ownerChannels.Any())
{ {
@ -400,7 +401,10 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
{ {
try try
{ {
await _client.SetGameAsync(data.Name, data.Link, data.Type); if (data.Type is { } activityType)
await _client.SetGameAsync(data.Name, data.Link, activityType);
else
await _client.SetCustomStatusAsync(data.Name);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -408,7 +412,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
} }
}); });
public Task SetGameAsync(string game, ActivityType type) public Task SetActivityAsync(string game, ActivityType? type)
=> _pubSub.Pub(_activitySetKey, => _pubSub.Pub(_activitySetKey,
new() new()
{ {
@ -430,7 +434,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
{ {
public string Name { get; init; } public string Name { get; init; }
public string Link { get; init; } public string Link { get; init; }
public ActivityType Type { get; init; } public ActivityType? Type { get; init; }
} }
@ -445,39 +449,44 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
{ {
await using var ctx = _db.GetDbContext(); await using var ctx = _db.GetDbContext();
var presentDbUsers = await ctx.GetTable<DiscordUser>() var presentDbUsers = await ctx.GetTable<DiscordUser>()
.Select(x => new { x.UserId, x.Username, x.Discriminator }) .Select(x => new
.Where(x => users.Select(y => y.Id).Contains(x.UserId)) {
.ToArrayAsyncEF(); x.UserId,
x.Username,
x.Discriminator
})
.Where(x => users.Select(y => y.Id).Contains(x.UserId))
.ToArrayAsyncEF();
var usersToAdd = users var usersToAdd = users
.Where(x => !presentDbUsers.Select(x => x.UserId).Contains(x.Id)) .Where(x => !presentDbUsers.Select(x => x.UserId).Contains(x.Id))
.Select(x => new DiscordUser() .Select(x => new DiscordUser()
{ {
UserId = x.Id, UserId = x.Id,
AvatarId = x.AvatarId, AvatarId = x.AvatarId,
Username = x.Username, Username = x.Username,
Discriminator = x.Discriminator Discriminator = x.Discriminator
}); });
var added = (await ctx.BulkCopyAsync(usersToAdd)).RowsCopied; var added = (await ctx.BulkCopyAsync(usersToAdd)).RowsCopied;
var toUpdateUserIds = presentDbUsers var toUpdateUserIds = presentDbUsers
.Where(x => x.Username == "Unknown" && x.Discriminator == "????") .Where(x => x.Username == "Unknown" && x.Discriminator == "????")
.Select(x => x.UserId) .Select(x => x.UserId)
.ToArray(); .ToArray();
foreach (var user in users.Where(x => toUpdateUserIds.Contains(x.Id))) foreach (var user in users.Where(x => toUpdateUserIds.Contains(x.Id)))
{ {
await ctx.GetTable<DiscordUser>() await ctx.GetTable<DiscordUser>()
.Where(x => x.UserId == user.Id) .Where(x => x.UserId == user.Id)
.UpdateAsync(x => new DiscordUser() .UpdateAsync(x => new DiscordUser()
{ {
Username = user.Username, Username = user.Username,
Discriminator = user.Discriminator, Discriminator = user.Discriminator,
// .award tends to set AvatarId and DateAdded to NULL, so account for that. // .award tends to set AvatarId and DateAdded to NULL, so account for that.
AvatarId = user.AvatarId, AvatarId = user.AvatarId,
DateAdded = x.DateAdded ?? DateTime.UtcNow DateAdded = x.DateAdded ?? DateTime.UtcNow
}); });
} }
return (added, toUpdateUserIds.Length); return (added, toUpdateUserIds.Length);

View file

@ -208,7 +208,8 @@ setavatar:
- setav - setav
setbanner: setbanner:
- setbanner - setbanner
setgame: setactivity:
- setactivity
- setgame - setgame
send: send:
- send - send

View file

@ -813,12 +813,12 @@ setbanner:
params: params:
- img: - img:
desc: "The URL of the image file to be displayed as the bot's banner." desc: "The URL of the image file to be displayed as the bot's banner."
setgame: setactivity:
desc: Sets the bots game status to either Playing, Listening, or Watching. desc: Sets the bots game status to a Custom, Playing, Listening, or Watching status.
ex: ex:
- Playing with snakes. - Just chilling
- Watching anime. - Playing with canaries.
- Listening music. - Listening music
params: params:
- type: - type:
desc: "The activity type determines whether the bot is engaged in a game, listening to audio, or watching a video." desc: "The activity type determines whether the bot is engaged in a game, listening to audio, or watching a video."

View file

@ -195,7 +195,7 @@
"srvr_banner_too_large": "Specified image is too large! Maximum size is 8MB.", "srvr_banner_too_large": "Specified image is too large! Maximum size is 8MB.",
"srvr_banner_invalid_url": "Specified url is not valid. Make sure you're specifying a direct image url.", "srvr_banner_invalid_url": "Specified url is not valid. Make sure you're specifying a direct image url.",
"set_channel_name": "New channel name set.", "set_channel_name": "New channel name set.",
"set_game": "New game set!", "set_activity": "New activity set!",
"set_stream": "New stream set!", "set_stream": "New stream set!",
"set_topic": "New channel topic set.", "set_topic": "New channel topic set.",
"shard_reconnecting": "Shard {0} reconnecting.", "shard_reconnecting": "Shard {0} reconnecting.",