Files
nadekobot/src/NadekoBot/Modules/Administration/Services/PlayingRotateService.cs
Kwoth 65b4c1fab7 - Owner only attributes will now use fresh creds every time (no need for restart for owner only commands to start working once creds are changed)
- setgame/setstream use the new pubsub (also setstream will actually apply to all shards now)
- setgame/setstream moved to SelfService
- small cleanup
2021-09-06 21:34:49 +02:00

124 lines
3.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Discord.WebSocket;
using NadekoBot.Common.Replacements;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using Discord;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Common;
using Serilog;
namespace NadekoBot.Modules.Administration.Services
{
public sealed class PlayingRotateService : INService
{
private readonly Timer _t;
private readonly BotConfigService _bss;
private readonly SelfService _selfService;
private readonly Replacer _rep;
private readonly DbService _db;
private readonly Bot _bot;
private class TimerState
{
public int Index { get; set; }
}
public PlayingRotateService(DiscordSocketClient client, DbService db, Bot bot,
BotConfigService bss, IEnumerable<IPlaceholderProvider> phProviders, SelfService selfService)
{
_db = db;
_bot = bot;
_bss = bss;
_selfService = selfService;
if (client.ShardId == 0)
{
_rep = new ReplacementBuilder()
.WithClient(client)
.WithProviders(phProviders)
.Build();
_t = new Timer(RotatingStatuses, new TimerState(), TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
}
}
private async void RotatingStatuses(object objState)
{
try
{
var state = (TimerState) objState;
if (!_bss.Data.RotateStatuses) return;
IReadOnlyList<RotatingPlayingStatus> rotatingStatuses;
using (var uow = _db.GetDbContext())
{
rotatingStatuses = uow.RotatingStatus
.AsNoTracking()
.OrderBy(x => x.Id)
.ToList();
}
if (rotatingStatuses.Count == 0)
return;
var playingStatus = state.Index >= rotatingStatuses.Count
? rotatingStatuses[state.Index = 0]
: rotatingStatuses[state.Index++];
var statusText = _rep.Replace(playingStatus.Status);
await _selfService.SetGameAsync(statusText, playingStatus.Type);
}
catch (Exception ex)
{
Log.Warning(ex, "Rotating playing status errored: {ErrorMessage}", ex.Message);
}
}
public async Task<string> RemovePlayingAsync(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index));
using var uow = _db.GetDbContext();
var toRemove = await uow.RotatingStatus
.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 t, string status)
{
using var uow = _db.GetDbContext();
var toAdd = new RotatingPlayingStatus {Status = status, Type = t};
uow.Add(toAdd);
await uow.SaveChangesAsync();
}
public bool ToggleRotatePlaying()
{
var enabled = false;
_bss.ModifyConfig(bs => { enabled = bs.RotateStatuses = !bs.RotateStatuses; });
return enabled;
}
public IReadOnlyList<RotatingPlayingStatus> GetRotatingStatuses()
{
using var uow = _db.GetDbContext();
return uow.RotatingStatus.AsNoTracking().ToList();
}
}
}