diff --git a/src/Nadeko.Common/Nadeko.Common.csproj b/src/Nadeko.Common/Nadeko.Common.csproj
index 1e19eb78b..1aa7abe0d 100644
--- a/src/Nadeko.Common/Nadeko.Common.csproj
+++ b/src/Nadeko.Common/Nadeko.Common.csproj
@@ -7,8 +7,8 @@
-
+
-
+
diff --git a/src/Nadeko.Medusa/Nadeko.Medusa.csproj b/src/Nadeko.Medusa/Nadeko.Medusa.csproj
index 4f71c41ff..4b7cc9b6e 100644
--- a/src/Nadeko.Medusa/Nadeko.Medusa.csproj
+++ b/src/Nadeko.Medusa/Nadeko.Medusa.csproj
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/src/NadekoBot.Coordinator/NadekoBot.Coordinator.csproj b/src/NadekoBot.Coordinator/NadekoBot.Coordinator.csproj
index 10ebe4b4d..f5535c759 100644
--- a/src/NadekoBot.Coordinator/NadekoBot.Coordinator.csproj
+++ b/src/NadekoBot.Coordinator/NadekoBot.Coordinator.csproj
@@ -10,11 +10,11 @@
-
-
-
+
+
+
-
+
diff --git a/src/NadekoBot.Generators/Command/CommandAttributesGenerator.cs b/src/NadekoBot.Generators/Command/CommandAttributesGenerator.cs
deleted file mode 100644
index ca18bb71d..000000000
--- a/src/NadekoBot.Generators/Command/CommandAttributesGenerator.cs
+++ /dev/null
@@ -1,336 +0,0 @@
-// #nullable enable
-// using System;
-// using System.CodeDom.Compiler;
-// using System.Collections.Generic;
-// using System.Collections.Immutable;
-// using System.Collections.ObjectModel;
-// using System.Diagnostics;
-// using System.IO;
-// using System.Linq;
-// using System.Text;
-// using System.Threading;
-// using Microsoft.CodeAnalysis;
-// using Microsoft.CodeAnalysis.CSharp;
-// using Microsoft.CodeAnalysis.CSharp.Syntax;
-// using Microsoft.CodeAnalysis.Text;
-//
-// namespace NadekoBot.Generators.Command;
-//
-// [Generator]
-// public class CommandAttributesGenerator : IIncrementalGenerator
-// {
-// public const string ATTRIBUTE = @"//
-//
-// namespace NadekoBot.Common;
-//
-// [System.AttributeUsage(System.AttributeTargets.Method)]
-// public class CmdAttribute : System.Attribute
-// {
-//
-// }";
-//
-// public class MethodModel
-// {
-// public string? Namespace { get; }
-// public IReadOnlyCollection Classes { get; }
-// public string ReturnType { get; }
-// public string MethodName { get; }
-// public IEnumerable Params { get; }
-//
-// public MethodModel(string? ns, IReadOnlyCollection classes, string returnType, string methodName, IEnumerable @params)
-// {
-// Namespace = ns;
-// Classes = classes;
-// ReturnType = returnType;
-// MethodName = methodName;
-// Params = @params;
-// }
-// }
-//
-// public class FileModel
-// {
-// public string? Namespace { get; }
-// public IReadOnlyCollection ClassHierarchy { get; }
-// public IReadOnlyCollection Methods { get; }
-//
-// public FileModel(string? ns, IReadOnlyCollection classHierarchy, IReadOnlyCollection methods)
-// {
-// Namespace = ns;
-// ClassHierarchy = classHierarchy;
-// Methods = methods;
-// }
-// }
-//
-// public void Initialize(IncrementalGeneratorInitializationContext context)
-// {
-// // #if DEBUG
-// // if (!Debugger.IsAttached)
-// // Debugger.Launch();
-// // // SpinWait.SpinUntil(() => Debugger.IsAttached);
-// // #endif
-// context.RegisterPostInitializationOutput(static ctx => ctx.AddSource(
-// "CmdAttribute.g.cs",
-// SourceText.From(ATTRIBUTE, Encoding.UTF8)));
-//
-// var methods = context.SyntaxProvider
-// .CreateSyntaxProvider(
-// static (node, _) => node is MethodDeclarationSyntax { AttributeLists.Count: > 0 },
-// static (ctx, cancel) => Transform(ctx, cancel))
-// .Where(static m => m is not null)
-// .Where(static m => m?.ChildTokens().Any(static x => x.IsKind(SyntaxKind.PublicKeyword)) ?? false);
-//
-// var compilationMethods = context.CompilationProvider.Combine(methods.Collect());
-//
-// context.RegisterSourceOutput(compilationMethods,
-// static (ctx, tuple) => RegisterAction(in ctx, tuple.Left, in tuple.Right));
-// }
-//
-// private static void RegisterAction(in SourceProductionContext ctx,
-// Compilation comp,
-// in ImmutableArray methods)
-// {
-// if (methods is { IsDefaultOrEmpty: true })
-// return;
-//
-// var models = GetModels(comp, methods, ctx.CancellationToken);
-//
-// foreach (var model in models)
-// {
-// var name = $"{model.Namespace}.{string.Join(".", model.ClassHierarchy)}.g.cs";
-// try
-// {
-// var source = GetSourceText(model);
-// ctx.AddSource(name, SourceText.From(source, Encoding.UTF8));
-// }
-// catch (Exception ex)
-// {
-// Console.WriteLine($"Error writing source file {name}\n" + ex);
-// }
-// }
-// }
-//
-// private static string GetSourceText(FileModel model)
-// {
-// using var sw = new StringWriter();
-// using var tw = new IndentedTextWriter(sw);
-//
-// tw.WriteLine("// ");
-// tw.WriteLine("#pragma warning disable CS1066");
-//
-// if (model.Namespace is not null)
-// {
-// tw.WriteLine($"namespace {model.Namespace};");
-// tw.WriteLine();
-// }
-//
-// foreach (var className in model.ClassHierarchy)
-// {
-// tw.WriteLine($"public partial class {className}");
-// tw.WriteLine("{");
-// tw.Indent ++;
-// }
-//
-// foreach (var method in model.Methods)
-// {
-// tw.WriteLine("[NadekoCommand]");
-// tw.WriteLine("[NadekoDescription]");
-// tw.WriteLine("[Aliases]");
-// tw.WriteLine($"public partial {method.ReturnType} {method.MethodName}({string.Join(", ", method.Params)});");
-// }
-//
-// foreach (var _ in model.ClassHierarchy)
-// {
-// tw.Indent --;
-// tw.WriteLine("}");
-// }
-//
-// tw.Flush();
-// return sw.ToString();
-// }
-//
-// private static IReadOnlyCollection GetModels(Compilation compilation,
-// in ImmutableArray inputMethods,
-// CancellationToken cancel)
-// {
-// var models = new List();
-//
-// var methods = inputMethods
-// .Where(static x => x is not null)
-// .Distinct();
-//
-// var methodModels = methods
-// .Select(x => MethodDeclarationToMethodModel(compilation, x!))
-// .Where(static x => x is not null)
-// .Cast();
-//
-// var groups = methodModels
-// .GroupBy(static x => $"{x.Namespace}.{string.Join(".", x.Classes)}");
-//
-// foreach (var group in groups)
-// {
-// if (cancel.IsCancellationRequested)
-// return new Collection();
-//
-// if (group is null)
-// continue;
-//
-// var elems = group.ToList();
-// if (elems.Count is 0)
-// continue;
-//
-// var model = new FileModel(
-// methods: elems,
-// ns: elems[0].Namespace,
-// classHierarchy: elems![0].Classes
-// );
-//
-// models.Add(model);
-// }
-//
-//
-// return models;
-// }
-//
-// private static MethodModel? MethodDeclarationToMethodModel(Compilation comp, MethodDeclarationSyntax decl)
-// {
-// // SpinWait.SpinUntil(static () => Debugger.IsAttached);
-//
-// SemanticModel semanticModel;
-// try
-// {
-// semanticModel = comp.GetSemanticModel(decl.SyntaxTree);
-// }
-// catch
-// {
-// // for some reason this method can throw "Not part of this compilation" argument exception
-// return null;
-// }
-//
-// var methodModel = new MethodModel(
-// @params: decl.ParameterList.Parameters
-// .Where(p => p.Type is not null)
-// .Select(p =>
-// {
-// var prefix = p.Modifiers.Any(static x => x.IsKind(SyntaxKind.ParamsKeyword))
-// ? "params "
-// : string.Empty;
-//
-// var type = semanticModel
-// .GetTypeInfo(p.Type!)
-// .Type
-// ?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
-//
-//
-// var name = p.Identifier.Text;
-//
-// var suffix = string.Empty;
-// if (p.Default is not null)
-// {
-// if (p.Default.Value is LiteralExpressionSyntax)
-// {
-// suffix = " = " + p.Default.Value;
-// }
-// else if (p.Default.Value is MemberAccessExpressionSyntax maes)
-// {
-// var maesSemModel = comp.GetSemanticModel(maes.SyntaxTree);
-// var sym = maesSemModel.GetSymbolInfo(maes.Name);
-// if (sym.Symbol is null)
-// {
-// suffix = " = " + p.Default.Value;
-// }
-// else
-// {
-// suffix = " = " + sym.Symbol.ToDisplayString();
-// }
-// }
-// }
-//
-// return $"{prefix}{type} {name}{suffix}";
-// })
-// .ToList(),
-// methodName: decl.Identifier.Text,
-// returnType: decl.ReturnType.ToString(),
-// ns: GetNamespace(decl),
-// classes: GetClasses(decl)
-// );
-//
-// return methodModel;
-// }
-//
-// //https://github.com/andrewlock/NetEscapades.EnumGenerators/blob/main/src/NetEscapades.EnumGenerators/EnumGenerator.cs
-// static string? GetNamespace(MethodDeclarationSyntax declarationSyntax)
-// {
-// // determine the namespace the class is declared in, if any
-// string? nameSpace = null;
-// var parentOfInterest = declarationSyntax.Parent;
-// while (parentOfInterest is not null)
-// {
-// parentOfInterest = parentOfInterest.Parent;
-//
-// if (parentOfInterest is BaseNamespaceDeclarationSyntax ns)
-// {
-// nameSpace = ns.Name.ToString();
-// while (true)
-// {
-// if (ns.Parent is not NamespaceDeclarationSyntax parent)
-// {
-// break;
-// }
-//
-// ns = parent;
-// nameSpace = $"{ns.Name}.{nameSpace}";
-// }
-//
-// return nameSpace;
-// }
-//
-// }
-//
-// return nameSpace;
-// }
-//
-// static IReadOnlyCollection GetClasses(MethodDeclarationSyntax declarationSyntax)
-// {
-// // determine the namespace the class is declared in, if any
-// var classes = new LinkedList();
-// var parentOfInterest = declarationSyntax.Parent;
-// while (parentOfInterest is not null)
-// {
-// if (parentOfInterest is ClassDeclarationSyntax cds)
-// {
-// classes.AddFirst(cds.Identifier.ToString());
-// }
-//
-// parentOfInterest = parentOfInterest.Parent;
-// }
-//
-// Debug.WriteLine($"Method {declarationSyntax.Identifier.Text} has {classes.Count} classes");
-//
-// return classes;
-// }
-//
-// private static MethodDeclarationSyntax? Transform(GeneratorSyntaxContext ctx, CancellationToken cancel)
-// {
-// var methodDecl = ctx.Node as MethodDeclarationSyntax;
-// if (methodDecl is null)
-// return default;
-//
-// foreach (var attListSyntax in methodDecl.AttributeLists)
-// {
-// foreach (var attSyntax in attListSyntax.Attributes)
-// {
-// if (cancel.IsCancellationRequested)
-// return default;
-//
-// var symbol = ctx.SemanticModel.GetSymbolInfo(attSyntax).Symbol;
-// if (symbol is not IMethodSymbol attSymbol)
-// continue;
-//
-// if (attSymbol.ContainingType.ToDisplayString() == "NadekoBot.Common.CmdAttribute")
-// return methodDecl;
-// }
-// }
-//
-// return default;
-// }
-// }
\ No newline at end of file
diff --git a/src/NadekoBot.Generators/NadekoBot.Generators.csproj b/src/NadekoBot.Generators/NadekoBot.Generators.csproj
index 4ff08c5d9..de4842b04 100644
--- a/src/NadekoBot.Generators/NadekoBot.Generators.csproj
+++ b/src/NadekoBot.Generators/NadekoBot.Generators.csproj
@@ -5,12 +5,13 @@
latest
false
true
+ true
-
-
-
+
+
+
diff --git a/src/NadekoBot.Tests/NadekoBot.Tests.csproj b/src/NadekoBot.Tests/NadekoBot.Tests.csproj
index 328c1a6a8..874320c22 100644
--- a/src/NadekoBot.Tests/NadekoBot.Tests.csproj
+++ b/src/NadekoBot.Tests/NadekoBot.Tests.csproj
@@ -7,8 +7,8 @@
-
-
+
+
diff --git a/src/NadekoBot.VotesApi/NadekoBot.VotesApi.csproj b/src/NadekoBot.VotesApi/NadekoBot.VotesApi.csproj
index 59f8966dc..d9a3e5f68 100644
--- a/src/NadekoBot.VotesApi/NadekoBot.VotesApi.csproj
+++ b/src/NadekoBot.VotesApi/NadekoBot.VotesApi.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/src/NadekoBot/Common/Attributes/NadekoOptions.cs b/src/NadekoBot/Common/Attributes/NadekoOptions.cs
index a5c0db5b1..474e4c827 100644
--- a/src/NadekoBot/Common/Attributes/NadekoOptions.cs
+++ b/src/NadekoBot/Common/Attributes/NadekoOptions.cs
@@ -1,10 +1,7 @@
namespace NadekoBot.Common.Attributes;
[AttributeUsage(AttributeTargets.Method)]
-public sealed class NadekoOptionsAttribute : Attribute
+public sealed class NadekoOptionsAttribute : Attribute
+ where TOption: INadekoCommandOptions
{
- public Type OptionType { get; set; }
-
- public NadekoOptionsAttribute(Type t)
- => OptionType = t;
}
\ No newline at end of file
diff --git a/src/NadekoBot/Modules/Administration/Prune/PruneCommands.cs b/src/NadekoBot/Modules/Administration/Prune/PruneCommands.cs
index 9fa1f4cbb..25bf2e9b8 100644
--- a/src/NadekoBot/Modules/Administration/Prune/PruneCommands.cs
+++ b/src/NadekoBot/Modules/Administration/Prune/PruneCommands.cs
@@ -27,10 +27,10 @@ public partial class Administration
//deletes her own messages, no perm required
[Cmd]
[RequireContext(ContextType.Guild)]
- [NadekoOptions(typeof(PruneOptions))]
+ [NadekoOptions]
public async Task Prune(params string[] args)
{
- var (opts, _) = OptionsParser.ParseFrom(new PruneOptions(), args);
+ var (opts, _) = OptionsParser.ParseFrom(new PruneOptions(), args);
var user = await ctx.Guild.GetCurrentUserAsync();
@@ -47,7 +47,7 @@ public partial class Administration
[RequireContext(ContextType.Guild)]
[UserPerm(ChannelPerm.ManageMessages)]
[BotPerm(ChannelPerm.ManageMessages)]
- [NadekoOptions(typeof(PruneOptions))]
+ [NadekoOptions]
[Priority(1)]
public async Task Prune(int count, params string[] args)
{
@@ -70,7 +70,7 @@ public partial class Administration
[RequireContext(ContextType.Guild)]
[UserPerm(ChannelPerm.ManageMessages)]
[BotPerm(ChannelPerm.ManageMessages)]
- [NadekoOptions(typeof(PruneOptions))]
+ [NadekoOptions]
[Priority(0)]
public Task Prune(IGuildUser user, int count = 100, params string[] args)
=> Prune(user.Id, count, args);
@@ -80,7 +80,7 @@ public partial class Administration
[RequireContext(ContextType.Guild)]
[UserPerm(ChannelPerm.ManageMessages)]
[BotPerm(ChannelPerm.ManageMessages)]
- [NadekoOptions(typeof(PruneOptions))]
+ [NadekoOptions]
[Priority(0)]
public async Task Prune(ulong userId, int count = 100, params string[] args)
{
diff --git a/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommands.cs b/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommands.cs
index 1ddba679c..cec700537 100644
--- a/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommands.cs
+++ b/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommands.cs
@@ -97,7 +97,7 @@ public partial class Administration
{
var logSetting = _service.GetGuildLogSettings(ctx.Guild.Id);
var str = string.Join("\n",
- Enum.GetNames(typeof(LogType))
+ Enum.GetNames()
.Select(x =>
{
var val = logSetting is null ? null : GetLogProperty(logSetting, Enum.Parse(x));
diff --git a/src/NadekoBot/Modules/Administration/UserPunish/UserPunishCommands.cs b/src/NadekoBot/Modules/Administration/UserPunish/UserPunishCommands.cs
index c83eede44..80e04d04b 100644
--- a/src/NadekoBot/Modules/Administration/UserPunish/UserPunishCommands.cs
+++ b/src/NadekoBot/Modules/Administration/UserPunish/UserPunishCommands.cs
@@ -114,7 +114,7 @@ public partial class Administration
[Cmd]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
- [NadekoOptions(typeof(WarnExpireOptions))]
+ [NadekoOptions]
[Priority(1)]
public async Task WarnExpire()
{
@@ -129,7 +129,7 @@ public partial class Administration
[Cmd]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
- [NadekoOptions(typeof(WarnExpireOptions))]
+ [NadekoOptions]
[Priority(2)]
public async Task WarnExpire(int days, params string[] args)
{
diff --git a/src/NadekoBot/Modules/Gambling/AnimalRacing/AnimalRacingCommands.cs b/src/NadekoBot/Modules/Gambling/AnimalRacing/AnimalRacingCommands.cs
index f2a71075a..28f5e929e 100644
--- a/src/NadekoBot/Modules/Gambling/AnimalRacing/AnimalRacingCommands.cs
+++ b/src/NadekoBot/Modules/Gambling/AnimalRacing/AnimalRacingCommands.cs
@@ -34,7 +34,7 @@ public partial class Gambling
[Cmd]
[RequireContext(ContextType.Guild)]
- [NadekoOptionsAttribute(typeof(RaceOptions))]
+ [NadekoOptions]
public Task Race(params string[] args)
{
var (options, _) = OptionsParser.ParseFrom(new RaceOptions(), args);
diff --git a/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs b/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs
index c1e9aeea2..6f70eecbe 100644
--- a/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs
+++ b/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs
@@ -44,7 +44,7 @@ public partial class Gambling
[Cmd]
[RequireContext(ContextType.Guild)]
- [NadekoOptionsAttribute(typeof(Connect4Game.Options))]
+ [NadekoOptions]
public async Task Connect4(params string[] args)
{
var (options, _) = OptionsParser.ParseFrom(new Connect4Game.Options(), args);
diff --git a/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsCommands.cs b/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsCommands.cs
index d7b7496a8..f05b247ce 100644
--- a/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsCommands.cs
+++ b/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsCommands.cs
@@ -18,7 +18,7 @@ public partial class Gambling
[Cmd]
[RequireContext(ContextType.Guild)]
- [NadekoOptionsAttribute(typeof(EventOptions))]
+ [NadekoOptions]
[OwnerOnly]
public async Task EventStart(CurrencyEvent.Type ev, params string[] options)
{
diff --git a/src/NadekoBot/Modules/Gambling/Gambling.cs b/src/NadekoBot/Modules/Gambling/Gambling.cs
index b1b15acd1..c64cc4411 100644
--- a/src/NadekoBot/Modules/Gambling/Gambling.cs
+++ b/src/NadekoBot/Modules/Gambling/Gambling.cs
@@ -710,13 +710,13 @@ public partial class Gambling : GamblingModule
}
[Cmd]
- [NadekoOptions(typeof(LbOpts))]
+ [NadekoOptions]
[Priority(0)]
public Task Leaderboard(params string[] args)
=> Leaderboard(1, args);
[Cmd]
- [NadekoOptions(typeof(LbOpts))]
+ [NadekoOptions]
[Priority(1)]
public async Task Leaderboard(int page = 1, params string[] args)
{
diff --git a/src/NadekoBot/Modules/Games/Acrophobia/AcropobiaCommands.cs b/src/NadekoBot/Modules/Games/Acrophobia/AcropobiaCommands.cs
index 6c4e083b5..e8a246fa4 100644
--- a/src/NadekoBot/Modules/Games/Acrophobia/AcropobiaCommands.cs
+++ b/src/NadekoBot/Modules/Games/Acrophobia/AcropobiaCommands.cs
@@ -17,7 +17,7 @@ public partial class Games
[Cmd]
[RequireContext(ContextType.Guild)]
- [NadekoOptions(typeof(AcrophobiaGame.Options))]
+ [NadekoOptions]
public async Task Acrophobia(params string[] args)
{
var (options, _) = OptionsParser.ParseFrom(new AcrophobiaGame.Options(), args);
diff --git a/src/NadekoBot/Modules/Games/SpeedTyping/SpeedTypingCommands.cs b/src/NadekoBot/Modules/Games/SpeedTyping/SpeedTypingCommands.cs
index 9b6dff52f..420768e7d 100644
--- a/src/NadekoBot/Modules/Games/SpeedTyping/SpeedTypingCommands.cs
+++ b/src/NadekoBot/Modules/Games/SpeedTyping/SpeedTypingCommands.cs
@@ -20,7 +20,7 @@ public partial class Games
[Cmd]
[RequireContext(ContextType.Guild)]
- [NadekoOptionsAttribute(typeof(TypingGame.Options))]
+ [NadekoOptions]
public async Task TypeStart(params string[] args)
{
var (options, _) = OptionsParser.ParseFrom(new TypingGame.Options(), args);
diff --git a/src/NadekoBot/Modules/Games/TicTacToe/TicTacToeCommands.cs b/src/NadekoBot/Modules/Games/TicTacToe/TicTacToeCommands.cs
index b01282a6f..e1885bc81 100644
--- a/src/NadekoBot/Modules/Games/TicTacToe/TicTacToeCommands.cs
+++ b/src/NadekoBot/Modules/Games/TicTacToe/TicTacToeCommands.cs
@@ -17,7 +17,7 @@ public partial class Games
[Cmd]
[RequireContext(ContextType.Guild)]
- [NadekoOptions(typeof(TicTacToe.Options))]
+ [NadekoOptions]
public async Task TicTacToe(params string[] args)
{
var (options, _) = OptionsParser.ParseFrom(new TicTacToe.Options(), args);
diff --git a/src/NadekoBot/Modules/Games/Trivia/Games.cs b/src/NadekoBot/Modules/Games/Trivia/Games.cs
index 9dbdb87ee..a9d4d8b9d 100644
--- a/src/NadekoBot/Modules/Games/Trivia/Games.cs
+++ b/src/NadekoBot/Modules/Games/Trivia/Games.cs
@@ -30,7 +30,7 @@ public partial class Games
[Cmd]
[RequireContext(ContextType.Guild)]
[Priority(0)]
- [NadekoOptions(typeof(TriviaOptions))]
+ [NadekoOptions]
public async Task Trivia(params string[] args)
{
var (opts, _) = OptionsParser.ParseFrom(new TriviaOptions(), args);
diff --git a/src/NadekoBot/Modules/Help/Help.cs b/src/NadekoBot/Modules/Help/Help.cs
index e45f849b9..ab0da1fb9 100644
--- a/src/NadekoBot/Modules/Help/Help.cs
+++ b/src/NadekoBot/Modules/Help/Help.cs
@@ -88,7 +88,7 @@ public partial class Help : NadekoModule
embed = embed.WithOkColor().WithDescription(GetText(strs.module_page_empty));
return embed;
}
-
+
localModules.OrderBy(module => module.Name)
.ToList()
.ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}",
@@ -111,10 +111,11 @@ public partial class Help : NadekoModule
if (key.Key == strs.module_description_missing.Key)
{
var desc = _medusae
- .GetLoadedMedusae(Culture)
- .FirstOrDefault(m => m.Sneks
- .Any(x => x.Name.Equals(moduleName, StringComparison.InvariantCultureIgnoreCase)))
- ?.Description;
+ .GetLoadedMedusae(Culture)
+ .FirstOrDefault(m => m.Sneks
+ .Any(x => x.Name.Equals(moduleName,
+ StringComparison.InvariantCultureIgnoreCase)))
+ ?.Description;
if (desc is not null)
return desc;
@@ -122,7 +123,7 @@ public partial class Help : NadekoModule
return GetText(key);
}
-
+
private LocStr GetModuleLocStr(string moduleName)
{
switch (moduleName.ToLowerInvariant())
@@ -189,7 +190,7 @@ public partial class Help : NadekoModule
}
[Cmd]
- [NadekoOptions(typeof(CommandsOptions))]
+ [NadekoOptions]
public async Task Commands(string module = null, params string[] args)
{
module = module?.Trim().ToUpperInvariant();
@@ -374,9 +375,8 @@ public partial class Help : NadekoModule
.Select(com =>
{
List optHelpStr = null;
- var opt = ((NadekoOptionsAttribute)com.Attributes.FirstOrDefault(static x
- => x is NadekoOptionsAttribute))
- ?.OptionType;
+
+ var opt = HelpService.GetNadekoOptionType(com.Attributes);
if (opt is not null)
optHelpStr = HelpService.GetCommandOptionHelpList(opt);
@@ -512,7 +512,7 @@ public partial class Help : NadekoModule
customId: "donate:selfhosting",
label: "Selfhosting"),
SelfhostAction));
-
+
var eb = _eb.Create(ctx)
.WithOkColor()
.WithTitle("Thank you for considering to donate to the NadekoBot project!");
diff --git a/src/NadekoBot/Modules/Help/HelpService.cs b/src/NadekoBot/Modules/Help/HelpService.cs
index 0a8d8efaa..6c614ad79 100644
--- a/src/NadekoBot/Modules/Help/HelpService.cs
+++ b/src/NadekoBot/Modules/Help/HelpService.cs
@@ -86,7 +86,7 @@ public class HelpService : IExecNoCommand, INService
.WithFooter(GetText(strs.module(com.Module.GetTopLevelModule().Name), guild))
.WithOkColor();
- var opt = ((NadekoOptionsAttribute)com.Attributes.FirstOrDefault(x => x is NadekoOptionsAttribute))?.OptionType;
+ var opt = GetNadekoOptionType(com.Attributes);
if (opt is not null)
{
var hs = GetCommandOptionHelp(opt);
@@ -97,6 +97,14 @@ public class HelpService : IExecNoCommand, INService
return em;
}
+ public static Type GetNadekoOptionType(IEnumerable attributes)
+ => attributes
+ .Select(a => a.GetType())
+ .Where(a => a.IsGenericType
+ && a.GetGenericTypeDefinition() == typeof(NadekoOptionsAttribute<>))
+ .Select(a => a.GenericTypeArguments[0])
+ .FirstOrDefault();
+
public static string GetCommandOptionHelp(Type opt)
{
var strs = GetCommandOptionHelpList(opt);
diff --git a/src/NadekoBot/Modules/Searches/PlaceCommands.cs b/src/NadekoBot/Modules/Searches/PlaceCommands.cs
index 363f7b851..6cbd79409 100644
--- a/src/NadekoBot/Modules/Searches/PlaceCommands.cs
+++ b/src/NadekoBot/Modules/Searches/PlaceCommands.cs
@@ -18,7 +18,7 @@ public partial class Searches
Xoart //http://xoart.link
}
- private static readonly string _typesStr = string.Join(", ", Enum.GetNames(typeof(PlaceType)));
+ private static readonly string _typesStr = string.Join(", ", Enum.GetNames());
[Cmd]
public async Task Placelist()
diff --git a/src/NadekoBot/Modules/Utility/Info/InviteCommands.cs b/src/NadekoBot/Modules/Utility/Info/InviteCommands.cs
index d9633019b..38ab1c708 100644
--- a/src/NadekoBot/Modules/Utility/Info/InviteCommands.cs
+++ b/src/NadekoBot/Modules/Utility/Info/InviteCommands.cs
@@ -12,7 +12,7 @@ public partial class Utility
[RequireContext(ContextType.Guild)]
[BotPerm(ChannelPerm.CreateInstantInvite)]
[UserPerm(ChannelPerm.CreateInstantInvite)]
- [NadekoOptions(typeof(InviteService.Options))]
+ [NadekoOptions]
public async Task InviteCreate(params string[] args)
{
var (opts, success) = OptionsParser.ParseFrom(new InviteService.Options(), args);
diff --git a/src/NadekoBot/Modules/Xp/Xp.cs b/src/NadekoBot/Modules/Xp/Xp.cs
index bcb3b6fe3..7ff05075b 100644
--- a/src/NadekoBot/Modules/Xp/Xp.cs
+++ b/src/NadekoBot/Modules/Xp/Xp.cs
@@ -155,14 +155,14 @@ public partial class Xp : NadekoModule
}
[Cmd]
- [NadekoOptions(typeof(LbOpts))]
+ [NadekoOptions]
[Priority(0)]
[RequireContext(ContextType.Guild)]
public Task XpLeaderboard(params string[] args)
=> XpLeaderboard(1, args);
[Cmd]
- [NadekoOptions(typeof(LbOpts))]
+ [NadekoOptions]
[Priority(1)]
[RequireContext(ContextType.Guild)]
public async Task XpLeaderboard(int page = 1, params string[] args)
diff --git a/src/NadekoBot/NadekoBot.csproj b/src/NadekoBot/NadekoBot.csproj
index cff093387..424303998 100644
--- a/src/NadekoBot/NadekoBot.csproj
+++ b/src/NadekoBot/NadekoBot.csproj
@@ -17,71 +17,71 @@
-
+
all
True
-
+
-
+
-
+
-
-
-
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
all
True
-
+
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
-
-
+
+
+
@@ -92,7 +92,7 @@
-
+
diff --git a/src/ayu/Ayu.Discord.Voice/Ayu.Discord.Voice.csproj b/src/ayu/Ayu.Discord.Voice/Ayu.Discord.Voice.csproj
index e10fcc782..b46dcbdcb 100644
--- a/src/ayu/Ayu.Discord.Voice/Ayu.Discord.Voice.csproj
+++ b/src/ayu/Ayu.Discord.Voice/Ayu.Discord.Voice.csproj
@@ -7,8 +7,8 @@
1.0.2
-
-
-
+
+
+
\ No newline at end of file