forked from EllieBotDevs/elliebot
.setstream and .setactivity will now pause .ropl
This commit is contained in:
parent
a21c7d2ab8
commit
dfd5b7a823
5 changed files with 122 additions and 104 deletions
|
@ -6,7 +6,7 @@ namespace EllieBot.Modules.Administration;
|
||||||
public partial class Administration
|
public partial class Administration
|
||||||
{
|
{
|
||||||
[Group]
|
[Group]
|
||||||
public partial class PlayingRotateCommands : EllieModule<PlayingRotateService>
|
public partial class PlayingRotateCommands : EllieModule<IBotActivityService>
|
||||||
{
|
{
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
|
|
|
@ -5,67 +5,28 @@ using EllieBot.Db.Models;
|
||||||
|
|
||||||
namespace EllieBot.Modules.Administration.Services;
|
namespace EllieBot.Modules.Administration.Services;
|
||||||
|
|
||||||
public sealed class PlayingRotateService : IEService, IReadyExecutor
|
public sealed class BotActivityService : IBotActivityService, IReadyExecutor, IEService
|
||||||
{
|
{
|
||||||
private readonly BotConfigService _bss;
|
private readonly TypedKey<ActivityPubData> _activitySetKey = new("activity.set");
|
||||||
private readonly SelfService _selfService;
|
|
||||||
|
|
||||||
private readonly IReplacementService _repService;
|
private readonly IPubSub _pubSub;
|
||||||
|
|
||||||
// private readonly Replacer _rep;
|
|
||||||
private readonly DbService _db;
|
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
|
private readonly DbService _db;
|
||||||
|
private readonly IReplacementService _rep;
|
||||||
|
private readonly BotConfigService _bss;
|
||||||
|
|
||||||
public PlayingRotateService(
|
public BotActivityService(
|
||||||
|
IPubSub pubSub,
|
||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
DbService db,
|
DbService db,
|
||||||
BotConfigService bss,
|
IReplacementService rep,
|
||||||
IEnumerable<IPlaceholderProvider> phProviders,
|
BotConfigService bss)
|
||||||
SelfService selfService,
|
|
||||||
IReplacementService repService)
|
|
||||||
{
|
{
|
||||||
_db = db;
|
_pubSub = pubSub;
|
||||||
_bss = bss;
|
|
||||||
_selfService = selfService;
|
|
||||||
_repService = repService;
|
|
||||||
_client = client;
|
_client = client;
|
||||||
}
|
_db = db;
|
||||||
|
_rep = rep;
|
||||||
public async Task OnReadyAsync()
|
_bss = bss;
|
||||||
{
|
|
||||||
if (_client.ShardId != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(1));
|
|
||||||
var index = 0;
|
|
||||||
while (await timer.WaitForNextTickAsync())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!_bss.Data.RotateStatuses)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
IReadOnlyList<RotatingPlayingStatus> rotatingStatuses;
|
|
||||||
await using (var uow = _db.GetDbContext())
|
|
||||||
{
|
|
||||||
rotatingStatuses = uow.Set<RotatingPlayingStatus>().AsNoTracking().OrderBy(x => x.Id).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rotatingStatuses.Count == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var playingStatus = index >= rotatingStatuses.Count
|
|
||||||
? rotatingStatuses[index = 0]
|
|
||||||
: rotatingStatuses[index++];
|
|
||||||
|
|
||||||
var statusText = await _repService.ReplaceAsync(playingStatus.Status, new(client: _client));
|
|
||||||
await _selfService.SetActivityAsync(statusText, (ActivityType)playingStatus.Type);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Warning(ex, "Rotating playing status errored: {ErrorMessage}", ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> RemovePlayingAsync(int index)
|
public async Task<string> RemovePlayingAsync(int index)
|
||||||
|
@ -116,4 +77,91 @@ public sealed class PlayingRotateService : IEService, IReadyExecutor
|
||||||
using var uow = _db.GetDbContext();
|
using var uow = _db.GetDbContext();
|
||||||
return uow.Set<RotatingPlayingStatus>().AsNoTracking().ToList();
|
return uow.Set<RotatingPlayingStatus>().AsNoTracking().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task SetActivityAsync(string game, ActivityType? type)
|
||||||
|
=> _pubSub.Pub(_activitySetKey,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Name = game,
|
||||||
|
Link = null,
|
||||||
|
Type = type
|
||||||
|
});
|
||||||
|
|
||||||
|
public Task SetStreamAsync(string name, string link)
|
||||||
|
=> _pubSub.Pub(_activitySetKey,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Link = link,
|
||||||
|
Type = ActivityType.Streaming
|
||||||
|
});
|
||||||
|
|
||||||
|
private sealed class ActivityPubData
|
||||||
|
{
|
||||||
|
public string Name { get; init; }
|
||||||
|
public string Link { get; init; }
|
||||||
|
public ActivityType? Type { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnReadyAsync()
|
||||||
|
{
|
||||||
|
await _pubSub.Sub(_activitySetKey,
|
||||||
|
async data =>
|
||||||
|
{
|
||||||
|
if (_client.ShardId == 0)
|
||||||
|
{
|
||||||
|
DisableRotatePlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (data.Type is { } activityType)
|
||||||
|
{
|
||||||
|
await _client.SetGameAsync(data.Name, data.Link, activityType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _client.SetCustomStatusAsync(data.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Warning(ex, "Error setting activity");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (_client.ShardId != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(1));
|
||||||
|
var index = 0;
|
||||||
|
while (await timer.WaitForNextTickAsync())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!_bss.Data.RotateStatuses)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
IReadOnlyList<RotatingPlayingStatus> rotatingStatuses;
|
||||||
|
await using (var uow = _db.GetDbContext())
|
||||||
|
{
|
||||||
|
rotatingStatuses = uow.Set<RotatingPlayingStatus>().AsNoTracking().OrderBy(x => x.Id).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rotatingStatuses.Count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var playingStatus = index >= rotatingStatuses.Count
|
||||||
|
? rotatingStatuses[index = 0]
|
||||||
|
: rotatingStatuses[index++];
|
||||||
|
|
||||||
|
var statusText = await _rep.ReplaceAsync(playingStatus.Status, new(client: _client));
|
||||||
|
await SetActivityAsync(statusText, (ActivityType)playingStatus.Type);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Warning(ex, "Rotating playing status errored: {ErrorMessage}", ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#nullable disable
|
||||||
|
using EllieBot.Db.Models;
|
||||||
|
|
||||||
|
namespace EllieBot.Modules.Administration.Services;
|
||||||
|
|
||||||
|
public interface IBotActivityService
|
||||||
|
{
|
||||||
|
Task SetActivityAsync(string game, ActivityType? type);
|
||||||
|
Task SetStreamAsync(string name, string link);
|
||||||
|
bool ToggleRotatePlaying();
|
||||||
|
Task AddPlaying(ActivityType statusType, string status);
|
||||||
|
Task<string> RemovePlayingAsync(int index);
|
||||||
|
IReadOnlyList<RotatingPlayingStatus> GetRotatingStatuses();
|
||||||
|
}
|
|
@ -24,19 +24,22 @@ public partial class Administration
|
||||||
private readonly IMarmaladeLoaderService _marmaladeLoader;
|
private readonly IMarmaladeLoaderService _marmaladeLoader;
|
||||||
private readonly ICoordinator _coord;
|
private readonly ICoordinator _coord;
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
|
private readonly IBotActivityService _bas;
|
||||||
|
|
||||||
public SelfCommands(
|
public SelfCommands(
|
||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
DbService db,
|
DbService db,
|
||||||
IBotStrings strings,
|
IBotStrings strings,
|
||||||
ICoordinator coord,
|
ICoordinator coord,
|
||||||
IMarmaladeLoaderService marmaladeLoader)
|
IMarmaladeLoaderService marmaladeLoader,
|
||||||
|
IBotActivityService bas)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
_db = db;
|
_db = db;
|
||||||
_strings = strings;
|
_strings = strings;
|
||||||
_coord = coord;
|
_coord = coord;
|
||||||
_marmaladeLoader = marmaladeLoader;
|
_marmaladeLoader = marmaladeLoader;
|
||||||
|
_bas = bas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -496,7 +499,7 @@ public partial class Administration
|
||||||
// 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.SetActivityAsync(game is null ? game : await repSvc.ReplaceAsync(game, repCtx), type);
|
await _bas.SetActivityAsync(game is null ? game : await repSvc.ReplaceAsync(game, repCtx), type);
|
||||||
|
|
||||||
await Response().Confirm(strs.set_activity).SendAsync();
|
await Response().Confirm(strs.set_activity).SendAsync();
|
||||||
}
|
}
|
||||||
|
@ -518,7 +521,7 @@ public partial class Administration
|
||||||
{
|
{
|
||||||
name ??= "";
|
name ??= "";
|
||||||
|
|
||||||
await _service.SetStreamAsync(name, url);
|
await _bas.SetStreamAsync(name, url);
|
||||||
|
|
||||||
await Response().Confirm(strs.set_stream).SendAsync();
|
await Response().Confirm(strs.set_stream).SendAsync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
private readonly IMessageSenderService _sender;
|
private readonly IMessageSenderService _sender;
|
||||||
|
|
||||||
//keys
|
//keys
|
||||||
private readonly TypedKey<ActivityPubData> _activitySetKey;
|
|
||||||
private readonly TypedKey<string> _guildLeaveKey;
|
private readonly TypedKey<string> _guildLeaveKey;
|
||||||
|
|
||||||
public SelfService(
|
public SelfService(
|
||||||
|
@ -51,11 +50,8 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
_bss = bss;
|
_bss = bss;
|
||||||
_pubSub = pubSub;
|
_pubSub = pubSub;
|
||||||
_sender = sender;
|
_sender = sender;
|
||||||
_activitySetKey = new("activity.set");
|
|
||||||
_guildLeaveKey = new("guild.leave");
|
_guildLeaveKey = new("guild.leave");
|
||||||
|
|
||||||
HandleStatusChanges();
|
|
||||||
|
|
||||||
_pubSub.Sub(_guildLeaveKey,
|
_pubSub.Sub(_guildLeaveKey,
|
||||||
async input =>
|
async input =>
|
||||||
{
|
{
|
||||||
|
@ -394,49 +390,6 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
return channelId is not null;
|
return channelId is not null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleStatusChanges()
|
|
||||||
=> _pubSub.Sub(_activitySetKey,
|
|
||||||
async data =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (data.Type is { } activityType)
|
|
||||||
await _client.SetGameAsync(data.Name, data.Link, activityType);
|
|
||||||
else
|
|
||||||
await _client.SetCustomStatusAsync(data.Name);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Warning(ex, "Error setting activity");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
public Task SetActivityAsync(string game, ActivityType? type)
|
|
||||||
=> _pubSub.Pub(_activitySetKey,
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Name = game,
|
|
||||||
Link = null,
|
|
||||||
Type = type
|
|
||||||
});
|
|
||||||
|
|
||||||
public Task SetStreamAsync(string name, string link)
|
|
||||||
=> _pubSub.Pub(_activitySetKey,
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Name = name,
|
|
||||||
Link = link,
|
|
||||||
Type = ActivityType.Streaming
|
|
||||||
});
|
|
||||||
|
|
||||||
private sealed class ActivityPubData
|
|
||||||
{
|
|
||||||
public string Name { get; init; }
|
|
||||||
public string Link { get; init; }
|
|
||||||
public ActivityType? Type { get; init; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the specified <paramref name="users"/> to the database. If a database user with placeholder name
|
/// Adds the specified <paramref name="users"/> to the database. If a database user with placeholder name
|
||||||
/// and discriminator is present in <paramref name="users"/>, their name and discriminator get updated accordingly.
|
/// and discriminator is present in <paramref name="users"/>, their name and discriminator get updated accordingly.
|
||||||
|
|
Reference in a new issue