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