diff --git a/src/NadekoBot/DataStructures/ExecuteCommandResult.cs b/src/NadekoBot/DataStructures/ExecuteCommandResult.cs
deleted file mode 100644
index c7106f19..00000000
--- a/src/NadekoBot/DataStructures/ExecuteCommandResult.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Discord.Commands;
-
-namespace NadekoBot.DataStructures
-{
- public struct ExecuteCommandResult
- {
- public readonly CommandInfo CommandInfo;
- public readonly PermissionCache PermissionCache;
- public readonly IResult Result;
-
- public ExecuteCommandResult(CommandInfo commandInfo, PermissionCache cache, IResult result)
- {
- this.CommandInfo = commandInfo;
- this.PermissionCache = cache;
- this.Result = result;
- }
- }
-}
diff --git a/src/NadekoBot/DataStructures/ModuleBehaviors/IBlockingExecutor.cs b/src/NadekoBot/DataStructures/ModuleBehaviors/IBlockingExecutor.cs
new file mode 100644
index 00000000..3754faa6
--- /dev/null
+++ b/src/NadekoBot/DataStructures/ModuleBehaviors/IBlockingExecutor.cs
@@ -0,0 +1,22 @@
+using Discord;
+using Discord.WebSocket;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NadekoBot.DataStructures.ModuleBehaviors
+{
+ ///
+ /// Implemented by modules which can execute something and prevent further commands from being executed.
+ ///
+ public interface IBlockingExecutor
+ {
+ ///
+ /// Try to execute some logic within some module's service.
+ ///
+ /// Whether it should block other command executions after it.
+ Task TryExecute(DiscordShardedClient client, IGuild guild, IUserMessage msg);
+ }
+}
diff --git a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs
index e9b8827f..2b1d07c3 100644
--- a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs
+++ b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs
@@ -3,26 +3,31 @@ using System.Threading.Tasks;
using Discord.Commands;
using NadekoBot.Services;
using NadekoBot.Attributes;
-using System.Collections.Concurrent;
using NadekoBot.Services.Database.Models;
using Discord;
using NadekoBot.Extensions;
-using NLog;
-using System.Diagnostics;
using Discord.WebSocket;
using System;
-using NadekoBot.DataStructures;
+using NadekoBot.Services.CustomReactions;
namespace NadekoBot.Modules.CustomReactions
{
- public static class CustomReactionExtensions
- {
-
- }
-
- [NadekoModule("CustomReactions", ".")]
public class CustomReactions : NadekoTopLevelModule
{
+ private readonly IBotCredentials _creds;
+ private readonly DbHandler _db;
+ private readonly CustomReactionsService _crs;
+ private readonly DiscordShardedClient _client;
+
+ public CustomReactions(IBotCredentials creds, DbHandler db, CustomReactionsService crs,
+ DiscordShardedClient client)
+ {
+ _creds = creds;
+ _db = db;
+ _crs = crs;
+ _client = client;
+ }
+
[NadekoCommand, Usage, Description, Aliases]
public async Task AddCustReact(string key, [Remainder] string message)
{
@@ -32,7 +37,7 @@ namespace NadekoBot.Modules.CustomReactions
key = key.ToLowerInvariant();
- if ((channel == null && !NadekoBot.Credentials.IsOwner(Context.User)) || (channel != null && !((IGuildUser)Context.User).GuildPermissions.Administrator))
+ if ((channel == null && !_creds.IsOwner(Context.User)) || (channel != null && !((IGuildUser)Context.User).GuildPermissions.Administrator))
{
await ReplyErrorLocalized("insuff_perms").ConfigureAwait(false);
return;
@@ -55,12 +60,12 @@ namespace NadekoBot.Modules.CustomReactions
if (channel == null)
{
- Array.Resize(ref _globalReactions, _globalReactions.Length + 1);
- _globalReactions[_globalReactions.Length - 1] = cr;
+ Array.Resize(ref _crs.GlobalReactions, _crs.GlobalReactions.Length + 1);
+ _crs.GlobalReactions[_crs.GlobalReactions.Length - 1] = cr;
}
else
{
- GuildReactions.AddOrUpdate(Context.Guild.Id,
+ _crs.GuildReactions.AddOrUpdate(Context.Guild.Id,
new CustomReaction[] { cr },
(k, old) =>
{
@@ -86,9 +91,9 @@ namespace NadekoBot.Modules.CustomReactions
return;
CustomReaction[] customReactions;
if (Context.Guild == null)
- customReactions = GlobalReactions.Where(cr => cr != null).ToArray();
+ customReactions = _crs.GlobalReactions.Where(cr => cr != null).ToArray();
else
- customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, Array.Empty()).Where(cr => cr != null).ToArray();
+ customReactions = _crs.GuildReactions.GetOrAdd(Context.Guild.Id, Array.Empty()).Where(cr => cr != null).ToArray();
if (customReactions == null || !customReactions.Any())
{
@@ -97,7 +102,7 @@ namespace NadekoBot.Modules.CustomReactions
}
var lastPage = customReactions.Length / 20;
- await Context.Channel.SendPaginatedConfirmAsync(page, curPage =>
+ await Context.Channel.SendPaginatedConfirmAsync(_client, page, curPage =>
new EmbedBuilder().WithOkColor()
.WithTitle(GetText("name"))
.WithDescription(string.Join("\n", customReactions.OrderBy(cr => cr.Trigger)
@@ -130,9 +135,9 @@ namespace NadekoBot.Modules.CustomReactions
{
CustomReaction[] customReactions;
if (Context.Guild == null)
- customReactions = GlobalReactions.Where(cr => cr != null).ToArray();
+ customReactions = _crs.GlobalReactions.Where(cr => cr != null).ToArray();
else
- customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, new CustomReaction[]{ }).Where(cr => cr != null).ToArray();
+ customReactions = _crs.GuildReactions.GetOrAdd(Context.Guild.Id, new CustomReaction[]{ }).Where(cr => cr != null).ToArray();
if (customReactions == null || !customReactions.Any())
{
@@ -160,9 +165,9 @@ namespace NadekoBot.Modules.CustomReactions
return;
CustomReaction[] customReactions;
if (Context.Guild == null)
- customReactions = GlobalReactions.Where(cr => cr != null).ToArray();
+ customReactions = _crs.GlobalReactions.Where(cr => cr != null).ToArray();
else
- customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, new CustomReaction[]{ }).Where(cr => cr != null).ToArray();
+ customReactions = _crs.GuildReactions.GetOrAdd(Context.Guild.Id, new CustomReaction[]{ }).Where(cr => cr != null).ToArray();
if (customReactions == null || !customReactions.Any())
{
@@ -176,7 +181,7 @@ namespace NadekoBot.Modules.CustomReactions
.ToList();
var lastPage = ordered.Count / 20;
- await Context.Channel.SendPaginatedConfirmAsync(page, (curPage) =>
+ await Context.Channel.SendPaginatedConfirmAsync(_client, page, (curPage) =>
new EmbedBuilder().WithOkColor()
.WithTitle(GetText("name"))
.WithDescription(string.Join("\r\n", ordered
@@ -192,9 +197,9 @@ namespace NadekoBot.Modules.CustomReactions
{
CustomReaction[] customReactions;
if (Context.Guild == null)
- customReactions = GlobalReactions;
+ customReactions = _crs.GlobalReactions;
else
- customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, new CustomReaction[]{ });
+ customReactions = _crs.GuildReactions.GetOrAdd(Context.Guild.Id, new CustomReaction[]{ });
var found = customReactions.FirstOrDefault(cr => cr?.Id == id);
@@ -216,7 +221,7 @@ namespace NadekoBot.Modules.CustomReactions
[NadekoCommand, Usage, Description, Aliases]
public async Task DelCustReact(int id)
{
- if ((Context.Guild == null && !NadekoBot.Credentials.IsOwner(Context.User)) || (Context.Guild != null && !((IGuildUser)Context.User).GuildPermissions.Administrator))
+ if ((Context.Guild == null && !_creds.IsOwner(Context.User)) || (Context.Guild != null && !((IGuildUser)Context.User).GuildPermissions.Administrator))
{
await ReplyErrorLocalized("insuff_perms").ConfigureAwait(false);
return;
@@ -235,13 +240,13 @@ namespace NadekoBot.Modules.CustomReactions
{
uow.CustomReactions.Remove(toDelete);
//todo i can dramatically improve performance of this, if Ids are ordered.
- _globalReactions = GlobalReactions.Where(cr => cr?.Id != toDelete.Id).ToArray();
+ _crs.GlobalReactions = _crs.GlobalReactions.Where(cr => cr?.Id != toDelete.Id).ToArray();
success = true;
}
else if ((toDelete.GuildId != null && toDelete.GuildId != 0) && Context.Guild.Id == toDelete.GuildId)
{
uow.CustomReactions.Remove(toDelete);
- GuildReactions.AddOrUpdate(Context.Guild.Id, new CustomReaction[] { }, (key, old) =>
+ _crs.GuildReactions.AddOrUpdate(Context.Guild.Id, new CustomReaction[] { }, (key, old) =>
{
return old.Where(cr => cr?.Id != toDelete.Id).ToArray();
});
@@ -269,7 +274,7 @@ namespace NadekoBot.Modules.CustomReactions
[NadekoCommand, Usage, Description, Aliases]
public async Task CrDm(int id)
{
- if ((Context.Guild == null && !NadekoBot.Credentials.IsOwner(Context.User)) ||
+ if ((Context.Guild == null && !_creds.IsOwner(Context.User)) ||
(Context.Guild != null && !((IGuildUser)Context.User).GuildPermissions.Administrator))
{
await ReplyErrorLocalized("insuff_perms").ConfigureAwait(false);
@@ -279,10 +284,10 @@ namespace NadekoBot.Modules.CustomReactions
CustomReaction[] reactions = new CustomReaction[0];
if (Context.Guild == null)
- reactions = GlobalReactions;
+ reactions = _crs.GlobalReactions;
else
{
- GuildReactions.TryGetValue(Context.Guild.Id, out reactions);
+ _crs.GuildReactions.TryGetValue(Context.Guild.Id, out reactions);
}
if (reactions.Any())
{
@@ -320,7 +325,7 @@ namespace NadekoBot.Modules.CustomReactions
[NadekoCommand, Usage, Description, Aliases]
public async Task CrAd(int id)
{
- if ((Context.Guild == null && !NadekoBot.Credentials.IsOwner(Context.User)) ||
+ if ((Context.Guild == null && !_creds.IsOwner(Context.User)) ||
(Context.Guild != null && !((IGuildUser)Context.User).GuildPermissions.Administrator))
{
await ReplyErrorLocalized("insuff_perms").ConfigureAwait(false);
@@ -330,10 +335,10 @@ namespace NadekoBot.Modules.CustomReactions
CustomReaction[] reactions = new CustomReaction[0];
if (Context.Guild == null)
- reactions = GlobalReactions;
+ reactions = _crs.GlobalReactions;
else
{
- GuildReactions.TryGetValue(Context.Guild.Id, out reactions);
+ _crs.GuildReactions.TryGetValue(Context.Guild.Id, out reactions);
}
if (reactions.Any())
{
@@ -374,13 +379,13 @@ namespace NadekoBot.Modules.CustomReactions
{
if (string.IsNullOrWhiteSpace(trigger))
{
- ClearStats();
+ _crs.ClearStats();
await ReplyConfirmLocalized("all_stats_cleared").ConfigureAwait(false);
}
else
{
uint throwaway;
- if (ReactionStats.TryRemove(trigger, out throwaway))
+ if (_crs.ReactionStats.TryRemove(trigger, out throwaway))
{
await ReplyErrorLocalized("stats_cleared", Format.Bold(trigger)).ConfigureAwait(false);
}
@@ -396,11 +401,11 @@ namespace NadekoBot.Modules.CustomReactions
{
if (page < 1)
return;
- var ordered = ReactionStats.OrderByDescending(x => x.Value).ToArray();
+ var ordered = _crs.ReactionStats.OrderByDescending(x => x.Value).ToArray();
if (!ordered.Any())
return;
var lastPage = ordered.Length / 9;
- await Context.Channel.SendPaginatedConfirmAsync(page,
+ await Context.Channel.SendPaginatedConfirmAsync(_client, page,
(curPage) => ordered.Skip((curPage - 1) * 9)
.Take(9)
.Aggregate(new EmbedBuilder().WithOkColor().WithTitle(GetText("stats")),
diff --git a/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs
index ee3cd844..75a1425f 100644
--- a/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs
+++ b/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs
@@ -38,14 +38,14 @@ namespace NadekoBot.Modules.Gambling
{
using (var heads = _images.Heads.ToStream())
{
- await Context.Channel.SendFileAsync(heads, "heads.jpg", Context.User.Mention + " " + GetText("flipped", Format.Bold(GetText("heads"))) + ".").ConfigureAwait(false);
+ await Context.Channel.SendFileAsync(heads, "heads.jpg", Context.User.Mention + " " + GetText("flipped", Format.Bold(GetText("heads")))).ConfigureAwait(false);
}
}
else
{
using (var tails = _images.Tails.ToStream())
{
- await Context.Channel.SendFileAsync(tails, "tails.jpg", Context.User.Mention + " " + GetText("flipped", Format.Bold(GetText("tails"))) + ".").ConfigureAwait(false);
+ await Context.Channel.SendFileAsync(tails, "tails.jpg", Context.User.Mention + " " + GetText("flipped", Format.Bold(GetText("tails")))).ConfigureAwait(false);
}
}
return;
diff --git a/src/NadekoBot/NadekoBot.cs b/src/NadekoBot/NadekoBot.cs
index bb105ec1..ebacc438 100644
--- a/src/NadekoBot/NadekoBot.cs
+++ b/src/NadekoBot/NadekoBot.cs
@@ -20,6 +20,7 @@ using NadekoBot.Modules.Utility;
using NadekoBot.Services.Searches;
using NadekoBot.Services.ClashOfClans;
using NadekoBot.Services.Music;
+using NadekoBot.Services.CustomReactions;
namespace NadekoBot
{
@@ -99,6 +100,7 @@ namespace NadekoBot
var searchesService = new SearchesService();
var clashService = new ClashOfClansService(Client, db, localization, strings);
var musicService = new MusicService(google, strings, localization, db, soundcloud, credentials);
+ var crService = new CustomReactionsService(db, Client);
//initialize Services
Services = new NServiceProvider.ServiceProviderBuilder() //todo all Adds should be interfaces
@@ -111,16 +113,17 @@ namespace NadekoBot
.Add(commandService)
.Add(strings)
.Add(Client)
- .Add(greetSettingsService)
.Add(BotConfig)
.Add(currencyHandler)
- .Add(musicService)
.Add(commandHandler)
.Add(db)
//modules
.Add(utilityService)
.Add(searchesService)
.Add(clashService)
+ .Add(musicService)
+ .Add(greetSettingsService)
+ .Add(crService)
.Build();
commandHandler.AddServices(Services);
diff --git a/src/NadekoBot/NadekoBot.csproj b/src/NadekoBot/NadekoBot.csproj
index a2450bcb..51178169 100644
--- a/src/NadekoBot/NadekoBot.csproj
+++ b/src/NadekoBot/NadekoBot.csproj
@@ -29,28 +29,21 @@
-
-
-
-
-
-
-
PreserveNewest
diff --git a/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs b/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs
index fadbf637..13ea5ba2 100644
--- a/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs
+++ b/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs
@@ -1,5 +1,6 @@
using Discord;
using Discord.WebSocket;
+using NadekoBot.DataStructures.ModuleBehaviors;
using NadekoBot.Extensions;
using NadekoBot.Services.Database.Models;
using System;
diff --git a/src/NadekoBot/Services/CommandHandler.cs b/src/NadekoBot/Services/CommandHandler.cs
index 12174924..6c72d118 100644
--- a/src/NadekoBot/Services/CommandHandler.cs
+++ b/src/NadekoBot/Services/CommandHandler.cs
@@ -11,6 +11,7 @@ using System.Collections.Concurrent;
using System.Threading;
using NadekoBot.DataStructures;
using System.Collections.Immutable;
+using NadekoBot.DataStructures.ModuleBehaviors;
namespace NadekoBot.Services
{
@@ -201,7 +202,7 @@ namespace NadekoBot.Services
private const float _oneThousandth = 1.0f / 1000;
- private Task LogSuccessfulExecution(IUserMessage usrMsg, ExecuteCommandResult exec, ITextChannel channel, params int[] execPoints)
+ private Task LogSuccessfulExecution(IUserMessage usrMsg, bool exec, ITextChannel channel, params int[] execPoints)
{
_log.Info("Command Executed after " + string.Join("/", execPoints.Select(x => x * _oneThousandth)) + "s\n\t" +
"User: {0}\n\t" +
@@ -216,7 +217,7 @@ namespace NadekoBot.Services
return Task.CompletedTask;
}
- private void LogErroredExecution(IUserMessage usrMsg, ExecuteCommandResult exec, ITextChannel channel, params int[] execPoints)
+ private void LogErroredExecution(IUserMessage usrMsg, bool exec, ITextChannel channel, params int[] execPoints)
{
_log.Warn("Command Errored after " + string.Join("/", execPoints.Select(x => x * _oneThousandth)) + "s\n\t" +
"User: {0}\n\t" +
@@ -228,7 +229,8 @@ namespace NadekoBot.Services
(channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1}
(channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2}
usrMsg.Content,// {3}
- exec.Result.ErrorReason // {4}
+ exec
+ //exec.Result.ErrorReason // {4}
);
}
////todo invite filtering
@@ -323,6 +325,17 @@ namespace NadekoBot.Services
{
var execTime = Environment.TickCount;
+ foreach (var svc in _services)
+ {
+ if (svc is IBlockingExecutor _executor &&
+ await _executor.TryExecute(_client, guild, usrMsg))
+ {
+ _log.Info("User [{0}] executed [{1}] in [{2}]", usrMsg.Author, usrMsg.Content, svc.GetType().Name);
+ return;
+ }
+ }
+
+
////todo word and invite filtering
//if (guild != null && guild.OwnerId != usrMsg.Author.Id)
//{
@@ -423,22 +436,23 @@ namespace NadekoBot.Services
var exec = await Task.Run(() => ExecuteCommandAsync(new CommandContext(_client, usrMsg), NadekoBot.Prefix.Length, _services, MultiMatchHandling.Best)).ConfigureAwait(false);
execTime = Environment.TickCount - execTime;
- if (exec.Result.IsSuccess)
- {
- await CommandExecuted(usrMsg, exec.CommandInfo).ConfigureAwait(false);
- await LogSuccessfulExecution(usrMsg, exec, channel, exec2, exec3, execTime).ConfigureAwait(false);
- return;
- }
- else if (!exec.Result.IsSuccess && exec.Result.Error != CommandError.UnknownCommand)
- {
- LogErroredExecution(usrMsg, exec, channel, exec2, exec3, execTime);
- if (guild != null && exec.CommandInfo != null && exec.Result.Error == CommandError.Exception)
- {
- if (exec.PermissionCache != null && exec.PermissionCache.Verbose)
- try { await usrMsg.Channel.SendMessageAsync("⚠️ " + exec.Result.ErrorReason).ConfigureAwait(false); } catch { }
- }
- return;
- }
+ ////todo permissions
+ //if (exec.Result.IsSuccess)
+ //{
+ // await CommandExecuted(usrMsg, exec.CommandInfo).ConfigureAwait(false);
+ // await LogSuccessfulExecution(usrMsg, exec, channel, exec2, exec3, execTime).ConfigureAwait(false);
+ // return;
+ //}
+ //else if (!exec.Result.IsSuccess && exec.Result.Error != CommandError.UnknownCommand)
+ //{
+ // LogErroredExecution(usrMsg, exec, channel, exec2, exec3, execTime);
+ // if (guild != null && exec.CommandInfo != null && exec.Result.Error == CommandError.Exception)
+ // {
+ // if (exec.PermissionCache != null && exec.PermissionCache.Verbose)
+ // try { await usrMsg.Channel.SendMessageAsync("⚠️ " + exec.Result.ErrorReason).ConfigureAwait(false); } catch { }
+ // }
+ // return;
+ //}
}
if (usrMsg.Channel is IPrivateChannel)
@@ -455,15 +469,15 @@ namespace NadekoBot.Services
}
}
- public Task ExecuteCommandAsync(CommandContext context, int argPos, IServiceProvider serviceProvider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
+ public Task ExecuteCommandAsync(CommandContext context, int argPos, IServiceProvider serviceProvider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
=> ExecuteCommand(context, context.Message.Content.Substring(argPos), serviceProvider, multiMatchHandling);
- public async Task ExecuteCommand(CommandContext context, string input, IServiceProvider serviceProvider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
+ public async Task ExecuteCommand(CommandContext context, string input, IServiceProvider serviceProvider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
{
var searchResult = _commandService.Search(context, input);
if (!searchResult.IsSuccess)
- return new ExecuteCommandResult(null, null, searchResult);
+ return false;
var commands = searchResult.Commands;
for (int i = commands.Count - 1; i >= 0; i--)
@@ -472,7 +486,7 @@ namespace NadekoBot.Services
if (!preconditionResult.IsSuccess)
{
if (commands.Count == 1)
- return new ExecuteCommandResult(null, null, preconditionResult);
+ return false;
else
continue;
}
@@ -496,7 +510,7 @@ namespace NadekoBot.Services
if (!parseResult.IsSuccess)
{
if (commands.Count == 1)
- return new ExecuteCommandResult(null, null, parseResult);
+ return false;
else
continue;
}
@@ -549,16 +563,19 @@ namespace NadekoBot.Services
// Bot will ignore commands which are ran more often than what specified by
// GlobalCommandsCooldown constant (miliseconds)
if (!UsersOnShortCooldown.Add(context.Message.Author.Id))
- return new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, "You are on a global cooldown."));
+ return false;
+ //return SearchResult.FromError(CommandError.Exception, "You are on a global cooldown.");
////todo cmdcds
//if (CmdCdsCommands.HasCooldown(cmd, context.Guild, context.User))
// return new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, "That command is on a cooldown for you."));
-
- return new ExecuteCommandResult(cmd, null, await commands[i].ExecuteAsync(context, parseResult, serviceProvider));
+
+ await commands[i].ExecuteAsync(context, parseResult, serviceProvider);
+ return true;
}
- return new ExecuteCommandResult(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload."));
+ return false;
+ //return new ExecuteCommandResult(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload."));
}
}
}
\ No newline at end of file
diff --git a/src/NadekoBot/Services/CustomReactions/CustomReactions.cs b/src/NadekoBot/Services/CustomReactions/CustomReactionsService.cs
similarity index 53%
rename from src/NadekoBot/Services/CustomReactions/CustomReactions.cs
rename to src/NadekoBot/Services/CustomReactions/CustomReactionsService.cs
index d2a3e08e..6f5a8228 100644
--- a/src/NadekoBot/Services/CustomReactions/CustomReactions.cs
+++ b/src/NadekoBot/Services/CustomReactions/CustomReactionsService.cs
@@ -1,34 +1,39 @@
using Discord;
using Discord.WebSocket;
+using NadekoBot.DataStructures.ModuleBehaviors;
using NadekoBot.Services.Database.Models;
using NLog;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq;
+using System;
+using System.Threading.Tasks;
-namespace NadekoBot.Services
+namespace NadekoBot.Services.CustomReactions
{
- public class CustomReactions
+ public class CustomReactionsService : IBlockingExecutor
{
- private CustomReaction[] _globalReactions = new CustomReaction[] { };
- public CustomReaction[] GlobalReactions => _globalReactions;
+ public CustomReaction[] GlobalReactions = new CustomReaction[] { };
public ConcurrentDictionary GuildReactions { get; } = new ConcurrentDictionary();
public ConcurrentDictionary ReactionStats { get; } = new ConcurrentDictionary();
private readonly Logger _log;
private readonly DbHandler _db;
+ private readonly DiscordShardedClient _client;
- public CustomReactions(DbHandler db)
+ public CustomReactionsService(DbHandler db, DiscordShardedClient client)
{
_log = LogManager.GetCurrentClassLogger();
_db = db;
+ _client = client;
+
var sw = Stopwatch.StartNew();
using (var uow = _db.UnitOfWork)
{
var items = uow.CustomReactions.GetAll();
GuildReactions = new ConcurrentDictionary(items.Where(g => g.GuildId != null && g.GuildId != 0).GroupBy(k => k.GuildId.Value).ToDictionary(g => g.Key, g => g.ToArray()));
- _globalReactions = items.Where(g => g.GuildId == null || g.GuildId == 0).ToArray();
+ GlobalReactions = items.Where(g => g.GuildId == null || g.GuildId == 0).ToArray();
}
sw.Stop();
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
@@ -54,7 +59,7 @@ namespace NadekoBot.Services
return false;
var hasTarget = cr.Response.ToLowerInvariant().Contains("%target%");
- var trigger = cr.TriggerWithContext(umsg).Trim().ToLowerInvariant();
+ var trigger = cr.TriggerWithContext(umsg, _client).Trim().ToLowerInvariant();
return ((hasTarget && content.StartsWith(trigger + " ")) || content == trigger);
}).ToArray();
@@ -75,7 +80,7 @@ namespace NadekoBot.Services
if (cr == null)
return false;
var hasTarget = cr.Response.ToLowerInvariant().Contains("%target%");
- var trigger = cr.TriggerWithContext(umsg).Trim().ToLowerInvariant();
+ var trigger = cr.TriggerWithContext(umsg, _client).Trim().ToLowerInvariant();
return ((hasTarget && content.StartsWith(trigger + " ")) || content == trigger);
}).ToArray();
if (grs.Length == 0)
@@ -84,5 +89,46 @@ namespace NadekoBot.Services
return greaction;
}
+
+ public async Task TryExecute(DiscordShardedClient client, IGuild guild, IUserMessage msg)
+ {
+ //todo custom reactions
+ // maybe this message is a custom reaction
+ // todo log custom reaction executions. return struct with info
+ var cr = await Task.Run(() => TryGetCustomReaction(msg)).ConfigureAwait(false);
+ if (cr != null) //if it was, don't execute the command
+ {
+ try
+ {
+ //if (guild != null)
+ //{
+ // PermissionCache pc = Permissions.GetCache(guild.Id);
+
+ // if (!pc.Permissions.CheckPermissions(usrMsg, cr.Trigger, "ActualCustomReactions",
+ // out int index))
+ // {
+ // //todo print in guild actually
+ // var returnMsg =
+ // $"Permission number #{index + 1} **{pc.Permissions[index].GetCommand(guild)}** is preventing this action.";
+ // _log.Info(returnMsg);
+ // return;
+ // }
+ //}
+ await cr.Send(msg, _client, this).ConfigureAwait(false);
+
+ if (cr.AutoDeleteTrigger)
+ {
+ try { await msg.DeleteAsync().ConfigureAwait(false); } catch { }
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ _log.Warn("Sending CREmbed failed");
+ _log.Warn(ex);
+ }
+ }
+ return false;
+ }
}
}
diff --git a/src/NadekoBot/Services/CustomReactions/Extensions.cs b/src/NadekoBot/Services/CustomReactions/Extensions.cs
index fdcd9f54..b6a7b12f 100644
--- a/src/NadekoBot/Services/CustomReactions/Extensions.cs
+++ b/src/NadekoBot/Services/CustomReactions/Extensions.cs
@@ -1,4 +1,5 @@
using Discord;
+using Discord.WebSocket;
using NadekoBot.DataStructures;
using NadekoBot.Extensions;
using NadekoBot.Services;
@@ -8,7 +9,7 @@ using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
-namespace NadekoBot.Modules.CustomReactions
+namespace NadekoBot.Services.CustomReactions
{
public static class Extensions
{
@@ -17,11 +18,11 @@ namespace NadekoBot.Modules.CustomReactions
{"%target%", (ctx, trigger) => { return ctx.Content.Substring(trigger.Length).Trim().SanitizeMentions(); } }
};
- public static Dictionary> placeholders = new Dictionary>()
+ public static Dictionary> placeholders = new Dictionary>()
{
- {"%mention%", (ctx) => { return $"<@{NadekoBot.Client.CurrentUser.Id}>"; } },
- {"%user%", (ctx) => { return ctx.Author.Mention; } },
- {"%rnduser%", (ctx) => {
+ {"%mention%", (ctx, client) => { return $"<@{client.CurrentUser.Id}>"; } },
+ {"%user%", (ctx, client) => { return ctx.Author.Mention; } },
+ {"%rnduser%", (ctx, client) => {
//var ch = ctx.Channel as ITextChannel;
//if(ch == null)
// return "";
@@ -69,20 +70,20 @@ namespace NadekoBot.Modules.CustomReactions
} }
};
- private static string ResolveTriggerString(this string str, IUserMessage ctx)
+ private static string ResolveTriggerString(this string str, IUserMessage ctx, DiscordShardedClient client)
{
foreach (var ph in placeholders)
{
- str = str.ToLowerInvariant().Replace(ph.Key, ph.Value(ctx));
+ str = str.ToLowerInvariant().Replace(ph.Key, ph.Value(ctx, client));
}
return str;
}
- private static string ResolveResponseString(this string str, IUserMessage ctx, string resolvedTrigger)
+ private static string ResolveResponseString(this string str, IUserMessage ctx, DiscordShardedClient client, string resolvedTrigger)
{
foreach (var ph in placeholders)
{
- str = str.Replace(ph.Key.ToLowerInvariant(), ph.Value(ctx));
+ str = str.Replace(ph.Key.ToLowerInvariant(), ph.Value(ctx, client));
}
foreach (var ph in responsePlaceholders)
@@ -97,24 +98,23 @@ namespace NadekoBot.Modules.CustomReactions
return str;
}
- public static string TriggerWithContext(this CustomReaction cr, IUserMessage ctx)
- => cr.Trigger.ResolveTriggerString(ctx);
+ public static string TriggerWithContext(this CustomReaction cr, IUserMessage ctx, DiscordShardedClient client)
+ => cr.Trigger.ResolveTriggerString(ctx, client);
- public static string ResponseWithContext(this CustomReaction cr, IUserMessage ctx)
- => cr.Response.ResolveResponseString(ctx, cr.Trigger.ResolveTriggerString(ctx));
+ public static string ResponseWithContext(this CustomReaction cr, IUserMessage ctx, DiscordShardedClient client)
+ => cr.Response.ResolveResponseString(ctx, client, cr.Trigger.ResolveTriggerString(ctx, client));
- public static async Task Send(this CustomReaction cr, IUserMessage context)
+ public static async Task Send(this CustomReaction cr, IUserMessage context, DiscordShardedClient client, CustomReactionsService crs)
{
var channel = cr.DmResponse ? await context.Author.CreateDMChannelAsync() : context.Channel;
- CustomReactions.ReactionStats.AddOrUpdate(cr.Trigger, 1, (k, old) => ++old);
+ crs.ReactionStats.AddOrUpdate(cr.Trigger, 1, (k, old) => ++old);
- CREmbed crembed;
- if (CREmbed.TryParse(cr.Response, out crembed))
+ if (CREmbed.TryParse(cr.Response, out CREmbed crembed))
{
return await channel.EmbedAsync(crembed.ToEmbed(), crembed.PlainText ?? "");
}
- return await channel.SendMessageAsync(cr.ResponseWithContext(context).SanitizeMentions());
+ return await channel.SendMessageAsync(cr.ResponseWithContext(context, client).SanitizeMentions());
}
}
}
diff --git a/src/NadekoBot/DataStructures/PermissionCache.cs b/src/NadekoBot/Services/Permissions/PermissionCache.cs
similarity index 93%
rename from src/NadekoBot/DataStructures/PermissionCache.cs
rename to src/NadekoBot/Services/Permissions/PermissionCache.cs
index 9d2288bf..9ed7ec8c 100644
--- a/src/NadekoBot/DataStructures/PermissionCache.cs
+++ b/src/NadekoBot/Services/Permissions/PermissionCache.cs
@@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace NadekoBot.DataStructures
+namespace NadekoBot.Services.Permissions
{
public class OldPermissionCache
{
diff --git a/src/NadekoBot/DataStructures/PermissionsCollection.cs b/src/NadekoBot/Services/Permissions/PermissionsCollection.cs
similarity index 96%
rename from src/NadekoBot/DataStructures/PermissionsCollection.cs
rename to src/NadekoBot/Services/Permissions/PermissionsCollection.cs
index 484c4f9d..5709c910 100644
--- a/src/NadekoBot/DataStructures/PermissionsCollection.cs
+++ b/src/NadekoBot/Services/Permissions/PermissionsCollection.cs
@@ -3,8 +3,9 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NadekoBot.Services.Database.Models;
+using NadekoBot.DataStructures;
-namespace NadekoBot.DataStructures
+namespace NadekoBot.Services.Permissions
{
public class PermissionsCollection : IndexedCollection where T : IIndexed
{
diff --git a/src/NadekoBot/Services/Permissions/PermissionsService.cs b/src/NadekoBot/Services/Permissions/PermissionsService.cs
new file mode 100644
index 00000000..b10d8b21
--- /dev/null
+++ b/src/NadekoBot/Services/Permissions/PermissionsService.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NadekoBot.Services.Permissions
+{
+ public class PermissionsService
+ {
+
+ }
+}
diff --git a/src/NadekoBot/Services/ServiceProvider.cs b/src/NadekoBot/Services/ServiceProvider.cs
index b90be9aa..8b28af4d 100644
--- a/src/NadekoBot/Services/ServiceProvider.cs
+++ b/src/NadekoBot/Services/ServiceProvider.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
@@ -8,7 +9,7 @@ using System.Threading.Tasks;
namespace NadekoBot.Services
{
- public interface INServiceProvider : IServiceProvider
+ public interface INServiceProvider : IServiceProvider, IEnumerable