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