diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..d959cc9
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "BrackeysBot.API"]
+ path = BrackeysBot.API
+ url = https://github.com/BrackeysBot/BrackeysBot.API
diff --git a/BrackeysBot.API b/BrackeysBot.API
new file mode 160000
index 0000000..c3c06cf
--- /dev/null
+++ b/BrackeysBot.API
@@ -0,0 +1 @@
+Subproject commit c3c06cf5bc4fcf842d9b163541c4eeed6c4ab9a2
diff --git a/BrackeysBot.API/Assembly.cs b/BrackeysBot.API/Assembly.cs
deleted file mode 100644
index 9756300..0000000
--- a/BrackeysBot.API/Assembly.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-using System.Runtime.CompilerServices;
-
-[assembly: InternalsVisibleTo("BrackeysBot")]
diff --git a/BrackeysBot.API/Attributes/RequireMentionPrefix.cs b/BrackeysBot.API/Attributes/RequireMentionPrefix.cs
deleted file mode 100644
index 405aa01..0000000
--- a/BrackeysBot.API/Attributes/RequireMentionPrefix.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System.Threading.Tasks;
-using DisCatSharp.CommandsNext;
-using DisCatSharp.CommandsNext.Attributes;
-
-namespace BrackeysBot.API.Attributes;
-
-///
-/// Defines that usage of this command must require a bot mention prefix rather than the plugin's defined prefix.
-///
-public sealed class RequireMentionPrefix : CheckBaseAttribute
-{
- ///
- public override Task ExecuteCheckAsync(CommandContext ctx, bool help)
- {
- return Task.FromResult(MentionUtility.TryParseUser(ctx.Prefix[..^1], out ulong id) && id == ctx.Client.CurrentUser.Id);
- }
-}
diff --git a/BrackeysBot.API/BrackeysBot.API.csproj b/BrackeysBot.API/BrackeysBot.API.csproj
deleted file mode 100644
index 2e814f8..0000000
--- a/BrackeysBot.API/BrackeysBot.API.csproj
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
- net6.0
- enable
- 4.0.0.12
- 4.0.0-prerelease.12
- 4.0.0-prerelease.12
- 4.0.0-prerelease.12
- en-US
- true
- https://github.com/oliverbooth/BrackeysBot
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/BrackeysBot.API/Configuration/IConfiguration.cs b/BrackeysBot.API/Configuration/IConfiguration.cs
deleted file mode 100644
index 6078ce8..0000000
--- a/BrackeysBot.API/Configuration/IConfiguration.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.IO;
-
-namespace BrackeysBot.API.Configuration;
-
-///
-/// Represents a configuration object.
-///
-public interface IConfiguration
-{
- ///
- /// Gets the configuration file for this object.
- ///
- /// The configuration file.
- FileInfo ConfigurationFile { get; }
-
- ///
- /// Gets a configuration value and attempts to convert it to a specified type.
- ///
- /// The name of the property to retrieve.
- /// The default value to return if was not found.
- /// The value type.
- /// The configuration value, or if the property name was not found.
- /// Nested types are supported using a period (.) to specify child property names.
- T? Get(string propertyName, T? defaultValue = default);
-
- ///
- /// Sets a configuration value, creating the property if it does not exist.
- ///
- /// The name of the property to create or modify.
- /// The value to save.
- /// The value type.
- /// Nested types are supported using a period (.) to specify child property names.
- void Set(string propertyName, T? value);
-
- ///
- /// Saves the default configuration for this object, merging the current configuration (if any) with the default. Existing
- /// keys are not overwritten.
- ///
- void SaveDefault();
-}
diff --git a/BrackeysBot.API/Configuration/IConfigurationHolder.cs b/BrackeysBot.API/Configuration/IConfigurationHolder.cs
deleted file mode 100644
index 60e1e7b..0000000
--- a/BrackeysBot.API/Configuration/IConfigurationHolder.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace BrackeysBot.API.Configuration;
-
-///
-/// Represents an object which can hold mutable configuration.
-///
-public interface IConfigurationHolder
-{
- ///
- /// Gets the configuration for this object.
- ///
- IConfiguration Configuration { get; }
-}
diff --git a/BrackeysBot.API/Exceptions/CircularPluginDependencyException.cs b/BrackeysBot.API/Exceptions/CircularPluginDependencyException.cs
deleted file mode 100644
index 84eab8b..0000000
--- a/BrackeysBot.API/Exceptions/CircularPluginDependencyException.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System;
-
-namespace BrackeysBot.API.Exceptions;
-
-///
-/// The exception that is thrown when a plugin could not be loaded because it contains a circular dependency.
-///
-public sealed class CircularPluginDependencyException : Exception
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// The name of the plugin.
- internal CircularPluginDependencyException(string pluginName)
- : base($"The plugin {pluginName} could not be loaded because it contains a circular dependency.")
- {
- PluginName = pluginName;
- }
-
- ///
- /// Gets the name of the plugin which contains a circular dependency.
- ///
- /// The plugin name.
- public string PluginName { get; }
-}
diff --git a/BrackeysBot.API/Exceptions/InvalidPluginException.cs b/BrackeysBot.API/Exceptions/InvalidPluginException.cs
deleted file mode 100644
index 6d1edb2..0000000
--- a/BrackeysBot.API/Exceptions/InvalidPluginException.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-
-namespace BrackeysBot.API.Exceptions;
-
-///
-/// The exception that is thrown when an attempt to load a plugin failed because the plugin was invalid in some way.
-///
-public sealed class InvalidPluginException : Exception
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// The name of the plugin.
- /// The exception message.
- internal InvalidPluginException(string pluginName, string message)
- : base(message)
- {
- PluginName = pluginName;
- }
-
- ///
- /// Gets the name of the invalid plugin.
- ///
- /// The plugin name.
- public string PluginName { get; }
-}
diff --git a/BrackeysBot.API/Exceptions/PluginNotFoundException.cs b/BrackeysBot.API/Exceptions/PluginNotFoundException.cs
deleted file mode 100644
index 54d02b0..0000000
--- a/BrackeysBot.API/Exceptions/PluginNotFoundException.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.IO;
-
-namespace BrackeysBot.API.Exceptions;
-
-///
-/// The exception that is thrown when an attempt to load a named plugin failed because the file does not exist.
-///
-public sealed class PluginNotFoundException : FileNotFoundException
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// The name of the plugin.
- internal PluginNotFoundException(string pluginName)
- : base($"The plugin with the name {pluginName} could not be found", $"{pluginName}.dll")
- {
- PluginName = pluginName;
- }
-
- ///
- /// Gets the name of the plugin which was not found.
- ///
- /// The plugin name.
- public string PluginName { get; }
-}
diff --git a/BrackeysBot.API/Exceptions/PluginNotLoadedException.cs b/BrackeysBot.API/Exceptions/PluginNotLoadedException.cs
deleted file mode 100644
index 6965ae4..0000000
--- a/BrackeysBot.API/Exceptions/PluginNotLoadedException.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using BrackeysBot.API.Plugins;
-
-namespace BrackeysBot.API.Exceptions;
-
-///
-/// The exception that is thrown when an attempt was made to operate on a plugin that is not currently loaded.
-///
-public sealed class PluginNotLoadedException : Exception
-{
- internal PluginNotLoadedException(IPlugin plugin)
- : base($"{plugin} is not loaded.")
- {
- Plugin = plugin;
- }
-
- ///
- /// Gets the plugin.
- ///
- /// The plugin.
- public IPlugin Plugin { get; }
-}
diff --git a/BrackeysBot.API/Exceptions/PluginTypeMismatchException.cs b/BrackeysBot.API/Exceptions/PluginTypeMismatchException.cs
deleted file mode 100644
index 725c1ee..0000000
--- a/BrackeysBot.API/Exceptions/PluginTypeMismatchException.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System;
-using BrackeysBot.API.Plugins;
-
-namespace BrackeysBot.API.Exceptions;
-
-///
-/// The exception that is thrown when attempting to retrieve a plugin with ,
-/// but the type parameter does not match the type of the retrieved plugin.
-///
-public sealed class PluginTypeMismatchException : Exception
-{
- internal PluginTypeMismatchException(Type expectedType, Type actualType)
- {
- ExpectedType = expectedType;
- ActualType = actualType;
- }
-
- ///
- /// Gets the actual type.
- ///
- /// The actual type.
- public Type ActualType { get; }
-
- ///
- /// Gets the expected type.
- ///
- /// The expected type.
- public Type ExpectedType { get; }
-}
diff --git a/BrackeysBot.API/Extensions/CommandContextExtensions.cs b/BrackeysBot.API/Extensions/CommandContextExtensions.cs
deleted file mode 100644
index 8413d89..0000000
--- a/BrackeysBot.API/Extensions/CommandContextExtensions.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Threading.Tasks;
-using DisCatSharp.CommandsNext;
-
-namespace BrackeysBot.API.Extensions;
-
-///
-/// Extension methods for .
-///
-public static class CommandContextExtensions
-{
- ///
- /// Acknowledges the message provided by a by reacting to it.
- ///
- /// The command context.
- public static Task AcknowledgeAsync(this CommandContext context)
- {
- return context.Message.AcknowledgeAsync();
- }
-}
diff --git a/BrackeysBot.API/Extensions/DiscordChannelExtensions.cs b/BrackeysBot.API/Extensions/DiscordChannelExtensions.cs
deleted file mode 100644
index aa46c24..0000000
--- a/BrackeysBot.API/Extensions/DiscordChannelExtensions.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using DisCatSharp;
-using DisCatSharp.Entities;
-
-namespace BrackeysBot.API.Extensions;
-
-///
-/// Extension methods for .
-///
-public static class DiscordChannelExtensions
-{
- ///
- /// Normalizes a so that the internal client is assured to be a specified value.
- ///
- /// The to normalize.
- /// The target client.
- ///
- /// A whose public values will match , but whose internal client
- /// is .
- ///
- ///
- /// is
- /// -or-
- /// is
- ///
- public static async Task NormalizeClientAsync(this DiscordChannel channel, DiscordClient client)
- {
- if (channel is null) throw new ArgumentNullException(nameof(channel));
- if (client is null) throw new ArgumentNullException(nameof(client));
-
- return await client.GetChannelAsync(channel.Id);
- }
-}
diff --git a/BrackeysBot.API/Extensions/DiscordEmbedBuilderExtensions.cs b/BrackeysBot.API/Extensions/DiscordEmbedBuilderExtensions.cs
deleted file mode 100644
index fb8258b..0000000
--- a/BrackeysBot.API/Extensions/DiscordEmbedBuilderExtensions.cs
+++ /dev/null
@@ -1,259 +0,0 @@
-using System;
-using DisCatSharp;
-using DisCatSharp.Entities;
-
-namespace BrackeysBot.API.Extensions;
-
-///
-/// Extension methods for .
-///
-public static class DiscordEmbedBuilderExtensions
-{
- ///
- /// Adds a field of any value to an embed.
- ///
- /// The to modify.
- /// The field name.
- /// The field value.
- /// to display the field inline; otherwise, .
- /// The value type of the field.
- /// , to allow for method chaining.
- public static DiscordEmbedBuilder AddField(this DiscordEmbedBuilder embedBuilder, string name, T value,
- bool inline = false)
- {
- return embedBuilder.AddField(name, value?.ToString(), inline);
- }
-
- ///
- /// Conditionally adds a field to an embed.
- ///
- /// The to modify.
- ///
- /// A delegate which returns if the field should be added; otherwise, returns
- /// .
- ///
- /// The field name.
- /// The field value.
- /// to display the field inline; otherwise, .
- /// The value type of the field.
- /// , to allow for method chaining.
- public static DiscordEmbedBuilder AddFieldIf(this DiscordEmbedBuilder embedBuilder, Func conditionEvaluator,
- string name, T value, bool inline = false)
- {
- if (conditionEvaluator is null) throw new ArgumentNullException(nameof(conditionEvaluator));
-
- if (!conditionEvaluator()) return embedBuilder;
- return embedBuilder.AddField(name, value, inline);
- }
-
- ///
- /// Conditionally adds a field to an embed.
- ///
- /// The to modify.
- ///
- /// A delegate which returns if the field should be added; otherwise, returns
- /// .
- ///
- /// The field name.
- /// The delegate to execute if is .
- /// to display the field inline; otherwise, .
- /// The value type of the field.
- /// , to allow for method chaining.
- public static DiscordEmbedBuilder AddFieldIf(this DiscordEmbedBuilder embedBuilder, Func conditionEvaluator,
- string name, Func valueEvaluator, bool inline = false)
- {
- if (valueEvaluator is null) throw new ArgumentNullException(nameof(valueEvaluator));
-
- if (!conditionEvaluator()) return embedBuilder;
- return embedBuilder.AddField(name, valueEvaluator(), inline);
- }
-
- ///
- /// Conditionally adds a field to an embed, lazily.
- ///
- /// The to modify.
- /// if the field should be added; otherwise, .
- /// The field name.
- /// The delegate to execute if is .
- /// to display the field inline; otherwise, .
- /// The value type of the field.
- /// , to allow for method chaining.
- public static DiscordEmbedBuilder AddFieldIf(this DiscordEmbedBuilder embedBuilder, bool condition, string name,
- Func valueEvaluator, bool inline = false)
- {
- if (valueEvaluator is null) throw new ArgumentNullException(nameof(valueEvaluator));
-
- if (!condition) return embedBuilder;
- return embedBuilder.AddField(name, valueEvaluator(), inline);
- }
-
- ///
- /// Conditionally adds a field to an embed.
- ///
- /// The to modify.
- /// if the field should be added; otherwise, .
- /// The field name.
- /// The field value.
- /// to display the field inline; otherwise, .
- /// The value type of the field.
- /// , to allow for method chaining.
- public static DiscordEmbedBuilder AddFieldIf(this DiscordEmbedBuilder embedBuilder, bool condition, string name, T value,
- bool inline = false)
- {
- if (!condition) return embedBuilder;
- return embedBuilder.AddField(name, value, inline);
- }
-
- ///
- /// Adds a field to an embed whose value will be one of two values, determined by a specified condition.
- ///
- /// The to modify.
- ///
- /// if the value used will be .
- /// if the value used will be .
- ///
- /// The field name.
- ///
- /// The value to be used as the field value if is .
- ///
- ///
- /// The value to be used as the field value if is .
- ///
- /// to display the field inline; otherwise, .
- /// The type of the truthy value.
- /// The type of the falsey value.
- /// , to allow for method chaining.
- public static DiscordEmbedBuilder AddFieldOrElse(this DiscordEmbedBuilder embedBuilder, bool condition,
- string name, TTrue valueIfTrue, TFalse valueIfFalse, bool inline = false)
- {
- return condition
- ? embedBuilder.AddField(name, valueIfTrue, inline)
- : embedBuilder.AddField(name, valueIfFalse, inline);
- }
-
- ///
- /// Adds a field to an embed whose value will be one of two values, determined by a specified condition.
- ///
- /// The to modify.
- ///
- /// if the value used will be determined by ; or returns
- /// if the value used will be determined by .
- ///
- /// The field name.
- ///
- /// The delegate whose return value is used if is .
- ///
- ///
- /// The delegate whose return value is used if is .
- ///
- /// to display the field inline; otherwise, .
- /// The type of the truthy value.
- /// The type of the falsey value.
- /// , to allow for method chaining.
- public static DiscordEmbedBuilder AddFieldOrElse(this DiscordEmbedBuilder embedBuilder, bool condition,
- string name, Func valueEvaluatorIfTrue, Func valueEvaluatorIfFalse, bool inline = false)
- {
- if (valueEvaluatorIfTrue is null) throw new ArgumentNullException(nameof(valueEvaluatorIfTrue));
- if (valueEvaluatorIfFalse is null) throw new ArgumentNullException(nameof(valueEvaluatorIfFalse));
-
- return condition
- ? embedBuilder.AddField(name, valueEvaluatorIfTrue(), inline)
- : embedBuilder.AddField(name, valueEvaluatorIfFalse(), inline);
- }
-
- ///
- /// Adds a field to an embed whose value will be one of two values, determined by a specified condition.
- ///
- /// The to modify.
- ///
- /// A delegate which returns if the value used will be determined by
- /// ; or returns if the value used will be determined by
- /// .
- ///
- /// The field name.
- ///
- /// The delegate whose return value is used as the field value if the value returned by
- /// is .
- ///
- ///
- /// The delegate whose return value is used as the field value if the value returned by
- /// is .
- ///
- /// to display the field inline; otherwise, .
- /// The type of the truthy value.
- /// The type of the falsey value.
- /// , to allow for method chaining.
- public static DiscordEmbedBuilder AddFieldOrElse(this DiscordEmbedBuilder embedBuilder,
- Func conditionEvaluator, string name, Func valueEvaluatorIfTrue, Func valueEvaluatorIfFalse,
- bool inline = false)
- {
- if (conditionEvaluator is null) throw new ArgumentNullException(nameof(conditionEvaluator));
- if (valueEvaluatorIfTrue is null) throw new ArgumentNullException(nameof(valueEvaluatorIfTrue));
- if (valueEvaluatorIfFalse is null) throw new ArgumentNullException(nameof(valueEvaluatorIfFalse));
-
- return conditionEvaluator()
- ? embedBuilder.AddField(name, valueEvaluatorIfTrue(), inline)
- : embedBuilder.AddField(name, valueEvaluatorIfFalse(), inline);
- }
-
- ///
- /// Adds a field to an embed whose value will be one of two values, determined by a specified condition.
- ///
- /// The to modify.
- ///
- /// A delegate which returns if the value used will be ; or returns
- /// if the value used will be .
- /// .
- ///
- /// The field name.
- ///
- /// The delegate whose return value will be used as the field value if the value returned by
- /// is .
- ///
- ///
- /// The delegate whose return value will be used as the field value if the value returned by
- /// is .
- ///
- /// to display the field inline; otherwise, .
- /// The type of the truthy value.
- /// The type of the falsey value.
- /// , to allow for method chaining.
- public static DiscordEmbedBuilder AddFieldOrElse(this DiscordEmbedBuilder embedBuilder,
- Func conditionEvaluator, string name, TTrue valueIfTrue, TFalse valueIfFalse, bool inline = false)
- {
- if (conditionEvaluator is null) throw new ArgumentNullException(nameof(conditionEvaluator));
-
- return conditionEvaluator()
- ? embedBuilder.AddField(name, valueIfTrue, inline)
- : embedBuilder.AddField(name, valueIfFalse, inline);
- }
-
- ///
- /// Sets the embed's author to a specified .
- ///
- /// The embed builder to modify.
- /// The author.
- /// , to allow for method chaining.
- public static DiscordEmbedBuilder WithAuthor(this DiscordEmbedBuilder embedBuilder, DiscordUser author)
- {
- return embedBuilder.WithAuthor(author.UsernameWithDiscriminator, iconUrl: author.GetAvatarUrl(ImageFormat.Png));
- }
-
- ///
- /// Populates the thumbnail and footer of this embed builder with the guild's branding.
- ///
- /// The embed builder to modify.
- /// The guild whose branding to apply.
- ///
- /// to include the guild icon as a thumbnail; otherwise, .
- ///
- /// , to allow for method chaining.
- public static DiscordEmbedBuilder WithGuildInfo(this DiscordEmbedBuilder embedBuilder, DiscordGuild guild,
- bool addThumbnail = true)
- {
- embedBuilder.WithFooter(guild.Name, guild.IconUrl);
-
- if (addThumbnail) embedBuilder.WithThumbnail(guild.IconUrl);
- return embedBuilder;
- }
-}
diff --git a/BrackeysBot.API/Extensions/DiscordGuildExtensions.cs b/BrackeysBot.API/Extensions/DiscordGuildExtensions.cs
deleted file mode 100644
index 2b377a2..0000000
--- a/BrackeysBot.API/Extensions/DiscordGuildExtensions.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using DisCatSharp;
-using DisCatSharp.Entities;
-
-namespace BrackeysBot.API.Extensions;
-
-///
-/// Extension methods for .
-///
-public static class DiscordGuildExtensions
-{
- ///
- /// Normalizes a so that the internal client is assured to be a specified value.
- ///
- /// The to normalize.
- /// The target client.
- ///
- /// A whose public values will match , but whose internal client is
- /// .
- ///
- ///
- /// is
- /// -or-
- /// is
- ///
- public static async Task NormalizeClientAsync(this DiscordGuild guild, DiscordClient client)
- {
- if (guild is null) throw new ArgumentNullException(nameof(guild));
- if (client is null) throw new ArgumentNullException(nameof(client));
-
- return await client.GetGuildAsync(guild.Id);
- }
-}
diff --git a/BrackeysBot.API/Extensions/DiscordMemberExtensions.cs b/BrackeysBot.API/Extensions/DiscordMemberExtensions.cs
deleted file mode 100644
index b936a2f..0000000
--- a/BrackeysBot.API/Extensions/DiscordMemberExtensions.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using DisCatSharp;
-using DisCatSharp.Entities;
-
-namespace BrackeysBot.API.Extensions;
-
-///
-/// Extension methods for .
-///
-public static class DiscordMemberExtensions
-{
- ///
- /// Normalizes a so that the internal client is assured to be a specified value.
- ///
- /// The to normalize.
- /// The target client.
- ///
- /// A whose public values will match , but whose internal client
- /// is .
- ///
- ///
- /// is
- /// -or-
- /// is
- ///
- public static async Task NormalizeClientAsync(this DiscordMember member, DiscordClient client)
- {
- if (member is null) throw new ArgumentNullException(nameof(member));
- if (client is null) throw new ArgumentNullException(nameof(client));
-
- DiscordGuild guild = await member.Guild.NormalizeClientAsync(client);
- return await guild.GetMemberAsync(member.Id);
- }
-}
diff --git a/BrackeysBot.API/Extensions/DiscordMessageExtensions.cs b/BrackeysBot.API/Extensions/DiscordMessageExtensions.cs
deleted file mode 100644
index c23f884..0000000
--- a/BrackeysBot.API/Extensions/DiscordMessageExtensions.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using DisCatSharp;
-using DisCatSharp.Entities;
-
-namespace BrackeysBot.API.Extensions;
-
-///
-/// Extension methods for .
-///
-public static class DiscordMessageExtensions
-{
- ///
- /// Acknowledges a message by reacting to it.
- ///
- /// The message to acknowledge.
- public static Task AcknowledgeAsync(this DiscordMessage message)
- {
- return message.CreateReactionAsync(DiscordEmoji.FromUnicode("✅"));
- }
-
- ///
- /// Normalizes a so that the internal client is assured to be a specified value.
- ///
- /// The to normalize.
- /// The target client.
- ///
- /// A whose public values will match , but whose internal client
- /// is .
- ///
- ///
- /// is
- /// -or-
- /// is
- ///
- public static async Task NormalizeClientAsync(this DiscordMessage message, DiscordClient client)
- {
- if (message is null) throw new ArgumentNullException(nameof(message));
- if (client is null) throw new ArgumentNullException(nameof(client));
-
- DiscordChannel channel = await message.Channel.NormalizeClientAsync(client);
- return await channel.GetMessageAsync(message.Id);
- }
-}
diff --git a/BrackeysBot.API/Extensions/DiscordUserExtensions.cs b/BrackeysBot.API/Extensions/DiscordUserExtensions.cs
deleted file mode 100644
index 9930033..0000000
--- a/BrackeysBot.API/Extensions/DiscordUserExtensions.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using DisCatSharp;
-using DisCatSharp.Entities;
-
-namespace BrackeysBot.API.Extensions;
-
-///
-/// Extension methods for .
-///
-public static class DiscordUserExtensions
-{
- ///
- /// Normalizes a so that the internal client is assured to be a specified value.
- ///
- /// The to normalize.
- /// The target client.
- ///
- /// A whose public values will match , but whose internal client
- /// is .
- ///
- ///
- /// is
- /// -or-
- /// is
- ///
- public static Task NormalizeClientAsync(this DiscordUser user, DiscordClient client)
- {
- if (user is null) throw new ArgumentNullException(nameof(user));
- if (client is null) throw new ArgumentNullException(nameof(client));
-
- return client.GetUserAsync(user.Id);
- }
-}
diff --git a/BrackeysBot.API/IBot.cs b/BrackeysBot.API/IBot.cs
deleted file mode 100644
index ef21ec3..0000000
--- a/BrackeysBot.API/IBot.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using BrackeysBot.API.Plugins;
-using NLog;
-
-namespace BrackeysBot.API;
-
-///
-/// Represents a bot application instance.
-///
-public interface IBot
-{
- ///
- /// Gets the logger for this bot.
- ///
- /// The logger.
- ILogger Logger { get; }
-
- ///
- /// Gets the plugin manager.
- ///
- /// The plugin manager.
- IPluginManager PluginManager { get; }
-
- ///
- /// Gets the bot version.
- ///
- /// The bot version.
- static string Version { get; } = string.Empty;
-}
diff --git a/BrackeysBot.API/MentionUtility.cs b/BrackeysBot.API/MentionUtility.cs
deleted file mode 100644
index c4447f3..0000000
--- a/BrackeysBot.API/MentionUtility.cs
+++ /dev/null
@@ -1,138 +0,0 @@
-using System.Globalization;
-
-namespace BrackeysBot.API;
-
-///
-/// Provides methods for encoding and decoding Discord mention strings.
-///
-///
-/// The implementations in this class are designed to resemble MentionUtils as provided by Discord.NET. The source is
-/// available here.
-///
-public static class MentionUtility
-{
- ///
- /// Returns a channel mention string built from the specified channel ID.
- ///
- /// The ID of the channel to mention.
- /// A channel mention string in the format <#123>.
- public static string MentionChannel(ulong id)
- {
- return $"<#{id}>";
- }
-
- ///
- /// Returns a role mention string built from the specified role ID.
- ///
- /// The ID of the role to mention.
- /// A role mention string in the format <@&123>.
- public static string MentionRole(ulong id)
- {
- return $"<@&{id}>";
- }
-
- ///
- /// Returns a user mention string built from the specified user ID.
- ///
- /// The ID of the user to mention.
- ///
- /// if the mention string should account for nicknames; otherwise, .
- ///
- ///
- /// A user mention string in the format <@!123> if is ,
- /// or in the format <@123> if is .
- ///
- public static string MentionUser(ulong id, bool nickname = true)
- {
- return nickname ? $"<@!{id}>" : $"<@{id}>";
- }
-
- ///
- /// Parses a provided channel mention string to a 64-bit unsigned integer representing the channel ID. A return value
- /// indicates whether the parse succeeded.
- ///
- /// A string containing a mention string to parse, in the format <#123>.
- ///
- /// When this method returns, contains the 64-bit unsigned integer value representing the channel ID contained within
- /// , if the conversion succeeded, or zero if the conversion failed. The conversion fails if the
- /// parameter is or , is not of the correct
- /// format, or represents a number less than or greater than .
- ///
- ///
- public static bool TryParseChannel(string? value, out ulong result)
- {
- result = 0;
- if (string.IsNullOrWhiteSpace(value)) return false;
-
- if (value.Length >= 3 && value[0] == '<' && value[1] == '#' && value[^1] == '>')
- {
- value = value.Substring(2, value.Length - 3); // <#123>
-
- if (ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result))
- return true;
- }
-
- return false;
- }
-
- ///
- /// Parses a provided role mention string to a 64-bit unsigned integer representing the role ID. A return value indicates
- /// whether the parse succeeded.
- ///
- /// A string containing a mention string to parse, in the format <@&123>.
- ///
- /// When this method returns, contains the 64-bit unsigned integer value representing the role ID contained within
- /// , if the conversion succeeded, or zero if the conversion failed. The conversion fails if the
- /// parameter is or , is not of the correct
- /// format, or represents a number less than or greater than .
- ///
- ///
- public static bool TryParseRole(string? value, out ulong result)
- {
- result = 0;
- if (string.IsNullOrWhiteSpace(value)) return false;
-
- if (value.Length >= 4 && value[0] == '<' && value[1] == '@' && value[2] == '&' && value[^1] == '>')
- {
- value = value.Substring(3, value.Length - 4); // <@&123>
-
- if (ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result))
- return true;
- }
-
- return false;
- }
-
- ///
- /// Parses a provided user mention string to a 64-bit unsigned integer representing the user ID. A return value indicates
- /// whether the parse succeeded.
- ///
- ///
- /// A string containing a mention string to parse, in the format <@123> or <@!123>.
- ///
- ///
- /// When this method returns, contains the 64-bit unsigned integer value representing the user ID contained within
- /// , if the conversion succeeded, or zero if the conversion failed. The conversion fails if the
- /// parameter is or , is not of the correct
- /// format, or represents a number less than or greater than .
- ///
- ///
- public static bool TryParseUser(string? value, out ulong result)
- {
- result = 0;
- if (string.IsNullOrWhiteSpace(value)) return false;
-
- if (value.Length >= 3 && value[0] == '<' && value[1] == '@' && value[^1] == '>')
- {
- if (value.Length >= 4 && value[2] == '!')
- value = value.Substring(3, value.Length - 4); // <@!123>
- else
- value = value.Substring(2, value.Length - 3); // <@123>
-
- if (ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result))
- return true;
- }
-
- return false;
- }
-}
diff --git a/BrackeysBot.API/Plugins/IPlugin.cs b/BrackeysBot.API/Plugins/IPlugin.cs
deleted file mode 100644
index 4733541..0000000
--- a/BrackeysBot.API/Plugins/IPlugin.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using System.IO;
-using BrackeysBot.API.Configuration;
-using NLog;
-
-namespace BrackeysBot.API.Plugins;
-
-///
-/// Represents a bot plugin.
-///
-public interface IPlugin : IDisposable, IConfigurationHolder
-{
- ///
- /// Gets the data directory for this plugin.
- ///
- /// The data directory.
- DirectoryInfo DataDirectory { get; }
-
- ///
- /// Gets the date and time at which this plugin was last enabled.
- ///
- ///
- /// A representing the date and time at which this plugin was enabled, or
- /// if this plugin is not currently enabled.
- ///
- DateTimeOffset? EnableTime { get; }
-
- ///
- /// Gets the logger for this plugin.
- ///
- /// The plugin's logger.
- ILogger Logger { get; }
-
- ///
- /// Gets the information about this plugin.
- ///
- /// A object containing
- PluginInfo PluginInfo { get; }
-
- ///
- /// Gets the manager which owns this plugin.
- ///
- /// The plugin manager.
- IPluginManager PluginManager { get; }
-
- ///
- /// Gets the service provider for this plugin.
- ///
- /// The service provider.
- public IServiceProvider ServiceProvider { get; }
-}
diff --git a/BrackeysBot.API/Plugins/IPluginManager.cs b/BrackeysBot.API/Plugins/IPluginManager.cs
deleted file mode 100644
index 2a8fbf1..0000000
--- a/BrackeysBot.API/Plugins/IPluginManager.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using BrackeysBot.API.Exceptions;
-using NLog;
-
-namespace BrackeysBot.API.Plugins;
-
-///
-/// Represents an object which can load, manage, and unload plugins.
-///
-public interface IPluginManager
-{
- ///
- /// Gets a read-only view of the plugins enabled by this manager.
- ///
- /// A read-only view of instances which are currently enabled.
- IReadOnlyList EnabledPlugins { get; }
-
- ///
- /// Gets a read-only view of the plugins loaded by this manager.
- ///
- /// A read-only view of instances which are currently loaded.
- IReadOnlyList LoadedPlugins { get; }
-
- ///
- /// Gets the logger for this plugin manager.
- ///
- /// The logger.
- ILogger Logger { get; }
-
- ///
- /// Disables a plugin.
- ///
- /// The plugin to disable.
- /// is .
- /// refers to a plugin that is not loaded.
- void DisablePlugin(IPlugin plugin);
-
- ///
- /// Enables a plugin.
- ///
- /// The plugin to enable.
- /// is .
- /// refers to a plugin that is not loaded.
- void EnablePlugin(IPlugin plugin);
-
- ///
- /// Attempts to find a plugin by its type.
- ///
- /// The plugin type.
- ///
- /// The plugin, or if the plugin with the specified type was not found, or is not loaded.
- ///
- T? GetPlugin() where T : IPlugin;
-
- ///
- /// Attempts to find a plugin by its name.
- ///
- /// The name of the plugin to find.
- ///
- /// The plugin, or if the plugin with the specified name was not found, or is not loaded.
- ///
- IPlugin? GetPlugin(string name);
-
- ///
- /// Returns a value indicating whether a specified plugin is currently loaded and enabled.
- ///
- /// The plugin whose enabled state to retrieve.
- ///
- /// if refers to a plugin that is loaded and enabled; otherwise,
- /// .
- ///
- bool IsPluginEnabled(IPlugin plugin);
-
- ///
- /// Returns a value indicating whether a specified plugin is currently loaded.
- ///
- /// The plugin whose loaded state to retrieve.
- ///
- /// if refers to a loaded plugin; otherwise, .
- ///
- bool IsPluginLoaded(IPlugin plugin);
-
- ///
- /// Loads a plugin with a specified name.
- ///
- /// The name of the plugin to load, sans the .dll extension.
- /// The newly loaded plugin.
- ///
- /// is , empty, or consists of only whitespace characters.
- ///
- /// No plugin by the name could be found.
- ///
- /// The plugin does not contain an embedded resource named plugin.json.
- ///
- IPlugin LoadPlugin(string name);
-
- ///
- /// Loads all plugins that this plugin manager can detect.
- ///
- /// The read-only view of the loaded instances.
- IReadOnlyList LoadPlugins();
-
- ///
- /// Retrieves a plugin by name, case-sensitively. A return value indicates whether the retrieval succeeded.
- ///
- /// The name of the plugin to retrieve.
- ///
- /// When this method returns, contains the plugin instance if the retrieval succeeded, or if the
- /// retrieval failed. Retrieval can fail if there is no loaded plugin with the specified name.
- ///
- ///
- /// if a plugin with the name was successfully found; otherwise
- /// .
- ///
- bool TryGetPlugin(string name, [NotNullWhen(true)] out IPlugin? plugin);
-
- ///
- /// Unloads a plugin.
- ///
- /// The plugin to unload.
- /// is .
- /// refers to a plugin that is not loaded.
- void UnloadPlugin(IPlugin plugin);
-}
diff --git a/BrackeysBot.API/Plugins/MonoPlugin.cs b/BrackeysBot.API/Plugins/MonoPlugin.cs
deleted file mode 100644
index 633e1ae..0000000
--- a/BrackeysBot.API/Plugins/MonoPlugin.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-using System;
-using System.IO;
-using System.Runtime.Loader;
-using System.Threading.Tasks;
-using BrackeysBot.API.Configuration;
-using DisCatSharp;
-using Microsoft.Extensions.DependencyInjection;
-using NLog;
-
-namespace BrackeysBot.API.Plugins;
-
-///
-/// Represents a bot plugin.
-///
-public abstract class MonoPlugin : IPlugin
-{
- internal AssemblyLoadContext LoadContext { get; set; } = null!;
-
- ///
- /// Gets the underlying instance.
- ///
- /// The underlying .
- protected internal DiscordClient? DiscordClient { get; internal set; }
-
- ///
- public IConfiguration Configuration { get; internal set; } = null!;
-
- ///
- public DirectoryInfo DataDirectory { get; internal set; } = null!;
-
- ///
- public DateTimeOffset? EnableTime { get; internal set; } = null!;
-
- ///
- public ILogger Logger { get; internal set; } = null!;
-
- ///
- public PluginInfo PluginInfo { get; internal set; } = null!;
-
- ///
- public IPluginManager PluginManager { get; internal set; } = null!;
-
- ///
- public IServiceProvider ServiceProvider { get; internal set; } = null!;
-
- ///
- public virtual void Dispose()
- {
- }
-
- ///
- ~MonoPlugin()
- {
- Dispose();
- }
-
- ///
- /// Allows configuration of the plugin's .
- ///
- /// The service collection.
- protected internal virtual void ConfigureServices(IServiceCollection services)
- {
- }
-
- ///
- /// Called when this plugin is disabled.
- ///
- protected internal virtual Task OnDisable()
- {
- return Task.CompletedTask;
- }
-
- ///
- /// Called when this plugin is enabled.
- ///
- protected internal virtual Task OnEnable()
- {
- return Task.CompletedTask;
- }
-
- ///
- /// Called when this plugin is loaded.
- ///
- /// This method is always called upon a plugin's load, even if the plugin is not yet enabled.
- /// Event subscriptions for should be placed here.
- protected internal virtual Task OnLoad()
- {
- return Task.CompletedTask;
- }
-
- ///
- /// Called when this plugin is unloaded.
- ///
- /// This method is always called upon a plugin's unload, even if the plugin is not currently enabled.
- protected internal virtual Task OnUnload()
- {
- return Task.CompletedTask;
- }
-}
diff --git a/BrackeysBot.API/Plugins/PluginAttribute.cs b/BrackeysBot.API/Plugins/PluginAttribute.cs
deleted file mode 100644
index b40604e..0000000
--- a/BrackeysBot.API/Plugins/PluginAttribute.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-
-namespace BrackeysBot.API.Plugins;
-
-///
-/// Specifies information such as the plugin's name and version.
-///
-[AttributeUsage(AttributeTargets.Class)]
-public sealed class PluginAttribute : Attribute
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// The name of this plugin.
- /// The version of this plugin.
- public PluginAttribute(string name, string version)
- {
- Name = name ?? throw new ArgumentNullException(nameof(name));
- Version = version ?? throw new ArgumentNullException(nameof(version));
- }
-
- ///
- /// Gets the name of the plugin.
- ///
- /// The name of the plugin.
- public string Name { get; }
-
- ///
- /// Gets the version of this plugin.
- ///
- /// The version of this plugin.
- public string Version { get; }
-}
diff --git a/BrackeysBot.API/Plugins/PluginAuthorAttribute.cs b/BrackeysBot.API/Plugins/PluginAuthorAttribute.cs
deleted file mode 100644
index 4032d0e..0000000
--- a/BrackeysBot.API/Plugins/PluginAuthorAttribute.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-
-namespace BrackeysBot.API.Plugins;
-
-///
-/// Specifies the author of a .
-///
-[AttributeUsage(AttributeTargets.Class)]
-public sealed class PluginAuthorAttribute : Attribute
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// The name of the author.
- /// Optional. The author's email address. Default is .
- /// Optional. The author's homepage URL. Default is .
- public PluginAuthorAttribute(string name, string? email = null, string? url = null)
- {
- Name = name ?? throw new ArgumentNullException(nameof(name));
- Email = email;
- Url = url;
- }
-
- ///
- /// Gets the name of the author.
- ///
- /// The author's name.
- public string Name { get; }
-
- ///
- /// Gets the email address of the author.
- ///
- /// The author's email address, or if not this value is not specified.
- public string? Email { get; }
-
- ///
- /// Gets the homepage URL of the author.
- ///
- /// The author's homepage URL, or if not this value is not specified.
- public string? Url { get; }
-}
diff --git a/BrackeysBot.API/Plugins/PluginDependenciesAttribute.cs b/BrackeysBot.API/Plugins/PluginDependenciesAttribute.cs
deleted file mode 100644
index 4b5ef37..0000000
--- a/BrackeysBot.API/Plugins/PluginDependenciesAttribute.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-
-namespace BrackeysBot.API.Plugins;
-
-///
-/// Specifies the dependencies that should be loaded prior to this , so that this plugin functions
-/// correctly.
-///
-[AttributeUsage(AttributeTargets.Class)]
-public sealed class PluginDependenciesAttribute : Attribute
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// The first dependency.
- /// The dependencies of this plugin.
- public PluginDependenciesAttribute(string firstDependency, params string[] otherDependencies)
- {
- otherDependencies ??= Array.Empty();
-
- var dependencies = new string[otherDependencies.Length + 1];
- dependencies[0] = firstDependency;
- Array.Copy(otherDependencies, 0, dependencies, 1, otherDependencies.Length);
-
- Dependencies = dependencies;
- }
-
- ///
- /// Gets the dependencies of this plugin.
- ///
- /// The dependencies.
- public string[] Dependencies { get; }
-}
diff --git a/BrackeysBot.API/Plugins/PluginDescriptionAttribute.cs b/BrackeysBot.API/Plugins/PluginDescriptionAttribute.cs
deleted file mode 100644
index e68508c..0000000
--- a/BrackeysBot.API/Plugins/PluginDescriptionAttribute.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System;
-
-namespace BrackeysBot.API.Plugins;
-
-///
-/// Specifies the description of a .
-///
-[AttributeUsage(AttributeTargets.Class)]
-public sealed class PluginDescriptionAttribute : Attribute
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// The description of this plugin.
- public PluginDescriptionAttribute(string description)
- {
- Description = description ?? throw new ArgumentNullException(nameof(description));
- }
-
- ///
- /// Gets the description of this plugin.
- ///
- /// The description.
- public string Description { get; }
-}
diff --git a/BrackeysBot.API/Plugins/PluginInfo.cs b/BrackeysBot.API/Plugins/PluginInfo.cs
deleted file mode 100644
index 418e1e3..0000000
--- a/BrackeysBot.API/Plugins/PluginInfo.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-namespace BrackeysBot.API.Plugins;
-
-///
-/// Represents a class which contains deserialized data from a plugin.json file.
-///
-public class PluginInfo
-{
- internal PluginInfo(string name, string version, string? description, PluginAuthorInfo? author, PluginInfo[] dependencies)
- {
- Name = name;
- Version = version;
- Description = description;
- Author = author;
- Dependencies = dependencies;
- }
-
- ///
- /// Gets the author of this plugin.
- ///
- /// The plugin author, or if no author is specified.
- public PluginAuthorInfo? Author { get; }
-
- ///
- /// Gets the dependencies of this plugin.
- ///
- /// The plugin dependencies.
- public PluginInfo[] Dependencies { get; }
-
- ///
- /// Gets the description of this plugin.
- ///
- /// The plugin description.
- public string? Description { get; }
-
- ///
- /// Gets the name of this plugin.
- ///
- /// The plugin name.
- public string Name { get; }
-
- ///
- /// Gets the version of this plugin.
- ///
- /// The plugin version.
- public string Version { get; }
-
- ///
- /// Represents a class which contains deserialized data from the author property of a plugin.json file.
- ///
- public class PluginAuthorInfo
- {
- internal PluginAuthorInfo(string name, string? email, string? url)
- {
- Email = email;
- Name = name;
- Url = url;
- }
-
- ///
- /// Gets the email address of the author.
- ///
- /// The author's email address.
- public string? Email { get; }
-
- ///
- /// Gets the name of the author.
- ///
- /// The author's name.
- public string Name { get; }
-
- ///
- /// Gets the URL of the author.
- ///
- /// The author's URL.
- public string? Url { get; }
- }
-}
diff --git a/BrackeysBot.API/Plugins/PluginIntentsAttribute.cs b/BrackeysBot.API/Plugins/PluginIntentsAttribute.cs
deleted file mode 100644
index 3529f38..0000000
--- a/BrackeysBot.API/Plugins/PluginIntentsAttribute.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using DisCatSharp;
-
-namespace BrackeysBot.API.Plugins;
-
-///
-/// Specifies the Discord client intents that this plugin will utilise.
-///
-[AttributeUsage(AttributeTargets.Class)]
-public sealed class PluginIntentsAttribute : Attribute
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// The intents.
- public PluginIntentsAttribute(DiscordIntents intents)
- {
- Intents = intents;
- }
-
- ///
- /// Gets the intents.
- ///
- /// The intents.
- public DiscordIntents Intents { get; }
-}
diff --git a/BrackeysBot.sln b/BrackeysBot.sln
index 5a2e714..dac31bd 100644
--- a/BrackeysBot.sln
+++ b/BrackeysBot.sln
@@ -2,8 +2,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BrackeysBot", "BrackeysBot\BrackeysBot.csproj", "{7EE46295-3778-4452-9BAA-91EAFC0F72C3}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BrackeysBot.API", "BrackeysBot.API\BrackeysBot.API.csproj", "{2FFBAEAA-4577-4710-ABF4-3AC78DCCAD8E}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -14,10 +12,6 @@ Global
{7EE46295-3778-4452-9BAA-91EAFC0F72C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EE46295-3778-4452-9BAA-91EAFC0F72C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EE46295-3778-4452-9BAA-91EAFC0F72C3}.Release|Any CPU.Build.0 = Release|Any CPU
- {2FFBAEAA-4577-4710-ABF4-3AC78DCCAD8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2FFBAEAA-4577-4710-ABF4-3AC78DCCAD8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2FFBAEAA-4577-4710-ABF4-3AC78DCCAD8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2FFBAEAA-4577-4710-ABF4-3AC78DCCAD8E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
EndGlobalSection