NadekoBot/NadekoBot.Core/Services/GreetSettingsService.cs

419 lines
16 KiB
C#
Raw Normal View History

2017-05-27 08:19:27 +00:00
using Discord;
using Discord.WebSocket;
using NadekoBot.Extensions;
2017-05-10 14:08:31 +00:00
using NadekoBot.Services.Database.Models;
2017-05-27 08:19:27 +00:00
using NLog;
2017-05-10 14:08:31 +00:00
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
2017-07-17 19:42:36 +00:00
using NadekoBot.Common;
using NadekoBot.Common.Replacements;
2017-05-10 14:08:31 +00:00
namespace NadekoBot.Services
{
public class GreetSettingsService : INService
2017-05-10 14:08:31 +00:00
{
private readonly DbService _db;
2017-05-10 14:08:31 +00:00
2017-05-22 23:59:31 +00:00
public readonly ConcurrentDictionary<ulong, GreetSettings> GuildConfigsCache;
private readonly DiscordSocketClient _client;
2017-05-27 08:19:27 +00:00
private readonly Logger _log;
2017-05-22 23:59:31 +00:00
public GreetSettingsService(DiscordSocketClient client, NadekoBot bot, DbService db)
2017-05-10 14:08:31 +00:00
{
2017-05-22 23:59:31 +00:00
_db = db;
2017-05-27 08:19:27 +00:00
_client = client;
_log = LogManager.GetCurrentClassLogger();
GuildConfigsCache = new ConcurrentDictionary<ulong, GreetSettings>(
bot.AllGuildConfigs
.ToDictionary(g => g.GuildId, GreetSettings.Create));
2017-05-27 08:19:27 +00:00
_client.UserJoined += UserJoined;
_client.UserLeft += UserLeft;
}
private Task UserLeft(IGuildUser user)
{
var _ = Task.Run(async () =>
{
try
{
var conf = GetOrAddSettingsForGuild(user.GuildId);
if (!conf.SendChannelByeMessage) return;
var channel = (await user.Guild.GetTextChannelsAsync()).SingleOrDefault(c => c.Id == conf.ByeMessageChannelId);
if (channel == null) //maybe warn the server owner that the channel is missing
return;
var rep = new ReplacementBuilder()
.WithDefault(user, channel, user.Guild, _client)
.Build();
if (CREmbed.TryParse(conf.ChannelByeMessageText, out var embedData))
2017-05-27 08:19:27 +00:00
{
rep.Replace(embedData);
2017-05-27 08:19:27 +00:00
try
{
var toDelete = await channel.EmbedAsync(embedData.ToEmbed(), embedData.PlainText?.SanitizeMentions() ?? "").ConfigureAwait(false);
2017-05-27 08:19:27 +00:00
if (conf.AutoDeleteByeMessagesTimer > 0)
{
toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer);
}
}
catch (Exception ex) { _log.Warn(ex); }
}
else
{
var msg = rep.Replace(conf.ChannelByeMessageText);
2017-05-27 08:19:27 +00:00
if (string.IsNullOrWhiteSpace(msg))
return;
try
{
var toDelete = await channel.SendMessageAsync(msg.SanitizeMentions()).ConfigureAwait(false);
if (conf.AutoDeleteByeMessagesTimer > 0)
{
toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer);
}
}
catch (Exception ex) { _log.Warn(ex); }
}
}
catch
{
// ignored
}
});
return Task.CompletedTask;
}
private Task UserJoined(IGuildUser user)
{
var _ = Task.Run(async () =>
{
try
{
var conf = GetOrAddSettingsForGuild(user.GuildId);
if (conf.SendChannelGreetMessage)
{
var channel = (await user.Guild.GetTextChannelsAsync()).SingleOrDefault(c => c.Id == conf.GreetMessageChannelId);
if (channel != null) //maybe warn the server owner that the channel is missing
{
var rep = new ReplacementBuilder()
.WithDefault(user, channel, user.Guild, _client)
.Build();
2017-05-27 08:19:27 +00:00
if (CREmbed.TryParse(conf.ChannelGreetMessageText, out var embedData))
2017-05-27 08:19:27 +00:00
{
rep.Replace(embedData);
2017-05-27 08:19:27 +00:00
try
{
var toDelete = await channel.EmbedAsync(embedData.ToEmbed(), embedData.PlainText?.SanitizeMentions() ?? "").ConfigureAwait(false);
2017-05-27 08:19:27 +00:00
if (conf.AutoDeleteGreetMessagesTimer > 0)
{
toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer);
}
}
catch (Exception ex) { _log.Warn(ex); }
}
else
{
var msg = rep.Replace(conf.ChannelGreetMessageText);
2017-05-27 08:19:27 +00:00
if (!string.IsNullOrWhiteSpace(msg))
{
try
{
var toDelete = await channel.SendMessageAsync(msg.SanitizeMentions()).ConfigureAwait(false);
if (conf.AutoDeleteGreetMessagesTimer > 0)
{
toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer);
}
}
catch (Exception ex) { _log.Warn(ex); }
}
}
}
}
if (conf.SendDmGreetMessage)
{
2017-07-05 15:38:38 +00:00
var channel = await user.GetOrCreateDMChannelAsync();
2017-05-27 08:19:27 +00:00
if (channel != null)
{
var rep = new ReplacementBuilder()
.WithDefault(user, channel, user.Guild, _client)
.Build();
if (CREmbed.TryParse(conf.DmGreetMessageText, out var embedData))
2017-05-27 08:19:27 +00:00
{
rep.Replace(embedData);
2017-05-27 08:19:27 +00:00
try
{
await channel.EmbedAsync(embedData.ToEmbed(), embedData.PlainText?.SanitizeMentions() ?? "").ConfigureAwait(false);
2017-05-27 08:19:27 +00:00
}
2017-07-08 11:27:53 +00:00
catch (Exception ex)
{
_log.Warn(ex);
}
2017-05-27 08:19:27 +00:00
}
else
{
var msg = rep.Replace(conf.DmGreetMessageText);
2017-05-27 08:19:27 +00:00
if (!string.IsNullOrWhiteSpace(msg))
{
await channel.SendConfirmAsync(msg).ConfigureAwait(false);
}
}
}
}
}
catch
{
// ignored
}
});
return Task.CompletedTask;
2017-05-10 14:08:31 +00:00
}
public GreetSettings GetOrAddSettingsForGuild(ulong guildId)
{
if(GuildConfigsCache.TryGetValue(guildId, out var settings) &&
settings != null)
2017-05-10 14:08:31 +00:00
return settings;
2017-05-22 23:59:31 +00:00
using (var uow = _db.UnitOfWork)
2017-05-10 14:08:31 +00:00
{
var gc = uow.GuildConfigs.For(guildId, set => set);
settings = GreetSettings.Create(gc);
}
GuildConfigsCache.TryAdd(guildId, settings);
return settings;
}
public async Task<bool> SetSettings(ulong guildId, GreetSettings settings)
{
if (settings.AutoDeleteByeMessagesTimer > 600 ||
settings.AutoDeleteByeMessagesTimer < 0 ||
settings.AutoDeleteGreetMessagesTimer > 600 ||
settings.AutoDeleteGreetMessagesTimer < 0)
{
return false;
}
2017-05-22 23:59:31 +00:00
using (var uow = _db.UnitOfWork)
{
var conf = uow.GuildConfigs.For(guildId, set => set);
conf.DmGreetMessageText = settings.DmGreetMessageText?.SanitizeMentions();
conf.ChannelGreetMessageText = settings.ChannelGreetMessageText?.SanitizeMentions();
conf.ChannelByeMessageText = settings.ChannelByeMessageText?.SanitizeMentions();
conf.AutoDeleteGreetMessagesTimer = settings.AutoDeleteGreetMessagesTimer;
conf.AutoDeleteGreetMessages = settings.AutoDeleteGreetMessagesTimer > 0;
conf.AutoDeleteByeMessagesTimer = settings.AutoDeleteByeMessagesTimer;
conf.AutoDeleteByeMessages = settings.AutoDeleteByeMessagesTimer > 0;
conf.GreetMessageChannelId = settings.GreetMessageChannelId;
conf.ByeMessageChannelId = settings.ByeMessageChannelId;
conf.SendChannelGreetMessage = settings.SendChannelGreetMessage;
conf.SendChannelByeMessage = settings.SendChannelByeMessage;
await uow.CompleteAsync().ConfigureAwait(false);
2017-05-15 14:05:52 +00:00
var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
}
return true;
}
2017-05-10 14:08:31 +00:00
public async Task<bool> SetGreet(ulong guildId, ulong channelId, bool? value = null)
{
bool enabled;
2017-05-22 23:59:31 +00:00
using (var uow = _db.UnitOfWork)
2017-05-10 14:08:31 +00:00
{
var conf = uow.GuildConfigs.For(guildId, set => set);
enabled = conf.SendChannelGreetMessage = value ?? !conf.SendChannelGreetMessage;
conf.GreetMessageChannelId = channelId;
var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
await uow.CompleteAsync().ConfigureAwait(false);
}
return enabled;
}
public bool SetGreetMessage(ulong guildId, ref string message)
{
message = message?.SanitizeMentions();
if (string.IsNullOrWhiteSpace(message))
throw new ArgumentNullException(nameof(message));
bool greetMsgEnabled;
2017-05-22 23:59:31 +00:00
using (var uow = _db.UnitOfWork)
2017-05-10 14:08:31 +00:00
{
var conf = uow.GuildConfigs.For(guildId, set => set);
conf.ChannelGreetMessageText = message;
greetMsgEnabled = conf.SendChannelGreetMessage;
var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
uow.Complete();
}
return greetMsgEnabled;
}
public async Task<bool> SetGreetDm(ulong guildId, bool? value = null)
{
bool enabled;
2017-05-22 23:59:31 +00:00
using (var uow = _db.UnitOfWork)
2017-05-10 14:08:31 +00:00
{
var conf = uow.GuildConfigs.For(guildId, set => set);
enabled = conf.SendDmGreetMessage = value ?? !conf.SendDmGreetMessage;
var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
await uow.CompleteAsync().ConfigureAwait(false);
}
return enabled;
}
public bool SetGreetDmMessage(ulong guildId, ref string message)
{
message = message?.SanitizeMentions();
if (string.IsNullOrWhiteSpace(message))
throw new ArgumentNullException(nameof(message));
bool greetMsgEnabled;
2017-05-22 23:59:31 +00:00
using (var uow = _db.UnitOfWork)
2017-05-10 14:08:31 +00:00
{
var conf = uow.GuildConfigs.For(guildId);
conf.DmGreetMessageText = message;
greetMsgEnabled = conf.SendDmGreetMessage;
var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
uow.Complete();
}
return greetMsgEnabled;
}
public async Task<bool> SetBye(ulong guildId, ulong channelId, bool? value = null)
{
bool enabled;
2017-05-22 23:59:31 +00:00
using (var uow = _db.UnitOfWork)
2017-05-10 14:08:31 +00:00
{
var conf = uow.GuildConfigs.For(guildId, set => set);
enabled = conf.SendChannelByeMessage = value ?? !conf.SendChannelByeMessage;
conf.ByeMessageChannelId = channelId;
var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
await uow.CompleteAsync();
}
return enabled;
}
public bool SetByeMessage(ulong guildId, ref string message)
{
message = message?.SanitizeMentions();
if (string.IsNullOrWhiteSpace(message))
throw new ArgumentNullException(nameof(message));
bool byeMsgEnabled;
2017-05-22 23:59:31 +00:00
using (var uow = _db.UnitOfWork)
2017-05-10 14:08:31 +00:00
{
var conf = uow.GuildConfigs.For(guildId, set => set);
conf.ChannelByeMessageText = message;
byeMsgEnabled = conf.SendChannelByeMessage;
var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
uow.Complete();
}
return byeMsgEnabled;
}
public async Task SetByeDel(ulong guildId, int timer)
{
if (timer < 0 || timer > 600)
return;
2017-05-22 23:59:31 +00:00
using (var uow = _db.UnitOfWork)
2017-05-10 14:08:31 +00:00
{
var conf = uow.GuildConfigs.For(guildId, set => set);
conf.AutoDeleteByeMessagesTimer = timer;
var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
await uow.CompleteAsync().ConfigureAwait(false);
}
}
2017-05-27 08:19:27 +00:00
public async Task SetGreetDel(ulong id, int timer)
{
if (timer < 0 || timer > 600)
return;
using (var uow = _db.UnitOfWork)
{
var conf = uow.GuildConfigs.For(id, set => set);
conf.AutoDeleteGreetMessagesTimer = timer;
var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(id, toAdd, (key, old) => toAdd);
await uow.CompleteAsync().ConfigureAwait(false);
}
}
2017-05-10 14:08:31 +00:00
}
public class GreetSettings
{
public int AutoDeleteGreetMessagesTimer { get; set; }
public int AutoDeleteByeMessagesTimer { get; set; }
public ulong GreetMessageChannelId { get; set; }
public ulong ByeMessageChannelId { get; set; }
public bool SendDmGreetMessage { get; set; }
public string DmGreetMessageText { get; set; }
public bool SendChannelGreetMessage { get; set; }
public string ChannelGreetMessageText { get; set; }
public bool SendChannelByeMessage { get; set; }
public string ChannelByeMessageText { get; set; }
public static GreetSettings Create(GuildConfig g) => new GreetSettings()
{
AutoDeleteByeMessagesTimer = g.AutoDeleteByeMessagesTimer,
AutoDeleteGreetMessagesTimer = g.AutoDeleteGreetMessagesTimer,
GreetMessageChannelId = g.GreetMessageChannelId,
ByeMessageChannelId = g.ByeMessageChannelId,
SendDmGreetMessage = g.SendDmGreetMessage,
DmGreetMessageText = g.DmGreetMessageText,
SendChannelGreetMessage = g.SendChannelGreetMessage,
ChannelGreetMessageText = g.ChannelGreetMessageText,
SendChannelByeMessage = g.SendChannelByeMessage,
ChannelByeMessageText = g.ChannelByeMessageText,
};
}
}