diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index ca14ed1..9f1a02d 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -33,7 +33,6 @@ jobs: run: | mkdir build dotnet pack X10D --configuration Debug --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='nightly' -p:BuildNumber=${{ github.run_number }} - dotnet pack X10D.DSharpPlus --configuration Debug --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='nightly' -p:BuildNumber=${{ github.run_number }} dotnet pack X10D.Hosting --configuration Debug --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='nightly' -p:BuildNumber=${{ github.run_number }} dotnet pack X10D.Unity --configuration Debug --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='nightly' -p:BuildNumber=${{ github.run_number }} diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index 7b9940b..01af506 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -32,7 +32,6 @@ jobs: run: | mkdir build dotnet pack X10D --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='prerelease' -p:BuildNumber=${{ github.run_number }} - dotnet pack X10D.DSharpPlus --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='prerelease' -p:BuildNumber=${{ github.run_number }} dotnet pack X10D.Hosting --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='prerelease' -p:BuildNumber=${{ github.run_number }} dotnet pack X10D.Unity --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='prerelease' -p:BuildNumber=${{ github.run_number }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0bdbb14..c5fd973 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,6 @@ jobs: run: | mkdir build dotnet pack X10D --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build - dotnet pack X10D.DSharpPlus --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build dotnet pack X10D.Hosting --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build dotnet pack X10D.Unity --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build diff --git a/CHANGELOG.md b/CHANGELOG.md index 23f6c22..c1d3e44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - X10D: Removed `IEnumerable.ConcatOne` - this functionality already exists with `Append`. +- X10D.DSharpPlus: Complete sunset of library. This library will not be updated to support DSharpPlus v5.0.0. ## [3.3.1] - 2023-08-21 diff --git a/X10D.DSharpPlus/X10D.DSharpPlus.csproj b/X10D.DSharpPlus/X10D.DSharpPlus.csproj deleted file mode 100644 index 9128252..0000000 --- a/X10D.DSharpPlus/X10D.DSharpPlus.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - net7.0;net6.0;netstandard2.1 - true - - - - - - - diff --git a/X10D.DSharpPlus/src/Assembly.cs b/X10D.DSharpPlus/src/Assembly.cs deleted file mode 100644 index 4e11466..0000000 --- a/X10D.DSharpPlus/src/Assembly.cs +++ /dev/null @@ -1 +0,0 @@ -[assembly: CLSCompliant(false)] diff --git a/X10D.DSharpPlus/src/DiscordChannelExtensions.cs b/X10D.DSharpPlus/src/DiscordChannelExtensions.cs deleted file mode 100644 index 820ced0..0000000 --- a/X10D.DSharpPlus/src/DiscordChannelExtensions.cs +++ /dev/null @@ -1,71 +0,0 @@ -using DSharpPlus; -using DSharpPlus.Entities; - -namespace X10D.DSharpPlus; - -/// -/// Extension methods for . -/// -public static class DiscordChannelExtensions -{ - /// - /// Gets the category of this channel. - /// - /// The channel whose category to retrieve. - /// - /// The category of , or itself if it is already a category; - /// if this channel is not defined in a category. - /// - /// is . - public static DiscordChannel? GetCategory(this DiscordChannel channel) - { - if (channel is null) - { - throw new ArgumentNullException(nameof(channel)); - } - - while (true) - { - if (channel.IsCategory) - { - return channel; - } - - if (channel.Parent is not { } parent) - { - return null; - } - - channel = parent; - } - } - - /// - /// 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).ConfigureAwait(false); - } -} diff --git a/X10D.DSharpPlus/src/DiscordClientExtensions.cs b/X10D.DSharpPlus/src/DiscordClientExtensions.cs deleted file mode 100644 index 5dfd415..0000000 --- a/X10D.DSharpPlus/src/DiscordClientExtensions.cs +++ /dev/null @@ -1,71 +0,0 @@ -using DSharpPlus; -using DSharpPlus.Entities; -using DSharpPlus.Exceptions; - -namespace X10D.DSharpPlus; - -/// -/// Extension methods for . -/// -public static class DiscordClientExtensions -{ - /// - /// Instructs the client to automatically join all existing threads, and any newly-created threads. - /// - /// The whose events should be subscribed. - /// - /// to automatically rejoin a thread if this client was removed; otherwise, - /// . - /// - /// is . - public static void AutoJoinThreads(this DiscordClient client, bool rejoinIfRemoved = true) - { - if (client is null) - { - throw new ArgumentNullException(nameof(client)); - } - - client.GuildAvailable += (_, args) => args.Guild.JoinAllThreadsAsync(); - client.ThreadCreated += (_, args) => args.Thread.JoinThreadAsync(); - - if (rejoinIfRemoved) - { - client.ThreadMembersUpdated += (_, args) => - { - if (args.RemovedMembers.Any(m => m.Id == client.CurrentUser.Id)) - return args.Thread.JoinThreadAsync(); - - return Task.CompletedTask; - }; - } - } - - /// - /// Gets a user by their ID. If the user is not found, is returned instead of - /// being thrown. - /// - /// The Discord client. - /// The ID of the user to retrieve. - /// is . - public static async Task GetUserOrNullAsync(this DiscordClient client, ulong userId) - { - if (client is null) - { - throw new ArgumentNullException(nameof(client)); - } - - try - { - // we should never use exceptions for flow control but this is D#+ we're talking about. - // NotFoundException isn't even documented, and yet it gets thrown when a user doesn't exist. - // so this method should hopefully clearly express that - and at least using exceptions for flow control *here*, - // removes the need to do the same in consumer code. - // god I hate this. - return await client.GetUserAsync(userId).ConfigureAwait(false); - } - catch (NotFoundException) - { - return null; - } - } -} diff --git a/X10D.DSharpPlus/src/DiscordEmbedBuilderExtensions.cs b/X10D.DSharpPlus/src/DiscordEmbedBuilderExtensions.cs deleted file mode 100644 index 1c2c479..0000000 --- a/X10D.DSharpPlus/src/DiscordEmbedBuilderExtensions.cs +++ /dev/null @@ -1,212 +0,0 @@ -using DSharpPlus.Entities; - -namespace X10D.DSharpPlus; - -/// -/// Extension methods for . -/// -public static class DiscordEmbedBuilderExtensions -{ - /// - /// Adds a field of any value type to the embed. - /// - /// The to modify. - /// The name of the embed field. - /// The value of the embed field. - /// to display this field inline; otherwise, . - /// The type of . - /// The current instance of ; that is, . - /// is . - public static DiscordEmbedBuilder AddField( - this DiscordEmbedBuilder builder, - string name, - T? value, - bool inline = false) - { - if (builder is null) - { - throw new ArgumentNullException(nameof(builder)); - } - - return builder.AddField(name, value?.ToString(), inline); - } - - /// - /// Conditionally adds a field to the embed. - /// - /// The to modify. - /// The condition whose value is used to determine whether the field will be added. - /// The name of the embed field. - /// The value of the embed field. - /// to display this field inline; otherwise, . - /// The type of . - /// The current instance of ; that is, . - /// is . - public static DiscordEmbedBuilder AddFieldIf( - this DiscordEmbedBuilder builder, - bool condition, - string name, - T? value, - bool inline = false) - { - if (builder is null) - { - throw new ArgumentNullException(nameof(builder)); - } - - if (condition) - { - builder.AddField(name, value?.ToString(), inline); - } - - return builder; - } - - /// - /// Conditionally adds a field to the embed. - /// - /// The to modify. - /// The predicate whose return value is used to determine whether the field will be added. - /// The name of the embed field. - /// The value of the embed field. - /// to display this field inline; otherwise, . - /// The type of . - /// The current instance of ; that is, . - /// - /// is . - /// -or- - /// is . - /// - public static DiscordEmbedBuilder AddFieldIf( - this DiscordEmbedBuilder builder, - Func predicate, - string name, - T? value, - bool inline = false) - { - if (builder is null) - { - throw new ArgumentNullException(nameof(builder)); - } - - if (predicate is null) - { - throw new ArgumentNullException(nameof(predicate)); - } - - if (predicate.Invoke()) - { - builder.AddField(name, value?.ToString(), inline); - } - - return builder; - } - - /// - /// Conditionally adds a field to the embed. - /// - /// The to modify. - /// The predicate whose return value is used to determine whether the field will be added. - /// The name of the embed field. - /// The delegate whose return value will be used as the value of the embed field. - /// to display this field inline; otherwise, . - /// The return type of . - /// The current instance of ; that is, . - /// - /// is . - /// -or- - /// is . - /// -or- - /// is . - /// - public static DiscordEmbedBuilder AddFieldIf( - this DiscordEmbedBuilder builder, - Func predicate, - string name, - Func valueFactory, - bool inline = false) - { - if (builder is null) - { - throw new ArgumentNullException(nameof(builder)); - } - - if (predicate is null) - { - throw new ArgumentNullException(nameof(predicate)); - } - - if (valueFactory is null) - { - throw new ArgumentNullException(nameof(valueFactory)); - } - - if (predicate.Invoke()) - { - builder.AddField(name, valueFactory.Invoke()?.ToString(), inline); - } - - return builder; - } - - /// - /// Conditionally adds a field to the embed. - /// - /// The to modify. - /// The condition whose value is used to determine whether the field will be added. - /// The name of the embed field. - /// The delegate whose return value will be used as the value of the embed field. - /// to display this field inline; otherwise, . - /// The return type of . - /// The current instance of ; that is, . - /// - /// is . - /// -or- - /// is . - /// - public static DiscordEmbedBuilder AddFieldIf( - this DiscordEmbedBuilder builder, - bool condition, - string name, - Func valueFactory, - bool inline = false) - { - if (builder is null) - { - throw new ArgumentNullException(nameof(builder)); - } - - if (valueFactory is null) - { - throw new ArgumentNullException(nameof(valueFactory)); - } - - if (condition) - { - builder.AddField(name, valueFactory.Invoke()?.ToString(), inline); - } - - return builder; - } - - /// - /// Sets the embed's author. - /// - /// The embed builder to modify. - /// The author. - /// The current instance of . - public static DiscordEmbedBuilder WithAuthor(this DiscordEmbedBuilder builder, DiscordUser user) - { - if (builder is null) - { - throw new ArgumentNullException(nameof(builder)); - } - - if (user is null) - { - throw new ArgumentNullException(nameof(user)); - } - - return builder.WithAuthor(user.GetUsernameWithDiscriminator(), iconUrl: user.AvatarUrl); - } -} diff --git a/X10D.DSharpPlus/src/DiscordGuildExtensions.cs b/X10D.DSharpPlus/src/DiscordGuildExtensions.cs deleted file mode 100644 index ff4636e..0000000 --- a/X10D.DSharpPlus/src/DiscordGuildExtensions.cs +++ /dev/null @@ -1,84 +0,0 @@ -using DSharpPlus; -using DSharpPlus.Entities; -using DSharpPlus.Exceptions; - -namespace X10D.DSharpPlus; - -/// -/// Extension methods for . -/// -public static class DiscordGuildExtensions -{ - /// - /// Joins all active threads in the guild that this client has permission to view. - /// - /// The guild whose active threads to join. - /// is . - public static async Task JoinAllThreadsAsync(this DiscordGuild guild) - { - if (guild is null) - { - throw new ArgumentNullException(nameof(guild)); - } - - await Task.WhenAll(guild.Threads.Values.Select(t => t.JoinThreadAsync())).ConfigureAwait(false); - } - - /// - /// Gets a guild member by their ID. If the member is not found, is returned instead of - /// being thrown. - /// - /// The guild whose member list to search. - /// The ID of the member to retrieve. - /// is . - public static async Task GetMemberOrNullAsync(this DiscordGuild guild, ulong userId) - { - if (guild is null) - { - throw new ArgumentNullException(nameof(guild)); - } - - try - { - // we should never use exceptions for flow control but this is D#+ we're talking about. - // NotFoundException isn't even documented, and yet it gets thrown when a member doesn't exist. - // so this method should hopefully clearly express that - and at least using exceptions for flow control *here*, - // removes the need to do the same in consumer code. - // god I hate this. - return await guild.GetMemberAsync(userId).ConfigureAwait(false); - } - catch (NotFoundException) - { - return null; - } - } - - /// - /// 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).ConfigureAwait(false); - } -} diff --git a/X10D.DSharpPlus/src/DiscordMemberExtensions.cs b/X10D.DSharpPlus/src/DiscordMemberExtensions.cs deleted file mode 100644 index 7ec9925..0000000 --- a/X10D.DSharpPlus/src/DiscordMemberExtensions.cs +++ /dev/null @@ -1,63 +0,0 @@ -using DSharpPlus; -using DSharpPlus.Entities; - -namespace X10D.DSharpPlus; - -/// -/// Extension methods for . -/// -public static class DiscordMemberExtensions -{ - /// - /// Returns a value indicating whether this member has the specified role. - /// - /// The member whose roles to search. - /// The role for which to check. - /// - /// if has the role; otherwise, . - /// - public static bool HasRole(this DiscordMember member, DiscordRole role) - { - if (member is null) - { - throw new ArgumentNullException(nameof(member)); - } - - if (role is null) - { - throw new ArgumentNullException(nameof(role)); - } - - return member.Roles.Contains(role); - } - - /// - /// 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).ConfigureAwait(false); - return await guild.GetMemberAsync(member.Id).ConfigureAwait(false); - } -} diff --git a/X10D.DSharpPlus/src/DiscordMessageExtensions.cs b/X10D.DSharpPlus/src/DiscordMessageExtensions.cs deleted file mode 100644 index f43116d..0000000 --- a/X10D.DSharpPlus/src/DiscordMessageExtensions.cs +++ /dev/null @@ -1,76 +0,0 @@ -using DSharpPlus; -using DSharpPlus.Entities; - -namespace X10D.DSharpPlus; - -/// -/// Extension methods for . -/// -public static class DiscordMessageExtensions -{ - /// - /// Deletes this message after a specified delay. - /// - /// The message to delete. - /// The delay before deletion. - /// The reason for the deletion. - /// is . - public static async Task DeleteAfterAsync(this DiscordMessage message, TimeSpan delay, string? reason = null) - { - if (message is null) - { - throw new ArgumentNullException(nameof(message)); - } - - await Task.Delay(delay).ConfigureAwait(false); - await message.DeleteAsync(reason).ConfigureAwait(false); - } - - /// - /// Deletes the message as created by this task after a specified delay. - /// - /// The task whose result should be deleted. - /// The delay before deletion. - /// The reason for the deletion. - /// is . - public static async Task DeleteAfterAsync(this Task task, TimeSpan delay, string? reason = null) - { - if (task is null) - { - throw new ArgumentNullException(nameof(task)); - } - - DiscordMessage message = await task.ConfigureAwait(false); - await message.DeleteAfterAsync(delay, reason).ConfigureAwait(false); - } - - /// - /// 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).ConfigureAwait(false); - return await channel.GetMessageAsync(message.Id).ConfigureAwait(false); - } -} diff --git a/X10D.DSharpPlus/src/DiscordUserExtensions.cs b/X10D.DSharpPlus/src/DiscordUserExtensions.cs deleted file mode 100644 index 33eaa6e..0000000 --- a/X10D.DSharpPlus/src/DiscordUserExtensions.cs +++ /dev/null @@ -1,145 +0,0 @@ -using DSharpPlus; -using DSharpPlus.Entities; -using DSharpPlus.Exceptions; - -namespace X10D.DSharpPlus; - -/// -/// Extension methods for . -/// -public static class DiscordUserExtensions -{ - /// - /// Returns the current as a member of the specified guild. - /// - /// The user to transform. - /// The guild whose member list to search. - /// - /// A whose is equal to , or - /// if this user is not in the specified . - /// - /// - /// is . - /// -or- - /// is . - /// - public static async Task GetAsMemberOfAsync(this DiscordUser user, DiscordGuild guild) - { - if (user is null) - { - throw new ArgumentNullException(nameof(user)); - } - - if (guild is null) - { - throw new ArgumentNullException(nameof(guild)); - } - - if (user is DiscordMember member && member.Guild == guild) - { - return member; - } - - if (guild.Members.TryGetValue(user.Id, out member!)) - { - return member; - } - - try - { - return await guild.GetMemberAsync(user.Id).ConfigureAwait(false); - } - catch (NotFoundException) - { - return null; - } - } - - /// - /// Returns the user's username with the discriminator, in the format username#discriminator. - /// - /// The user whose username and discriminator to retrieve. - /// A string in the format username#discriminator - /// is . - public static string GetUsernameWithDiscriminator(this DiscordUser user) - { - if (user is null) - { - throw new ArgumentNullException(nameof(user)); - } - - if (user.Discriminator == "0") - { - // user has a new username. see: https://discord.com/blog/usernames - return user.Username; - } - - return $"{user.Username}#{user.Discriminator}"; - } - - /// - /// Returns a value indicating whether the current user is in the specified guild. - /// - /// The user to check. - /// The guild whose member list to search. - /// - /// if is a member of ; otherwise, - /// . - /// - public static async Task IsInGuildAsync(this DiscordUser user, DiscordGuild guild) - { - if (user is null) - { - throw new ArgumentNullException(nameof(user)); - } - - if (guild is null) - { - throw new ArgumentNullException(nameof(guild)); - } - - if (guild.Members.TryGetValue(user.Id, out _)) - { - return true; - } - - try - { - DiscordMember? member = await guild.GetMemberAsync(user.Id).ConfigureAwait(false); - return member is not null; - } - catch (NotFoundException) - { - return false; - } - } - - /// - /// 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 DiscordUser user, DiscordClient client) - { - if (user is null) - { - throw new ArgumentNullException(nameof(user)); - } - - if (client is null) - { - throw new ArgumentNullException(nameof(client)); - } - - return await client.GetUserAsync(user.Id).ConfigureAwait(false); - } -} diff --git a/X10D.DSharpPlus/src/MentionUtility.cs b/X10D.DSharpPlus/src/MentionUtility.cs deleted file mode 100644 index efda930..0000000 --- a/X10D.DSharpPlus/src/MentionUtility.cs +++ /dev/null @@ -1,329 +0,0 @@ -using System.Globalization; - -namespace X10D.DSharpPlus; - -/// -/// 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(decimal id) - { - return $"<#{id:N0}>"; - } - - /// - /// 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>. - [CLSCompliant(false)] - public static string MentionChannel(ulong id) - { - return $"<#{id}>"; - } - - /// - /// Returns a role mention string built from the specified channel ID. - /// - /// The ID of the role to mention. - /// A role mention string in the format <@&123>. - public static string MentionRole(decimal id) - { - return $"<@&{id:N0}>"; - } - - /// - /// 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>. - [CLSCompliant(false)] - 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. - /// A user mention string in the format <@123>. - [CLSCompliant(false)] - public static string MentionUser(decimal id) - { - return MentionUser(id, false); - } - - /// - /// 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 . - /// - [CLSCompliant(false)] - public static string MentionUser(decimal id, bool nickname) - { - return nickname ? $"<@!{id:N0}>" : $"<@{id:N0}>"; - } - - /// - /// Returns a user mention string built from the specified user ID. - /// - /// The ID of the user to mention. - /// A user mention string in the format <@123>. - [CLSCompliant(false)] - public static string MentionUser(ulong id) - { - return MentionUser(id, false); - } - - /// - /// 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 . - /// - [CLSCompliant(false)] - public static string MentionUser(ulong id, bool nickname) - { - return nickname ? $"<@!{id}>" : $"<@{id}>"; - } - - /// - /// Parses a provided channel mention string to a decimal value 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 decimal 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 . - /// - /// if the parse was successful; otherwise, . - public static bool TryParseChannel(string? value, out decimal result) - { - result = 0; - if (string.IsNullOrWhiteSpace(value)) - { - return false; - } - - if (value.Length < 3 || value[0] != '<' || value[1] != '#' || value[^1] != '>') - { - return false; - } - - value = value.Substring(2, value.Length - 3); // <#123> - if (!ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out ulong actual)) - { - return false; - } - - result = actual; - return true; - } - - /// - /// 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 . - /// - /// if the parse was successful; otherwise, . - [CLSCompliant(false)] - 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] != '>') - { - return false; - } - - value = value.Substring(2, value.Length - 3); // <#123> - return ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result); - } - - /// - /// Parses a provided role mention string to a decimal value 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 decimal 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 . - /// - /// if the parse was successful; otherwise, . - public static bool TryParseRole(string? value, out decimal result) - { - result = 0; - if (string.IsNullOrWhiteSpace(value)) - { - return false; - } - - if (value.Length < 4 || value[0] != '<' || value[1] != '@' || value[2] != '&' || value[^1] != '>') - { - return false; - } - - value = value.Substring(3, value.Length - 4); // <@&123> - if (!ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out ulong actual)) - { - return false; - } - - result = actual; - return true; - } - - /// - /// 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 . - /// - /// if the parse was successful; otherwise, . - [CLSCompliant(false)] - 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] != '>') - { - return false; - } - - value = value.Substring(3, value.Length - 4); // <@&123> - return ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result); - } - - /// - /// Parses a provided user mention string to a decimal value 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 decimal 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 . - /// - /// if the parse was successful; otherwise, . - public static bool TryParseUser(string? value, out decimal result) - { - result = 0; - if (string.IsNullOrWhiteSpace(value)) - { - return false; - } - - if (value.Length < 3 || value[0] != '<' || value[1] != '@' || value[^1] != '>') - { - return false; - } - - 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 ulong actual)) - { - return false; - } - - result = actual; - return true; - } - - /// - /// 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 . - /// - /// if the parse was successful; otherwise, . - [CLSCompliant(false)] - 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] != '>') - { - return false; - } - - if (value.Length >= 4 && value[2] == '!') - { - value = value.Substring(3, value.Length - 4); // <@!123> - } - else - { - value = value.Substring(2, value.Length - 3); // <@123> - } - - return ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result); - } -} diff --git a/X10D.sln b/X10D.sln index b114966..d552642 100644 --- a/X10D.sln +++ b/X10D.sln @@ -25,8 +25,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "X10D.Unity", "X10D.Unity\X1 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGenerator", "tools\SourceGenerator\SourceGenerator.csproj", "{077A5D33-AD55-4C55-8A67-972CEBC32C7A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "X10D.DSharpPlus", "X10D.DSharpPlus\X10D.DSharpPlus.csproj", "{675D3B25-7EA0-4FC3-B513-8DF27874F2CF}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "X10D.Hosting", "X10D.Hosting\X10D.Hosting.csproj", "{B04AF429-30CF-4B69-81BA-38F560CA9126}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Workflows", "Workflows", "{1FC74E58-F3BA-4F1A-8693-5F80895DA69D}" @@ -79,10 +77,6 @@ Global {077A5D33-AD55-4C55-8A67-972CEBC32C7A}.Debug|Any CPU.Build.0 = Debug|Any CPU {077A5D33-AD55-4C55-8A67-972CEBC32C7A}.Release|Any CPU.ActiveCfg = Release|Any CPU {077A5D33-AD55-4C55-8A67-972CEBC32C7A}.Release|Any CPU.Build.0 = Release|Any CPU - {675D3B25-7EA0-4FC3-B513-8DF27874F2CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {675D3B25-7EA0-4FC3-B513-8DF27874F2CF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {675D3B25-7EA0-4FC3-B513-8DF27874F2CF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {675D3B25-7EA0-4FC3-B513-8DF27874F2CF}.Release|Any CPU.Build.0 = Release|Any CPU {B04AF429-30CF-4B69-81BA-38F560CA9126}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B04AF429-30CF-4B69-81BA-38F560CA9126}.Debug|Any CPU.Build.0 = Debug|Any CPU {B04AF429-30CF-4B69-81BA-38F560CA9126}.Release|Any CPU.ActiveCfg = Release|Any CPU