#nullable disable using Microsoft.EntityFrameworkCore; using NadekoBot.Common.ModuleBehaviors; using NadekoBot.Db.Models; namespace NadekoBot.Modules.Administration.Services; public sealed class PlayingRotateService : INService, IReadyExecutor { private readonly BotConfigService _bss; private readonly SelfService _selfService; private readonly IReplacementService _repService; // private readonly Replacer _rep; private readonly DbService _db; private readonly DiscordSocketClient _client; public PlayingRotateService( DiscordSocketClient client, DbService db, BotConfigService bss, IEnumerable phProviders, SelfService selfService, IReplacementService repService) { _db = db; _bss = bss; _selfService = selfService; _repService = repService; _client = client; } public async Task OnReadyAsync() { 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 rotatingStatuses; await using (var uow = _db.GetDbContext()) { rotatingStatuses = uow.Set().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 RemovePlayingAsync(int index) { ArgumentOutOfRangeException.ThrowIfNegative(index); await using var uow = _db.GetDbContext(); var toRemove = await uow.Set() .AsQueryable() .AsNoTracking() .Skip(index) .FirstOrDefaultAsync(); if (toRemove is null) return null; uow.Remove(toRemove); await uow.SaveChangesAsync(); return toRemove.Status; } public async Task AddPlaying(ActivityType activityType, string status) { await using var uow = _db.GetDbContext(); var toAdd = new RotatingPlayingStatus { Status = status, Type = (NadekoBot.Db.DbActivityType)activityType }; uow.Add(toAdd); await uow.SaveChangesAsync(); } public void DisableRotatePlaying() { _bss.ModifyConfig(bs => { bs.RotateStatuses = false; }); } public bool ToggleRotatePlaying() { var enabled = false; _bss.ModifyConfig(bs => { enabled = bs.RotateStatuses = !bs.RotateStatuses; }); return enabled; } public IReadOnlyList GetRotatingStatuses() { using var uow = _db.GetDbContext(); return uow.Set().AsNoTracking().ToList(); } }