NadekoBot/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs

154 lines
5.4 KiB
C#
Raw Normal View History

2016-08-28 12:19:50 +00:00
using Discord;
using Discord.Commands;
2016-08-29 12:34:46 +00:00
using Discord.WebSocket;
2016-08-28 20:59:12 +00:00
using NadekoBot.Attributes;
using NadekoBot.Services;
using NadekoBot.Services.Database;
using NadekoBot.Services.Database.Models;
2016-08-28 12:19:50 +00:00
using System;
using System.Collections.Concurrent;
2016-08-28 20:59:12 +00:00
using System.Collections.Generic;
using System.Linq;
2016-08-29 12:34:46 +00:00
using System.Threading;
2016-08-28 12:19:50 +00:00
using System.Threading.Tasks;
2016-08-28 12:19:50 +00:00
//todo DB
namespace NadekoBot.Modules.Administration
{
2016-08-28 20:59:12 +00:00
public partial class Administration
2016-08-28 12:19:50 +00:00
{
2016-08-28 20:59:12 +00:00
[Group]
public class RepeatCommands
{
2016-08-29 12:34:46 +00:00
public ConcurrentDictionary<ulong, RepeatRunner> repeaters;
public class RepeatRunner
{
private CancellationTokenSource source { get; set; }
private CancellationToken token { get; set; }
public Repeater Repeater { get; }
public ITextChannel Channel { get; }
public RepeatRunner(Repeater repeater)
{
this.Repeater = repeater;
this.Channel = NadekoBot.Client.GetGuild(repeater.GuildId)?.GetTextChannel(repeater.ChannelId);
if (Channel == null)
return;
Task.Run(Run);
}
private async Task Run()
{
source = new CancellationTokenSource();
token = source.Token;
try
{
while (!token.IsCancellationRequested)
{
await Task.Delay(Repeater.Interval, token).ConfigureAwait(false);
await Channel.SendMessageAsync("🔄 " + Repeater.Message).ConfigureAwait(false);
}
}
catch (OperationCanceledException) { }
}
public void Reset()
{
source.Cancel();
var t = Task.Run(Run);
}
public void Stop()
{
source.Cancel();
}
}
2016-05-23 20:50:16 +00:00
2016-08-28 20:59:12 +00:00
public RepeatCommands()
2016-08-28 12:19:50 +00:00
{
2016-08-28 20:59:12 +00:00
using (var uow = DbHandler.UnitOfWork())
{
2016-08-29 12:34:46 +00:00
repeaters = new ConcurrentDictionary<ulong, RepeatRunner>(uow.Repeaters.GetAll().Select(r => new RepeatRunner(r)).Where(r => r != null).ToDictionary(r => r.Repeater.ChannelId));
2016-08-28 20:59:12 +00:00
}
2016-08-28 12:19:50 +00:00
}
2016-08-28 20:59:12 +00:00
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
[RequirePermission(GuildPermission.ManageMessages)]
2016-08-29 12:34:46 +00:00
public async Task RepeatInvoke(IUserMessage imsg)
2016-08-28 12:19:50 +00:00
{
2016-08-28 20:59:12 +00:00
var channel = (ITextChannel)imsg.Channel;
2016-08-29 12:34:46 +00:00
RepeatRunner rep;
2016-08-28 20:59:12 +00:00
if (!repeaters.TryGetValue(channel.Id, out rep))
2016-08-28 12:19:50 +00:00
{
2016-08-28 20:59:12 +00:00
await channel.SendMessageAsync("`No repeating message found on this server.`").ConfigureAwait(false);
return;
2016-08-28 12:19:50 +00:00
}
2016-08-29 12:34:46 +00:00
rep.Reset();
await channel.SendMessageAsync("🔄 " + rep.Repeater.Message);
2016-08-28 12:19:50 +00:00
}
2016-05-23 20:50:16 +00:00
2016-08-28 20:59:12 +00:00
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
2016-08-29 12:34:46 +00:00
public async Task Repeat(IUserMessage imsg, int minutes, [Remainder] string message = null)
2016-08-28 20:59:12 +00:00
{
var channel = (ITextChannel)imsg.Channel;
if (minutes < 1 || minutes > 1500)
return;
2016-08-29 12:34:46 +00:00
RepeatRunner rep;
2016-08-28 20:59:12 +00:00
if (string.IsNullOrWhiteSpace(message)) //turn off
2016-08-28 12:19:50 +00:00
{
2016-08-28 20:59:12 +00:00
if (repeaters.TryRemove(channel.Id, out rep))
2016-08-28 12:19:50 +00:00
{
2016-08-28 20:59:12 +00:00
using (var uow = DbHandler.UnitOfWork())
{
2016-08-29 12:34:46 +00:00
uow.Repeaters.Remove(rep.Repeater);
2016-08-28 20:59:12 +00:00
await uow.CompleteAsync();
}
2016-08-29 12:34:46 +00:00
rep.Stop();
2016-08-28 20:59:12 +00:00
await channel.SendMessageAsync("`Stopped repeating a message.`").ConfigureAwait(false);
2016-08-28 12:19:50 +00:00
}
2016-08-28 20:59:12 +00:00
else
await channel.SendMessageAsync("`No message is repeating.`").ConfigureAwait(false);
return;
}
2016-05-23 20:50:16 +00:00
2016-08-28 20:59:12 +00:00
rep = repeaters.AddOrUpdate(channel.Id, (cid) =>
2016-08-28 12:19:50 +00:00
{
2016-08-28 20:59:12 +00:00
using (var uow = DbHandler.UnitOfWork())
2016-08-28 12:19:50 +00:00
{
2016-08-28 20:59:12 +00:00
var localRep = new Repeater
{
ChannelId = channel.Id,
GuildId = channel.Guild.Id,
Interval = TimeSpan.FromMinutes(minutes),
Message = message,
};
uow.Repeaters.Add(localRep);
uow.Complete();
2016-08-29 12:34:46 +00:00
return new RepeatRunner(localRep);
2016-08-28 12:19:50 +00:00
}
2016-08-28 20:59:12 +00:00
}, (cid, old) =>
{
using (var uow = DbHandler.UnitOfWork())
2016-08-28 12:19:50 +00:00
{
2016-08-29 12:34:46 +00:00
old.Repeater.Message = message;
old.Repeater.Interval = TimeSpan.FromMinutes(minutes);
uow.Repeaters.Update(old.Repeater);
2016-08-28 20:59:12 +00:00
uow.Complete();
2016-08-28 12:19:50 +00:00
}
2016-08-29 12:34:46 +00:00
old.Reset();
return old;
2016-08-28 12:19:50 +00:00
});
2016-08-28 20:59:12 +00:00
}
2016-08-28 12:19:50 +00:00
2016-08-28 20:59:12 +00:00
}
2016-08-28 12:19:50 +00:00
}
2016-08-28 20:59:12 +00:00
}