From 4c0c3c9228785e211d411b280dec596a55033f9b Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 3 Jul 2021 23:16:53 +0200 Subject: [PATCH] Refactored typereaders to use DI instead of getting services manually --- src/NadekoBot/Bot.cs | 2 +- .../TypeReaders/BotCommandTypeReader.cs | 39 ++++++++------- .../TypeReaders/GuildDateTimeTypeReader.cs | 27 +++++----- .../Common/TypeReaders/GuildTypeReader.cs | 10 ++-- .../Common/TypeReaders/KwumTypeReader.cs | 12 ++--- .../Common/TypeReaders/ModuleTypeReader.cs | 19 +++---- .../Common/TypeReaders/NadekoTypeReader.cs | 16 +++--- .../TypeReaders/PermissionActionTypeReader.cs | 13 ++--- .../Common/TypeReaders/Rgba32TypeReader.cs | 9 +--- .../TypeReaders/ShmartNumberTypeReader.cs | 50 +++++++++---------- .../TypeReaders/StoopidTimeTypeReader.cs | 9 +--- 11 files changed, 86 insertions(+), 120 deletions(-) diff --git a/src/NadekoBot/Bot.cs b/src/NadekoBot/Bot.cs index 1723e7621..f7a43e1c6 100644 --- a/src/NadekoBot/Bot.cs +++ b/src/NadekoBot/Bot.cs @@ -198,7 +198,7 @@ namespace NadekoBot var toReturn = new List(); foreach (var ft in filteredTypes) { - var x = (TypeReader)Activator.CreateInstance(ft, Client, _commandService); + var x = (TypeReader)ActivatorUtilities.CreateInstance(Services, ft); var baseType = ft.BaseType; var typeArgs = baseType.GetGenericArguments(); _commandService.AddTypeReader(typeArgs[0], x); diff --git a/src/NadekoBot/Common/TypeReaders/BotCommandTypeReader.cs b/src/NadekoBot/Common/TypeReaders/BotCommandTypeReader.cs index 8e5dde165..fc9e8e422 100644 --- a/src/NadekoBot/Common/TypeReaders/BotCommandTypeReader.cs +++ b/src/NadekoBot/Common/TypeReaders/BotCommandTypeReader.cs @@ -4,31 +4,30 @@ using System.Threading.Tasks; using Discord.Commands; using NadekoBot.Services; using NadekoBot.Modules.CustomReactions.Services; -using Discord.WebSocket; -using Microsoft.Extensions.DependencyInjection; namespace NadekoBot.Common.TypeReaders { public sealed class CommandTypeReader : NadekoTypeReader { - public CommandTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds) + private readonly CommandHandler _handler; + private readonly CommandService _cmds; + + public CommandTypeReader(CommandHandler handler, CommandService cmds) { + _handler = handler; + _cmds = cmds; } - public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services) + public override Task ReadAsync(ICommandContext context, string input) { - var cmds = services.GetRequiredService(); - var cmdHandler = services.GetRequiredService(); - input = input.ToUpperInvariant(); - var prefix = cmdHandler.GetPrefix(context.Guild); + var prefix = _handler.GetPrefix(context.Guild); if (!input.StartsWith(prefix.ToUpperInvariant(), StringComparison.InvariantCulture)) return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "No such command found.")); input = input.Substring(prefix.Length); - var cmd = cmds.Commands.FirstOrDefault(c => - c.Aliases.Select(a => a.ToUpperInvariant()).Contains(input)); + var cmd = _cmds.Commands.FirstOrDefault(c => c.Aliases.Select(a => a.ToUpperInvariant()).Contains(input)); if (cmd is null) return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "No such command found.")); @@ -38,26 +37,30 @@ namespace NadekoBot.Common.TypeReaders public sealed class CommandOrCrTypeReader : NadekoTypeReader { - private readonly DiscordSocketClient _client; private readonly CommandService _cmds; - public CommandOrCrTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds) + private readonly CustomReactionsService _crs; + private readonly CommandHandler _commandHandler; + + public CommandOrCrTypeReader( + CommandService cmds, + CustomReactionsService crs, + CommandHandler commandHandler) { - _client = client; _cmds = cmds; + _crs = crs; + _commandHandler = commandHandler; } - public override async Task ReadAsync(ICommandContext context, string input, IServiceProvider services) + public override async Task ReadAsync(ICommandContext context, string input) { input = input.ToUpperInvariant(); - var crs = services.GetRequiredService(); - - if (crs.ReactionExists(context.Guild?.Id, input)) + if (_crs.ReactionExists(context.Guild?.Id, input)) { return TypeReaderResult.FromSuccess(new CommandOrCrInfo(input, CommandOrCrInfo.Type.Custom)); } - var cmd = await new CommandTypeReader(_client, _cmds).ReadAsync(context, input, services).ConfigureAwait(false); + var cmd = await new CommandTypeReader(_commandHandler, _cmds).ReadAsync(context, input).ConfigureAwait(false); if (cmd.IsSuccess) { return TypeReaderResult.FromSuccess(new CommandOrCrInfo(((CommandInfo)cmd.Values.First().Value).Name, CommandOrCrInfo.Type.Normal)); diff --git a/src/NadekoBot/Common/TypeReaders/GuildDateTimeTypeReader.cs b/src/NadekoBot/Common/TypeReaders/GuildDateTimeTypeReader.cs index ba48221e8..ee71b031a 100644 --- a/src/NadekoBot/Common/TypeReaders/GuildDateTimeTypeReader.cs +++ b/src/NadekoBot/Common/TypeReaders/GuildDateTimeTypeReader.cs @@ -2,36 +2,35 @@ using System.Threading.Tasks; using Discord.Commands; using NadekoBot.Modules.Administration.Services; -using NadekoBot.Common.TypeReaders; -using Discord.WebSocket; -using Microsoft.Extensions.DependencyInjection; namespace NadekoBot.Common.TypeReaders { - public class GuildDateTimeTypeReader : NadekoTypeReader + public sealed class GuildDateTimeTypeReader : NadekoTypeReader { - public GuildDateTimeTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds) - { - } + private readonly GuildTimezoneService _gts; - public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services) + public GuildDateTimeTypeReader(GuildTimezoneService gts) { - var gdt = Parse(services, context.Guild.Id, input); + _gts = gts; + } + + public override Task ReadAsync(ICommandContext context, string input) + { + var gdt = Parse(context.Guild.Id, input); if(gdt is null) return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input string is in an incorrect format.")); return Task.FromResult(TypeReaderResult.FromSuccess(gdt)); } - public static GuildDateTime Parse(IServiceProvider services, ulong guildId, string input) + private GuildDateTime Parse(ulong guildId, string input) { - var gts = services.GetRequiredService(); if (!DateTime.TryParse(input, out var dt)) return null; - var tz = gts.GetTimeZoneOrUtc(guildId); + var tz = _gts.GetTimeZoneOrUtc(guildId); - return new GuildDateTime(tz, dt); + return new(tz, dt); } } @@ -42,8 +41,6 @@ namespace NadekoBot.Common.TypeReaders public DateTime InputTime { get; } public DateTime InputTimeUtc { get; } - private GuildDateTime() { } - public GuildDateTime(TimeZoneInfo guildTimezone, DateTime inputTime) { var now = DateTime.UtcNow; diff --git a/src/NadekoBot/Common/TypeReaders/GuildTypeReader.cs b/src/NadekoBot/Common/TypeReaders/GuildTypeReader.cs index 0ccd78d03..ab8434484 100644 --- a/src/NadekoBot/Common/TypeReaders/GuildTypeReader.cs +++ b/src/NadekoBot/Common/TypeReaders/GuildTypeReader.cs @@ -1,23 +1,21 @@ -using System; -using System.Linq; +using System.Linq; using System.Threading.Tasks; using Discord.Commands; using Discord.WebSocket; -using NadekoBot.Common.TypeReaders; using Discord; namespace NadekoBot.Common.TypeReaders { - public class GuildTypeReader : NadekoTypeReader + public sealed class GuildTypeReader : NadekoTypeReader { private readonly DiscordSocketClient _client; - public GuildTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds) + public GuildTypeReader(DiscordSocketClient client) { _client = client; } - public override Task ReadAsync(ICommandContext context, string input, IServiceProvider _) + public override Task ReadAsync(ICommandContext context, string input) { input = input.Trim().ToUpperInvariant(); var guilds = _client.Guilds; diff --git a/src/NadekoBot/Common/TypeReaders/KwumTypeReader.cs b/src/NadekoBot/Common/TypeReaders/KwumTypeReader.cs index b4bf425f8..4d0485035 100644 --- a/src/NadekoBot/Common/TypeReaders/KwumTypeReader.cs +++ b/src/NadekoBot/Common/TypeReaders/KwumTypeReader.cs @@ -1,17 +1,11 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; using Discord.Commands; -using Discord.WebSocket; namespace NadekoBot.Common.TypeReaders { - public class KwumTypeReader : NadekoTypeReader + public sealed class KwumTypeReader : NadekoTypeReader { - public KwumTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds) - { - } - - public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services) + public override Task ReadAsync(ICommandContext context, string input) { if (kwum.TryParse(input, out var val)) return Task.FromResult(TypeReaderResult.FromSuccess(val)); diff --git a/src/NadekoBot/Common/TypeReaders/ModuleTypeReader.cs b/src/NadekoBot/Common/TypeReaders/ModuleTypeReader.cs index 91c687ffe..99cd3f679 100644 --- a/src/NadekoBot/Common/TypeReaders/ModuleTypeReader.cs +++ b/src/NadekoBot/Common/TypeReaders/ModuleTypeReader.cs @@ -1,23 +1,20 @@ -using System; -using System.Linq; +using System.Linq; using System.Threading.Tasks; using Discord.Commands; using NadekoBot.Extensions; -using NadekoBot.Common.TypeReaders; -using Discord.WebSocket; namespace NadekoBot.Common.TypeReaders { - public class ModuleTypeReader : NadekoTypeReader + public sealed class ModuleTypeReader : NadekoTypeReader { private readonly CommandService _cmds; - public ModuleTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds) + public ModuleTypeReader(CommandService cmds) { _cmds = cmds; } - public override Task ReadAsync(ICommandContext context, string input, IServiceProvider _) + public override Task ReadAsync(ICommandContext context, string input) { input = input.ToUpperInvariant(); var module = _cmds.Modules.GroupBy(m => m.GetTopLevelModule()).FirstOrDefault(m => m.Key.Name.ToUpperInvariant() == input)?.Key; @@ -28,16 +25,16 @@ namespace NadekoBot.Common.TypeReaders } } - public class ModuleOrCrTypeReader : NadekoTypeReader + public sealed class ModuleOrCrTypeReader : NadekoTypeReader { private readonly CommandService _cmds; - public ModuleOrCrTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds) + public ModuleOrCrTypeReader(CommandService cmds) { _cmds = cmds; } - public override Task ReadAsync(ICommandContext context, string input, IServiceProvider _) + public override Task ReadAsync(ICommandContext context, string input) { input = input.ToUpperInvariant(); var module = _cmds.Modules.GroupBy(m => m.GetTopLevelModule()).FirstOrDefault(m => m.Key.Name.ToUpperInvariant() == input)?.Key; @@ -51,7 +48,7 @@ namespace NadekoBot.Common.TypeReaders } } - public class ModuleOrCrInfo + public sealed class ModuleOrCrInfo { public string Name { get; set; } } diff --git a/src/NadekoBot/Common/TypeReaders/NadekoTypeReader.cs b/src/NadekoBot/Common/TypeReaders/NadekoTypeReader.cs index 1c766ce4b..972d55450 100644 --- a/src/NadekoBot/Common/TypeReaders/NadekoTypeReader.cs +++ b/src/NadekoBot/Common/TypeReaders/NadekoTypeReader.cs @@ -1,18 +1,14 @@ -using Discord.Commands; -using Discord.WebSocket; +using System; +using System.Threading.Tasks; +using Discord.Commands; namespace NadekoBot.Common.TypeReaders { public abstract class NadekoTypeReader : TypeReader { - private readonly DiscordSocketClient _client; - private readonly CommandService _cmds; + public abstract Task ReadAsync(ICommandContext ctx, string input); - private NadekoTypeReader() { } - protected NadekoTypeReader(DiscordSocketClient client, CommandService cmds) - { - _client = client; - _cmds = cmds; - } + public override Task ReadAsync(ICommandContext ctx, string input, IServiceProvider services) + => ReadAsync(ctx, input); } } diff --git a/src/NadekoBot/Common/TypeReaders/PermissionActionTypeReader.cs b/src/NadekoBot/Common/TypeReaders/PermissionActionTypeReader.cs index e668fdfc5..6ab50b3a7 100644 --- a/src/NadekoBot/Common/TypeReaders/PermissionActionTypeReader.cs +++ b/src/NadekoBot/Common/TypeReaders/PermissionActionTypeReader.cs @@ -1,22 +1,15 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; using Discord.Commands; -using Discord.WebSocket; using NadekoBot.Common.TypeReaders.Models; -using NadekoBot.Common.TypeReaders; namespace NadekoBot.Common.TypeReaders { /// /// Used instead of bool for more flexible keywords for true/false only in the permission module /// - public class PermissionActionTypeReader : NadekoTypeReader + public sealed class PermissionActionTypeReader : NadekoTypeReader { - public PermissionActionTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds) - { - } - - public override Task ReadAsync(ICommandContext context, string input, IServiceProvider _) + public override Task ReadAsync(ICommandContext context, string input) { input = input.ToUpperInvariant(); switch (input) diff --git a/src/NadekoBot/Common/TypeReaders/Rgba32TypeReader.cs b/src/NadekoBot/Common/TypeReaders/Rgba32TypeReader.cs index 05aba330c..65b1bdd1f 100644 --- a/src/NadekoBot/Common/TypeReaders/Rgba32TypeReader.cs +++ b/src/NadekoBot/Common/TypeReaders/Rgba32TypeReader.cs @@ -1,18 +1,13 @@ using System; using System.Threading.Tasks; using Discord.Commands; -using Discord.WebSocket; using SixLabors.ImageSharp; namespace NadekoBot.Common.TypeReaders { - public class Rgba32TypeReader : NadekoTypeReader + public sealed class Rgba32TypeReader : NadekoTypeReader { - public Rgba32TypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds) - { - } - - public override async Task ReadAsync(ICommandContext context, string input, IServiceProvider services) + public override async Task ReadAsync(ICommandContext context, string input) { await Task.Yield(); diff --git a/src/NadekoBot/Common/TypeReaders/ShmartNumberTypeReader.cs b/src/NadekoBot/Common/TypeReaders/ShmartNumberTypeReader.cs index 13a320424..3a497f346 100644 --- a/src/NadekoBot/Common/TypeReaders/ShmartNumberTypeReader.cs +++ b/src/NadekoBot/Common/TypeReaders/ShmartNumberTypeReader.cs @@ -1,22 +1,26 @@ using Discord.Commands; -using Discord.WebSocket; -using Microsoft.Extensions.DependencyInjection; -using NadekoBot.Services; using System; using System.Text.RegularExpressions; using System.Threading.Tasks; using NadekoBot.Db; using NadekoBot.Modules.Gambling.Services; +using NadekoBot.Services; namespace NadekoBot.Common.TypeReaders { - public class ShmartNumberTypeReader : NadekoTypeReader + // todo test max/half/all + public sealed class ShmartNumberTypeReader : NadekoTypeReader { - public ShmartNumberTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds) + private readonly DbService _db; + private readonly GamblingConfigService _gambling; + + public ShmartNumberTypeReader(DbService db, GamblingConfigService gambling) { + _db = db; + _gambling = gambling; } - public override async Task ReadAsync(ICommandContext context, string input, IServiceProvider services) + public override async Task ReadAsync(ICommandContext context, string input) { await Task.Yield(); @@ -29,12 +33,12 @@ namespace NadekoBot.Common.TypeReaders //can't add m because it will conflict with max atm - if (TryHandlePercentage(services, context, i, out var num)) + if (TryHandlePercentage(context, i, out var num)) return TypeReaderResult.FromSuccess(new ShmartNumber(num, i)); try { var expr = new NCalc.Expression(i, NCalc.EvaluateOptions.IgnoreCase); - expr.EvaluateParameter += (str, ev) => EvaluateParam(str, ev, context, services); + expr.EvaluateParameter += (str, ev) => EvaluateParam(str, ev, context); var lon = (long)(decimal.Parse(expr.Evaluate().ToString())); return TypeReaderResult.FromSuccess(new ShmartNumber(lon, input)); } @@ -44,7 +48,7 @@ namespace NadekoBot.Common.TypeReaders } } - private static void EvaluateParam(string name, NCalc.ParameterArgs args, ICommandContext ctx, IServiceProvider svc) + private void EvaluateParam(string name, NCalc.ParameterArgs args, ICommandContext ctx) { switch (name.ToUpperInvariant()) { @@ -56,13 +60,13 @@ namespace NadekoBot.Common.TypeReaders break; case "ALL": case "ALLIN": - args.Result = Cur(svc, ctx); + args.Result = Cur(ctx); break; case "HALF": - args.Result = Cur(svc, ctx) / 2; + args.Result = Cur(ctx) / 2; break; case "MAX": - args.Result = Max(svc, ctx); + args.Result = Max(ctx); break; default: break; @@ -71,28 +75,22 @@ namespace NadekoBot.Common.TypeReaders private static readonly Regex percentRegex = new Regex(@"^((?100|\d{1,2})%)$", RegexOptions.Compiled); - private static long Cur(IServiceProvider services, ICommandContext ctx) + private long Cur(ICommandContext ctx) { - var db = services.GetRequiredService(); - long cur; - using (var uow = db.GetDbContext()) - { - cur = uow.DiscordUser.GetUserCurrency(ctx.User.Id); - uow.SaveChanges(); - } - return cur; + using var uow = _db.GetDbContext(); + return uow.DiscordUser.GetUserCurrency(ctx.User.Id); } - private static long Max(IServiceProvider services, ICommandContext ctx) + private long Max(ICommandContext ctx) { - var settings = services.GetRequiredService().Data; + var settings = _gambling.Data; var max = settings.MaxBet; return max == 0 - ? Cur(services, ctx) + ? Cur(ctx) : max; } - private static bool TryHandlePercentage(IServiceProvider services, ICommandContext ctx, string input, out long num) + private bool TryHandlePercentage(ICommandContext ctx, string input, out long num) { num = 0; var m = percentRegex.Match(input); @@ -101,7 +99,7 @@ namespace NadekoBot.Common.TypeReaders if (!long.TryParse(m.Groups["num"].ToString(), out var percent)) return false; - num = (long)(Cur(services, ctx) * (percent / 100.0f)); + num = (long)(Cur(ctx) * (percent / 100.0f)); return true; } return false; diff --git a/src/NadekoBot/Common/TypeReaders/StoopidTimeTypeReader.cs b/src/NadekoBot/Common/TypeReaders/StoopidTimeTypeReader.cs index 42626ab93..71eb5066b 100644 --- a/src/NadekoBot/Common/TypeReaders/StoopidTimeTypeReader.cs +++ b/src/NadekoBot/Common/TypeReaders/StoopidTimeTypeReader.cs @@ -1,18 +1,13 @@ using Discord.Commands; -using Discord.WebSocket; using NadekoBot.Common.TypeReaders.Models; using System; using System.Threading.Tasks; namespace NadekoBot.Common.TypeReaders { - public class StoopidTimeTypeReader : NadekoTypeReader + public sealed class StoopidTimeTypeReader : NadekoTypeReader { - public StoopidTimeTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds) - { - } - - public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services) + public override Task ReadAsync(ICommandContext context, string input) { if (string.IsNullOrWhiteSpace(input)) return Task.FromResult(TypeReaderResult.FromError(CommandError.Unsuccessful, "Input is empty."));