Refactored typereaders to use DI instead of getting services manually

This commit is contained in:
Kwoth
2021-07-03 23:16:53 +02:00
parent 3cc34bfdc3
commit 4c0c3c9228
11 changed files with 86 additions and 120 deletions

View File

@@ -198,7 +198,7 @@ namespace NadekoBot
var toReturn = new List<object>();
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);

View File

@@ -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<CommandInfo>
{
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<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input)
{
var cmds = services.GetRequiredService<CommandService>();
var cmdHandler = services.GetRequiredService<CommandHandler>();
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<CommandOrCrInfo>
{
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<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
public override async Task<TypeReaderResult> ReadAsync(ICommandContext context, string input)
{
input = input.ToUpperInvariant();
var crs = services.GetRequiredService<CustomReactionsService>();
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));

View File

@@ -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<GuildDateTime>
public sealed class GuildDateTimeTypeReader : NadekoTypeReader<GuildDateTime>
{
public GuildDateTimeTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
}
private readonly GuildTimezoneService _gts;
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
public GuildDateTimeTypeReader(GuildTimezoneService gts)
{
var gdt = Parse(services, context.Guild.Id, input);
_gts = gts;
}
public override Task<TypeReaderResult> 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<GuildTimezoneService>();
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;

View File

@@ -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<IGuild>
public sealed class GuildTypeReader : NadekoTypeReader<IGuild>
{
private readonly DiscordSocketClient _client;
public GuildTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
public GuildTypeReader(DiscordSocketClient client)
{
_client = client;
}
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider _)
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input)
{
input = input.Trim().ToUpperInvariant();
var guilds = _client.Guilds;

View File

@@ -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<kwum>
public sealed class KwumTypeReader : NadekoTypeReader<kwum>
{
public KwumTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
}
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input)
{
if (kwum.TryParse(input, out var val))
return Task.FromResult(TypeReaderResult.FromSuccess(val));

View File

@@ -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<ModuleInfo>
public sealed class ModuleTypeReader : NadekoTypeReader<ModuleInfo>
{
private readonly CommandService _cmds;
public ModuleTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
public ModuleTypeReader(CommandService cmds)
{
_cmds = cmds;
}
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider _)
public override Task<TypeReaderResult> 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<ModuleOrCrInfo>
public sealed class ModuleOrCrTypeReader : NadekoTypeReader<ModuleOrCrInfo>
{
private readonly CommandService _cmds;
public ModuleOrCrTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
public ModuleOrCrTypeReader(CommandService cmds)
{
_cmds = cmds;
}
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider _)
public override Task<TypeReaderResult> 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; }
}

View File

@@ -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<T> : TypeReader
{
private readonly DiscordSocketClient _client;
private readonly CommandService _cmds;
public abstract Task<TypeReaderResult> ReadAsync(ICommandContext ctx, string input);
private NadekoTypeReader() { }
protected NadekoTypeReader(DiscordSocketClient client, CommandService cmds)
{
_client = client;
_cmds = cmds;
}
public override Task<TypeReaderResult> ReadAsync(ICommandContext ctx, string input, IServiceProvider services)
=> ReadAsync(ctx, input);
}
}

View File

@@ -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
{
/// <summary>
/// Used instead of bool for more flexible keywords for true/false only in the permission module
/// </summary>
public class PermissionActionTypeReader : NadekoTypeReader<PermissionAction>
public sealed class PermissionActionTypeReader : NadekoTypeReader<PermissionAction>
{
public PermissionActionTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
}
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider _)
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input)
{
input = input.ToUpperInvariant();
switch (input)

View File

@@ -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<Color>
public sealed class Rgba32TypeReader : NadekoTypeReader<Color>
{
public Rgba32TypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
}
public override async Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
public override async Task<TypeReaderResult> ReadAsync(ICommandContext context, string input)
{
await Task.Yield();

View File

@@ -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<ShmartNumber>
// todo test max/half/all
public sealed class ShmartNumberTypeReader : NadekoTypeReader<ShmartNumber>
{
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<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
public override async Task<TypeReaderResult> 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(@"^((?<num>100|\d{1,2})%)$", RegexOptions.Compiled);
private static long Cur(IServiceProvider services, ICommandContext ctx)
private long Cur(ICommandContext ctx)
{
var db = services.GetRequiredService<DbService>();
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<GamblingConfigService>().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;

View File

@@ -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<StoopidTime>
public sealed class StoopidTimeTypeReader : NadekoTypeReader<StoopidTime>
{
public StoopidTimeTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
}
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input)
{
if (string.IsNullOrWhiteSpace(input))
return Task.FromResult(TypeReaderResult.FromError(CommandError.Unsuccessful, "Input is empty."));