CustomReactions almost done
This commit is contained in:
parent
9e3dc6d5a1
commit
351ebabd64
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Implemented by modules which can execute something and prevent further commands from being executed.
|
||||
/// </summary>
|
||||
public interface IBlockingExecutor
|
||||
{
|
||||
/// <summary>
|
||||
/// Try to execute some logic within some module's service.
|
||||
/// </summary>
|
||||
/// <returns>Whether it should block other command executions after it.</returns>
|
||||
Task<bool> TryExecute(DiscordShardedClient client, IGuild guild, IUserMessage msg);
|
||||
}
|
||||
}
|
@ -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<CustomReaction>()).Where(cr => cr != null).ToArray();
|
||||
customReactions = _crs.GuildReactions.GetOrAdd(Context.Guild.Id, Array.Empty<CustomReaction>()).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")),
|
||||
|
@ -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;
|
||||
|
@ -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>(commandService)
|
||||
.Add<NadekoStrings>(strings)
|
||||
.Add<DiscordShardedClient>(Client)
|
||||
.Add<GreetSettingsService>(greetSettingsService)
|
||||
.Add<BotConfig>(BotConfig)
|
||||
.Add<CurrencyHandler>(currencyHandler)
|
||||
.Add(musicService)
|
||||
.Add<CommandHandler>(commandHandler)
|
||||
.Add<DbHandler>(db)
|
||||
//modules
|
||||
.Add<UtilityService>(utilityService)
|
||||
.Add<SearchesService>(searchesService)
|
||||
.Add<ClashOfClansService>(clashService)
|
||||
.Add<MusicService>(musicService)
|
||||
.Add<GreetSettingsService>(greetSettingsService)
|
||||
.Add<CustomReactionsService>(crService)
|
||||
.Build();
|
||||
|
||||
commandHandler.AddServices(Services);
|
||||
|
@ -29,28 +29,21 @@
|
||||
<ItemGroup>
|
||||
<Compile Remove="data\**\*;credentials.json;credentials_example.json" />
|
||||
<Compile Remove="Modules\Administration\**" />
|
||||
<Compile Remove="Modules\CustomReactions\**" />
|
||||
<Compile Remove="Modules\Games\**" />
|
||||
<Compile Remove="Modules\NSFW\**" />
|
||||
<Compile Remove="Modules\Permissions\**" />
|
||||
<Compile Remove="Modules\Searches\**" />
|
||||
<Compile Remove="Services\CustomReactions\**" />
|
||||
<EmbeddedResource Remove="Modules\Administration\**" />
|
||||
<EmbeddedResource Remove="Modules\CustomReactions\**" />
|
||||
<EmbeddedResource Remove="Modules\Games\**" />
|
||||
<EmbeddedResource Remove="Modules\NSFW\**" />
|
||||
<EmbeddedResource Remove="Modules\Permissions\**" />
|
||||
<EmbeddedResource Remove="Modules\Searches\**" />
|
||||
<EmbeddedResource Remove="Services\CustomReactions\**" />
|
||||
<None Remove="Modules\Administration\**" />
|
||||
<None Remove="Modules\CustomReactions\**" />
|
||||
<None Remove="Modules\Games\**" />
|
||||
<None Remove="Modules\NSFW\**" />
|
||||
<None Remove="Modules\Permissions\**" />
|
||||
<None Remove="Modules\Searches\**" />
|
||||
<None Remove="Services\CustomReactions\**" />
|
||||
<Compile Remove="Modules\Gambling\Commands\Lucky7Commands.cs" />
|
||||
<Compile Remove="Modules\Gambling\Commands\WaifuClaimCommands.cs" />
|
||||
<None Update="libsodium.dll;opus.dll;libsodium.so;libopus.so">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Discord;
|
||||
using Discord.WebSocket;
|
||||
using NadekoBot.DataStructures.ModuleBehaviors;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using System;
|
||||
|
@ -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<ExecuteCommandResult> ExecuteCommandAsync(CommandContext context, int argPos, IServiceProvider serviceProvider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
|
||||
public Task<bool> ExecuteCommandAsync(CommandContext context, int argPos, IServiceProvider serviceProvider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
|
||||
=> ExecuteCommand(context, context.Message.Content.Substring(argPos), serviceProvider, multiMatchHandling);
|
||||
|
||||
|
||||
public async Task<ExecuteCommandResult> ExecuteCommand(CommandContext context, string input, IServiceProvider serviceProvider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
|
||||
public async Task<bool> 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."));
|
||||
}
|
||||
}
|
||||
}
|
@ -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<ulong, CustomReaction[]> GuildReactions { get; } = new ConcurrentDictionary<ulong, CustomReaction[]>();
|
||||
|
||||
public ConcurrentDictionary<string, uint> ReactionStats { get; } = new ConcurrentDictionary<string, uint>();
|
||||
|
||||
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<ulong, CustomReaction[]>(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<bool> 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<string, Func<IUserMessage, string>> placeholders = new Dictionary<string, Func<IUserMessage, string>>()
|
||||
public static Dictionary<string, Func<IUserMessage, DiscordShardedClient, string>> placeholders = new Dictionary<string, Func<IUserMessage, DiscordShardedClient, string>>()
|
||||
{
|
||||
{"%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<IUserMessage> Send(this CustomReaction cr, IUserMessage context)
|
||||
public static async Task<IUserMessage> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.DataStructures
|
||||
namespace NadekoBot.Services.Permissions
|
||||
{
|
||||
public class OldPermissionCache
|
||||
{
|
@ -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<T> : IndexedCollection<T> where T : IIndexed
|
||||
{
|
13
src/NadekoBot/Services/Permissions/PermissionsService.cs
Normal file
13
src/NadekoBot/Services/Permissions/PermissionsService.cs
Normal file
@ -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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -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<object>
|
||||
{
|
||||
T GetService<T>();
|
||||
}
|
||||
@ -49,5 +50,9 @@ namespace NadekoBot.Services
|
||||
_services.TryGetValue(serviceType, out var toReturn);
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => _services.Values.GetEnumerator();
|
||||
|
||||
public IEnumerator<object> GetEnumerator() => _services.Values.GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user