.ve (verbose errors) command added. Server-based toggle.
This commit is contained in:
parent
21a72c182e
commit
2ff55a49fb
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,7 @@
|
||||
#Manually added files
|
||||
|
||||
command_errors*.txt
|
||||
|
||||
src/NadekoBot/Command Errors*.txt
|
||||
|
||||
src/NadekoBot/credentials.json
|
||||
|
1562
src/NadekoBot/Migrations/20170612094138_verbose-errors.Designer.cs
generated
Normal file
1562
src/NadekoBot/Migrations/20170612094138_verbose-errors.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
src/NadekoBot/Migrations/20170612094138_verbose-errors.cs
Normal file
25
src/NadekoBot/Migrations/20170612094138_verbose-errors.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class verboseerrors : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "VerboseErrors",
|
||||
table: "GuildConfigs",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "VerboseErrors",
|
||||
table: "GuildConfigs");
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,9 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NadekoBot.Services.Database;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
@ -582,6 +584,8 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.Property<string>("TimeZoneId");
|
||||
|
||||
b.Property<bool>("VerboseErrors");
|
||||
|
||||
b.Property<bool>("VerbosePermissions");
|
||||
|
||||
b.Property<bool>("VoicePlusTextEnabled");
|
||||
|
@ -11,6 +11,7 @@ using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using NadekoBot.Services.Permissions;
|
||||
using NadekoBot.Services.Help;
|
||||
|
||||
namespace NadekoBot.Modules.Help
|
||||
{
|
||||
@ -22,16 +23,18 @@ namespace NadekoBot.Modules.Help
|
||||
private readonly BotConfig _config;
|
||||
private readonly CommandService _cmds;
|
||||
private readonly GlobalPermissionService _perms;
|
||||
private readonly HelpService _h;
|
||||
|
||||
public string HelpString => String.Format(_config.HelpString, _creds.ClientId, Prefix);
|
||||
public string DMHelpString => _config.DMHelpString;
|
||||
|
||||
public Help(IBotCredentials creds, GlobalPermissionService perms, BotConfig config, CommandService cmds)
|
||||
public Help(IBotCredentials creds, GlobalPermissionService perms, BotConfig config, CommandService cmds, HelpService h)
|
||||
{
|
||||
_creds = creds;
|
||||
_config = config;
|
||||
_cmds = cmds;
|
||||
_perms = perms;
|
||||
_h = h;
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
@ -91,37 +94,16 @@ namespace NadekoBot.Modules.Help
|
||||
return;
|
||||
}
|
||||
|
||||
if (com == null)
|
||||
{
|
||||
await ReplyErrorLocalized("command_not_found").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var str = string.Format("**`{0}`**", Prefix + com.Aliases.First());
|
||||
var alias = com.Aliases.Skip(1).FirstOrDefault();
|
||||
if (alias != null)
|
||||
str += string.Format(" **/ `{0}`**", Prefix + alias);
|
||||
var embed = new EmbedBuilder()
|
||||
.AddField(fb => fb.WithName(str).WithValue($"{com.RealSummary(Prefix)} {GetCommandRequirements(com)}").WithIsInline(true))
|
||||
.AddField(fb => fb.WithName(GetText("usage")).WithValue(com.RealRemarks(Prefix)).WithIsInline(false))
|
||||
.WithColor(NadekoBot.OkColor);
|
||||
//if (com == null)
|
||||
//{
|
||||
// await ReplyErrorLocalized("command_not_found").ConfigureAwait(false);
|
||||
// return;
|
||||
//}
|
||||
|
||||
var embed = _h.GetCommandHelp(com, Context.Guild);
|
||||
await channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private string GetCommandRequirements(CommandInfo cmd) =>
|
||||
string.Join(" ", cmd.Preconditions
|
||||
.Where(ca => ca is OwnerOnlyAttribute || ca is RequireUserPermissionAttribute)
|
||||
.Select(ca =>
|
||||
{
|
||||
if (ca is OwnerOnlyAttribute)
|
||||
return Format.Bold(GetText("bot_owner_only"));
|
||||
var cau = (RequireUserPermissionAttribute)ca;
|
||||
if (cau.GuildPermission != null)
|
||||
return Format.Bold(GetText("server_permission", cau.GuildPermission))
|
||||
.Replace("Guild", "Server");
|
||||
return Format.Bold(GetText("channel_permission", cau.ChannelPermission))
|
||||
.Replace("Guild", "Server");
|
||||
}));
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[OwnerOnly]
|
||||
@ -155,7 +137,7 @@ namespace NadekoBot.Modules.Help
|
||||
lastModule = module.Name;
|
||||
}
|
||||
helpstr.AppendLine($"{string.Join(" ", com.Aliases.Select(a => "`" + a + "`"))} |" +
|
||||
$" {string.Format(com.Summary, Prefix)} {GetCommandRequirements(com)} |" +
|
||||
$" {string.Format(com.Summary, Prefix)} {_h.GetCommandRequirements(com, Context.Guild)} |" +
|
||||
$" {string.Format(com.Remarks, Prefix)}");
|
||||
}
|
||||
File.WriteAllText("../../docs/Commands List.md", helpstr.ToString());
|
||||
|
@ -0,0 +1,34 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Attributes;
|
||||
using NadekoBot.Services.Utility;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Utility
|
||||
{
|
||||
public partial class Utility
|
||||
{
|
||||
[Group]
|
||||
public class VerboseCommandErrors : NadekoSubmodule
|
||||
{
|
||||
private readonly VerboseErrorsService _ves;
|
||||
|
||||
public VerboseCommandErrors(VerboseErrorsService ves)
|
||||
{
|
||||
_ves = ves;
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(Discord.GuildPermission.ManageMessages)]
|
||||
public async Task VerboseError()
|
||||
{
|
||||
var state = _ves.ToggleVerboseErrors(Context.Guild.Id);
|
||||
|
||||
if (state)
|
||||
await ReplyConfirmLocalized("verbose_errors_enabled").ConfigureAwait(false);
|
||||
else
|
||||
await ReplyConfirmLocalized("verbose_errors_disabled").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -111,6 +111,10 @@ namespace NadekoBot
|
||||
{
|
||||
var soundcloudApiService = new SoundCloudApiService(Credentials);
|
||||
|
||||
#region help
|
||||
var helpService = new HelpService(BotConfig, CommandHandler, Strings);
|
||||
#endregion
|
||||
|
||||
//module services
|
||||
//todo 90 - autodiscover, DI, and add instead of manual like this
|
||||
#region utility
|
||||
@ -120,6 +124,7 @@ namespace NadekoBot
|
||||
var converterService = new ConverterService(Db);
|
||||
var commandMapService = new CommandMapService(AllGuildConfigs);
|
||||
var patreonRewardsService = new PatreonRewardsService(Credentials, Db, Currency);
|
||||
var verboseErrorsService = new VerboseErrorsService(AllGuildConfigs, Db, CommandHandler, helpService);
|
||||
#endregion
|
||||
|
||||
#region permissions
|
||||
@ -139,7 +144,6 @@ namespace NadekoBot
|
||||
var clashService = new ClashOfClansService(Client, Db, Localization, Strings);
|
||||
var musicService = new MusicService(GoogleApi, Strings, Localization, Db, soundcloudApiService, Credentials, AllGuildConfigs);
|
||||
var crService = new CustomReactionsService(permissionsService, Db, Client, CommandHandler);
|
||||
var helpService = new HelpService(BotConfig);
|
||||
|
||||
#region Games
|
||||
var gamesService = new GamesService(Client, BotConfig, AllGuildConfigs, Strings, Images, CommandHandler);
|
||||
@ -188,6 +192,7 @@ namespace NadekoBot
|
||||
.Add(remindService)
|
||||
.Add(repeaterService)
|
||||
.Add(converterService)
|
||||
.Add(verboseErrorsService)
|
||||
.Add<SearchesService>(searchesService)
|
||||
.Add(streamNotificationService)
|
||||
.Add(animeSearchService)
|
||||
|
@ -3501,4 +3501,13 @@
|
||||
<data name="defprefix_desc" xml:space="preserve">
|
||||
<value>Sets bot's default prefix for all bot commands. Provide no arguments to see the current default prefix. This will not change this server's current prefix.</value>
|
||||
</data>
|
||||
<data name="verboseerror_cmd" xml:space="preserve">
|
||||
<value>verboseerror ve</value>
|
||||
</data>
|
||||
<data name="verboseerror_usage" xml:space="preserve">
|
||||
<value>`{0}ve`</value>
|
||||
</data>
|
||||
<data name="verboseerror_desc" xml:space="preserve">
|
||||
<value>Toggles whether the bot should print command errors when a command is incorrectly used.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
@ -40,6 +40,7 @@ namespace NadekoBot.Services
|
||||
private ImmutableArray<AsyncLazy<IDMChannel>> ownerChannels { get; set; } = new ImmutableArray<AsyncLazy<IDMChannel>>();
|
||||
|
||||
public event Func<IUserMessage, CommandInfo, Task> CommandExecuted = delegate { return Task.CompletedTask; };
|
||||
public event Func<CommandInfo, ITextChannel, string, Task> CommandErrored = delegate { return Task.CompletedTask; };
|
||||
|
||||
//userid/msg count
|
||||
public ConcurrentDictionary<ulong, uint> UserMessagesSent { get; } = new ConcurrentDictionary<ulong, uint>();
|
||||
@ -276,6 +277,8 @@ namespace NadekoBot.Services
|
||||
//todo 80 should have log levels and it should return some kind of result,
|
||||
// instead of tuple with the type of thing that went wrong, like before
|
||||
LogErroredExecution(result.Error, usrMsg, channel as ITextChannel, exec2, exec3, execTime);
|
||||
if (guild != null)
|
||||
await CommandErrored(result.Info, channel as ITextChannel, result.Error);
|
||||
}
|
||||
|
||||
}
|
||||
@ -306,10 +309,7 @@ namespace NadekoBot.Services
|
||||
var preconditionResult = await commands[i].CheckPreconditionsAsync(context, serviceProvider).ConfigureAwait(false);
|
||||
if (!preconditionResult.IsSuccess)
|
||||
{
|
||||
if (commands.Count == 1)
|
||||
return (false, null, null);
|
||||
else
|
||||
continue;
|
||||
return (false, preconditionResult.ErrorReason, commands[i].Command);
|
||||
}
|
||||
|
||||
var parseResult = await commands[i].ParseAsync(context, searchResult, preconditionResult).ConfigureAwait(false);
|
||||
@ -331,7 +331,7 @@ namespace NadekoBot.Services
|
||||
if (!parseResult.IsSuccess)
|
||||
{
|
||||
if (commands.Count == 1)
|
||||
return (false, null, null);
|
||||
return (false, parseResult.ErrorReason, commands[i].Command);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
@ -342,7 +342,7 @@ 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 (false, null, null);
|
||||
return (false, null, commands[i].Command);
|
||||
//return SearchResult.FromError(CommandError.Exception, "You are on a global cooldown.");
|
||||
|
||||
var commandName = cmd.Aliases.First();
|
||||
@ -352,7 +352,7 @@ namespace NadekoBot.Services
|
||||
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);
|
||||
return (false, null, null);
|
||||
return (false, null, commands[i].Command);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,7 @@ namespace NadekoBot.Services.Database.Models
|
||||
|
||||
public List<ShopEntry> ShopEntries { get; set; }
|
||||
public ulong? GameVoiceChannel { get; set; } = null;
|
||||
public bool VerboseErrors { get; set; } = false;
|
||||
|
||||
//public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>();
|
||||
}
|
||||
|
@ -4,16 +4,24 @@ using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.WebSocket;
|
||||
using System;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Linq;
|
||||
using NadekoBot.Attributes;
|
||||
|
||||
namespace NadekoBot.Services.Help
|
||||
{
|
||||
public class HelpService : ILateExecutor
|
||||
{
|
||||
private readonly BotConfig _bc;
|
||||
private readonly CommandHandler _ch;
|
||||
private readonly NadekoStrings _strings;
|
||||
|
||||
public HelpService(BotConfig bc)
|
||||
public HelpService(BotConfig bc, CommandHandler ch, NadekoStrings strings)
|
||||
{
|
||||
_bc = bc;
|
||||
_ch = ch;
|
||||
_strings = strings;
|
||||
}
|
||||
|
||||
public async Task LateExecute(DiscordShardedClient client, IGuild guild, IUserMessage msg)
|
||||
@ -28,5 +36,37 @@ namespace NadekoBot.Services.Help
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
public EmbedBuilder GetCommandHelp(CommandInfo com, IGuild guild)
|
||||
{
|
||||
var prefix = _ch.GetPrefix(guild);
|
||||
|
||||
var str = string.Format("**`{0}`**", prefix + com.Aliases.First());
|
||||
var alias = com.Aliases.Skip(1).FirstOrDefault();
|
||||
if (alias != null)
|
||||
str += string.Format(" **/ `{0}`**", prefix + alias);
|
||||
return new EmbedBuilder()
|
||||
.AddField(fb => fb.WithName(str).WithValue($"{com.RealSummary(prefix)} {GetCommandRequirements(com, guild)}").WithIsInline(true))
|
||||
.AddField(fb => fb.WithName(GetText("usage", guild)).WithValue(com.RealRemarks(prefix)).WithIsInline(false))
|
||||
.WithColor(NadekoBot.OkColor);
|
||||
}
|
||||
|
||||
public string GetCommandRequirements(CommandInfo cmd, IGuild guild) =>
|
||||
string.Join(" ", cmd.Preconditions
|
||||
.Where(ca => ca is OwnerOnlyAttribute || ca is RequireUserPermissionAttribute)
|
||||
.Select(ca =>
|
||||
{
|
||||
if (ca is OwnerOnlyAttribute)
|
||||
return Format.Bold(GetText("bot_owner_only", guild));
|
||||
var cau = (RequireUserPermissionAttribute)ca;
|
||||
if (cau.GuildPermission != null)
|
||||
return Format.Bold(GetText("server_permission", guild, cau.GuildPermission))
|
||||
.Replace("Guild", "Server");
|
||||
return Format.Bold(GetText("channel_permission", guild, cau.ChannelPermission))
|
||||
.Replace("Guild", "Server");
|
||||
}));
|
||||
|
||||
private string GetText(string text, IGuild guild, params object[] replacements) =>
|
||||
_strings.GetText(text, guild?.Id, "Help".ToLowerInvariant(), replacements);
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ namespace NadekoBot.Services
|
||||
return val;
|
||||
}
|
||||
|
||||
public string GetText(string key, ulong guildId, string lowerModuleTypeName, params object[] replacements) =>
|
||||
public string GetText(string key, ulong? guildId, string lowerModuleTypeName, params object[] replacements) =>
|
||||
GetText(key, _localization.GetCultureInfo(guildId), lowerModuleTypeName, replacements);
|
||||
|
||||
public string GetText(string key, CultureInfo cultureInfo, string lowerModuleTypeName)
|
||||
|
80
src/NadekoBot/Services/Utility/VerboseErrorsService.cs
Normal file
80
src/NadekoBot/Services/Utility/VerboseErrorsService.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Services.Help;
|
||||
using Discord.Commands;
|
||||
using System.Linq;
|
||||
|
||||
namespace NadekoBot.Services.Utility
|
||||
{
|
||||
public class VerboseErrorsService
|
||||
{
|
||||
private readonly ConcurrentHashSet<ulong> guildsEnabled;
|
||||
private readonly DbService _db;
|
||||
private readonly CommandHandler _ch;
|
||||
private readonly HelpService _hs;
|
||||
|
||||
public VerboseErrorsService(IEnumerable<GuildConfig> gcs, DbService db, CommandHandler ch, HelpService hs)
|
||||
{
|
||||
_db = db;
|
||||
_ch = ch;
|
||||
_hs = hs;
|
||||
|
||||
ch.CommandErrored += LogVerboseError;
|
||||
|
||||
guildsEnabled = new ConcurrentHashSet<ulong>(gcs.Where(x => x.VerboseErrors).Select(x => x.GuildId));
|
||||
}
|
||||
|
||||
private async Task LogVerboseError(CommandInfo cmd, ITextChannel channel, string reason)
|
||||
{
|
||||
if (channel == null || !guildsEnabled.Contains(channel.GuildId))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var embed = _hs.GetCommandHelp(cmd, channel.Guild)
|
||||
.WithTitle("Command Error")
|
||||
.WithDescription(reason)
|
||||
.WithErrorColor();
|
||||
|
||||
await channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
public bool ToggleVerboseErrors(ulong guildId)
|
||||
{
|
||||
|
||||
using (var uow = _db.UnitOfWork)
|
||||
{
|
||||
var gc = uow.GuildConfigs.For(guildId, set => set);
|
||||
|
||||
gc.VerboseErrors = !gc.VerboseErrors;
|
||||
|
||||
uow.Complete();
|
||||
|
||||
if (gc.VerboseErrors)
|
||||
guildsEnabled.Add(guildId);
|
||||
else
|
||||
guildsEnabled.TryRemove(guildId);
|
||||
}
|
||||
|
||||
if (guildsEnabled.Add(guildId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
guildsEnabled.TryRemove(guildId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -674,6 +674,8 @@
|
||||
"utility_uptime": "Uptime",
|
||||
"utility_userid": "{0} of the user {1} is {2}",
|
||||
"utility_users": "Users",
|
||||
"utility_verbose_errors_enabled": "Incorrectly used commands will now show errors.",
|
||||
"utility_verbose_errors_disabled": "Incorrectly used commands will no longer show errors.",
|
||||
"utility_voice_channels": "Voice channels",
|
||||
"gambling_animal_race_already_in": "You've already joined this race!",
|
||||
"games_current_poll_results": "Current poll results",
|
||||
|
Loading…
Reference in New Issue
Block a user