mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 09:48:26 -04:00
Global usings and file scoped namespaces
This commit is contained in:
@@ -1,23 +1,22 @@
|
||||
using CommandLine;
|
||||
using NadekoBot.Common;
|
||||
|
||||
namespace NadekoBot.Modules.Help.Common
|
||||
namespace NadekoBot.Modules.Help.Common;
|
||||
|
||||
public class CommandsOptions : INadekoCommandOptions
|
||||
{
|
||||
public class CommandsOptions : INadekoCommandOptions
|
||||
public enum ViewType
|
||||
{
|
||||
public enum ViewType
|
||||
{
|
||||
Hide,
|
||||
Cross,
|
||||
All,
|
||||
}
|
||||
|
||||
[Option('v', "view", Required = false, Default = ViewType.Hide, HelpText = "Specifies how to output the list of commands. 0 - Hide commands which you can't use, 1 - Cross out commands which you can't use, 2 - Show all.")]
|
||||
public ViewType View { get; set; } = ViewType.Hide;
|
||||
|
||||
public void NormalizeOptions()
|
||||
{
|
||||
|
||||
}
|
||||
Hide,
|
||||
Cross,
|
||||
All,
|
||||
}
|
||||
}
|
||||
|
||||
[Option('v', "view", Required = false, Default = ViewType.Hide, HelpText = "Specifies how to output the list of commands. 0 - Hide commands which you can't use, 1 - Cross out commands which you can't use, 2 - Show all.")]
|
||||
public ViewType View { get; set; } = ViewType.Hide;
|
||||
|
||||
public void NormalizeOptions()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -9,451 +9,446 @@ using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Help.Services;
|
||||
using NadekoBot.Modules.Permissions.Services;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Amazon.S3;
|
||||
using Amazon.S3.Model;
|
||||
using Discord.WebSocket;
|
||||
using Serilog;
|
||||
|
||||
namespace NadekoBot.Modules.Help
|
||||
namespace NadekoBot.Modules.Help;
|
||||
|
||||
public class Help : NadekoModule<HelpService>
|
||||
{
|
||||
public class Help : NadekoModule<HelpService>
|
||||
public const string PatreonUrl = "https://patreon.com/nadekobot";
|
||||
public const string PaypalUrl = "https://paypal.me/Kwoth";
|
||||
private readonly CommandService _cmds;
|
||||
private readonly BotConfigService _bss;
|
||||
private readonly GlobalPermissionService _perms;
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IBotStrings _strings;
|
||||
|
||||
private readonly AsyncLazy<ulong> _lazyClientId;
|
||||
|
||||
public Help(GlobalPermissionService perms, CommandService cmds, BotConfigService bss,
|
||||
IServiceProvider services, DiscordSocketClient client, IBotStrings strings)
|
||||
{
|
||||
public const string PatreonUrl = "https://patreon.com/nadekobot";
|
||||
public const string PaypalUrl = "https://paypal.me/Kwoth";
|
||||
private readonly CommandService _cmds;
|
||||
private readonly BotConfigService _bss;
|
||||
private readonly GlobalPermissionService _perms;
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IBotStrings _strings;
|
||||
_cmds = cmds;
|
||||
_bss = bss;
|
||||
_perms = perms;
|
||||
_services = services;
|
||||
_client = client;
|
||||
_strings = strings;
|
||||
|
||||
private readonly AsyncLazy<ulong> _lazyClientId;
|
||||
_lazyClientId = new AsyncLazy<ulong>(async () => (await _client.GetApplicationInfoAsync()).Id);
|
||||
}
|
||||
|
||||
public Help(GlobalPermissionService perms, CommandService cmds, BotConfigService bss,
|
||||
IServiceProvider services, DiscordSocketClient client, IBotStrings strings)
|
||||
{
|
||||
_cmds = cmds;
|
||||
_bss = bss;
|
||||
_perms = perms;
|
||||
_services = services;
|
||||
_client = client;
|
||||
_strings = strings;
|
||||
|
||||
_lazyClientId = new AsyncLazy<ulong>(async () => (await _client.GetApplicationInfoAsync()).Id);
|
||||
}
|
||||
|
||||
public async Task<SmartText> GetHelpString()
|
||||
{
|
||||
var botSettings = _bss.Data;
|
||||
if (string.IsNullOrWhiteSpace(botSettings.HelpText) || botSettings.HelpText == "-")
|
||||
return default;
|
||||
public async Task<SmartText> GetHelpString()
|
||||
{
|
||||
var botSettings = _bss.Data;
|
||||
if (string.IsNullOrWhiteSpace(botSettings.HelpText) || botSettings.HelpText == "-")
|
||||
return default;
|
||||
|
||||
var clientId = await _lazyClientId.Value;
|
||||
var r = new ReplacementBuilder()
|
||||
.WithDefault(Context)
|
||||
.WithOverride("{0}", () => clientId.ToString())
|
||||
.WithOverride("{1}", () => Prefix)
|
||||
.WithOverride("%prefix%", () => Prefix)
|
||||
.WithOverride("%bot.prefix%", () => Prefix)
|
||||
.Build();
|
||||
var clientId = await _lazyClientId.Value;
|
||||
var r = new ReplacementBuilder()
|
||||
.WithDefault(Context)
|
||||
.WithOverride("{0}", () => clientId.ToString())
|
||||
.WithOverride("{1}", () => Prefix)
|
||||
.WithOverride("%prefix%", () => Prefix)
|
||||
.WithOverride("%bot.prefix%", () => Prefix)
|
||||
.Build();
|
||||
|
||||
var text = SmartText.CreateFrom(botSettings.HelpText);
|
||||
return r.Replace(text);
|
||||
}
|
||||
var text = SmartText.CreateFrom(botSettings.HelpText);
|
||||
return r.Replace(text);
|
||||
}
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
public async Task Modules(int page = 1)
|
||||
[NadekoCommand, Aliases]
|
||||
public async Task Modules(int page = 1)
|
||||
{
|
||||
if (--page < 0)
|
||||
return;
|
||||
|
||||
var topLevelModules = _cmds.Modules.GroupBy(m => m.GetTopLevelModule())
|
||||
.Where(m => !_perms.BlockedModules.Contains(m.Key.Name.ToLowerInvariant()))
|
||||
.Select(x => x.Key)
|
||||
.ToList();
|
||||
|
||||
await ctx.SendPaginatedConfirmAsync(page, cur =>
|
||||
{
|
||||
if (--page < 0)
|
||||
return;
|
||||
var embed = _eb.Create().WithOkColor()
|
||||
.WithTitle(GetText(strs.list_of_modules));
|
||||
|
||||
var topLevelModules = _cmds.Modules.GroupBy(m => m.GetTopLevelModule())
|
||||
.Where(m => !_perms.BlockedModules.Contains(m.Key.Name.ToLowerInvariant()))
|
||||
.Select(x => x.Key)
|
||||
var localModules = topLevelModules.Skip(12 * cur)
|
||||
.Take(12)
|
||||
.ToList();
|
||||
|
||||
await ctx.SendPaginatedConfirmAsync(page, cur =>
|
||||
|
||||
if (!localModules.Any())
|
||||
{
|
||||
var embed = _eb.Create().WithOkColor()
|
||||
.WithTitle(GetText(strs.list_of_modules));
|
||||
|
||||
var localModules = topLevelModules.Skip(12 * cur)
|
||||
.Take(12)
|
||||
.ToList();
|
||||
|
||||
if (!localModules.Any())
|
||||
{
|
||||
embed = embed.WithOkColor()
|
||||
.WithDescription(GetText(strs.module_page_empty));
|
||||
return embed;
|
||||
}
|
||||
|
||||
localModules
|
||||
.OrderBy(module => module.Name)
|
||||
.ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}",
|
||||
GetText(GetModuleLocStr(module.Name)) + "\n" +
|
||||
Format.Code(GetText(strs.module_footer(Prefix, module.Name.ToLowerInvariant()))),
|
||||
true));
|
||||
|
||||
embed = embed.WithOkColor()
|
||||
.WithDescription(GetText(strs.module_page_empty));
|
||||
return embed;
|
||||
}, topLevelModules.Count(), 12, false);
|
||||
}
|
||||
|
||||
private LocStr GetModuleLocStr(string moduleName)
|
||||
{
|
||||
switch (moduleName.ToLowerInvariant())
|
||||
{
|
||||
case "help":
|
||||
return strs.module_description_help;
|
||||
case "administration":
|
||||
return strs.module_description_administration;
|
||||
case "customreactions":
|
||||
return strs.module_description_customreactions;
|
||||
case "searches":
|
||||
return strs.module_description_searches;
|
||||
case "utility":
|
||||
return strs.module_description_utility;
|
||||
case "games":
|
||||
return strs.module_description_games;
|
||||
case "gambling":
|
||||
return strs.module_description_gambling;
|
||||
case "music":
|
||||
return strs.module_description_music;
|
||||
case "nsfw":
|
||||
return strs.module_description_nsfw;
|
||||
case "permissions":
|
||||
return strs.module_description_permissions;
|
||||
case "xp":
|
||||
return strs.module_description_xp;
|
||||
default:
|
||||
return strs.module_description_missing;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
private string GetModuleEmoji(string moduleName)
|
||||
localModules
|
||||
.OrderBy(module => module.Name)
|
||||
.ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}",
|
||||
GetText(GetModuleLocStr(module.Name)) + "\n" +
|
||||
Format.Code(GetText(strs.module_footer(Prefix, module.Name.ToLowerInvariant()))),
|
||||
true));
|
||||
|
||||
return embed;
|
||||
}, topLevelModules.Count(), 12, false);
|
||||
}
|
||||
|
||||
private LocStr GetModuleLocStr(string moduleName)
|
||||
{
|
||||
switch (moduleName.ToLowerInvariant())
|
||||
{
|
||||
moduleName = moduleName.ToLowerInvariant();
|
||||
switch (moduleName)
|
||||
{
|
||||
case "help":
|
||||
return "❓";
|
||||
case "administration":
|
||||
return "🛠️";
|
||||
case "customreactions":
|
||||
return "🗣️";
|
||||
case "searches":
|
||||
return "🔍";
|
||||
case "utility":
|
||||
return "🔧";
|
||||
case "games":
|
||||
return "🎲";
|
||||
case "gambling":
|
||||
return "💰";
|
||||
case "music":
|
||||
return "🎶";
|
||||
case "nsfw":
|
||||
return "😳";
|
||||
case "permissions":
|
||||
return "🚓";
|
||||
case "xp":
|
||||
return "📝";
|
||||
default:
|
||||
return "📖";
|
||||
case "help":
|
||||
return strs.module_description_help;
|
||||
case "administration":
|
||||
return strs.module_description_administration;
|
||||
case "customreactions":
|
||||
return strs.module_description_customreactions;
|
||||
case "searches":
|
||||
return strs.module_description_searches;
|
||||
case "utility":
|
||||
return strs.module_description_utility;
|
||||
case "games":
|
||||
return strs.module_description_games;
|
||||
case "gambling":
|
||||
return strs.module_description_gambling;
|
||||
case "music":
|
||||
return strs.module_description_music;
|
||||
case "nsfw":
|
||||
return strs.module_description_nsfw;
|
||||
case "permissions":
|
||||
return strs.module_description_permissions;
|
||||
case "xp":
|
||||
return strs.module_description_xp;
|
||||
default:
|
||||
return strs.module_description_missing;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
private string GetModuleEmoji(string moduleName)
|
||||
{
|
||||
moduleName = moduleName.ToLowerInvariant();
|
||||
switch (moduleName)
|
||||
{
|
||||
case "help":
|
||||
return "❓";
|
||||
case "administration":
|
||||
return "🛠️";
|
||||
case "customreactions":
|
||||
return "🗣️";
|
||||
case "searches":
|
||||
return "🔍";
|
||||
case "utility":
|
||||
return "🔧";
|
||||
case "games":
|
||||
return "🎲";
|
||||
case "gambling":
|
||||
return "💰";
|
||||
case "music":
|
||||
return "🎶";
|
||||
case "nsfw":
|
||||
return "😳";
|
||||
case "permissions":
|
||||
return "🚓";
|
||||
case "xp":
|
||||
return "📝";
|
||||
default:
|
||||
return "📖";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
[NadekoOptions(typeof(CommandsOptions))]
|
||||
public async Task Commands(string module = null, params string[] args)
|
||||
{
|
||||
var channel = ctx.Channel;
|
||||
|
||||
|
||||
module = module?.Trim().ToUpperInvariant();
|
||||
if (string.IsNullOrWhiteSpace(module))
|
||||
{
|
||||
await Modules();
|
||||
return;
|
||||
}
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
[NadekoOptions(typeof(CommandsOptions))]
|
||||
public async Task Commands(string module = null, params string[] args)
|
||||
var (opts, _) = OptionsParser.ParseFrom(new CommandsOptions(), args);
|
||||
|
||||
// Find commands for that module
|
||||
// don't show commands which are blocked
|
||||
// order by name
|
||||
var cmds = _cmds.Commands.Where(c => c.Module.GetTopLevelModule().Name.ToUpperInvariant().StartsWith(module, StringComparison.InvariantCulture))
|
||||
.Where(c => !_perms.BlockedCommands.Contains(c.Aliases[0].ToLowerInvariant()))
|
||||
.OrderBy(c => c.Aliases[0])
|
||||
.Distinct(new CommandTextEqualityComparer());
|
||||
|
||||
|
||||
// check preconditions for all commands, but only if it's not 'all'
|
||||
// because all will show all commands anyway, no need to check
|
||||
var succ = new HashSet<CommandInfo>();
|
||||
if (opts.View != CommandsOptions.ViewType.All)
|
||||
{
|
||||
var channel = ctx.Channel;
|
||||
|
||||
|
||||
module = module?.Trim().ToUpperInvariant();
|
||||
if (string.IsNullOrWhiteSpace(module))
|
||||
{
|
||||
await Modules();
|
||||
return;
|
||||
}
|
||||
|
||||
var (opts, _) = OptionsParser.ParseFrom(new CommandsOptions(), args);
|
||||
|
||||
// Find commands for that module
|
||||
// don't show commands which are blocked
|
||||
// order by name
|
||||
var cmds = _cmds.Commands.Where(c => c.Module.GetTopLevelModule().Name.ToUpperInvariant().StartsWith(module, StringComparison.InvariantCulture))
|
||||
.Where(c => !_perms.BlockedCommands.Contains(c.Aliases[0].ToLowerInvariant()))
|
||||
.OrderBy(c => c.Aliases[0])
|
||||
.Distinct(new CommandTextEqualityComparer());
|
||||
|
||||
|
||||
// check preconditions for all commands, but only if it's not 'all'
|
||||
// because all will show all commands anyway, no need to check
|
||||
var succ = new HashSet<CommandInfo>();
|
||||
if (opts.View != CommandsOptions.ViewType.All)
|
||||
{
|
||||
succ = new HashSet<CommandInfo>((await Task.WhenAll(cmds.Select(async x =>
|
||||
succ = new HashSet<CommandInfo>((await Task.WhenAll(cmds.Select(async x =>
|
||||
{
|
||||
var pre = (await x.CheckPreconditionsAsync(Context, _services).ConfigureAwait(false));
|
||||
return (Cmd: x, Succ: pre.IsSuccess);
|
||||
})).ConfigureAwait(false))
|
||||
.Where(x => x.Succ)
|
||||
.Select(x => x.Cmd));
|
||||
.Where(x => x.Succ)
|
||||
.Select(x => x.Cmd));
|
||||
|
||||
if (opts.View == CommandsOptions.ViewType.Hide)
|
||||
{
|
||||
// if hidden is specified, completely remove these commands from the list
|
||||
cmds = cmds.Where(x => succ.Contains(x));
|
||||
}
|
||||
}
|
||||
|
||||
var cmdsWithGroup = cmds.GroupBy(c => c.Module.Name.Replace("Commands", "", StringComparison.InvariantCulture))
|
||||
.OrderBy(x => x.Key == x.First().Module.Name ? int.MaxValue : x.Count());
|
||||
|
||||
if (!cmds.Any())
|
||||
if (opts.View == CommandsOptions.ViewType.Hide)
|
||||
{
|
||||
if (opts.View != CommandsOptions.ViewType.Hide)
|
||||
await ReplyErrorLocalizedAsync(strs.module_not_found).ConfigureAwait(false);
|
||||
else
|
||||
await ReplyErrorLocalizedAsync(strs.module_not_found_or_cant_exec).ConfigureAwait(false);
|
||||
return;
|
||||
// if hidden is specified, completely remove these commands from the list
|
||||
cmds = cmds.Where(x => succ.Contains(x));
|
||||
}
|
||||
var i = 0;
|
||||
var groups = cmdsWithGroup.GroupBy(x => i++ / 48).ToArray();
|
||||
var embed = _eb.Create().WithOkColor();
|
||||
foreach (var g in groups)
|
||||
{
|
||||
var last = g.Count();
|
||||
for (i = 0; i < last; i++)
|
||||
{
|
||||
var transformed = g.ElementAt(i).Select(x =>
|
||||
{
|
||||
//if cross is specified, and the command doesn't satisfy the requirements, cross it out
|
||||
if (opts.View == CommandsOptions.ViewType.Cross)
|
||||
{
|
||||
return $"{(succ.Contains(x) ? "✅" : "❌")}{Prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}";
|
||||
}
|
||||
return $"{Prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}";
|
||||
});
|
||||
}
|
||||
|
||||
if (i == last - 1 && (i + 1) % 2 != 0)
|
||||
var cmdsWithGroup = cmds.GroupBy(c => c.Module.Name.Replace("Commands", "", StringComparison.InvariantCulture))
|
||||
.OrderBy(x => x.Key == x.First().Module.Name ? int.MaxValue : x.Count());
|
||||
|
||||
if (!cmds.Any())
|
||||
{
|
||||
if (opts.View != CommandsOptions.ViewType.Hide)
|
||||
await ReplyErrorLocalizedAsync(strs.module_not_found).ConfigureAwait(false);
|
||||
else
|
||||
await ReplyErrorLocalizedAsync(strs.module_not_found_or_cant_exec).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var i = 0;
|
||||
var groups = cmdsWithGroup.GroupBy(x => i++ / 48).ToArray();
|
||||
var embed = _eb.Create().WithOkColor();
|
||||
foreach (var g in groups)
|
||||
{
|
||||
var last = g.Count();
|
||||
for (i = 0; i < last; i++)
|
||||
{
|
||||
var transformed = g.ElementAt(i).Select(x =>
|
||||
{
|
||||
//if cross is specified, and the command doesn't satisfy the requirements, cross it out
|
||||
if (opts.View == CommandsOptions.ViewType.Cross)
|
||||
{
|
||||
var grp = 0;
|
||||
var count = transformed.Count();
|
||||
transformed = transformed
|
||||
.GroupBy(x => grp++ % count / 2)
|
||||
.Select(x =>
|
||||
{
|
||||
if (x.Count() == 1)
|
||||
return $"{x.First()}";
|
||||
else
|
||||
return String.Concat(x);
|
||||
});
|
||||
return $"{(succ.Contains(x) ? "✅" : "❌")}{Prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}";
|
||||
}
|
||||
embed.AddField(g.ElementAt(i).Key, "```css\n" + string.Join("\n", transformed) + "\n```", true);
|
||||
}
|
||||
}
|
||||
embed.WithFooter(GetText(strs.commands_instr(Prefix)));
|
||||
await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||
}
|
||||
return $"{Prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}";
|
||||
});
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
[Priority(0)]
|
||||
public async Task H([Leftover] string fail)
|
||||
{
|
||||
var prefixless = _cmds.Commands.FirstOrDefault(x => x.Aliases.Any(cmdName => cmdName.ToLowerInvariant() == fail));
|
||||
if (prefixless != null)
|
||||
{
|
||||
await H(prefixless).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await ReplyErrorLocalizedAsync(strs.command_not_found).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
[Priority(1)]
|
||||
public async Task H([Leftover] CommandInfo com = null)
|
||||
{
|
||||
var channel = ctx.Channel;
|
||||
|
||||
if (com is null)
|
||||
{
|
||||
IMessageChannel ch = channel is ITextChannel
|
||||
? await ((IGuildUser)ctx.User).GetOrCreateDMChannelAsync().ConfigureAwait(false)
|
||||
: channel;
|
||||
try
|
||||
if (i == last - 1 && (i + 1) % 2 != 0)
|
||||
{
|
||||
var data = await GetHelpString();
|
||||
if (data == default)
|
||||
return;
|
||||
await ch.SendAsync(data);
|
||||
try{ await ctx.OkAsync(); } catch { } // ignore if bot can't react
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.cant_dm).ConfigureAwait(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var embed = _service.GetCommandHelp(com, ctx.Guild);
|
||||
await channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
[OwnerOnly]
|
||||
public async Task GenCmdList()
|
||||
{
|
||||
_ = ctx.Channel.TriggerTypingAsync();
|
||||
|
||||
// order commands by top level module name
|
||||
// and make a dictionary of <ModuleName, Array<JsonCommandData>>
|
||||
var cmdData = _cmds
|
||||
.Commands
|
||||
.GroupBy(x => x.Module.GetTopLevelModule().Name)
|
||||
.OrderBy(x => x.Key)
|
||||
.ToDictionary(
|
||||
x => x.Key,
|
||||
x => x.Distinct(c => c.Aliases.First())
|
||||
.Select(com =>
|
||||
var grp = 0;
|
||||
var count = transformed.Count();
|
||||
transformed = transformed
|
||||
.GroupBy(x => grp++ % count / 2)
|
||||
.Select(x =>
|
||||
{
|
||||
List<string> optHelpStr = null;
|
||||
var opt = ((NadekoOptionsAttribute)com.Attributes.FirstOrDefault(x => x is NadekoOptionsAttribute))?.OptionType;
|
||||
if (opt != null)
|
||||
{
|
||||
optHelpStr = HelpService.GetCommandOptionHelpList(opt);
|
||||
}
|
||||
|
||||
return new CommandJsonObject
|
||||
{
|
||||
Aliases = com.Aliases.Select(alias => Prefix + alias).ToArray(),
|
||||
Description = com.RealSummary(_strings, ctx.Guild?.Id, Prefix),
|
||||
Usage = com.RealRemarksArr(_strings, ctx.Guild?.Id, Prefix),
|
||||
Submodule = com.Module.Name,
|
||||
Module = com.Module.GetTopLevelModule().Name,
|
||||
Options = optHelpStr,
|
||||
Requirements = HelpService.GetCommandRequirements(com),
|
||||
};
|
||||
})
|
||||
.ToList()
|
||||
);
|
||||
if (x.Count() == 1)
|
||||
return $"{x.First()}";
|
||||
else
|
||||
return String.Concat(x);
|
||||
});
|
||||
}
|
||||
embed.AddField(g.ElementAt(i).Key, "```css\n" + string.Join("\n", transformed) + "\n```", true);
|
||||
}
|
||||
}
|
||||
embed.WithFooter(GetText(strs.commands_instr(Prefix)));
|
||||
await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var readableData = JsonConvert.SerializeObject(cmdData, Formatting.Indented);
|
||||
var uploadData = JsonConvert.SerializeObject(cmdData, Formatting.None);
|
||||
[NadekoCommand, Aliases]
|
||||
[Priority(0)]
|
||||
public async Task H([Leftover] string fail)
|
||||
{
|
||||
var prefixless = _cmds.Commands.FirstOrDefault(x => x.Aliases.Any(cmdName => cmdName.ToLowerInvariant() == fail));
|
||||
if (prefixless != null)
|
||||
{
|
||||
await H(prefixless).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// for example https://nyc.digitaloceanspaces.com (without your space name)
|
||||
var serviceUrl = Environment.GetEnvironmentVariable("do_spaces_address");
|
||||
await ReplyErrorLocalizedAsync(strs.command_not_found).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// generate spaces access key on https://cloud.digitalocean.com/account/api/tokens
|
||||
// you will get 2 keys, first, shorter one is id, longer one is secret
|
||||
var accessKey = Environment.GetEnvironmentVariable("do_access_key_id");
|
||||
var secretAcccessKey = Environment.GetEnvironmentVariable("do_access_key_secret");
|
||||
[NadekoCommand, Aliases]
|
||||
[Priority(1)]
|
||||
public async Task H([Leftover] CommandInfo com = null)
|
||||
{
|
||||
var channel = ctx.Channel;
|
||||
|
||||
// if all env vars are set, upload the unindented file (to save space) there
|
||||
if (!(serviceUrl is null || accessKey is null || secretAcccessKey is null))
|
||||
if (com is null)
|
||||
{
|
||||
IMessageChannel ch = channel is ITextChannel
|
||||
? await ((IGuildUser)ctx.User).GetOrCreateDMChannelAsync().ConfigureAwait(false)
|
||||
: channel;
|
||||
try
|
||||
{
|
||||
var config = new AmazonS3Config {ServiceURL = serviceUrl};
|
||||
var data = await GetHelpString();
|
||||
if (data == default)
|
||||
return;
|
||||
await ch.SendAsync(data);
|
||||
try{ await ctx.OkAsync(); } catch { } // ignore if bot can't react
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.cant_dm).ConfigureAwait(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var embed = _service.GetCommandHelp(com, ctx.Guild);
|
||||
await channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
[OwnerOnly]
|
||||
public async Task GenCmdList()
|
||||
{
|
||||
_ = ctx.Channel.TriggerTypingAsync();
|
||||
|
||||
// order commands by top level module name
|
||||
// and make a dictionary of <ModuleName, Array<JsonCommandData>>
|
||||
var cmdData = _cmds
|
||||
.Commands
|
||||
.GroupBy(x => x.Module.GetTopLevelModule().Name)
|
||||
.OrderBy(x => x.Key)
|
||||
.ToDictionary(
|
||||
x => x.Key,
|
||||
x => x.Distinct(c => c.Aliases.First())
|
||||
.Select(com =>
|
||||
{
|
||||
List<string> optHelpStr = null;
|
||||
var opt = ((NadekoOptionsAttribute)com.Attributes.FirstOrDefault(x => x is NadekoOptionsAttribute))?.OptionType;
|
||||
if (opt != null)
|
||||
{
|
||||
optHelpStr = HelpService.GetCommandOptionHelpList(opt);
|
||||
}
|
||||
|
||||
return new CommandJsonObject
|
||||
{
|
||||
Aliases = com.Aliases.Select(alias => Prefix + alias).ToArray(),
|
||||
Description = com.RealSummary(_strings, ctx.Guild?.Id, Prefix),
|
||||
Usage = com.RealRemarksArr(_strings, ctx.Guild?.Id, Prefix),
|
||||
Submodule = com.Module.Name,
|
||||
Module = com.Module.GetTopLevelModule().Name,
|
||||
Options = optHelpStr,
|
||||
Requirements = HelpService.GetCommandRequirements(com),
|
||||
};
|
||||
})
|
||||
.ToList()
|
||||
);
|
||||
|
||||
var readableData = JsonConvert.SerializeObject(cmdData, Formatting.Indented);
|
||||
var uploadData = JsonConvert.SerializeObject(cmdData, Formatting.None);
|
||||
|
||||
// for example https://nyc.digitaloceanspaces.com (without your space name)
|
||||
var serviceUrl = Environment.GetEnvironmentVariable("do_spaces_address");
|
||||
|
||||
// generate spaces access key on https://cloud.digitalocean.com/account/api/tokens
|
||||
// you will get 2 keys, first, shorter one is id, longer one is secret
|
||||
var accessKey = Environment.GetEnvironmentVariable("do_access_key_id");
|
||||
var secretAcccessKey = Environment.GetEnvironmentVariable("do_access_key_secret");
|
||||
|
||||
// if all env vars are set, upload the unindented file (to save space) there
|
||||
if (!(serviceUrl is null || accessKey is null || secretAcccessKey is null))
|
||||
{
|
||||
var config = new AmazonS3Config {ServiceURL = serviceUrl};
|
||||
|
||||
using var dlClient = new AmazonS3Client(accessKey, secretAcccessKey, config);
|
||||
var oldVersionObject = await dlClient.GetObjectAsync(new GetObjectRequest()
|
||||
using var dlClient = new AmazonS3Client(accessKey, secretAcccessKey, config);
|
||||
var oldVersionObject = await dlClient.GetObjectAsync(new GetObjectRequest()
|
||||
{
|
||||
BucketName = "nadeko-pictures",
|
||||
Key = "cmds/versions.json",
|
||||
});
|
||||
|
||||
using (var client = new AmazonS3Client(accessKey, secretAcccessKey, config))
|
||||
{
|
||||
await client.PutObjectAsync(new PutObjectRequest()
|
||||
{
|
||||
BucketName = "nadeko-pictures",
|
||||
Key = "cmds/versions.json",
|
||||
ContentType = "application/json",
|
||||
ContentBody = uploadData,
|
||||
// either use a path provided in the argument or the default one for public nadeko, other/cmds.json
|
||||
Key = $"cmds/{StatsService.BotVersion}.json",
|
||||
CannedACL = S3CannedACL.PublicRead
|
||||
});
|
||||
|
||||
using (var client = new AmazonS3Client(accessKey, secretAcccessKey, config))
|
||||
{
|
||||
await client.PutObjectAsync(new PutObjectRequest()
|
||||
{
|
||||
BucketName = "nadeko-pictures",
|
||||
ContentType = "application/json",
|
||||
ContentBody = uploadData,
|
||||
// either use a path provided in the argument or the default one for public nadeko, other/cmds.json
|
||||
Key = $"cmds/{StatsService.BotVersion}.json",
|
||||
CannedACL = S3CannedACL.PublicRead
|
||||
});
|
||||
}
|
||||
|
||||
using var ms = new MemoryStream();
|
||||
await oldVersionObject.ResponseStream.CopyToAsync(ms);
|
||||
var versionListString = Encoding.UTF8.GetString(ms.ToArray());
|
||||
|
||||
var versionList = System.Text.Json.JsonSerializer.Deserialize<List<string>>(versionListString);
|
||||
if (!versionList.Contains(StatsService.BotVersion))
|
||||
{
|
||||
// save the file with new version added
|
||||
// versionList.Add(StatsService.BotVersion);
|
||||
versionListString = System.Text.Json.JsonSerializer.Serialize(
|
||||
versionList.Prepend(StatsService.BotVersion),
|
||||
new JsonSerializerOptions()
|
||||
{
|
||||
WriteIndented = true
|
||||
});
|
||||
|
||||
// upload the updated version list
|
||||
using var client = new AmazonS3Client(accessKey, secretAcccessKey, config);
|
||||
await client.PutObjectAsync(new PutObjectRequest()
|
||||
{
|
||||
BucketName = "nadeko-pictures",
|
||||
ContentType = "application/json",
|
||||
ContentBody = versionListString,
|
||||
// either use a path provided in the argument or the default one for public nadeko, other/cmds.json
|
||||
Key = "cmds/versions.json",
|
||||
CannedACL = S3CannedACL.PublicRead
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning("Version {Version} already exists in the version file. " +
|
||||
"Did you forget to increment it?", StatsService.BotVersion);
|
||||
}
|
||||
}
|
||||
|
||||
// also send the file, but indented one, to chat
|
||||
using var rDataStream = new MemoryStream(Encoding.ASCII.GetBytes(readableData));
|
||||
await ctx.Channel.SendFileAsync(rDataStream, "cmds.json", GetText(strs.commandlist_regen)).ConfigureAwait(false);
|
||||
using var ms = new MemoryStream();
|
||||
await oldVersionObject.ResponseStream.CopyToAsync(ms);
|
||||
var versionListString = Encoding.UTF8.GetString(ms.ToArray());
|
||||
|
||||
var versionList = System.Text.Json.JsonSerializer.Deserialize<List<string>>(versionListString);
|
||||
if (!versionList.Contains(StatsService.BotVersion))
|
||||
{
|
||||
// save the file with new version added
|
||||
// versionList.Add(StatsService.BotVersion);
|
||||
versionListString = System.Text.Json.JsonSerializer.Serialize(
|
||||
versionList.Prepend(StatsService.BotVersion),
|
||||
new JsonSerializerOptions()
|
||||
{
|
||||
WriteIndented = true
|
||||
});
|
||||
|
||||
// upload the updated version list
|
||||
using var client = new AmazonS3Client(accessKey, secretAcccessKey, config);
|
||||
await client.PutObjectAsync(new PutObjectRequest()
|
||||
{
|
||||
BucketName = "nadeko-pictures",
|
||||
ContentType = "application/json",
|
||||
ContentBody = versionListString,
|
||||
// either use a path provided in the argument or the default one for public nadeko, other/cmds.json
|
||||
Key = "cmds/versions.json",
|
||||
CannedACL = S3CannedACL.PublicRead
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning("Version {Version} already exists in the version file. " +
|
||||
"Did you forget to increment it?", StatsService.BotVersion);
|
||||
}
|
||||
}
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
public async Task Guide()
|
||||
{
|
||||
await ConfirmLocalizedAsync(strs.guide(
|
||||
"https://nadeko.bot/commands",
|
||||
"http://nadekobot.readthedocs.io/en/latest/"));
|
||||
}
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
public async Task Donate()
|
||||
{
|
||||
await ReplyConfirmLocalizedAsync(strs.donate(PatreonUrl, PaypalUrl));
|
||||
}
|
||||
// also send the file, but indented one, to chat
|
||||
using var rDataStream = new MemoryStream(Encoding.ASCII.GetBytes(readableData));
|
||||
await ctx.Channel.SendFileAsync(rDataStream, "cmds.json", GetText(strs.commandlist_regen)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public class CommandTextEqualityComparer : IEqualityComparer<CommandInfo>
|
||||
[NadekoCommand, Aliases]
|
||||
public async Task Guide()
|
||||
{
|
||||
public bool Equals(CommandInfo x, CommandInfo y) => x.Aliases[0] == y.Aliases[0];
|
||||
|
||||
public int GetHashCode(CommandInfo obj) => obj.Aliases[0].GetHashCode(StringComparison.InvariantCulture);
|
||||
|
||||
await ConfirmLocalizedAsync(strs.guide(
|
||||
"https://nadeko.bot/commands",
|
||||
"http://nadekobot.readthedocs.io/en/latest/"));
|
||||
}
|
||||
|
||||
internal class CommandJsonObject
|
||||
[NadekoCommand, Aliases]
|
||||
public async Task Donate()
|
||||
{
|
||||
public string[] Aliases { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string[] Usage { get; set; }
|
||||
public string Submodule { get; set; }
|
||||
public string Module { get; set; }
|
||||
public List<string> Options { get; set; }
|
||||
public string[] Requirements { get; set; }
|
||||
await ReplyConfirmLocalizedAsync(strs.donate(PatreonUrl, PaypalUrl));
|
||||
}
|
||||
}
|
||||
|
||||
public class CommandTextEqualityComparer : IEqualityComparer<CommandInfo>
|
||||
{
|
||||
public bool Equals(CommandInfo x, CommandInfo y) => x.Aliases[0] == y.Aliases[0];
|
||||
|
||||
public int GetHashCode(CommandInfo obj) => obj.Aliases[0].GetHashCode(StringComparison.InvariantCulture);
|
||||
|
||||
}
|
||||
|
||||
internal class CommandJsonObject
|
||||
{
|
||||
public string[] Aliases { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string[] Usage { get; set; }
|
||||
public string Submodule { get; set; }
|
||||
public string Module { get; set; }
|
||||
public List<string> Options { get; set; }
|
||||
public string[] Requirements { get; set; }
|
||||
}
|
@@ -1,183 +1,177 @@
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using System;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Linq;
|
||||
using NadekoBot.Common.Attributes;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Services;
|
||||
using NadekoBot.Common;
|
||||
using CommandLine;
|
||||
using System.Collections.Generic;
|
||||
using NadekoBot.Common.Replacements;
|
||||
using NadekoBot.Modules.Administration.Services;
|
||||
using Serilog;
|
||||
|
||||
namespace NadekoBot.Modules.Help.Services
|
||||
namespace NadekoBot.Modules.Help.Services;
|
||||
|
||||
public class HelpService : ILateExecutor, INService
|
||||
{
|
||||
public class HelpService : ILateExecutor, INService
|
||||
private readonly CommandHandler _ch;
|
||||
private readonly IBotStrings _strings;
|
||||
private readonly DiscordPermOverrideService _dpos;
|
||||
private readonly BotConfigService _bss;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
|
||||
public HelpService(CommandHandler ch,
|
||||
IBotStrings strings,
|
||||
DiscordPermOverrideService dpos,
|
||||
BotConfigService bss,
|
||||
IEmbedBuilderService eb)
|
||||
{
|
||||
private readonly CommandHandler _ch;
|
||||
private readonly IBotStrings _strings;
|
||||
private readonly DiscordPermOverrideService _dpos;
|
||||
private readonly BotConfigService _bss;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
_ch = ch;
|
||||
_strings = strings;
|
||||
_dpos = dpos;
|
||||
_bss = bss;
|
||||
_eb = eb;
|
||||
}
|
||||
|
||||
public HelpService(CommandHandler ch,
|
||||
IBotStrings strings,
|
||||
DiscordPermOverrideService dpos,
|
||||
BotConfigService bss,
|
||||
IEmbedBuilderService eb)
|
||||
public Task LateExecute(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
var settings = _bss.Data;
|
||||
if (guild is null)
|
||||
{
|
||||
_ch = ch;
|
||||
_strings = strings;
|
||||
_dpos = dpos;
|
||||
_bss = bss;
|
||||
_eb = eb;
|
||||
}
|
||||
|
||||
public Task LateExecute(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
var settings = _bss.Data;
|
||||
if (guild is null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(settings.DmHelpText) || settings.DmHelpText == "-")
|
||||
return Task.CompletedTask;
|
||||
if (string.IsNullOrWhiteSpace(settings.DmHelpText) || settings.DmHelpText == "-")
|
||||
return Task.CompletedTask;
|
||||
|
||||
// only send dm help text if it contains one of the keywords, if they're specified
|
||||
// if they're not, then reply to every DM
|
||||
if (settings.DmHelpTextKeywords.Any() && !settings.DmHelpTextKeywords.Any(k => msg.Content.Contains(k)))
|
||||
return Task.CompletedTask;
|
||||
// only send dm help text if it contains one of the keywords, if they're specified
|
||||
// if they're not, then reply to every DM
|
||||
if (settings.DmHelpTextKeywords.Any() && !settings.DmHelpTextKeywords.Any(k => msg.Content.Contains(k)))
|
||||
return Task.CompletedTask;
|
||||
|
||||
var rep = new ReplacementBuilder()
|
||||
.WithOverride("%prefix%", () => _bss.Data.Prefix)
|
||||
.WithOverride("%bot.prefix%", () => _bss.Data.Prefix)
|
||||
.WithUser(msg.Author)
|
||||
.Build();
|
||||
var rep = new ReplacementBuilder()
|
||||
.WithOverride("%prefix%", () => _bss.Data.Prefix)
|
||||
.WithOverride("%bot.prefix%", () => _bss.Data.Prefix)
|
||||
.WithUser(msg.Author)
|
||||
.Build();
|
||||
|
||||
var text = SmartText.CreateFrom(settings.DmHelpText);
|
||||
text = rep.Replace(text);
|
||||
var text = SmartText.CreateFrom(settings.DmHelpText);
|
||||
text = rep.Replace(text);
|
||||
|
||||
return msg.Channel.SendAsync(text);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
return msg.Channel.SendAsync(text);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public IEmbedBuilder GetCommandHelp(CommandInfo com, IGuild guild)
|
||||
{
|
||||
var prefix = _ch.GetPrefix(guild);
|
||||
|
||||
var str = $"**`{prefix + com.Aliases.First()}`**";
|
||||
var alias = com.Aliases.Skip(1).FirstOrDefault();
|
||||
if (alias != null)
|
||||
str += $" **/ `{prefix + alias}`**";
|
||||
var em = _eb.Create()
|
||||
.AddField(str, $"{com.RealSummary(_strings, guild?.Id, prefix)}", true);
|
||||
|
||||
_dpos.TryGetOverrides(guild?.Id ?? 0, com.Name, out var overrides);
|
||||
var reqs = GetCommandRequirements(com, overrides);
|
||||
if(reqs.Any())
|
||||
{
|
||||
em.AddField(GetText(strs.requires, guild), string.Join("\n", reqs));
|
||||
}
|
||||
|
||||
public IEmbedBuilder GetCommandHelp(CommandInfo com, IGuild guild)
|
||||
em
|
||||
.AddField(_strings.GetText(strs.usage),
|
||||
string.Join("\n", Array.ConvertAll(com.RealRemarksArr(_strings, guild?.Id, prefix),
|
||||
arg => Format.Code(arg))),
|
||||
false)
|
||||
.WithFooter(GetText(strs.module(com.Module.GetTopLevelModule().Name), guild))
|
||||
.WithOkColor();
|
||||
|
||||
var opt = ((NadekoOptionsAttribute)com.Attributes.FirstOrDefault(x => x is NadekoOptionsAttribute))?.OptionType;
|
||||
if (opt != null)
|
||||
{
|
||||
var prefix = _ch.GetPrefix(guild);
|
||||
var hs = GetCommandOptionHelp(opt);
|
||||
if(!string.IsNullOrWhiteSpace(hs))
|
||||
em.AddField(GetText(strs.options, guild), hs, false);
|
||||
}
|
||||
|
||||
var str = $"**`{prefix + com.Aliases.First()}`**";
|
||||
var alias = com.Aliases.Skip(1).FirstOrDefault();
|
||||
if (alias != null)
|
||||
str += $" **/ `{prefix + alias}`**";
|
||||
var em = _eb.Create()
|
||||
.AddField(str, $"{com.RealSummary(_strings, guild?.Id, prefix)}", true);
|
||||
return em;
|
||||
}
|
||||
|
||||
_dpos.TryGetOverrides(guild?.Id ?? 0, com.Name, out var overrides);
|
||||
var reqs = GetCommandRequirements(com, overrides);
|
||||
if(reqs.Any())
|
||||
public static string GetCommandOptionHelp(Type opt)
|
||||
{
|
||||
var strs = GetCommandOptionHelpList(opt);
|
||||
|
||||
return string.Join("\n", strs);
|
||||
}
|
||||
|
||||
public static List<string> GetCommandOptionHelpList(Type opt)
|
||||
{
|
||||
var strs = opt.GetProperties()
|
||||
.Select(x => x.GetCustomAttributes(true).FirstOrDefault(a => a is OptionAttribute))
|
||||
.Where(x => x != null)
|
||||
.Cast<OptionAttribute>()
|
||||
.Select(x =>
|
||||
{
|
||||
em.AddField(GetText(strs.requires, guild), string.Join("\n", reqs));
|
||||
}
|
||||
var toReturn = $"`--{x.LongName}`";
|
||||
|
||||
em
|
||||
.AddField(_strings.GetText(strs.usage),
|
||||
string.Join("\n", Array.ConvertAll(com.RealRemarksArr(_strings, guild?.Id, prefix),
|
||||
arg => Format.Code(arg))),
|
||||
false)
|
||||
.WithFooter(GetText(strs.module(com.Module.GetTopLevelModule().Name), guild))
|
||||
.WithOkColor();
|
||||
if (!string.IsNullOrWhiteSpace(x.ShortName))
|
||||
toReturn += $" (`-{x.ShortName}`)";
|
||||
|
||||
var opt = ((NadekoOptionsAttribute)com.Attributes.FirstOrDefault(x => x is NadekoOptionsAttribute))?.OptionType;
|
||||
if (opt != null)
|
||||
{
|
||||
var hs = GetCommandOptionHelp(opt);
|
||||
if(!string.IsNullOrWhiteSpace(hs))
|
||||
em.AddField(GetText(strs.options, guild), hs, false);
|
||||
}
|
||||
toReturn += $" {x.HelpText} ";
|
||||
return toReturn;
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return em;
|
||||
}
|
||||
|
||||
public static string GetCommandOptionHelp(Type opt)
|
||||
{
|
||||
var strs = GetCommandOptionHelpList(opt);
|
||||
|
||||
return string.Join("\n", strs);
|
||||
}
|
||||
|
||||
public static List<string> GetCommandOptionHelpList(Type opt)
|
||||
{
|
||||
var strs = opt.GetProperties()
|
||||
.Select(x => x.GetCustomAttributes(true).FirstOrDefault(a => a is OptionAttribute))
|
||||
.Where(x => x != null)
|
||||
.Cast<OptionAttribute>()
|
||||
.Select(x =>
|
||||
{
|
||||
var toReturn = $"`--{x.LongName}`";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(x.ShortName))
|
||||
toReturn += $" (`-{x.ShortName}`)";
|
||||
|
||||
toReturn += $" {x.HelpText} ";
|
||||
return toReturn;
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return strs;
|
||||
}
|
||||
return strs;
|
||||
}
|
||||
|
||||
|
||||
public static string[] GetCommandRequirements(CommandInfo cmd, GuildPerm? overrides = null)
|
||||
{
|
||||
var toReturn = new List<string>();
|
||||
public static string[] GetCommandRequirements(CommandInfo cmd, GuildPerm? overrides = null)
|
||||
{
|
||||
var toReturn = new List<string>();
|
||||
|
||||
if(cmd.Preconditions.Any(x => x is OwnerOnlyAttribute))
|
||||
toReturn.Add("Bot Owner Only");
|
||||
if(cmd.Preconditions.Any(x => x is OwnerOnlyAttribute))
|
||||
toReturn.Add("Bot Owner Only");
|
||||
|
||||
var userPerm = (UserPermAttribute)cmd.Preconditions
|
||||
.FirstOrDefault(ca => ca is UserPermAttribute);
|
||||
var userPerm = (UserPermAttribute)cmd.Preconditions
|
||||
.FirstOrDefault(ca => ca is UserPermAttribute);
|
||||
|
||||
string userPermString = string.Empty;
|
||||
if (userPerm is not null)
|
||||
{
|
||||
if (userPerm.UserPermissionAttribute.ChannelPermission is ChannelPermission cPerm)
|
||||
userPermString = GetPreconditionString((ChannelPerm) cPerm);
|
||||
if (userPerm.UserPermissionAttribute.GuildPermission is GuildPermission gPerm)
|
||||
userPermString = GetPreconditionString((GuildPerm) gPerm);
|
||||
}
|
||||
string userPermString = string.Empty;
|
||||
if (userPerm is not null)
|
||||
{
|
||||
if (userPerm.UserPermissionAttribute.ChannelPermission is ChannelPermission cPerm)
|
||||
userPermString = GetPreconditionString((ChannelPerm) cPerm);
|
||||
if (userPerm.UserPermissionAttribute.GuildPermission is GuildPermission gPerm)
|
||||
userPermString = GetPreconditionString((GuildPerm) gPerm);
|
||||
}
|
||||
|
||||
if (overrides is null)
|
||||
{
|
||||
if(!string.IsNullOrWhiteSpace(userPermString))
|
||||
toReturn.Add(userPermString);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!string.IsNullOrWhiteSpace(userPermString))
|
||||
toReturn.Add(Format.Strikethrough(userPermString));
|
||||
if (overrides is null)
|
||||
{
|
||||
if(!string.IsNullOrWhiteSpace(userPermString))
|
||||
toReturn.Add(userPermString);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!string.IsNullOrWhiteSpace(userPermString))
|
||||
toReturn.Add(Format.Strikethrough(userPermString));
|
||||
|
||||
toReturn.Add(GetPreconditionString(overrides.Value));
|
||||
}
|
||||
|
||||
return toReturn.ToArray();
|
||||
toReturn.Add(GetPreconditionString(overrides.Value));
|
||||
}
|
||||
|
||||
public static string GetPreconditionString(ChannelPerm perm)
|
||||
{
|
||||
return (perm.ToString() + " Channel Permission")
|
||||
.Replace("Guild", "Server", StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
public static string GetPreconditionString(GuildPerm perm)
|
||||
{
|
||||
return (perm.ToString() + " Server Permission")
|
||||
.Replace("Guild", "Server", StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
private string GetText(LocStr str, IGuild guild, params object[] replacements) =>
|
||||
_strings.GetText(str, guild?.Id);
|
||||
return toReturn.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPreconditionString(ChannelPerm perm)
|
||||
{
|
||||
return (perm.ToString() + " Channel Permission")
|
||||
.Replace("Guild", "Server", StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
public static string GetPreconditionString(GuildPerm perm)
|
||||
{
|
||||
return (perm.ToString() + " Server Permission")
|
||||
.Replace("Guild", "Server", StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
private string GetText(LocStr str, IGuild guild, params object[] replacements) =>
|
||||
_strings.GetText(str, guild?.Id);
|
||||
}
|
Reference in New Issue
Block a user