Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4d85806
centralize the service provider
akiraveliara May 17, 2024
4f42a50
prepare the rest client for IOC
akiraveliara May 17, 2024
eaf6a5e
obsolete all the old events...
akiraveliara May 17, 2024
1b0e386
obsolete SocketErrored even more
akiraveliara May 18, 2024
6c22cd2
enables registering event handlers to the service collection
akiraveliara May 21, 2024
6fc8ed7
fix event-related build errors
akiraveliara May 21, 2024
1e62cd4
make DiscordApiClient IOC-constructible
akiraveliara May 21, 2024
5c8f2c4
death (migrate events (not dispatch yet) to the interim model)
akiraveliara May 24, 2024
b2ebdae
update DiscordClient.Dipshit.cs
akiraveliara May 26, 2024
905ce60
fix most trivial build errors
akiraveliara May 26, 2024
68675df
more progress towards usability
akiraveliara May 29, 2024
32035b6
DSharpPlus.dll should now work:tm:
akiraveliara May 29, 2024
5a3e002
build?
akiraveliara May 29, 2024
af572a6
miser, miser
akiraveliara May 29, 2024
06a7058
add public construction code
akiraveliara May 29, 2024
0fc1bbd
Merge branch 'master' into aki/discordclient-ioc
akiraveliara May 30, 2024
7284840
update docs
akiraveliara May 30, 2024
edd2984
convenience
akiraveliara May 30, 2024
ec97bdc
details
akiraveliara May 31, 2024
bfef5fc
migration guide (partial, only as far as this PR is concerned)
akiraveliara May 31, 2024
8948ab0
build
akiraveliara May 31, 2024
a6de76c
merge conflicts
akiraveliara Jun 2, 2024
72efde2
switch to CreateDefault
akiraveliara Jun 2, 2024
989eab0
nit
akiraveliara Jun 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions DSharpPlus.Commands/CommandsConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
using System;

namespace DSharpPlus.Commands;

/// <summary>
/// The configuration copied to an instance of <see cref="CommandsExtension"/>.
/// </summary>
public sealed record CommandsConfiguration
{
/// <summary>
/// The service provider to use for dependency injection.
/// </summary>
public required IServiceProvider ServiceProvider { get; set; }

/// <summary>
/// The guild id to use for debugging. Leave as 0 to disable.
/// </summary>
Expand Down
49 changes: 33 additions & 16 deletions DSharpPlus.Commands/CommandsExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

using DSharpPlus.AsyncEvents;
using DSharpPlus.Commands.ContextChecks;
using DSharpPlus.Commands.ContextChecks.ParameterChecks;
Expand All @@ -23,16 +24,18 @@
using DSharpPlus.Commands.Trees.Metadata;
using DSharpPlus.Entities;
using DSharpPlus.Exceptions;

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;

using CheckFunc = System.Func
<
object,
DSharpPlus.Commands.ContextChecks.ContextCheckAttribute,
DSharpPlus.Commands.CommandContext,
System.Threading.Tasks.ValueTask<string?>
>;

using ParameterCheckFunc = System.Func
<
object,
Expand All @@ -49,8 +52,8 @@ namespace DSharpPlus.Commands;
/// </summary>
public sealed class CommandsExtension : BaseExtension
{
/// <inheritdoc cref="CommandsConfiguration.ServiceProvider"/>
public IServiceProvider ServiceProvider { get; init; }
/// <inheritdoc cref="DiscordClient.ServiceProvider"/>
public IServiceProvider ServiceProvider { get; private set; }

/// <inheritdoc cref="CommandsConfiguration.DebugGuildId"/>
public ulong DebugGuildId { get; init; }
Expand Down Expand Up @@ -84,19 +87,29 @@ public sealed class CommandsExtension : BaseExtension
/// <summary>
/// Executed everytime a command is finished executing.
/// </summary>
public event AsyncEventHandler<CommandsExtension, CommandExecutedEventArgs> CommandExecuted { add => this.commandExecuted.Register(value); remove => this.commandExecuted.Unregister(value); }
internal readonly AsyncEvent<CommandsExtension, CommandExecutedEventArgs> commandExecuted = new("COMMANDS_COMMAND_EXECUTED", EverythingWentWrongErrorHandler);
public event AsyncEventHandler<CommandsExtension, CommandExecutedEventArgs> CommandExecuted
{
add => this.commandExecuted.Register(value);
remove => this.commandExecuted.Unregister(value);
}

internal AsyncEvent<CommandsExtension, CommandExecutedEventArgs> commandExecuted;

/// <summary>
/// Executed everytime a command has errored.
/// </summary>
public event AsyncEventHandler<CommandsExtension, CommandErroredEventArgs> CommandErrored { add => this.commandErrored.Register(value); remove => this.commandErrored.Unregister(value); }
internal readonly AsyncEvent<CommandsExtension, CommandErroredEventArgs> commandErrored = new("COMMANDS_COMMAND_ERRORED", EverythingWentWrongErrorHandler);
public event AsyncEventHandler<CommandsExtension, CommandErroredEventArgs> CommandErrored
{
add => this.commandErrored.Register(value);
remove => this.commandErrored.Unregister(value);
}

internal AsyncEvent<CommandsExtension, CommandErroredEventArgs> commandErrored;

/// <summary>
/// Used to log messages from this extension.
/// </summary>
private readonly ILogger<CommandsExtension> logger;
private ILogger<CommandsExtension> logger;

/// <summary>
/// Creates a new instance of the <see cref="CommandsExtension"/> class.
Expand All @@ -106,18 +119,10 @@ internal CommandsExtension(CommandsConfiguration configuration)
{
ArgumentNullException.ThrowIfNull(configuration);

this.ServiceProvider = configuration.ServiceProvider;
this.DebugGuildId = configuration.DebugGuildId;
this.UseDefaultCommandErrorHandler = configuration.UseDefaultCommandErrorHandler;
this.RegisterDefaultCommandProcessors = configuration.RegisterDefaultCommandProcessors;
this.CommandExecutor = configuration.CommandExecutor;
if (this.UseDefaultCommandErrorHandler)
{
this.CommandErrored += DefaultCommandErrorHandlerAsync;
}

// Attempt to get the user defined logging, otherwise setup a null logger since the D#+ Default Logger is internal.
this.logger = this.ServiceProvider.GetService<ILogger<CommandsExtension>>() ?? NullLogger<CommandsExtension>.Instance;
}

/// <summary>
Expand All @@ -136,8 +141,20 @@ protected override void Setup(DiscordClient client)
}

this.Client = client;
this.ServiceProvider = client.ServiceProvider;
this.Client.SessionCreated += async (_, _) => await RefreshAsync();

this.logger = client.ServiceProvider.GetService<ILogger<CommandsExtension>>();

DefaultClientErrorHandler errorHandler = new(client.Logger);
this.commandErrored = new(errorHandler);
this.commandExecuted = new(errorHandler);

if (this.UseDefaultCommandErrorHandler)
{
this.CommandErrored += DefaultCommandErrorHandlerAsync;
}

AddCheck<DirectMessageUsageCheck>();
AddCheck<RequireApplicationOwnerCheck>();
AddCheck<RequireGuildCheck>();
Expand Down
4 changes: 2 additions & 2 deletions DSharpPlus.Commands/Converters/BooleanConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ public class BooleanConverter : ISlashArgumentConverter<bool>, ITextArgumentConv
public bool RequiresText => true;

/// <inheritdoc/>
public Task<Optional<bool>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs) => Task.FromResult(context.Argument.ToLowerInvariant() switch
public Task<Optional<bool>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs) => Task.FromResult(context.Argument.ToLowerInvariant() switch
{
"true" or "yes" or "y" or "1" or "on" or "enable" or "enabled" or "t" => Optional.FromValue(true),
"false" or "no" or "n" or "0" or "off" or "disable" or "disabled" or "f" => Optional.FromValue(false),
_ => Optional.FromNoValue<bool>()
});

public Task<Optional<bool>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs)
public Task<Optional<bool>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs)
{
return bool.TryParse(context.Argument.RawValue, out bool result)
? Task.FromResult(Optional.FromValue(result))
Expand Down
4 changes: 2 additions & 2 deletions DSharpPlus.Commands/Converters/ByteConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ public class ByteConverter : ISlashArgumentConverter<byte>, ITextArgumentConvert
public string ReadableName => "Positive Tiny Integer";
public bool RequiresText => true;

public Task<Optional<byte>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs) => byte.TryParse(context.Argument, CultureInfo.InvariantCulture, out byte result)
public Task<Optional<byte>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs) => byte.TryParse(context.Argument, CultureInfo.InvariantCulture, out byte result)
? Task.FromResult(Optional.FromValue(result))
: Task.FromResult(Optional.FromNoValue<byte>());

public Task<Optional<byte>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => byte.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out byte result)
public Task<Optional<byte>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => byte.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out byte result)
? Task.FromResult(Optional.FromValue(result))
: Task.FromResult(Optional.FromNoValue<byte>());
}
4 changes: 2 additions & 2 deletions DSharpPlus.Commands/Converters/DateTimeOffsetConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ public class DateTimeOffsetConverter : ISlashArgumentConverter<DateTimeOffset>,
public string ReadableName => "Date and Time";
public bool RequiresText => true;

public Task<Optional<DateTimeOffset>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs) => DateTimeOffset.TryParse(context.Argument, CultureInfo.InvariantCulture, out DateTimeOffset result)
public Task<Optional<DateTimeOffset>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs) => DateTimeOffset.TryParse(context.Argument, CultureInfo.InvariantCulture, out DateTimeOffset result)
? Task.FromResult(Optional.FromValue(result))
: Task.FromResult(Optional.FromNoValue<DateTimeOffset>());

public Task<Optional<DateTimeOffset>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => DateTimeOffset.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out DateTimeOffset result)
public Task<Optional<DateTimeOffset>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => DateTimeOffset.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out DateTimeOffset result)
? Task.FromResult(Optional.FromValue(result))
: Task.FromResult(Optional.FromNoValue<DateTimeOffset>());
}
4 changes: 2 additions & 2 deletions DSharpPlus.Commands/Converters/DiscordAttachmentConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class AttachmentConverter : ISlashArgumentConverter<DiscordAttachment>, I
public string ReadableName => "Discord File";
public bool RequiresText => false;

public Task<Optional<DiscordAttachment>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs)
public Task<Optional<DiscordAttachment>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs)
{
DiscordMessage message = eventArgs.Message;
int currentAttachmentArgumentIndex = context.Command.Parameters.Where(argument => argument.Type == typeof(DiscordAttachment)).IndexOf(context.Parameter);
Expand All @@ -37,7 +37,7 @@ public Task<Optional<DiscordAttachment>> ConvertAsync(TextConverterContext conte
: Task.FromResult(Optional.FromValue(message.Attachments[currentAttachmentArgumentIndex]));
}

public Task<Optional<DiscordAttachment>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs)
public Task<Optional<DiscordAttachment>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs)
{
int currentAttachmentArgumentIndex = context.Command.Parameters.Where(argument => argument.Type == typeof(DiscordAttachment)).IndexOf(context.Parameter);
if (eventArgs.Interaction.Data.Resolved is null)
Expand Down
4 changes: 2 additions & 2 deletions DSharpPlus.Commands/Converters/DiscordChannelConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public partial class DiscordChannelConverter : ISlashArgumentConverter<DiscordCh
public string ReadableName => "Discord Channel";
public bool RequiresText => true;

public Task<Optional<DiscordChannel>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs)
public Task<Optional<DiscordChannel>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs)
{
// Attempt to parse the channel id
if (!ulong.TryParse(context.Argument, CultureInfo.InvariantCulture, out ulong channelId))
Expand Down Expand Up @@ -52,7 +52,7 @@ public Task<Optional<DiscordChannel>> ConvertAsync(TextConverterContext context,
return Task.FromResult(Optional.FromNoValue<DiscordChannel>());
}

public Task<Optional<DiscordChannel>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => context.Interaction.Data.Resolved is null
public Task<Optional<DiscordChannel>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => context.Interaction.Data.Resolved is null
|| !ulong.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out ulong channelId)
|| !context.Interaction.Data.Resolved.Channels.TryGetValue(channelId, out DiscordChannel? channel)
? Task.FromResult(Optional.FromNoValue<DiscordChannel>())
Expand Down
4 changes: 2 additions & 2 deletions DSharpPlus.Commands/Converters/DiscordEmojiConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public class DiscordEmojiConverter : ISlashArgumentConverter<DiscordEmoji>, ITex
public string ReadableName => "Discord Emoji";
public bool RequiresText => true;

public Task<Optional<DiscordEmoji>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs) => ConvertAsync(context, context.Argument);
public Task<Optional<DiscordEmoji>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => ConvertAsync(context, context.Argument.RawValue);
public Task<Optional<DiscordEmoji>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs) => ConvertAsync(context, context.Argument);
public Task<Optional<DiscordEmoji>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => ConvertAsync(context, context.Argument.RawValue);
public static Task<Optional<DiscordEmoji>> ConvertAsync(ConverterContext context, string? value) => !string.IsNullOrWhiteSpace(value)
&& (DiscordEmoji.TryFromUnicode(context.Client, value, out DiscordEmoji? emoji) || DiscordEmoji.TryFromName(context.Client, value, out emoji))
? Task.FromResult(Optional.FromValue(emoji))
Expand Down
4 changes: 2 additions & 2 deletions DSharpPlus.Commands/Converters/DiscordMemberConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public partial class DiscordMemberConverter : ISlashArgumentConverter<DiscordMem

public DiscordMemberConverter(ILogger<DiscordMemberConverter>? logger = null) => this.logger = logger ?? NullLogger<DiscordMemberConverter>.Instance;

public async Task<Optional<DiscordMember>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs)
public async Task<Optional<DiscordMember>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs)
{
if (context.Guild is null)
{
Expand Down Expand Up @@ -55,7 +55,7 @@ public async Task<Optional<DiscordMember>> ConvertAsync(TextConverterContext con
}
}

public Task<Optional<DiscordMember>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => context.Interaction.Data.Resolved is null
public Task<Optional<DiscordMember>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => context.Interaction.Data.Resolved is null
|| !ulong.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out ulong memberId)
|| !context.Interaction.Data.Resolved.Members.TryGetValue(memberId, out DiscordMember? member)
? Task.FromResult(Optional.FromNoValue<DiscordMember>())
Expand Down
4 changes: 2 additions & 2 deletions DSharpPlus.Commands/Converters/DiscordMessageConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ public partial class DiscordMessageConverter : ISlashArgumentConverter<DiscordMe
public string ReadableName => "Discord Message Link";
public bool RequiresText => true;

public Task<Optional<DiscordMessage>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs) => ConvertAsync(context, context.Argument);
public Task<Optional<DiscordMessage>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => ConvertAsync(context, context.Argument.RawValue);
public Task<Optional<DiscordMessage>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs) => ConvertAsync(context, context.Argument);
public Task<Optional<DiscordMessage>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => ConvertAsync(context, context.Argument.RawValue);

public static async Task<Optional<DiscordMessage>> ConvertAsync(ConverterContext context, string? value)
{
Expand Down
4 changes: 2 additions & 2 deletions DSharpPlus.Commands/Converters/DiscordRoleConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public partial class DiscordRoleConverter : ISlashArgumentConverter<DiscordRole>
public string ReadableName => "Discord Role";
public bool RequiresText => true;

public Task<Optional<DiscordRole>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs)
public Task<Optional<DiscordRole>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs)
{
if (context.Guild is null)
{
Expand All @@ -43,7 +43,7 @@ public Task<Optional<DiscordRole>> ConvertAsync(TextConverterContext context, Me
: Task.FromResult(Optional.FromNoValue<DiscordRole>());
}

public Task<Optional<DiscordRole>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => context.Interaction.Data.Resolved is null
public Task<Optional<DiscordRole>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => context.Interaction.Data.Resolved is null
|| !ulong.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out ulong roleId)
|| !context.Interaction.Data.Resolved.Roles.TryGetValue(roleId, out DiscordRole? role)
? Task.FromResult(Optional.FromNoValue<DiscordRole>())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public DiscordSnowflakeObjectConverter(ILogger<DiscordMemberConverter>? discordM
this.discordRoleSlashArgumentConverter = new DiscordRoleConverter();
}

public async Task<Optional<SnowflakeObject>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs)
public async Task<Optional<SnowflakeObject>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs)
{
//Checks through existing converters
if (context.Interaction.Data.Resolved?.Roles is not null && await this.discordRoleSlashArgumentConverter.ConvertAsync(context, eventArgs) is Optional<DiscordRole> role && role.HasValue)
Expand All @@ -45,7 +45,7 @@ public async Task<Optional<SnowflakeObject>> ConvertAsync(InteractionConverterCo
}

// Duplicated logic for overload resolving
public async Task<Optional<SnowflakeObject>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs)
public async Task<Optional<SnowflakeObject>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs)
{
//Checks through existing converters
if (context.Guild?.Roles is not null && await this.discordRoleSlashArgumentConverter.ConvertAsync(context, eventArgs) is Optional<DiscordRole> role && role.HasValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public partial class DiscordThreadChannelConverter : ISlashArgumentConverter<Dis
public string ReadableName => "Discord Thread";
public bool RequiresText => true;

public Task<Optional<DiscordThreadChannel>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs)
public Task<Optional<DiscordThreadChannel>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs)
{
if (context.Guild is null)
{
Expand All @@ -43,7 +43,7 @@ public Task<Optional<DiscordThreadChannel>> ConvertAsync(TextConverterContext co
: Task.FromResult(Optional.FromNoValue<DiscordThreadChannel>());
}

public Task<Optional<DiscordThreadChannel>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => context.Interaction.Data.Resolved is null
public Task<Optional<DiscordThreadChannel>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => context.Interaction.Data.Resolved is null
|| !ulong.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out ulong channelId)
|| !context.Interaction.Data.Resolved.Channels.TryGetValue(channelId, out DiscordChannel? channel)
? Task.FromResult(Optional.FromNoValue<DiscordThreadChannel>())
Expand Down
Loading