2016-08-28 12:19:50 +00:00
|
|
|
|
using Discord;
|
|
|
|
|
using Discord.Commands;
|
2017-01-16 13:27:39 +00:00
|
|
|
|
using Discord.Net;
|
2017-01-09 23:52:25 +00:00
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
2016-08-28 20:59:12 +00:00
|
|
|
|
using NadekoBot.Attributes;
|
2016-12-11 16:18:25 +00:00
|
|
|
|
using NadekoBot.Extensions;
|
2016-08-28 20:59:12 +00:00
|
|
|
|
using NadekoBot.Services;
|
2017-01-09 23:52:25 +00:00
|
|
|
|
using NadekoBot.Services.Database;
|
2016-08-28 20:59:12 +00:00
|
|
|
|
using NadekoBot.Services.Database.Models;
|
2016-10-05 05:01:19 +00:00
|
|
|
|
using NLog;
|
2016-08-28 12:19:50 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
2017-01-09 23:52:25 +00:00
|
|
|
|
using System.Collections.Generic;
|
2016-12-29 13:56:15 +00:00
|
|
|
|
using System.Diagnostics;
|
2016-08-28 20:59:12 +00:00
|
|
|
|
using System.Linq;
|
2017-01-09 23:52:25 +00:00
|
|
|
|
using System.Text;
|
2016-08-29 12:34:46 +00:00
|
|
|
|
using System.Threading;
|
2016-08-28 12:19:50 +00:00
|
|
|
|
using System.Threading.Tasks;
|
2016-03-08 21:42:43 +00:00
|
|
|
|
|
2017-01-11 13:08:50 +00:00
|
|
|
|
namespace NadekoBot.Modules.Utility
|
2016-08-28 12:19:50 +00:00
|
|
|
|
{
|
2017-01-11 13:08:50 +00:00
|
|
|
|
public partial class Utility
|
2016-08-28 12:19:50 +00:00
|
|
|
|
{
|
2016-08-28 20:59:12 +00:00
|
|
|
|
[Group]
|
2016-12-17 00:16:14 +00:00
|
|
|
|
public class RepeatCommands : ModuleBase
|
2016-08-28 20:59:12 +00:00
|
|
|
|
{
|
2017-01-09 23:52:25 +00:00
|
|
|
|
//guildid/RepeatRunners
|
|
|
|
|
public static ConcurrentDictionary<ulong, ConcurrentQueue<RepeatRunner>> repeaters { get; }
|
2016-08-29 12:34:46 +00:00
|
|
|
|
|
|
|
|
|
public class RepeatRunner
|
|
|
|
|
{
|
2016-10-05 05:01:19 +00:00
|
|
|
|
private Logger _log { get; }
|
|
|
|
|
|
2016-08-29 12:34:46 +00:00
|
|
|
|
private CancellationTokenSource source { get; set; }
|
|
|
|
|
private CancellationToken token { get; set; }
|
|
|
|
|
public Repeater Repeater { get; }
|
|
|
|
|
public ITextChannel Channel { get; }
|
|
|
|
|
|
2016-08-29 22:00:19 +00:00
|
|
|
|
public RepeatRunner(Repeater repeater, ITextChannel channel = null)
|
2016-08-29 12:34:46 +00:00
|
|
|
|
{
|
2016-10-05 05:01:19 +00:00
|
|
|
|
_log = LogManager.GetCurrentClassLogger();
|
2016-08-29 12:34:46 +00:00
|
|
|
|
this.Repeater = repeater;
|
2017-01-28 23:38:09 +00:00
|
|
|
|
this.Channel = channel ?? NadekoBot.Client.GetGuild(repeater.GuildId)?.GetTextChannel(repeater.ChannelId);
|
2016-08-29 12:34:46 +00:00
|
|
|
|
if (Channel == null)
|
|
|
|
|
return;
|
|
|
|
|
Task.Run(Run);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private async Task Run()
|
|
|
|
|
{
|
|
|
|
|
source = new CancellationTokenSource();
|
|
|
|
|
token = source.Token;
|
2016-10-13 00:31:10 +00:00
|
|
|
|
IUserMessage oldMsg = null;
|
2016-08-29 12:34:46 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
while (!token.IsCancellationRequested)
|
|
|
|
|
{
|
2016-12-24 10:15:22 +00:00
|
|
|
|
var toSend = "🔄 " + Repeater.Message;
|
2016-08-29 12:34:46 +00:00
|
|
|
|
await Task.Delay(Repeater.Interval, token).ConfigureAwait(false);
|
2016-12-24 10:15:22 +00:00
|
|
|
|
|
2017-01-10 12:37:35 +00:00
|
|
|
|
//var lastMsgInChannel = (await Channel.GetMessagesAsync(2)).FirstOrDefault();
|
|
|
|
|
// if (lastMsgInChannel.Id == oldMsg?.Id) //don't send if it's the same message in the channel
|
|
|
|
|
// continue;
|
2016-12-24 10:15:22 +00:00
|
|
|
|
|
2016-10-13 00:31:10 +00:00
|
|
|
|
if (oldMsg != null)
|
|
|
|
|
try { await oldMsg.DeleteAsync(); } catch { }
|
2017-01-16 13:27:39 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
oldMsg = await Channel.SendMessageAsync(toSend).ConfigureAwait(false);
|
|
|
|
|
}
|
2017-01-28 23:38:09 +00:00
|
|
|
|
catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.Forbidden)
|
2017-01-16 13:27:39 +00:00
|
|
|
|
{
|
|
|
|
|
_log.Warn("Missing permissions. Repeater stopped. ChannelId : {0}", Channel?.Id);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-01-28 23:38:09 +00:00
|
|
|
|
catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.NotFound)
|
2017-01-16 13:27:39 +00:00
|
|
|
|
{
|
|
|
|
|
_log.Warn("Channel not found. Repeater stopped. ChannelId : {0}", Channel?.Id);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_log.Warn(ex);
|
|
|
|
|
}
|
2016-08-29 12:34:46 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (OperationCanceledException) { }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Reset()
|
|
|
|
|
{
|
|
|
|
|
source.Cancel();
|
2017-02-14 13:30:21 +00:00
|
|
|
|
var _ = Task.Run(Run);
|
2016-08-29 12:34:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Stop()
|
|
|
|
|
{
|
|
|
|
|
source.Cancel();
|
|
|
|
|
}
|
2017-01-10 12:37:35 +00:00
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
|
|
|
|
return $"{this.Channel.Mention} | {(int)this.Repeater.Interval.TotalHours}:{this.Repeater.Interval:mm} | {this.Repeater.Message.TrimTo(33)}";
|
|
|
|
|
}
|
2016-08-29 12:34:46 +00:00
|
|
|
|
}
|
2016-05-23 20:50:16 +00:00
|
|
|
|
|
2016-12-08 17:35:34 +00:00
|
|
|
|
static RepeatCommands()
|
2016-08-28 12:19:50 +00:00
|
|
|
|
{
|
2016-12-29 13:56:15 +00:00
|
|
|
|
var _log = LogManager.GetCurrentClassLogger();
|
|
|
|
|
var sw = Stopwatch.StartNew();
|
2017-01-10 19:37:41 +00:00
|
|
|
|
|
|
|
|
|
repeaters = new ConcurrentDictionary<ulong, ConcurrentQueue<RepeatRunner>>(NadekoBot.AllGuildConfigs
|
|
|
|
|
.ToDictionary(gc => gc.GuildId,
|
|
|
|
|
gc => new ConcurrentQueue<RepeatRunner>(gc.GuildRepeaters.Select(gr => new RepeatRunner(gr))
|
|
|
|
|
.Where(gr => gr.Channel != null))));
|
2016-12-29 13:56:15 +00:00
|
|
|
|
|
|
|
|
|
sw.Stop();
|
|
|
|
|
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
2016-08-28 12:19:50 +00:00
|
|
|
|
}
|
2016-03-08 21:42:43 +00:00
|
|
|
|
|
2016-10-05 03:09:44 +00:00
|
|
|
|
[NadekoCommand, Usage, Description, Aliases]
|
2016-08-28 20:59:12 +00:00
|
|
|
|
[RequireContext(ContextType.Guild)]
|
2016-12-16 18:43:57 +00:00
|
|
|
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
2017-01-09 23:52:25 +00:00
|
|
|
|
public async Task RepeatInvoke(int index)
|
2016-08-28 12:19:50 +00:00
|
|
|
|
{
|
2017-01-09 23:52:25 +00:00
|
|
|
|
index -= 1;
|
|
|
|
|
ConcurrentQueue<RepeatRunner> rep;
|
2017-01-10 12:37:35 +00:00
|
|
|
|
if (!repeaters.TryGetValue(Context.Guild.Id, out rep))
|
2016-08-28 12:19:50 +00:00
|
|
|
|
{
|
2016-12-16 21:44:26 +00:00
|
|
|
|
await Context.Channel.SendErrorAsync("ℹ️ **No repeating message found on this server.**").ConfigureAwait(false);
|
2016-08-28 20:59:12 +00:00
|
|
|
|
return;
|
2016-08-28 12:19:50 +00:00
|
|
|
|
}
|
2017-01-09 23:52:25 +00:00
|
|
|
|
|
|
|
|
|
var repList = rep.ToList();
|
|
|
|
|
|
|
|
|
|
if (index >= repList.Count)
|
|
|
|
|
{
|
|
|
|
|
await Context.Channel.SendErrorAsync("Index out of range.").ConfigureAwait(false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var repeater = repList[index].Repeater;
|
|
|
|
|
|
2017-02-09 20:11:33 +00:00
|
|
|
|
repList[index].Reset();
|
2017-01-09 23:52:25 +00:00
|
|
|
|
await Context.Channel.SendMessageAsync("🔄 " + repeater.Message).ConfigureAwait(false);
|
2016-08-28 12:19:50 +00:00
|
|
|
|
}
|
2016-05-23 20:50:16 +00:00
|
|
|
|
|
2016-10-05 03:09:44 +00:00
|
|
|
|
[NadekoCommand, Usage, Description, Aliases]
|
2016-08-28 20:59:12 +00:00
|
|
|
|
[RequireContext(ContextType.Guild)]
|
2016-12-16 18:43:57 +00:00
|
|
|
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
2017-01-09 23:52:25 +00:00
|
|
|
|
[Priority(0)]
|
|
|
|
|
public async Task RepeatRemove(int index)
|
2016-08-28 20:59:12 +00:00
|
|
|
|
{
|
2017-01-09 23:52:25 +00:00
|
|
|
|
if (index < 1)
|
|
|
|
|
return;
|
|
|
|
|
index -= 1;
|
|
|
|
|
|
|
|
|
|
ConcurrentQueue<RepeatRunner> rep;
|
|
|
|
|
if (!repeaters.TryGetValue(Context.Guild.Id, out rep))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var repeaterList = rep.ToList();
|
|
|
|
|
|
|
|
|
|
if (index >= repeaterList.Count)
|
2016-08-28 12:19:50 +00:00
|
|
|
|
{
|
2017-01-09 23:52:25 +00:00
|
|
|
|
await Context.Channel.SendErrorAsync("Index out of range.").ConfigureAwait(false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var repeater = repeaterList[index];
|
|
|
|
|
repeater.Stop();
|
|
|
|
|
repeaterList.RemoveAt(index);
|
|
|
|
|
|
|
|
|
|
using (var uow = DbHandler.UnitOfWork())
|
|
|
|
|
{
|
|
|
|
|
var guildConfig = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(gc => gc.GuildRepeaters));
|
|
|
|
|
|
2017-01-10 12:37:35 +00:00
|
|
|
|
guildConfig.GuildRepeaters.RemoveWhere(r => r.Id == repeater.Repeater.Id);
|
2017-01-09 23:52:25 +00:00
|
|
|
|
await uow.CompleteAsync().ConfigureAwait(false);
|
2016-08-28 20:59:12 +00:00
|
|
|
|
}
|
2017-01-09 23:52:25 +00:00
|
|
|
|
|
|
|
|
|
if (repeaters.TryUpdate(Context.Guild.Id, new ConcurrentQueue<RepeatRunner>(repeaterList), rep))
|
2017-01-10 12:37:35 +00:00
|
|
|
|
await Context.Channel.SendConfirmAsync("Message Repeater",$"#{index+1} stopped.\n\n{repeater.ToString()}").ConfigureAwait(false);
|
2016-08-29 22:00:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-05 03:09:44 +00:00
|
|
|
|
[NadekoCommand, Usage, Description, Aliases]
|
2016-08-29 22:00:19 +00:00
|
|
|
|
[RequireContext(ContextType.Guild)]
|
2016-12-16 18:43:57 +00:00
|
|
|
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
2017-01-09 23:52:25 +00:00
|
|
|
|
[Priority(1)]
|
2016-12-21 08:33:47 +00:00
|
|
|
|
public async Task Repeat(int minutes, [Remainder] string message)
|
2016-08-29 22:00:19 +00:00
|
|
|
|
{
|
2016-10-17 10:26:26 +00:00
|
|
|
|
if (minutes < 1 || minutes > 10080)
|
2016-08-29 22:00:19 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(message))
|
|
|
|
|
return;
|
|
|
|
|
|
2017-01-10 12:37:35 +00:00
|
|
|
|
var toAdd = new GuildRepeater()
|
2016-08-28 12:19:50 +00:00
|
|
|
|
{
|
2017-01-09 23:52:25 +00:00
|
|
|
|
ChannelId = Context.Channel.Id,
|
|
|
|
|
GuildId = Context.Guild.Id,
|
|
|
|
|
Interval = TimeSpan.FromMinutes(minutes),
|
|
|
|
|
Message = message
|
|
|
|
|
};
|
|
|
|
|
|
2017-01-10 12:37:35 +00:00
|
|
|
|
using (var uow = DbHandler.UnitOfWork())
|
|
|
|
|
{
|
|
|
|
|
var gc = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.GuildRepeaters));
|
|
|
|
|
|
2017-01-10 22:12:52 +00:00
|
|
|
|
if (gc.GuildRepeaters.Count >= 5)
|
|
|
|
|
return;
|
2017-01-10 12:37:35 +00:00
|
|
|
|
gc.GuildRepeaters.Add(toAdd);
|
|
|
|
|
|
|
|
|
|
await uow.CompleteAsync().ConfigureAwait(false);
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-09 23:52:25 +00:00
|
|
|
|
var rep = new RepeatRunner(toAdd, (ITextChannel)Context.Channel);
|
|
|
|
|
|
|
|
|
|
repeaters.AddOrUpdate(Context.Guild.Id, new ConcurrentQueue<RepeatRunner>(new[] { rep }), (key, old) =>
|
2016-08-28 20:59:12 +00:00
|
|
|
|
{
|
2017-01-09 23:52:25 +00:00
|
|
|
|
old.Enqueue(rep);
|
2016-08-29 12:34:46 +00:00
|
|
|
|
return old;
|
2016-08-28 12:19:50 +00:00
|
|
|
|
});
|
2017-01-10 12:37:35 +00:00
|
|
|
|
|
2016-12-16 21:44:26 +00:00
|
|
|
|
await Context.Channel.SendConfirmAsync($"🔁 Repeating **\"{rep.Repeater.Message}\"** every `{rep.Repeater.Interval.Days} day(s), {rep.Repeater.Interval.Hours} hour(s) and {rep.Repeater.Interval.Minutes} minute(s)`.").ConfigureAwait(false);
|
2016-08-29 22:00:19 +00:00
|
|
|
|
}
|
2017-01-09 23:52:25 +00:00
|
|
|
|
|
|
|
|
|
[NadekoCommand, Usage, Description, Aliases]
|
|
|
|
|
[RequireContext(ContextType.Guild)]
|
|
|
|
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
|
|
|
|
public async Task RepeatList()
|
|
|
|
|
{
|
|
|
|
|
ConcurrentQueue<RepeatRunner> repRunners;
|
|
|
|
|
if (!repeaters.TryGetValue(Context.Guild.Id, out repRunners))
|
|
|
|
|
{
|
|
|
|
|
await Context.Channel.SendConfirmAsync("No repeaters running on this server.").ConfigureAwait(false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var replist = repRunners.ToList();
|
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < replist.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var rep = replist[i];
|
|
|
|
|
|
2017-01-10 12:37:35 +00:00
|
|
|
|
sb.AppendLine($"`{i + 1}.` {rep.ToString()}");
|
2017-01-09 23:52:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
|
|
|
|
|
.WithTitle("List Of Repeaters")
|
|
|
|
|
.WithDescription(sb.ToString()))
|
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
|
}
|
2016-08-28 20:59:12 +00:00
|
|
|
|
}
|
2016-08-28 12:19:50 +00:00
|
|
|
|
}
|
2017-01-10 12:37:35 +00:00
|
|
|
|
}
|