.aar cleanup, will disable itself if not enough permissions or when role gets deleted.

This commit is contained in:
Master Kwoth 2017-10-30 14:38:50 +01:00
parent 2c2b58ff99
commit 0f3004dce7
4 changed files with 109 additions and 50 deletions

View File

@ -31,29 +31,14 @@ namespace NadekoBot.Modules.Administration
if (Context.User.Id != guser.Guild.OwnerId && guser.GetRoles().Max(x => x.Position) <= role.Position) if (Context.User.Id != guser.Guild.OwnerId && guser.GetRoles().Max(x => x.Position) <= role.Position)
return; return;
using (var uow = _db.UnitOfWork)
{
var conf = uow.GuildConfigs.For(Context.Guild.Id, set => set);
if (role == null)
{
conf.AutoAssignRoleId = 0;
_service.AutoAssignedRoles.TryRemove(Context.Guild.Id, out _);
}
else
{
conf.AutoAssignRoleId = role.Id;
_service.AutoAssignedRoles.AddOrUpdate(Context.Guild.Id, role.Id, (key, val) => role.Id);
}
await uow.CompleteAsync().ConfigureAwait(false);
}
if (role == null) if (role == null)
{ {
_service.DisableAar(Context.Guild.Id);
await ReplyConfirmLocalized("aar_disabled").ConfigureAwait(false); await ReplyConfirmLocalized("aar_disabled").ConfigureAwait(false);
return; return;
} }
_service.EnableAar(Context.Guild.Id, role.Id);
await ReplyConfirmLocalized("aar_enabled").ConfigureAwait(false); await ReplyConfirmLocalized("aar_enabled").ConfigureAwait(false);
} }
} }

View File

@ -21,7 +21,9 @@ namespace NadekoBot.Modules.Administration.Services
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
_bot = bot; _bot = bot;
DeleteMessagesOnCommand = new ConcurrentHashSet<ulong>(bot.AllGuildConfigs.Where(g => g.DeleteMessageOnCommand).Select(g => g.GuildId)); DeleteMessagesOnCommand = new ConcurrentHashSet<ulong>(bot.AllGuildConfigs
.Where(g => g.DeleteMessageOnCommand)
.Select(g => g.GuildId));
cmdHandler.CommandExecuted += DelMsgOnCmd_Handler; cmdHandler.CommandExecuted += DelMsgOnCmd_Handler;
} }

View File

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using Discord.WebSocket; using Discord.WebSocket;
using NadekoBot.Core.Services; using NadekoBot.Core.Services;
using NLog; using NLog;
using Discord;
namespace NadekoBot.Modules.Administration.Services namespace NadekoBot.Modules.Administration.Services
{ {
@ -12,39 +13,87 @@ namespace NadekoBot.Modules.Administration.Services
{ {
private readonly Logger _log; private readonly Logger _log;
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly DbService _db;
//guildid/roleid //guildid/roleid
public ConcurrentDictionary<ulong, ulong> AutoAssignedRoles { get; } public ConcurrentDictionary<ulong, ulong> AutoAssignedRoles { get; }
public BlockingCollection<(IGuildUser, ulong)> AutoAssignQueue { get; } = new BlockingCollection<(IGuildUser, ulong)>();
public AutoAssignRoleService(DiscordSocketClient client, NadekoBot bot) public AutoAssignRoleService(DiscordSocketClient client, NadekoBot bot, DbService db)
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
_client = client; _client = client;
_db = db;
AutoAssignedRoles = new ConcurrentDictionary<ulong, ulong>( AutoAssignedRoles = new ConcurrentDictionary<ulong, ulong>(
bot.AllGuildConfigs.Where(x => x.AutoAssignRoleId != 0) bot.AllGuildConfigs
.Where(x => x.AutoAssignRoleId != 0)
.ToDictionary(k => k.GuildId, v => v.AutoAssignRoleId)); .ToDictionary(k => k.GuildId, v => v.AutoAssignRoleId));
_client.UserJoined += (user) => var _queueRunner = Task.Run(async () =>
{ {
var _ = Task.Run(async () => while (true)
{ {
var (user, roleId) = AutoAssignQueue.Take();
try try
{ {
AutoAssignedRoles.TryGetValue(user.Guild.Id, out ulong roleId);
if (roleId == 0)
return;
var role = user.Guild.Roles.FirstOrDefault(r => r.Id == roleId); var role = user.Guild.Roles.FirstOrDefault(r => r.Id == roleId);
if (role != null) if (role != null)
await user.AddRoleAsync(role).ConfigureAwait(false); await user.AddRoleAsync(role).ConfigureAwait(false);
else
{
_log.Info($"Disabled 'Auto assign role' feature on {0} server the role doesn't exist.",
roleId);
DisableAar(user.GuildId);
}
} }
catch (Exception ex) { _log.Warn(ex); } catch (Discord.Net.HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.Forbidden)
}); {
_log.Info($"Disabled 'Auto assign role' feature on {0} server because I don't have role management permissions.",
roleId);
DisableAar(user.GuildId);
}
catch (Exception ex)
{
_log.Warn(ex);
}
}
});
_client.UserJoined += (user) =>
{
if (AutoAssignedRoles.TryGetValue(user.Guild.Id, out ulong roleId)
&& roleId != 0)
{
AutoAssignQueue.Add((user, roleId));
}
return Task.CompletedTask; return Task.CompletedTask;
}; };
} }
public void EnableAar(ulong guildId, ulong roleId)
{
using (var uow = _db.UnitOfWork)
{
var gc = uow.GuildConfigs.For(guildId, set => set);
gc.AutoAssignRoleId = roleId;
uow.Complete();
}
AutoAssignedRoles.AddOrUpdate(guildId,
roleId,
delegate { return roleId; });
}
public void DisableAar(ulong guildId)
{
using (var uow = _db.UnitOfWork)
{
var gc = uow.GuildConfigs.For(guildId, set => set);
gc.AutoAssignRoleId = 0;
uow.Complete();
}
AutoAssignedRoles.TryRemove(guildId, out _);
}
} }
} }

View File

@ -10,7 +10,6 @@ using NadekoBot.Extensions;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading; using System.Threading;
using System.Collections.Immutable; using System.Collections.Immutable;
using NadekoBot.Core.Services.Database.Models;
using System.IO; using System.IO;
using Discord.Net; using Discord.Net;
using NadekoBot.Common; using NadekoBot.Common;
@ -36,6 +35,12 @@ namespace NadekoBot.Core.Services
private readonly IBotCredentials _creds; private readonly IBotCredentials _creds;
private readonly NadekoBot _bot; private readonly NadekoBot _bot;
private INServiceProvider _services; private INServiceProvider _services;
private IEnumerable<IEarlyBlocker> _earlyBlockers;
private IEarlyBlockingExecutor[] _earlyBlockingExecutors;
private IInputTransformer[] _inputTransformers;
private ILateBlocker[] _lateBlockers;
private ILateExecutor[] _lateExecutors;
public string DefaultPrefix { get; private set; } public string DefaultPrefix { get; private set; }
private ConcurrentDictionary<ulong, string> _prefixes { get; } = new ConcurrentDictionary<ulong, string>(); private ConcurrentDictionary<ulong, string> _prefixes { get; } = new ConcurrentDictionary<ulong, string>();
@ -124,6 +129,31 @@ namespace NadekoBot.Core.Services
public void AddServices(INServiceProvider services) public void AddServices(INServiceProvider services)
{ {
_services = services; _services = services;
_earlyBlockers = services
.Select(x => x as IEarlyBlocker)
.Where(x => x != null)
.ToArray();
_earlyBlockingExecutors = services
.Select(x => x as IEarlyBlockingExecutor)
.Where(x => x != null)
.ToArray();
_inputTransformers = services
.Select(x => x as IInputTransformer)
.Where(x => x != null)
.ToArray();
_lateBlockers = services
.Select(x => x as ILateBlocker)
.Where(x => x != null)
.ToArray();
_lateExecutors = services
.Select(x => x as ILateExecutor)
.Where(x => x != null)
.ToArray();
} }
public async Task ExecuteExternal(ulong? guildId, ulong channelId, string commandText) public async Task ExecuteExternal(ulong? guildId, ulong channelId, string commandText)
@ -228,24 +258,22 @@ namespace NadekoBot.Core.Services
//its nice to have early blockers and early blocking executors separate, but //its nice to have early blockers and early blocking executors separate, but
//i could also have one interface with priorities, and just put early blockers on //i could also have one interface with priorities, and just put early blockers on
//highest priority. :thinking: //highest priority. :thinking:
foreach (var svc in _services) foreach (var blocker in _earlyBlockers)
{ {
if (svc is IEarlyBlocker blocker && if (await blocker.TryBlockEarly(guild, usrMsg).ConfigureAwait(false))
await blocker.TryBlockEarly(guild, usrMsg).ConfigureAwait(false))
{ {
_log.Info("Blocked User: [{0}] Message: [{1}] Service: [{2}]", usrMsg.Author, usrMsg.Content, svc.GetType().Name); _log.Info("Blocked User: [{0}] Message: [{1}] Service: [{2}]", usrMsg.Author, usrMsg.Content, blocker.GetType().Name);
return; return;
} }
} }
var exec2 = Environment.TickCount - execTime; var exec2 = Environment.TickCount - execTime;
foreach (var svc in _services) foreach (var exec in _earlyBlockingExecutors)
{ {
if (svc is IEarlyBlockingExecutor exec && if (await exec.TryExecuteEarly(_client, guild, usrMsg).ConfigureAwait(false))
await exec.TryExecuteEarly(_client, guild, usrMsg).ConfigureAwait(false))
{ {
_log.Info("User [{0}] executed [{1}] in [{2}]", usrMsg.Author, usrMsg.Content, svc.GetType().Name); _log.Info("User [{0}] executed [{1}] in [{2}]", usrMsg.Author, usrMsg.Content, exec.GetType().Name);
return; return;
} }
} }
@ -253,11 +281,10 @@ namespace NadekoBot.Core.Services
var exec3 = Environment.TickCount - execTime; var exec3 = Environment.TickCount - execTime;
string messageContent = usrMsg.Content; string messageContent = usrMsg.Content;
foreach (var svc in _services) foreach (var exec in _inputTransformers)
{ {
string newContent; string newContent;
if (svc is IInputTransformer exec && if ((newContent = await exec.TransformInput(guild, usrMsg.Channel, usrMsg.Author, messageContent).ConfigureAwait(false)) != messageContent.ToLowerInvariant())
(newContent = await exec.TransformInput(guild, usrMsg.Channel, usrMsg.Author, messageContent).ConfigureAwait(false)) != messageContent.ToLowerInvariant())
{ {
messageContent = newContent; messageContent = newContent;
break; break;
@ -289,12 +316,9 @@ namespace NadekoBot.Core.Services
await OnMessageNoTrigger(usrMsg).ConfigureAwait(false); await OnMessageNoTrigger(usrMsg).ConfigureAwait(false);
} }
foreach (var svc in _services) foreach (var exec in _lateExecutors)
{ {
if (svc is ILateExecutor exec) await exec.LateExecute(_client, guild, usrMsg).ConfigureAwait(false);
{
await exec.LateExecute(_client, guild, usrMsg).ConfigureAwait(false);
}
} }
} }
@ -393,12 +417,11 @@ namespace NadekoBot.Core.Services
//return SearchResult.FromError(CommandError.Exception, "You are on a global cooldown."); //return SearchResult.FromError(CommandError.Exception, "You are on a global cooldown.");
var commandName = cmd.Aliases.First(); var commandName = cmd.Aliases.First();
foreach (var svc in _services) foreach (var exec in _lateBlockers)
{ {
if (svc is ILateBlocker exec && if (await exec.TryBlockLate(_client, context.Message, context.Guild, context.Channel, context.User, cmd.Module.GetTopLevelModule().Name, commandName).ConfigureAwait(false))
await exec.TryBlockLate(_client, context.Message, context.Guild, context.Channel, context.User, cmd.Module.GetTopLevelModule().Name, commandName).ConfigureAwait(false))
{ {
_log.Info("Late blocking User [{0}] Command: [{1}] in [{2}]", context.User, commandName, svc.GetType().Name); _log.Info("Late blocking User [{0}] Command: [{1}] in [{2}]", context.User, commandName, exec.GetType().Name);
return (false, null, cmd); return (false, null, cmd);
} }
} }