diff --git a/.gitignore b/.gitignore index 954362408..d72e0b5ea 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,6 @@ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ -x64/ -x86/ build/ bld/ [Bb]in/ diff --git a/docs/_template/description-generator/plugins/DocFX.Plugin.DescriptionGenerator.dll b/docs/_template/description-generator/plugins/DocFX.Plugin.DescriptionGenerator.dll index 3e3a6fb7c..644e9220e 100644 Binary files a/docs/_template/description-generator/plugins/DocFX.Plugin.DescriptionGenerator.dll and b/docs/_template/description-generator/plugins/DocFX.Plugin.DescriptionGenerator.dll differ diff --git a/docs/_template/last-modified/plugins/LICENSE b/docs/_template/last-modified/plugins/LICENSE index eb92c0a03..d74703f3d 100644 --- a/docs/_template/last-modified/plugins/LICENSE +++ b/docs/_template/last-modified/plugins/LICENSE @@ -19,3 +19,11 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +============================================================================== + +Humanizer (https://github.com/Humanizr/Humanizer) +The MIT License (MIT) +Copyright (c) .NET Foundation and Contributors + +============================================================================== \ No newline at end of file diff --git a/docs/_template/last-modified/plugins/LastModifiedPostProcessor.dll b/docs/_template/last-modified/plugins/LastModifiedPostProcessor.dll index d91cf0873..283f45297 100644 Binary files a/docs/_template/last-modified/plugins/LastModifiedPostProcessor.dll and b/docs/_template/last-modified/plugins/LastModifiedPostProcessor.dll differ diff --git a/docs/_template/last-modified/plugins/LibGit2Sharp.dll b/docs/_template/last-modified/plugins/LibGit2Sharp.dll new file mode 100644 index 000000000..b8e7f4a7b Binary files /dev/null and b/docs/_template/last-modified/plugins/LibGit2Sharp.dll differ diff --git a/docs/_template/last-modified/plugins/LibGit2Sharp.dll.config b/docs/_template/last-modified/plugins/LibGit2Sharp.dll.config new file mode 100644 index 000000000..d59fd738f --- /dev/null +++ b/docs/_template/last-modified/plugins/LibGit2Sharp.dll.config @@ -0,0 +1,4 @@ + + + + diff --git a/docs/_template/last-modified/plugins/lib/alpine-x64/libgit2-8e0b172.so b/docs/_template/last-modified/plugins/lib/alpine-x64/libgit2-8e0b172.so new file mode 100644 index 000000000..efd678335 Binary files /dev/null and b/docs/_template/last-modified/plugins/lib/alpine-x64/libgit2-8e0b172.so differ diff --git a/docs/_template/last-modified/plugins/lib/debian.9-x64/libgit2-8e0b172.so b/docs/_template/last-modified/plugins/lib/debian.9-x64/libgit2-8e0b172.so new file mode 100644 index 000000000..b51cf2342 Binary files /dev/null and b/docs/_template/last-modified/plugins/lib/debian.9-x64/libgit2-8e0b172.so differ diff --git a/docs/_template/last-modified/plugins/lib/fedora-x64/libgit2-8e0b172.so b/docs/_template/last-modified/plugins/lib/fedora-x64/libgit2-8e0b172.so new file mode 100644 index 000000000..7071c172f Binary files /dev/null and b/docs/_template/last-modified/plugins/lib/fedora-x64/libgit2-8e0b172.so differ diff --git a/docs/_template/last-modified/plugins/lib/linux-x64/libgit2-8e0b172.so b/docs/_template/last-modified/plugins/lib/linux-x64/libgit2-8e0b172.so new file mode 100644 index 000000000..3b678b6ec Binary files /dev/null and b/docs/_template/last-modified/plugins/lib/linux-x64/libgit2-8e0b172.so differ diff --git a/docs/_template/last-modified/plugins/lib/osx/libgit2-8e0b172.dylib b/docs/_template/last-modified/plugins/lib/osx/libgit2-8e0b172.dylib new file mode 100644 index 000000000..517c8135a Binary files /dev/null and b/docs/_template/last-modified/plugins/lib/osx/libgit2-8e0b172.dylib differ diff --git a/docs/_template/last-modified/plugins/lib/rhel-x64/libgit2-8e0b172.so b/docs/_template/last-modified/plugins/lib/rhel-x64/libgit2-8e0b172.so new file mode 100644 index 000000000..aac190aaf Binary files /dev/null and b/docs/_template/last-modified/plugins/lib/rhel-x64/libgit2-8e0b172.so differ diff --git a/docs/_template/last-modified/plugins/lib/win32/x64/git2-8e0b172.dll b/docs/_template/last-modified/plugins/lib/win32/x64/git2-8e0b172.dll new file mode 100644 index 000000000..117a78b49 Binary files /dev/null and b/docs/_template/last-modified/plugins/lib/win32/x64/git2-8e0b172.dll differ diff --git a/docs/_template/last-modified/plugins/lib/win32/x86/git2-8e0b172.dll b/docs/_template/last-modified/plugins/lib/win32/x86/git2-8e0b172.dll new file mode 100644 index 000000000..7b709023c Binary files /dev/null and b/docs/_template/last-modified/plugins/lib/win32/x86/git2-8e0b172.dll differ diff --git a/docs/_template/light-dark-theme/styles/dark.css b/docs/_template/light-dark-theme/styles/dark.css index 0a021b377..8ae0049d1 100644 --- a/docs/_template/light-dark-theme/styles/dark.css +++ b/docs/_template/light-dark-theme/styles/dark.css @@ -301,4 +301,8 @@ span.arrow-d{ span.arrow-r{ border-left: 5px solid white -} \ No newline at end of file +} + +.logo-switcher { + background: url("/marketing/logo/SVG/Combinationmark White.svg") no-repeat; +} diff --git a/docs/_template/light-dark-theme/styles/gray.css b/docs/_template/light-dark-theme/styles/gray.css index 1d914368a..32ff7d208 100644 --- a/docs/_template/light-dark-theme/styles/gray.css +++ b/docs/_template/light-dark-theme/styles/gray.css @@ -308,4 +308,8 @@ span.arrow-d{ span.arrow-r{ border-left: 5px solid white -} \ No newline at end of file +} + +.logo-switcher { + background: url("/marketing/logo/SVG/Combinationmark White.svg") no-repeat; +} diff --git a/docs/_template/light-dark-theme/styles/light.css b/docs/_template/light-dark-theme/styles/light.css index a5360711f..71910e774 100644 --- a/docs/_template/light-dark-theme/styles/light.css +++ b/docs/_template/light-dark-theme/styles/light.css @@ -110,4 +110,8 @@ span.arrow-d{ span.arrow-r{ border-left: 5px solid black -} \ No newline at end of file +} + +.logo-switcher { + background: url("/marketing/logo/SVG/Combinationmark.svg") no-repeat; +} diff --git a/docs/_template/light-dark-theme/styles/master.css b/docs/_template/light-dark-theme/styles/master.css index 4e0dffd7a..4c01568e0 100644 --- a/docs/_template/light-dark-theme/styles/master.css +++ b/docs/_template/light-dark-theme/styles/master.css @@ -9,6 +9,15 @@ body { scroll-behavior: smooth; } +#logo +{ + max-width: 100px; + max-height: 100px; + width: 38pt; + height: 38pt; + padding: 8pt; +} + p, li, .toc { @@ -23,6 +32,15 @@ img { margin-bottom: 15px; } +.big-logo { + display: block; + box-shadow: none !important; + /* Width value was taken from the original size of the combomark svg */ + width: 951pt; + /* Height was arbitrarily determined */ + min-height: 100pt; +} + article.content p{ -webkit-transition: all .75s ease-in-out; transition: all .75s ease-in-out; @@ -153,4 +171,4 @@ span.arrow-d{ span.arrow-r{ top: 6px; position: relative; -} \ No newline at end of file +} diff --git a/docs/docfx.json b/docs/docfx.json index 2a50869d6..5ea6b895b 100644 --- a/docs/docfx.json +++ b/docs/docfx.json @@ -24,13 +24,19 @@ }, { "files": ["guides/**.md", "guides/**/toc.yml"] + }, + { + "src": "../", + "files": [ "CHANGELOG.md" ] } ], "resource": [{ "files": [ "**/images/**", "**/samples/**", - "langwordMapping.yml" + "langwordMapping.yml", + "marketing/logo/SVG/**.svg", + "favicon.ico" ] }], "dest": "_site", @@ -45,7 +51,9 @@ "globalMetadata": { "_appTitle": "Discord.Net Documentation", "_appFooter": "Discord.Net (c) 2015-2018 2.0.0-beta", - "_enableSearch": true + "_enableSearch": true, + "_appLogoPath": "marketing/logo/SVG/Logomark Purple.svg", + "_appFaviconPath": "favicon.ico" }, "xrefService": [ "https://xref.docs.microsoft.com/query?uid={uid}" diff --git a/docs/faq/basics/basic-operations.md b/docs/faq/basics/basic-operations.md index 16f98c3b9..93811977f 100644 --- a/docs/faq/basics/basic-operations.md +++ b/docs/faq/basics/basic-operations.md @@ -27,7 +27,7 @@ A good and safe casting example: [!code-csharp[Casting](samples/cast.cs)] [InvalidCastException]: https://docs.microsoft.com/en-us/dotnet/api/system.invalidcastexception -[this post]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/how-to-safely-cast-by-using-as-and-is-operators +[this post]: https://docs.microsoft.com/en-us/dotnet/csharp/how-to/safely-cast-using-pattern-matching-is-and-as-operators ## How do I send a message? diff --git a/docs/faq/commands/general.md b/docs/faq/commands/general.md index fb6fe39b6..de6d48dc1 100644 --- a/docs/faq/commands/general.md +++ b/docs/faq/commands/general.md @@ -119,24 +119,29 @@ The following are the known caveats with `RunMode.Async`, 3. [ExecuteAsync] will immediately return [ExecuteResult] instead of other result types (this is particularly important for those who wish to utilize [RuntimeResult] in 2.0). -4. Exceptions are swallowed. +4. Exceptions are swallowed in the `ExecuteAsync` result. However, there are ways to remedy some of these. For #3, in Discord.Net 2.0, the library introduces a new event called -[CommandExecuted], which is raised whenever the command is -**successfully executed**. This event will be raised regardless of -the `RunMode` type and will return the appropriate execution result. +[CommandService.CommandExecuted], which is raised whenever the command is executed. +This event will be raised regardless of +the `RunMode` type and will return the appropriate execution result +and the associated @Discord.Commands.CommandInfo if applicable. For #4, exceptions are caught in [CommandService.Log] event under -[LogMessage.Exception] as [CommandException]. +[LogMessage.Exception] as [CommandException] and in the +[CommandService.CommandExecuted] event under the [IResult] as +[ExecuteResult.Exception]. [Task.Run]: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run [async state machine]: https://www.red-gate.com/simple-talk/dotnet/net-tools/c-async-what-is-it-and-how-does-it-work/ [ExecuteAsync]: xref:Discord.Commands.CommandService.ExecuteAsync* [ExecuteResult]: xref:Discord.Commands.ExecuteResult [RuntimeResult]: xref:Discord.Commands.RuntimeResult -[CommandExecuted]: xref:Discord.Commands.CommandService.CommandExecuted +[CommandService.CommandExecuted]: xref:Discord.Commands.CommandService.CommandExecuted [CommandService.Log]: xref:Discord.Commands.CommandService.Log [LogMessage.Exception]: xref:Discord.LogMessage.Exception* -[CommandException]: xref:Discord.Commands.CommandException \ No newline at end of file +[ExecuteResult.Exception]: xref:Discord.Commands.ExecuteResult.Exception* +[CommandException]: xref:Discord.Commands.CommandException +[IResult]: xref:Discord.Commands.IResult \ No newline at end of file diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 000000000..34a2cd1ca Binary files /dev/null and b/docs/favicon.ico differ diff --git a/docs/guides/commands/post-execution.md b/docs/guides/commands/post-execution.md index 28f63659b..782d256b2 100644 --- a/docs/guides/commands/post-execution.md +++ b/docs/guides/commands/post-execution.md @@ -31,17 +31,15 @@ be a violation of the SRP (Single Responsibility Principle). Another major issue is if your command is marked with `RunMode.Async`, [ExecuteAsync] will **always** return a successful [ExecuteResult] instead of the actual result. You can learn more -about the impact in the [FAQ](xref:FAQ.Commands.General). +about the impact in @FAQ.Commands.General. ## CommandExecuted Event Enter [CommandExecuted], an event that was introduced in Discord.Net 2.0. This event is raised whenever a command is -successfully executed **without any run-time exceptions** or **any -parsing or precondition failure**. This means this event can be -used to streamline your post-execution design, and the best thing -about this event is that it is not prone to `RunMode.Async`'s -[ExecuteAsync] drawbacks. +executed regardless of its execution status. This means this +event can be used to streamline your post-execution design, +is not prone to `RunMode.Async`'s [ExecuteAsync] drawbacks. Thus, we can begin working on code such as: diff --git a/docs/guides/commands/samples/intro/command_handler.cs b/docs/guides/commands/samples/intro/command_handler.cs index efb31f9b9..b962cdd6c 100644 --- a/docs/guides/commands/samples/intro/command_handler.cs +++ b/docs/guides/commands/samples/intro/command_handler.cs @@ -49,7 +49,7 @@ public class CommandHandler // Keep in mind that result does not indicate a return value // rather an object stating if the command executed successfully. - var result = await _command.ExecuteAsync( + var result = await _commands.ExecuteAsync( context: context, argPos: argPos, services: null); diff --git a/docs/guides/commands/samples/post-execution/command_executed_adv_demo.cs b/docs/guides/commands/samples/post-execution/command_executed_adv_demo.cs index 1ce40c51d..dbd75f040 100644 --- a/docs/guides/commands/samples/post-execution/command_executed_adv_demo.cs +++ b/docs/guides/commands/samples/post-execution/command_executed_adv_demo.cs @@ -1,4 +1,4 @@ -public async Task OnCommandExecutedAsync(CommandInfo command, ICommandContext context, IResult result) +public async Task OnCommandExecutedAsync(Optional command, ICommandContext context, IResult result) { switch(result) { diff --git a/docs/guides/commands/samples/post-execution/command_executed_demo.cs b/docs/guides/commands/samples/post-execution/command_executed_demo.cs index b87f4ef06..a0b26183e 100644 --- a/docs/guides/commands/samples/post-execution/command_executed_demo.cs +++ b/docs/guides/commands/samples/post-execution/command_executed_demo.cs @@ -6,7 +6,7 @@ public async Task SetupAsync() // Hook the command handler _client.MessageReceived += HandleCommandAsync; } -public async Task OnCommandExecutedAsync(CommandInfo command, ICommandContext context, IResult result) +public async Task OnCommandExecutedAsync(Optional command, ICommandContext context, IResult result) { // We have access to the information of the command executed, // the context of the command, and the result returned from the @@ -20,19 +20,19 @@ public async Task OnCommandExecutedAsync(CommandInfo command, ICommandContext co // ...or even log the result (the method used should fit into // your existing log handler) - await _log.LogAsync(new LogMessage(LogSeverity.Info, "CommandExecution", $"{command?.Name} was executed at {DateTime.UtcNow}.")); + var commandName = command.IsSpecified ? command.Value.Name : "A command"; + await _log.LogAsync(new LogMessage(LogSeverity.Info, + "CommandExecution", + $"{commandName} was executed at {DateTime.UtcNow}.")); } public async Task HandleCommandAsync(SocketMessage msg) { var message = messageParam as SocketUserMessage; if (message == null) return; int argPos = 0; - if (!(message.HasCharPrefix('!', ref argPos) || message.HasMentionPrefix(_client.CurrentUser, ref argPos)) || message.Author.IsBot) return; + if (!(message.HasCharPrefix('!', ref argPos) || + message.HasMentionPrefix(_client.CurrentUser, ref argPos)) || + message.Author.IsBot) return; var context = new SocketCommandContext(_client, message); - var result = await _commands.ExecuteAsync(context, argPos, _services); - // Optionally, you may pass the result manually into your - // CommandExecuted event handler if you wish to handle parsing or - // precondition failures in the same method. - - // await OnCommandExecutedAsync(null, context, result); + await _commands.ExecuteAsync(context, argPos, _services); } diff --git a/docs/guides/commands/samples/post-execution/post-execution_basic.cs b/docs/guides/commands/samples/post-execution/post-execution_basic.cs index 19c7bed59..d1361a1f2 100644 --- a/docs/guides/commands/samples/post-execution/post-execution_basic.cs +++ b/docs/guides/commands/samples/post-execution/post-execution_basic.cs @@ -1,11 +1,14 @@ +// Bad code!!! var result = await _commands.ExecuteAsync(context, argPos, _services); if (result.CommandError != null) switch(result.CommandError) { case CommandError.BadArgCount: - await context.Channel.SendMessageAsync("Parameter count does not match any command's."); + await context.Channel.SendMessageAsync( + "Parameter count does not match any command's."); break; default: - await context.Channel.SendMessageAsync($"An error has occurred {result.ErrorReason}"); + await context.Channel.SendMessageAsync( + $"An error has occurred {result.ErrorReason}"); break; } \ No newline at end of file diff --git a/docs/guides/deployment/deployment.md b/docs/guides/deployment/deployment.md index b75628dc0..0491e841d 100644 --- a/docs/guides/deployment/deployment.md +++ b/docs/guides/deployment/deployment.md @@ -52,33 +52,50 @@ enough. Here is a list of recommended VPS provider. > [!NOTE] > This section only covers the very basics of .NET Core deployment. -> To learn more about deployment, visit [.NET Core application deployment] -> by Microsoft. +> To learn more about .NET Core deployment, +> visit [.NET Core application deployment] by Microsoft. -By default, .NET Core compiles all projects as a DLL file, so that any -.NET Core runtime can execute the application. +When redistributing the application - whether for deployment on a +remote machine or for sharing with another user - you may want to +publish the application; in other words, to create a +self-contained package without installing the dependencies +and the runtime on the target platform. -You may execute the application via `dotnet myprogram.dll` assuming you -have the dotnet CLI installed. +### Framework-dependent Deployment -When redistributing the application, you may want to publish the -application, or in other words, create a self-contained package -for use on another machine without installing the dependencies first. - -This can be achieved by using the dotnet CLI too on the development -machine: +To deploy a framework-dependent package (i.e. files to be used on a +remote machine with the `dotnet` command), simply publish +the package with: * `dotnet publish -c Release` -Additionally, you may want to target a specific platform when -publishing the application so you may use the application without -having to install the Core runtime on the target machine. To do this, -you may specify an [Runtime ID] upon build/publish with the `-r` -option. - -For example, when targeting a Windows 10 machine, you may want to use -the following to create the application in Windows executable -format (.exe): +This will create a package with the **least dependencies** +included with the application; however, the remote machine +must have `dotnet` runtime installed before the remote could run the +program. + +> [!TIP] +> Do not know how to run a .NET Core application with +> the `dotnet` runtime? Navigate to the folder of the program +> (typically under `$projFolder/bin/Release`) and +> enter `dotnet program.dll` where `program.dll` is your compiled +> binaries. + +### Self-contained Deployment + +To deploy a self-contained package (i.e. files to be used on a remote +machine without the `dotnet` runtime), publish with a specific +[Runtime ID] with the `-r` switch. + +This will create a package with dependencies compiled for the target +platform, meaning that all the required dependencies will be included +with the program. This will result in **larger package size**; +however, that means the copy of the runtime that can be run +natively on the target platform. + +For example, the following command will create a Windows +executable (`.exe`) that is ready to be executed on any +Windows 10 x64 based machine: * `dotnet publish -c Release -r win10-x64` diff --git a/docs/index.md b/docs/index.md index 8622bc002..7262b1033 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,6 +5,8 @@ title: Home # Discord.Net Documentation + + ## What is Discord.Net? Discord.Net is an asynchronous, multi-platform .NET Library used to @@ -25,4 +27,4 @@ objects in the library. - [GitHub](https://github.com/RogueException/Discord.Net/) - [NuGet](https://www.nuget.org/packages/Discord.Net/) - [MyGet Feed](https://www.myget.org/feed/Packages/discord-net) - Add-ons and nightly builds -- [AppVeyor CI](https://ci.appveyor.com/project/RogueException/discord-net) - Nightly builds via Continuous Integration \ No newline at end of file +- [AppVeyor CI](https://ci.appveyor.com/project/RogueException/discord-net) - Nightly builds via Continuous Integration diff --git a/docs/marketing/logo/SVG/Logomark Purple.svg b/docs/marketing/logo/SVG/Logomark Purple.svg index 9f7efad83..16d3789a1 100644 --- a/docs/marketing/logo/SVG/Logomark Purple.svg +++ b/docs/marketing/logo/SVG/Logomark Purple.svg @@ -1 +1 @@ -Logomark Purple \ No newline at end of file +Discord.Net Docs \ No newline at end of file diff --git a/docs/toc.yml b/docs/toc.yml index 337294b1a..bea010c5a 100644 --- a/docs/toc.yml +++ b/docs/toc.yml @@ -6,4 +6,6 @@ topicUid: FAQ.Basics.GetStarted - name: API Documentation href: api/ - topicUid: API.Docs \ No newline at end of file + topicUid: API.Docs +- name: Changelog + topicHref: ../CHANGELOG.md \ No newline at end of file diff --git a/src/Discord.Net.Commands/Extensions/CommandServiceExtensions.cs b/src/Discord.Net.Commands/Extensions/CommandServiceExtensions.cs index 675a9073d..4c2262f9b 100644 --- a/src/Discord.Net.Commands/Extensions/CommandServiceExtensions.cs +++ b/src/Discord.Net.Commands/Extensions/CommandServiceExtensions.cs @@ -5,8 +5,20 @@ using System.Threading.Tasks; namespace Discord.Commands { + /// + /// Provides extension methods for the class. + /// public static class CommandServiceExtensions { + /// + /// Returns commands that can be executed under the current context. + /// + /// The set of commands to be checked against. + /// The current command context. + /// The service provider used for dependency injection upon precondition check. + /// + /// A read-only collection of commands that can be executed under the current context. + /// public static async Task> GetExecutableCommandsAsync(this ICollection commands, ICommandContext context, IServiceProvider provider) { var executableCommands = new List(); @@ -27,8 +39,26 @@ namespace Discord.Commands return executableCommands; } + /// + /// Returns commands that can be executed under the current context. + /// + /// The desired command service class to check against. + /// The current command context. + /// The service provider used for dependency injection upon precondition check. + /// + /// A read-only collection of commands that can be executed under the current context. + /// public static Task> GetExecutableCommandsAsync(this CommandService commandService, ICommandContext context, IServiceProvider provider) => GetExecutableCommandsAsync(commandService.Commands.ToArray(), context, provider); + /// + /// Returns commands that can be executed under the current context. + /// + /// The module to be checked against. + /// The current command context. + /// The service provider used for dependency injection upon precondition check. + /// + /// A read-only collection of commands that can be executed under the current context. + /// public static async Task> GetExecutableCommandsAsync(this ModuleInfo module, ICommandContext context, IServiceProvider provider) { var executableCommands = new List(); diff --git a/src/Discord.Net.Core/Entities/Activities/Game.cs b/src/Discord.Net.Core/Entities/Activities/Game.cs index 5be99cacb..f232cc5bf 100644 --- a/src/Discord.Net.Core/Entities/Activities/Game.cs +++ b/src/Discord.Net.Core/Entities/Activities/Game.cs @@ -15,10 +15,10 @@ namespace Discord internal Game() { } /// - /// Creates a with the provided and . + /// Creates a with the provided name and . /// /// The name of the game. - /// The type of activity. Default is . + /// The type of activity. public Game(string name, ActivityType type = ActivityType.Playing) { Name = name; diff --git a/src/Discord.Net.Core/Entities/Channels/Direction.cs b/src/Discord.Net.Core/Entities/Channels/Direction.cs index 6d5f7cd6b..278070bce 100644 --- a/src/Discord.Net.Core/Entities/Channels/Direction.cs +++ b/src/Discord.Net.Core/Entities/Channels/Direction.cs @@ -1,8 +1,16 @@ namespace Discord { /// - /// Specifies the direction of where message(s) should be gotten from. + /// Specifies the direction of where message(s) should be retrieved from. /// + /// + /// This enum is used to specify the direction for retrieving messages. + /// + /// At the time of writing, is not yet implemented into + /// . Attempting to use the method with + /// as its direction will throw a . + /// + /// public enum Direction { /// diff --git a/src/Discord.Net.Core/Entities/Channels/GuildChannelProperties.cs b/src/Discord.Net.Core/Entities/Channels/GuildChannelProperties.cs index 4e92a2369..9552b0a60 100644 --- a/src/Discord.Net.Core/Entities/Channels/GuildChannelProperties.cs +++ b/src/Discord.Net.Core/Entities/Channels/GuildChannelProperties.cs @@ -24,6 +24,11 @@ namespace Discord /// /// Gets or sets the category ID for this channel. /// + /// + /// Setting this value to a category's snowflake identifier will change or set this channel's parent to the + /// specified channel; setting this value to 0 will detach this channel from its parent if one + /// is set. + /// public Optional CategoryId { get; set; } } } diff --git a/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs b/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs index 1da1879de..dab7f436d 100644 --- a/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs +++ b/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs @@ -47,6 +47,10 @@ namespace Discord /// /// Modifies this guild channel. /// + /// + /// This method modifies the current guild channel with the specified properties. To see an example of this + /// method and what properties are available, please refer to . + /// /// The delegate containing the properties to modify the channel with. /// The options to be used when sending the request. /// @@ -92,16 +96,61 @@ namespace Discord /// /// Adds or updates the permission overwrite for the given role. /// + /// + /// The following example fetches a role via and a channel via + /// . Next, it checks if an overwrite had already been set via + /// ; if not, it denies the role from sending any + /// messages to the channel. + /// + /// // Fetches the role and channels + /// var role = guild.GetRole(339805618376540160); + /// var channel = await guild.GetChannelAsync(233937283911385098); + /// + /// // If either the of the object does not exist, bail + /// if (role == null || channel == null) return; + /// + /// // Fetches the previous overwrite and bail if one is found + /// var previousOverwrite = channel.GetPermissionOverwrite(role); + /// if (previousOverwrite.HasValue) return; + /// + /// // Creates a new OverwritePermissions with send message set to deny and pass it into the method + /// await channel.AddPermissionOverwriteAsync(role, + /// new OverwritePermissions(sendMessage: PermValue.Deny)); + /// + /// /// The role to add the overwrite to. /// The overwrite to add to the role. /// The options to be used when sending the request. /// - /// A task representing the asynchronous permission operation for adding the specified permissions to the channel. + /// A task representing the asynchronous permission operation for adding the specified permissions to the + /// channel. /// Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null); /// /// Adds or updates the permission overwrite for the given user. /// + /// + /// The following example fetches a user via and a channel via + /// . Next, it checks if an overwrite had already been set via + /// ; if not, it denies the user from sending any + /// messages to the channel. + /// + /// // Fetches the role and channels + /// var user = await guild.GetUserAsync(168693960628371456); + /// var channel = await guild.GetChannelAsync(233937283911385098); + /// + /// // If either the of the object does not exist, bail + /// if (user == null || channel == null) return; + /// + /// // Fetches the previous overwrite and bail if one is found + /// var previousOverwrite = channel.GetPermissionOverwrite(user); + /// if (previousOverwrite.HasValue) return; + /// + /// // Creates a new OverwritePermissions with send message set to deny and pass it into the method + /// await channel.AddPermissionOverwriteAsync(role, + /// new OverwritePermissions(sendMessage: PermValue.Deny)); + /// + /// /// The user to add the overwrite to. /// The overwrite to add to the user. /// The options to be used when sending the request. diff --git a/src/Discord.Net.Core/Entities/Channels/TextChannelProperties.cs b/src/Discord.Net.Core/Entities/Channels/TextChannelProperties.cs index fbe4bfa43..6dcbf860a 100644 --- a/src/Discord.Net.Core/Entities/Channels/TextChannelProperties.cs +++ b/src/Discord.Net.Core/Entities/Channels/TextChannelProperties.cs @@ -1,3 +1,5 @@ +using System; + namespace Discord { /// @@ -9,18 +11,29 @@ namespace Discord /// /// Gets or sets the topic of the channel. /// + /// + /// Setting this value to any string other than null or will set the + /// channel topic or description to the desired value. + /// public Optional Topic { get; set; } /// /// Gets or sets whether this channel should be flagged as NSFW. /// + /// + /// Setting this value to true will mark the channel as NSFW (Not Safe For Work) and will prompt the + /// user about its possibly mature nature before they may view the channel; setting this value to false will + /// remove the NSFW indicator. + /// public Optional IsNsfw { get; set; } /// /// Gets or sets the slow-mode ratelimit in seconds for this channel. /// /// - /// Setting this value to 0 will disable slow-mode for this channel. + /// Setting this value to anything above zero will require each user to wait X seconds before + /// sending another message; setting this value to 0 will disable slow-mode for this channel. /// - /// Users with will be exempt from slow-mode. + /// Users with or + /// will be exempt from slow-mode. /// /// /// Thrown if the value does not fall within [0, 120]. diff --git a/src/Discord.Net.Core/Entities/Emotes/GuildEmote.cs b/src/Discord.Net.Core/Entities/Emotes/GuildEmote.cs index 1c5b3af9e..4bd0845c8 100644 --- a/src/Discord.Net.Core/Entities/Emotes/GuildEmote.cs +++ b/src/Discord.Net.Core/Entities/Emotes/GuildEmote.cs @@ -31,10 +31,11 @@ namespace Discord /// public IReadOnlyList RoleIds { get; } /// - /// Gets the user Id that created this emoji. + /// Gets the user ID associated with the creation of this emoji. /// /// - /// A user Id of the user who created this emoji, which may be null. A null value only indicates that the creator was not supplied as part of the API response. + /// An snowflake identifier representing the user who created this emoji; + /// null if unknown. /// public ulong? CreatorId { get; } diff --git a/src/Discord.Net.Core/Entities/Invites/IInvite.cs b/src/Discord.Net.Core/Entities/Invites/IInvite.cs index 6455b9f5c..993f1f047 100644 --- a/src/Discord.Net.Core/Entities/Invites/IInvite.cs +++ b/src/Discord.Net.Core/Entities/Invites/IInvite.cs @@ -27,7 +27,9 @@ namespace Discord /// A generic channel that the invite points to. /// IChannel Channel { get; } - /// Gets the type of the channel this invite is linked to. + /// + /// Gets the type of the channel this invite is linked to. + /// ChannelType ChannelType { get; } /// /// Gets the ID of the channel this invite is linked to. diff --git a/src/Discord.Net.Core/Entities/Messages/IAttachment.cs b/src/Discord.Net.Core/Entities/Messages/IAttachment.cs index 13b2cf48a..655777998 100644 --- a/src/Discord.Net.Core/Entities/Messages/IAttachment.cs +++ b/src/Discord.Net.Core/Entities/Messages/IAttachment.cs @@ -1,7 +1,7 @@ namespace Discord { /// - /// Represents a Discord attachment. + /// Represents a message attachment found in a . /// public interface IAttachment { diff --git a/src/Discord.Net.Core/Entities/Messages/IMessage.cs b/src/Discord.Net.Core/Entities/Messages/IMessage.cs index 33e019419..a53ae71e4 100644 --- a/src/Discord.Net.Core/Entities/Messages/IMessage.cs +++ b/src/Discord.Net.Core/Entities/Messages/IMessage.cs @@ -48,7 +48,7 @@ namespace Discord /// Gets the time of this message's last edit. /// /// - /// Time of when the message was last edited; null when the message is never edited. + /// Time of when the message was last edited; null if the message is never edited. /// DateTimeOffset? EditedTimestamp { get; } @@ -62,56 +62,67 @@ namespace Discord IUser Author { get; } /// - /// Returns all attachments included in this message. + /// Gets all attachments included in this message. /// + /// + /// This property gets a read-only collection of attachments associated with this message. Depending on the + /// user's end-client, a sent message may contain one or more attachments. For example, mobile users may + /// attach more than one file in their message, while the desktop client only allows for one. + /// /// /// A read-only collection of attachments. /// IReadOnlyCollection Attachments { get; } /// - /// Returns all embeds included in this message. + /// Gets all embeds included in this message. /// + /// + /// + /// This property gets a read-only collection of embeds associated with this message. Depending on the + /// message, a sent message may contain one or more embeds. This is usually true when multiple link previews + /// are generated; however, only one can be featured. /// /// A read-only collection of embed objects. /// IReadOnlyCollection Embeds { get; } /// - /// Returns all tags included in this message's content. + /// Gets all tags included in this message's content. /// IReadOnlyCollection Tags { get; } /// - /// Returns the IDs of channels mentioned in this message. + /// Gets the IDs of channels mentioned in this message. /// /// /// A read-only collection of channel IDs. /// IReadOnlyCollection MentionedChannelIds { get; } /// - /// Returns the IDs of roles mentioned in this message. + /// Gets the IDs of roles mentioned in this message. /// /// /// A read-only collection of role IDs. /// IReadOnlyCollection MentionedRoleIds { get; } /// - /// Returns the IDs of users mentioned in this message. + /// Gets the IDs of users mentioned in this message. /// /// /// A read-only collection of user IDs. /// IReadOnlyCollection MentionedUserIds { get; } /// - /// Returns the Activity associated with a message. + /// Gets the activity associated with a message. /// /// - /// Sent with Rich Presence-related chat embeds. + /// Sent with Rich Presence-related chat embeds. This often refers to activity that requires end-user's + /// interaction, such as a Spotify Invite activity. /// /// /// A message's activity, if any is associated. /// MessageActivity Activity { get; } /// - /// Returns the Application associated with a messsage. + /// Gets the application associated with a message. /// /// /// Sent with Rich-Presence-related chat embeds. diff --git a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs index b31890e51..1a8c54ab1 100644 --- a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs +++ b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs @@ -12,10 +12,15 @@ namespace Discord /// /// Modifies this message. /// + /// + /// This method modifies this message with the specified properties. To see an example of this + /// method and what properties are available, please refer to . + /// /// - /// - /// await msg.ModifyAsync(x => x.Content = "Hello World!"); - /// + /// The following example replaces the content of the message with Hello World!. + /// + /// await msg.ModifyAsync(x => x.Content = "Hello World!"); + /// /// /// A delegate containing the properties to modify the message with. /// The options to be used when sending the request. @@ -49,9 +54,10 @@ namespace Discord /// Adds a reaction to this message. /// /// - /// - /// await msg.AddReactionAsync(new Emoji("\U0001f495")); - /// + /// The following example adds the reaction, 💕, to the message. + /// + /// await msg.AddReactionAsync(new Emoji("\U0001f495")); + /// /// /// The emoji used to react to this message. /// The options to be used when sending the request. @@ -64,9 +70,10 @@ namespace Discord /// Removes a reaction from message. /// /// - /// - /// await msg.RemoveReactionAsync(new Emoji("\U0001f495"), msg.Author); - /// + /// The following example removes the reaction, 💕, added by the message author from the message. + /// + /// await msg.RemoveReactionAsync(new Emoji("\U0001f495"), msg.Author); + /// /// /// The emoji used to react to this message. /// The user that added the emoji. @@ -89,6 +96,7 @@ namespace Discord /// Gets all users that reacted to a message with a given emote. /// /// + /// The following example gets the users that have reacted with the emoji 💕 to the message. /// /// var emoji = new Emoji("\U0001f495"); /// var reactedUsers = await message.GetReactionUsersAsync(emoji, 100).FlattenAsync(); diff --git a/src/Discord.Net.Core/Entities/Messages/MessageActivity.cs b/src/Discord.Net.Core/Entities/Messages/MessageActivity.cs index b539b8f9b..ff4ae406b 100644 --- a/src/Discord.Net.Core/Entities/Messages/MessageActivity.cs +++ b/src/Discord.Net.Core/Entities/Messages/MessageActivity.cs @@ -1,12 +1,17 @@ -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Discord { + /// + /// An activity object found in a sent message. + /// + /// + /// + /// This class refers to an activity object, visually similar to an embed within a message. However, a message + /// activity is interactive as opposed to a standard static embed. + /// + /// For example, a Spotify party invitation counts as a message activity. + /// [DebuggerDisplay(@"{DebuggerDisplay,nq}")] public class MessageActivity { diff --git a/src/Discord.Net.Core/Entities/Messages/MessageApplication.cs b/src/Discord.Net.Core/Entities/Messages/MessageApplication.cs index 05616cb59..39a599da3 100644 --- a/src/Discord.Net.Core/Entities/Messages/MessageApplication.cs +++ b/src/Discord.Net.Core/Entities/Messages/MessageApplication.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Discord { diff --git a/src/Discord.Net.Core/Entities/Messages/MessageProperties.cs b/src/Discord.Net.Core/Entities/Messages/MessageProperties.cs index 2cc0eab8e..b632d6a18 100644 --- a/src/Discord.Net.Core/Entities/Messages/MessageProperties.cs +++ b/src/Discord.Net.Core/Entities/Messages/MessageProperties.cs @@ -4,7 +4,8 @@ namespace Discord /// Properties that are used to modify an with the specified changes. /// /// - /// The content of a message can be cleared with if and only if an is present. + /// The content of a message can be cleared with if and only if an + /// is present. /// /// public class MessageProperties diff --git a/src/Discord.Net.Core/Entities/Roles/IRole.cs b/src/Discord.Net.Core/Entities/Roles/IRole.cs index dcfc89cc6..66556fc2c 100644 --- a/src/Discord.Net.Core/Entities/Roles/IRole.cs +++ b/src/Discord.Net.Core/Entities/Roles/IRole.cs @@ -69,16 +69,10 @@ namespace Discord /// /// Modifies this role. /// - /// - /// - /// await role.ModifyAsync(x => - /// { - /// x.Name = "Sonic"; - /// x.Color = new Color(0x1A50BC); - /// x.Mentionable = true; - /// }); - /// - /// + /// + /// This method modifies this role with the specified properties. To see an example of this + /// method and what properties are available, please refer to . + /// /// A delegate containing the properties to modify the role with. /// The options to be used when sending the request. /// diff --git a/src/Discord.Net.Core/Entities/Roles/RoleProperties.cs b/src/Discord.Net.Core/Entities/Roles/RoleProperties.cs index df23cf7b1..a58112b28 100644 --- a/src/Discord.Net.Core/Entities/Roles/RoleProperties.cs +++ b/src/Discord.Net.Core/Entities/Roles/RoleProperties.cs @@ -3,6 +3,18 @@ namespace Discord /// /// Properties that are used to modify an with the specified changes. /// + /// + /// The following example modifies the role to a mentionable one, renames the role into Sonic, and + /// changes the color to a light-blue. + /// + /// await role.ModifyAsync(x => + /// { + /// x.Name = "Sonic"; + /// x.Color = new Color(0x1A50BC); + /// x.Mentionable = true; + /// }); + /// + /// /// public class RoleProperties { diff --git a/src/Discord.Net.Core/Entities/Users/IGuildUser.cs b/src/Discord.Net.Core/Entities/Users/IGuildUser.cs index 633056733..718587ae4 100644 --- a/src/Discord.Net.Core/Entities/Users/IGuildUser.cs +++ b/src/Discord.Net.Core/Entities/Users/IGuildUser.cs @@ -50,15 +50,28 @@ namespace Discord /// /// Gets a collection of IDs for the roles that this user currently possesses in the guild. /// + /// + /// This property returns a read-only collection of the identifiers of the roles that this user possesses. + /// For WebSocket users, a Roles property can be found in place of this property. Due to the REST + /// implementation, only a collection of identifiers can be retrieved instead of the full role objects. + /// /// /// A read-only collection of , each representing a snowflake identifier for a role that - /// this user posesses. + /// this user possesses. /// IReadOnlyCollection RoleIds { get; } /// /// Gets the level permissions granted to this user to a given channel. /// + /// + /// The following example checks if the current user has the ability to send a message with attachment in + /// this channel; if so, uploads a file via . + /// + /// if (currentUser?.GetPermissions(targetChannel)?.AttachFiles) + /// await targetChannel.SendFileAsync("fortnite.png"); + /// + /// /// The channel to get the permission from. /// /// A structure representing the permissions that a user has in the @@ -78,16 +91,19 @@ namespace Discord /// /// Modifies this user's properties in this guild. /// + /// + /// This method modifies the current guild user with the specified properties. To see an example of this + /// method and what properties are available, please refer to . + /// /// The delegate containing the properties to modify the user with. /// The options to be used when sending the request. /// /// A task that represents the asynchronous modification operation. /// - /// Task ModifyAsync(Action func, RequestOptions options = null); /// - /// Adds the specified to this user in this guild. + /// Adds the specified role to this user in the guild. /// /// The role to be added to the user. /// The options to be used when sending the request. @@ -96,7 +112,7 @@ namespace Discord /// Task AddRoleAsync(IRole role, RequestOptions options = null); /// - /// Adds the specified to this user in this guild. + /// Adds the specified to this user in the guild. /// /// The roles to be added to the user. /// The options to be used when sending the request. @@ -105,7 +121,7 @@ namespace Discord /// Task AddRolesAsync(IEnumerable roles, RequestOptions options = null); /// - /// Removes the specified from this user in this guild. + /// Removes the specified from this user in the guild. /// /// The role to be removed from the user. /// The options to be used when sending the request. @@ -114,7 +130,7 @@ namespace Discord /// Task RemoveRoleAsync(IRole role, RequestOptions options = null); /// - /// Removes the specified from this user in this guild. + /// Removes the specified from this user in the guild. /// /// The roles to be removed from the user. /// The options to be used when sending the request. diff --git a/src/Discord.Net.Core/Entities/Users/IUser.cs b/src/Discord.Net.Core/Entities/Users/IUser.cs index ca9f092e0..5d7d0a0b0 100644 --- a/src/Discord.Net.Core/Entities/Users/IUser.cs +++ b/src/Discord.Net.Core/Entities/Users/IUser.cs @@ -8,21 +8,44 @@ namespace Discord public interface IUser : ISnowflakeEntity, IMentionable, IPresence { /// - /// Gets the ID of this user's avatar. + /// Gets the identifier of this user's avatar. /// string AvatarId { get; } /// - /// Returns a URL to this user's avatar. + /// Gets the avatar URL for this user. /// + /// + /// This property retrieves a URL for this user's avatar. In event that the user does not have a valid avatar + /// (i.e. their avatar identifier is not set), this property will return null. If you wish to + /// retrieve the default avatar for this user, consider using (see + /// example). + /// + /// + /// The following example attempts to retrieve the user's current avatar and send it to a channel; if one is + /// not set, a default avatar for this user will be returned instead. + /// + /// var userAvatarUrl = user.GetAvatarUrl() ?? user.GetDefaultAvatarUrl(); + /// await textChannel.SendMessageAsync(userAvatarUrl); + /// + /// /// The format to return. - /// The size of the image to return in. This can be any power of two between 16 and 2048. + /// The size of the image to return in. This can be any power of two between 16 and 2048. + /// /// - /// User's avatar URL. + /// A string representing the user's avatar URL; null if the user does not have an avatar in place. /// string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128); /// - /// Returns the URL to this user's default avatar. + /// Gets the default avatar URL for this user. /// + /// + /// This property retrieves a URL for this user's default avatar generated by Discord (Discord logo followed + /// by a random color as its background). This property will always return a value as it is calculated based + /// on the user's (discriminator % 5). + /// + /// + /// A string representing the user's avatar URL. + /// string GetDefaultAvatarUrl(); /// /// Gets the per-username unique ID for this user. @@ -33,10 +56,14 @@ namespace Discord /// ushort DiscriminatorValue { get; } /// - /// Gets a value that indicates whether this user is a bot user. + /// Gets a value that indicates whether this user is identified as a bot. /// + /// + /// This property retrieves a value that indicates whether this user is a registered bot application + /// (indicated by the blue BOT tag within the official chat client). + /// /// - /// true if the user is a bot; otherwise false. + /// true if the user is a bot application; otherwise false. /// bool IsBot { get; } /// @@ -52,11 +79,37 @@ namespace Discord string Username { get; } /// - /// Returns a direct message channel to this user, or create one if it does not already exist. + /// Gets the direct message channel of this user, or create one if it does not already exist. /// + /// + /// This method is used to obtain or create a channel used to send a direct message. + /// + /// In event that the current user cannot send a message to the target user, a channel can and will still be + /// created by Discord. However, attempting to send a message will yield a + /// with a 403 as its + /// . There are currently no official workarounds by + /// Discord. + /// + /// + /// + /// The following example attempts to send a direct message to the target user and logs the incident should + /// it fail. + /// + /// var channel = await user.GetOrCreateDMChannelAsync(); + /// try + /// { + /// await channel.SendMessageAsync("Awesome stuff!"); + /// } + /// catch (Discord.Net.HttpException ex) when (ex.HttpCode == 403) + /// { + /// Console.WriteLine($"Boo, I cannot message {user}"); + /// } + /// + /// /// The options to be used when sending the request. /// - /// A task that represents the asynchronous operation for getting or creating a DM channel. + /// A task that represents the asynchronous operation for getting or creating a DM channel. The task result + /// contains the DM channel associated with this user. /// Task GetOrCreateDMChannelAsync(RequestOptions options = null); } diff --git a/src/Discord.Net.Core/Entities/Users/IVoiceState.cs b/src/Discord.Net.Core/Entities/Users/IVoiceState.cs index abe06c3b3..2b3abc06f 100644 --- a/src/Discord.Net.Core/Entities/Users/IVoiceState.cs +++ b/src/Discord.Net.Core/Entities/Users/IVoiceState.cs @@ -6,28 +6,50 @@ namespace Discord public interface IVoiceState { /// - /// Returns true if the guild has deafened this user. + /// Gets a value that indicates whether this user is deafened by the guild. /// + /// + /// true if the user is deafened (i.e. not permitted to listen to or speak to others) by the guild; + /// otherwise false. + /// bool IsDeafened { get; } /// - /// Returns true if the guild has muted this user. + /// Gets a value that indicates whether this user is muted (i.e. not permitted to speak via voice) by the + /// guild. /// + /// + /// true if this user is muted by the guild; otherwise false. + /// bool IsMuted { get; } /// - /// Returns true if this user has marked themselves as deafened. + /// Gets a value that indicates whether this user has marked themselves as deafened. /// + /// + /// true if this user has deafened themselves (i.e. not permitted to listen to or speak to others); otherwise false. + /// bool IsSelfDeafened { get; } /// - /// Returns true if this user has marked themselves as muted. + /// Gets a value that indicates whether this user has marked themselves as muted (i.e. not permitted to + /// speak via voice). /// + /// + /// true if this user has muted themselves; otherwise false. + /// bool IsSelfMuted { get; } /// - /// Returns true if the guild is temporarily blocking audio to/from this user. + /// Gets a value that indicates whether the user is muted by the current user. /// + /// + /// true if the guild is temporarily blocking audio to/from this user; otherwise false. + /// bool IsSuppressed { get; } /// - /// Gets the voice channel this user is currently in, or null if none. + /// Gets the voice channel this user is currently in. /// + /// + /// A generic voice channel object representing the voice channel that the user is currently in; null + /// if none. + /// IVoiceChannel VoiceChannel { get; } /// /// Gets the unique identifier for this user's voice session. diff --git a/src/Discord.Net.Core/Extensions/EmbedBuilderExtensions.cs b/src/Discord.Net.Core/Extensions/EmbedBuilderExtensions.cs index 60fdcfbee..138c8f40e 100644 --- a/src/Discord.Net.Core/Extensions/EmbedBuilderExtensions.cs +++ b/src/Discord.Net.Core/Extensions/EmbedBuilderExtensions.cs @@ -68,6 +68,10 @@ namespace Discord return builder; } + /// + /// Adds the specified fields into this . + /// + /// Field count exceeds . public static EmbedBuilder WithFields(this EmbedBuilder builder, IEnumerable fields) { foreach (var field in fields) @@ -75,6 +79,9 @@ namespace Discord return builder; } + /// + /// Adds the specified fields into this . + /// public static EmbedBuilder WithFields(this EmbedBuilder builder, params EmbedFieldBuilder[] fields) => WithFields(builder, fields.AsEnumerable()); } diff --git a/src/Discord.Net.Core/Utils/Preconditions.cs b/src/Discord.Net.Core/Utils/Preconditions.cs index d04d3be50..60415852c 100644 --- a/src/Discord.Net.Core/Utils/Preconditions.cs +++ b/src/Discord.Net.Core/Utils/Preconditions.cs @@ -5,7 +5,9 @@ namespace Discord internal static class Preconditions { //Objects + /// must not be . public static void NotNull(T obj, string name, string msg = null) where T : class { if (obj == null) throw CreateNotNullException(name, msg); } + /// must not be . public static void NotNull(Optional obj, string name, string msg = null) where T : class { if (obj.IsSpecified && obj.Value == null) throw CreateNotNullException(name, msg); } private static ArgumentNullException CreateNotNullException(string name, string msg) @@ -15,13 +17,19 @@ namespace Discord } //Strings + /// cannot be blank. public static void NotEmpty(string obj, string name, string msg = null) { if (obj.Length == 0) throw CreateNotEmptyException(name, msg); } + /// cannot be blank. public static void NotEmpty(Optional obj, string name, string msg = null) { if (obj.IsSpecified && obj.Value.Length == 0) throw CreateNotEmptyException(name, msg); } + /// cannot be blank. + /// must not be . public static void NotNullOrEmpty(string obj, string name, string msg = null) { if (obj == null) throw CreateNotNullException(name, msg); if (obj.Length == 0) throw CreateNotEmptyException(name, msg); } + /// cannot be blank. + /// must not be . public static void NotNullOrEmpty(Optional obj, string name, string msg = null) { if (obj.IsSpecified) @@ -30,11 +38,15 @@ namespace Discord if (obj.Value.Length == 0) throw CreateNotEmptyException(name, msg); } } + /// cannot be blank. + /// must not be . public static void NotNullOrWhitespace(string obj, string name, string msg = null) { if (obj == null) throw CreateNotNullException(name, msg); if (obj.Trim().Length == 0) throw CreateNotEmptyException(name, msg); } + /// cannot be blank. + /// must not be . public static void NotNullOrWhitespace(Optional obj, string name, string msg = null) { if (obj.IsSpecified) @@ -48,121 +60,217 @@ namespace Discord => new ArgumentException(message: msg ?? "Argument cannot be blank.", paramName: name); //Numerics + /// Value may not be equal to . public static void NotEqual(sbyte obj, sbyte value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(byte obj, byte value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(short obj, short value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(ushort obj, ushort value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(int obj, int value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(uint obj, uint value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(long obj, long value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(ulong obj, ulong value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(sbyte? obj, sbyte value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(byte? obj, byte value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(short? obj, short value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(ushort? obj, ushort value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(int? obj, int value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(uint? obj, uint value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(long? obj, long value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(ulong? obj, ulong value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } + /// Value may not be equal to . public static void NotEqual(Optional obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); } private static ArgumentException CreateNotEqualException(string name, string msg, T value) - => new ArgumentException(message: msg ?? $"Value may not be equal to {value}", paramName: name); + => new ArgumentException(message: msg ?? $"Value may not be equal to {value}.", paramName: name); + /// Value must be at least . public static void AtLeast(sbyte obj, sbyte value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(byte obj, byte value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(short obj, short value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(ushort obj, ushort value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(int obj, int value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(uint obj, uint value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(long obj, long value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(ulong obj, ulong value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(Optional obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(Optional obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(Optional obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(Optional obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(Optional obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(Optional obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(Optional obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); } + /// Value must be at least . public static void AtLeast(Optional obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); } private static ArgumentException CreateAtLeastException(string name, string msg, T value) - => new ArgumentException(message: msg ?? $"Value must be at least {value}", paramName: name); - + => new ArgumentException(message: msg ?? $"Value must be at least {value}.", paramName: name); + + /// Value must be greater than . public static void GreaterThan(sbyte obj, sbyte value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(byte obj, byte value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(short obj, short value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(ushort obj, ushort value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(int obj, int value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(uint obj, uint value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(long obj, long value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(ulong obj, ulong value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(Optional obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(Optional obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(Optional obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(Optional obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(Optional obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(Optional obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(Optional obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); } + /// Value must be greater than . public static void GreaterThan(Optional obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); } private static ArgumentException CreateGreaterThanException(string name, string msg, T value) - => new ArgumentException(message: msg ?? $"Value must be greater than {value}", paramName: name); - + => new ArgumentException(message: msg ?? $"Value must be greater than {value}.", paramName: name); + + /// Value must be at most . public static void AtMost(sbyte obj, sbyte value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(byte obj, byte value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(short obj, short value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(ushort obj, ushort value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(int obj, int value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(uint obj, uint value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(long obj, long value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(ulong obj, ulong value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(Optional obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(Optional obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(Optional obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(Optional obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(Optional obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(Optional obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(Optional obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); } + /// Value must be at most . public static void AtMost(Optional obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); } private static ArgumentException CreateAtMostException(string name, string msg, T value) - => new ArgumentException(message: msg ?? $"Value must be at most {value}", paramName: name); - + => new ArgumentException(message: msg ?? $"Value must be at most {value}.", paramName: name); + + /// Value must be less than . public static void LessThan(sbyte obj, sbyte value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(byte obj, byte value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(short obj, short value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(ushort obj, ushort value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(int obj, int value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(uint obj, uint value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(long obj, long value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(ulong obj, ulong value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(Optional obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(Optional obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(Optional obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(Optional obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(Optional obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(Optional obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(Optional obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); } + /// Value must be less than . public static void LessThan(Optional obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); } private static ArgumentException CreateLessThanException(string name, string msg, T value) - => new ArgumentException(message: msg ?? $"Value must be less than {value}", paramName: name); + => new ArgumentException(message: msg ?? $"Value must be less than {value}.", paramName: name); // Bulk Delete /// Messages are younger than 2 weeks. @@ -182,7 +290,7 @@ namespace Discord for (var i = 0; i < roles.Length; i++) { if (roles[i] == guildId) - throw new ArgumentException(message: "The everyone role cannot be assigned to a user", paramName: name); + throw new ArgumentException(message: "The everyone role cannot be assigned to a user.", paramName: name); } } } diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index eeeea4139..b1e04e9dc 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -348,6 +348,16 @@ namespace Discord.API var ids = new BucketIds(channelId: channelId); return await SendAsync("DELETE", () => $"channels/{channelId}", ids, options: options).ConfigureAwait(false); } + /// + /// must not be equal to zero. + /// -and- + /// must be greater than zero. + /// + /// + /// must not be . + /// -and- + /// must not be or empty. + /// public async Task ModifyGuildChannelAsync(ulong channelId, Rest.ModifyGuildChannelParams args, RequestOptions options = null) { Preconditions.NotEqual(channelId, 0, nameof(channelId)); @@ -836,6 +846,12 @@ namespace Discord.API var ids = new BucketIds(guildId: guildId); return await SendAsync("GET", () => $"guilds/{guildId}/bans/{userId}", ids, options: options).ConfigureAwait(false); } + /// + /// and must not be equal to zero. + /// -and- + /// must be between 0 to 7. + /// + /// must not be . public async Task CreateGuildBanAsync(ulong guildId, ulong userId, CreateGuildBanParams args, RequestOptions options = null) { Preconditions.NotEqual(guildId, 0, nameof(guildId)); @@ -849,6 +865,7 @@ namespace Discord.API string reason = string.IsNullOrWhiteSpace(args.Reason) ? "" : $"&reason={Uri.EscapeDataString(args.Reason)}"; await SendAsync("PUT", () => $"guilds/{guildId}/bans/{userId}?delete-message-days={args.DeleteMessageDays}{reason}", ids, options: options).ConfigureAwait(false); } + /// and must not be equal to zero. public async Task RemoveGuildBanAsync(ulong guildId, ulong userId, RequestOptions options = null) { Preconditions.NotEqual(guildId, 0, nameof(guildId)); @@ -860,6 +877,7 @@ namespace Discord.API } //Guild Embeds + /// must not be equal to zero. public async Task GetGuildEmbedAsync(ulong guildId, RequestOptions options = null) { Preconditions.NotEqual(guildId, 0, nameof(guildId)); @@ -872,6 +890,8 @@ namespace Discord.API } catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } } + /// must not be equal to zero. + /// must not be . public async Task ModifyGuildEmbedAsync(ulong guildId, Rest.ModifyGuildEmbedParams args, RequestOptions options = null) { Preconditions.NotNull(args, nameof(args)); @@ -883,6 +903,7 @@ namespace Discord.API } //Guild Integrations + /// must not be equal to zero. public async Task> GetGuildIntegrationsAsync(ulong guildId, RequestOptions options = null) { Preconditions.NotEqual(guildId, 0, nameof(guildId)); @@ -891,6 +912,8 @@ namespace Discord.API var ids = new BucketIds(guildId: guildId); return await SendAsync>("GET", () => $"guilds/{guildId}/integrations", ids, options: options).ConfigureAwait(false); } + /// and must not be equal to zero. + /// must not be . public async Task CreateGuildIntegrationAsync(ulong guildId, CreateGuildIntegrationParams args, RequestOptions options = null) { Preconditions.NotEqual(guildId, 0, nameof(guildId)); @@ -933,6 +956,8 @@ namespace Discord.API } //Guild Invites + /// cannot be blank. + /// must not be . public async Task GetInviteAsync(string inviteId, RequestOptions options = null) { Preconditions.NotNullOrEmpty(inviteId, nameof(inviteId)); @@ -952,6 +977,7 @@ namespace Discord.API } catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } } + /// may not be equal to zero. public async Task GetVanityInviteAsync(ulong guildId, RequestOptions options = null) { Preconditions.NotEqual(guildId, 0, nameof(guildId)); @@ -960,6 +986,7 @@ namespace Discord.API var ids = new BucketIds(guildId: guildId); return await SendAsync("GET", () => $"guilds/{guildId}/vanity-url", ids, options: options).ConfigureAwait(false); } + /// may not be equal to zero. public async Task> GetGuildInvitesAsync(ulong guildId, RequestOptions options = null) { Preconditions.NotEqual(guildId, 0, nameof(guildId)); @@ -968,6 +995,7 @@ namespace Discord.API var ids = new BucketIds(guildId: guildId); return await SendAsync>("GET", () => $"guilds/{guildId}/invites", ids, options: options).ConfigureAwait(false); } + /// may not be equal to zero. public async Task> GetChannelInvitesAsync(ulong channelId, RequestOptions options = null) { Preconditions.NotEqual(channelId, 0, nameof(channelId)); @@ -976,6 +1004,14 @@ namespace Discord.API var ids = new BucketIds(channelId: channelId); return await SendAsync>("GET", () => $"channels/{channelId}/invites", ids, options: options).ConfigureAwait(false); } + /// + /// may not be equal to zero. + /// -and- + /// and must be greater than zero. + /// -and- + /// must be lesser than 86400. + /// + /// must not be . public async Task CreateChannelInviteAsync(ulong channelId, CreateChannelInviteParams args, RequestOptions options = null) { Preconditions.NotEqual(channelId, 0, nameof(channelId)); diff --git a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs index 5c232f292..d8a97e85a 100644 --- a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs +++ b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs @@ -73,6 +73,13 @@ namespace Discord.Rest var models = await client.ApiClient.GetChannelInvitesAsync(channel.Id, options).ConfigureAwait(false); return models.Select(x => RestInviteMetadata.Create(client, null, channel, x)).ToImmutableArray(); } + /// + /// may not be equal to zero. + /// -and- + /// and must be greater than zero. + /// -and- + /// must be lesser than 86400. + /// public static async Task CreateInviteAsync(IGuildChannel channel, BaseDiscordClient client, int? maxAge, int? maxUses, bool isTemporary, bool isUnique, RequestOptions options) { @@ -352,6 +359,7 @@ namespace Discord.Rest var model = await client.ApiClient.GetChannelAsync(channel.CategoryId.Value, options).ConfigureAwait(false); return RestCategoryChannel.Create(client, model) as ICategoryChannel; } + /// This channel does not have a parent channel. public static async Task SyncPermissionsAsync(INestedChannel channel, BaseDiscordClient client, RequestOptions options) { var category = await GetCategoryAsync(channel, client, options).ConfigureAwait(false); diff --git a/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs b/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs index 42ca20f7c..204546cf3 100644 --- a/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs @@ -12,6 +12,10 @@ namespace Discord.Rest /// /// Sends a message to this message channel. /// + /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. + /// /// The message to be sent. /// Determines whether the message should be read aloud by Discord or not. /// The to be sent. @@ -25,12 +29,9 @@ namespace Discord.Rest /// Sends a file to this message channel with an optional caption. /// /// - /// This method sends a file as if you are uploading an attachment directly from your Discord client. - /// - /// If you wish to upload an image and have it embedded in a embed, - /// you may upload the file and refer to the file with "attachment://filename.ext" in the - /// . - /// + /// This method follows the same behavior as described in + /// . Please visit + /// its documentation for more details on this method. /// /// The file path of the file. /// The message to be sent. @@ -46,12 +47,8 @@ namespace Discord.Rest /// Sends a file to this message channel with an optional caption. /// /// - /// This method sends a file as if you are uploading an attachment directly from your Discord client. - /// - /// If you wish to upload an image and have it embedded in a embed, - /// you may upload the file and refer to the file with "attachment://filename.ext" in the - /// . - /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// /// The of the file to be sent. /// The name of the attachment. @@ -68,6 +65,10 @@ namespace Discord.Rest /// /// Gets a message from this message channel. /// + /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. + /// /// The snowflake identifier of the message. /// The options to be used when sending the request. /// @@ -79,30 +80,9 @@ namespace Discord.Rest /// Gets the last N messages from this message channel. /// /// - /// - /// The returned collection is an asynchronous enumerable object; one must call - /// to access the individual messages as a - /// collection. - /// - /// - /// Do not fetch too many messages at once! This may cause unwanted preemptive rate limit or even actual - /// rate limit, causing your bot to freeze! - /// - /// This method will attempt to fetch the number of messages specified under . The - /// library will attempt to split up the requests according to your and - /// . In other words, should the user request 500 messages, - /// and the constant is 100, the request will - /// be split into 5 individual requests; thus returning 5 individual asynchronous responses, hence the need - /// of flattening. + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// - /// - /// The following example downloads 300 messages and gets messages that belong to the user - /// 53905483156684800. - /// - /// var messages = await messageChannel.GetMessagesAsync(300).FlattenAsync(); - /// var userMessages = messages.Where(x => x.Author.Id == 53905483156684800); - /// - /// /// The numbers of message to be gotten from. /// The options to be used when sending the request. /// @@ -113,34 +93,12 @@ namespace Discord.Rest /// Gets a collection of messages in this channel. /// /// - /// - /// The returned collection is an asynchronous enumerable object; one must call - /// to access the individual messages as a - /// collection. - /// - /// - /// Do not fetch too many messages at once! This may cause unwanted preemptive rate limit or even actual - /// rate limit, causing your bot to freeze! - /// - /// This method will attempt to fetch the number of messages specified under around - /// the message depending on the . The library will - /// attempt to split up the requests according to your and - /// . In other words, should the user request 500 messages, - /// and the constant is 100, the request will - /// be split into 5 individual requests; thus returning 5 individual asynchronous responses, hence the need - /// of flattening. + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// - /// - /// The following example gets 5 message prior to the message identifier 442012544660537354. - /// - /// var messages = await channel.GetMessagesAsync(442012544660537354, Direction.Before, 5).FlattenAsync(); - /// - /// /// The ID of the starting message to get the messages from. /// The direction of the messages to be gotten from. /// The numbers of message to be gotten from. - /// The that determines whether the object should be fetched from - /// cache. /// The options to be used when sending the request. /// /// Paged collection of messages. @@ -150,34 +108,12 @@ namespace Discord.Rest /// Gets a collection of messages in this channel. /// /// - /// - /// The returned collection is an asynchronous enumerable object; one must call - /// to access the individual messages as a - /// collection. - /// - /// - /// Do not fetch too many messages at once! This may cause unwanted preemptive rate limit or even actual - /// rate limit, causing your bot to freeze! - /// - /// This method will attempt to fetch the number of messages specified under around - /// the message depending on the . The library will - /// attempt to split up the requests according to your and - /// . In other words, should the user request 500 messages, - /// and the constant is 100, the request will - /// be split into 5 individual requests; thus returning 5 individual asynchronous responses, hence the need - /// of flattening. + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// - /// - /// The following example gets 5 message prior to a specific message, oldMessage. - /// - /// var messages = await channel.GetMessagesAsync(oldMessage, Direction.Before, 5).FlattenAsync(); - /// - /// /// The starting message to get the messages from. /// The direction of the messages to be gotten from. /// The numbers of message to be gotten from. - /// The that determines whether the object should be fetched from - /// cache. /// The options to be used when sending the request. /// /// Paged collection of messages. @@ -186,6 +122,10 @@ namespace Discord.Rest /// /// Gets a collection of pinned messages in this channel. /// + /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. + /// /// The options to be used when sending the request. /// /// A task that represents the asynchronous get operation for retrieving pinned messages in this channel. diff --git a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs index 58de066fb..e95b6e877 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs @@ -16,6 +16,7 @@ namespace Discord.Rest { /// public string Topic { get; private set; } + /// public int SlowModeInterval { get; private set; } /// public ulong? CategoryId { get; private set; } @@ -201,6 +202,7 @@ namespace Discord.Rest /// public Task GetCategoryAsync(RequestOptions options = null) => ChannelHelper.GetCategoryAsync(this, Discord, options); + /// public Task SyncPermissionsAsync(RequestOptions options = null) => ChannelHelper.SyncPermissionsAsync(this, Discord, options); diff --git a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs index aaaaad373..3f3aa96c6 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs @@ -57,7 +57,7 @@ namespace Discord.Rest /// public Task GetCategoryAsync(RequestOptions options = null) => ChannelHelper.GetCategoryAsync(this, Discord, options); - + /// public Task SyncPermissionsAsync(RequestOptions options = null) => ChannelHelper.SyncPermissionsAsync(this, Discord, options); diff --git a/src/Discord.Net.Rest/Entities/Messages/Attachment.cs b/src/Discord.Net.Rest/Entities/Messages/Attachment.cs index a2c7b9cf7..abe049180 100644 --- a/src/Discord.Net.Rest/Entities/Messages/Attachment.cs +++ b/src/Discord.Net.Rest/Entities/Messages/Attachment.cs @@ -3,9 +3,7 @@ using Model = Discord.API.Attachment; namespace Discord { - /// - /// An attachment file seen in a . - /// + /// [DebuggerDisplay(@"{DebuggerDisplay,nq}")] public class Attachment : IAttachment { diff --git a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs index 3ac2a81a0..9674cff52 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs @@ -7,6 +7,22 @@ namespace Discord.WebSocket /// /// Represents a configuration class for . /// + /// + /// This configuration, based on , helps determine several key configurations the + /// socket client depend on. For instance, shards and connection timeout. + /// + /// + /// The following config enables the message cache and configures the client to always download user upon guild + /// availability. + /// + /// var config = new DiscordSocketConfig + /// { + /// AlwaysDownloadUsers = true, + /// MessageCacheSize = 100 + /// }; + /// var client = new DiscordSocketClient(config); + /// + /// public class DiscordSocketConfig : DiscordRestConfig { /// @@ -57,6 +73,30 @@ namespace Discord.WebSocket /// /// Gets or sets whether or not all users should be downloaded as guilds come available. /// + /// + /// + /// By default, the Discord gateway will only send offline members if a guild has less than a certain number + /// of members (determined by in this library). This behaviour is why + /// sometimes a user may be missing from the WebSocket cache for collections such as + /// . + /// + /// + /// This property ensures that whenever a guild becomes available (determined by + /// ), incomplete user chunks will be + /// downloaded to the WebSocket cache. + /// + /// + /// For more information, please see + /// Request Guild Members + /// on the official Discord API documentation. + /// + /// + /// Please note that it can be difficult to fill the cache completely on large guilds depending on the + /// traffic. If you are using the command system, the default user TypeReader may fail to find the user + /// due to this issue. This may be resolved at v3 of the library. Until then, you may want to consider + /// overriding the TypeReader and use as a backup. + /// + /// public bool AlwaysDownloadUsers { get; set; } = false; /// /// Gets or sets the timeout for event handlers, in milliseconds, after which a warning will be logged. Null diff --git a/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs index 9f04239ad..3c824166f 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs @@ -21,6 +21,10 @@ namespace Discord.WebSocket /// /// Sends a message to this message channel. /// + /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. + /// /// The message to be sent. /// Determines whether the message should be read aloud by Discord or not. /// The to be sent. @@ -34,12 +38,8 @@ namespace Discord.WebSocket /// Sends a file to this message channel with an optional caption. /// /// - /// This method sends a file as if you are uploading an attachment directly from your Discord client. - /// - /// If you wish to upload an image and have it embedded in a embed, - /// you may upload the file and refer to the file with "attachment://filename.ext" in the - /// . - /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// /// The file path of the file. /// The message to be sent. @@ -55,12 +55,8 @@ namespace Discord.WebSocket /// Sends a file to this message channel with an optional caption. /// /// - /// This method sends a file as if you are uploading an attachment directly from your Discord client. - /// - /// If you wish to upload an image and have it embedded in a embed, - /// you may upload the file and refer to the file with "attachment://filename.ext" in the - /// . - /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// /// The of the file to be sent. /// The name of the attachment. @@ -75,16 +71,41 @@ namespace Discord.WebSocket new Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); /// - /// Gets the cached message if one exists. + /// Gets a cached message from this channel. /// - /// The ID of the message. + /// + /// + /// This method requires the use of cache, which is not enabled by default; if caching is not enabled, + /// this method will always return null. Please refer to + /// for more details. + /// + /// + /// This method retrieves the message from the local WebSocket cache and does not send any additional + /// request to Discord. This message may be a message that has been deleted. + /// + /// + /// The snowflake identifier of the message. /// - /// Cached message object; null if it doesn't exist in the cache. + /// A WebSocket-based message object; null if it does not exist in the cache or if caching is not + /// enabled. /// SocketMessage GetCachedMessage(ulong id); /// - /// Gets the last N messages from this message channel. + /// Gets the last N cached messages from this message channel. /// + /// + /// + /// This method requires the use of cache, which is not enabled by default; if caching is not enabled, + /// this method will always return an empty collection. Please refer to + /// for more details. + /// + /// + /// This method retrieves the message(s) from the local WebSocket cache and does not send any additional + /// request to Discord. This read-only collection may include messages that have been deleted. The + /// maximum number of messages that can be retrieved from this method depends on the + /// set. + /// + /// /// The number of messages to get. /// /// A read-only collection of WebSocket-based messages. @@ -92,8 +113,21 @@ namespace Discord.WebSocket IReadOnlyCollection GetCachedMessages(int limit = DiscordConfig.MaxMessagesPerBatch); /// - /// Gets a collection of messages in this channel. + /// Gets the last N cached messages starting from a certain message in this message channel. /// + /// + /// + /// This method requires the use of cache, which is not enabled by default; if caching is not enabled, + /// this method will always return an empty collection. Please refer to + /// for more details. + /// + /// + /// This method retrieves the message(s) from the local WebSocket cache and does not send any additional + /// request to Discord. This read-only collection may include messages that have been deleted. The + /// maximum number of messages that can be retrieved from this method depends on the + /// set. + /// + /// /// The message ID to start the fetching from. /// The direction of which the message should be gotten from. /// The number of messages to get. @@ -102,8 +136,21 @@ namespace Discord.WebSocket /// IReadOnlyCollection GetCachedMessages(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch); /// - /// Gets a collection of messages in this channel. + /// Gets the last N cached messages starting from a certain message in this message channel. /// + /// + /// + /// This method requires the use of cache, which is not enabled by default; if caching is not enabled, + /// this method will always return an empty collection. Please refer to + /// for more details. + /// + /// + /// This method retrieves the message(s) from the local WebSocket cache and does not send any additional + /// request to Discord. This read-only collection may include messages that have been deleted. The + /// maximum number of messages that can be retrieved from this method depends on the + /// set. + /// + /// /// The message to start the fetching from. /// The direction of which the message should be gotten from. /// The number of messages to get. @@ -112,12 +159,16 @@ namespace Discord.WebSocket /// IReadOnlyCollection GetCachedMessages(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch); /// - /// Gets a collection of pinned messages in this channel. + /// Gets a read-only collection of pinned messages in this channel. /// + /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. + /// /// The options to be used when sending the request. /// /// A task that represents the asynchronous get operation for retrieving pinned messages in this channel. - /// The task result contains a collection of messages found in the pinned messages. + /// The task result contains a read-only collection of messages found in the pinned messages. /// new Task> GetPinnedMessagesAsync(RequestOptions options = null); } diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs index 6b6577167..cd03505ef 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs @@ -78,30 +78,9 @@ namespace Discord.WebSocket /// Gets the last N messages from this message channel. /// /// - /// - /// The returned collection is an asynchronous enumerable object; one must call - /// to access the individual messages as a - /// collection. - /// - /// - /// Do not fetch too many messages at once! This may cause unwanted preemptive rate limit or even actual - /// rate limit, causing your bot to freeze! - /// - /// This method will attempt to fetch the number of messages specified under . The - /// library will attempt to split up the requests according to your and - /// . In other words, should the user request 500 messages, - /// and the constant is 100, the request will - /// be split into 5 individual requests; thus returning 5 individual asynchronous responses, hence the need - /// of flattening. + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// - /// - /// The following example downloads 300 messages and gets messages that belong to the user - /// 53905483156684800. - /// - /// var messages = await messageChannel.GetMessagesAsync(300).FlattenAsync(); - /// var userMessages = messages.Where(x => x.Author.Id == 53905483156684800); - /// - /// /// The numbers of message to be gotten from. /// The options to be used when sending the request. /// @@ -113,29 +92,9 @@ namespace Discord.WebSocket /// Gets a collection of messages in this channel. /// /// - /// - /// The returned collection is an asynchronous enumerable object; one must call - /// to access the individual messages as a - /// collection. - /// - /// - /// Do not fetch too many messages at once! This may cause unwanted preemptive rate limit or even actual - /// rate limit, causing your bot to freeze! - /// - /// This method will attempt to fetch the number of messages specified under around - /// the message depending on the . The library will - /// attempt to split up the requests according to your and - /// . In other words, should the user request 500 messages, - /// and the constant is 100, the request will - /// be split into 5 individual requests; thus returning 5 individual asynchronous responses, hence the need - /// of flattening. + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// - /// - /// The following example gets 5 message prior to the message identifier 442012544660537354. - /// - /// var messages = await channel.GetMessagesAsync(442012544660537354, Direction.Before, 5).FlattenAsync(); - /// - /// /// The ID of the starting message to get the messages from. /// The direction of the messages to be gotten from. /// The numbers of message to be gotten from. @@ -149,29 +108,9 @@ namespace Discord.WebSocket /// Gets a collection of messages in this channel. /// /// - /// - /// The returned collection is an asynchronous enumerable object; one must call - /// to access the individual messages as a - /// collection. - /// - /// - /// Do not fetch too many messages at once! This may cause unwanted preemptive rate limit or even actual - /// rate limit, causing your bot to freeze! - /// - /// This method will attempt to fetch the number of messages specified under around - /// the message depending on the . The library will - /// attempt to split up the requests according to your and - /// . In other words, should the user request 500 messages, - /// and the constant is 100, the request will - /// be split into 5 individual requests; thus returning 5 individual asynchronous responses, hence the need - /// of flattening. + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// - /// - /// The following example gets 5 message prior to a specific message, oldMessage. - /// - /// var messages = await channel.GetMessagesAsync(oldMessage, Direction.Before, 5).FlattenAsync(); - /// - /// /// The starting message to get the messages from. /// The direction of the messages to be gotten from. /// The numbers of message to be gotten from. diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs index 1fc289f41..07b7066b9 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs @@ -81,6 +81,19 @@ namespace Discord.WebSocket /// public SocketMessage GetCachedMessage(ulong id) => _messages?.Get(id); + /// + /// Gets a message from this message channel. + /// + /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. + /// + /// The snowflake identifier of the message. + /// The options to be used when sending the request. + /// + /// A task that represents an asynchronous get operation for retrieving the message. The task result contains + /// the retrieved message; null if no message is found with the specified identifier. + /// public async Task GetMessageAsync(ulong id, RequestOptions options = null) { IMessage msg = _messages?.Get(id); @@ -88,10 +101,51 @@ namespace Discord.WebSocket msg = await ChannelHelper.GetMessageAsync(this, Discord, id, options).ConfigureAwait(false); return msg; } + + /// + /// Gets the last N messages from this message channel. + /// + /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. + /// + /// The numbers of message to be gotten from. + /// The options to be used when sending the request. + /// + /// Paged collection of messages. + /// public IAsyncEnumerable> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, null, Direction.Before, limit, CacheMode.AllowDownload, options); + /// + /// Gets a collection of messages in this channel. + /// + /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. + /// + /// The ID of the starting message to get the messages from. + /// The direction of the messages to be gotten from. + /// The numbers of message to be gotten from. + /// The options to be used when sending the request. + /// + /// Paged collection of messages. + /// public IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, fromMessageId, dir, limit, CacheMode.AllowDownload, options); + /// + /// Gets a collection of messages in this channel. + /// + /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. + /// + /// The starting message to get the messages from. + /// The direction of the messages to be gotten from. + /// The numbers of message to be gotten from. + /// The options to be used when sending the request. + /// + /// Paged collection of messages. + /// public IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, fromMessage.Id, dir, limit, CacheMode.AllowDownload, options); /// diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs index 728a4ad53..496b96d30 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs @@ -20,6 +20,7 @@ namespace Discord.WebSocket /// public string Topic { get; private set; } + /// public int SlowModeInterval { get; private set; } /// public ulong? CategoryId { get; private set; } @@ -31,6 +32,7 @@ namespace Discord.WebSocket /// public ICategoryChannel Category => CategoryId.HasValue ? Guild.GetChannel(CategoryId.Value) as ICategoryChannel : null; + /// public Task SyncPermissionsAsync(RequestOptions options = null) => ChannelHelper.SyncPermissionsAsync(this, Discord, options); @@ -80,6 +82,10 @@ namespace Discord.WebSocket /// /// Gets a message from this message channel. /// + /// + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. + /// /// The snowflake identifier of the message. /// The options to be used when sending the request. /// @@ -93,34 +99,14 @@ namespace Discord.WebSocket msg = await ChannelHelper.GetMessageAsync(this, Discord, id, options).ConfigureAwait(false); return msg; } + /// /// Gets the last N messages from this message channel. /// /// - /// - /// The returned collection is an asynchronous enumerable object; one must call - /// to access the individual messages as a - /// collection. - /// - /// - /// Do not fetch too many messages at once! This may cause unwanted preemptive rate limit or even actual - /// rate limit, causing your bot to freeze! - /// - /// This method will attempt to fetch the number of messages specified under . The - /// library will attempt to split up the requests according to your and - /// . In other words, should the user request 500 messages, - /// and the constant is 100, the request will - /// be split into 5 individual requests; thus returning 5 individual asynchronous responses, hence the need - /// of flattening. + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// - /// - /// The following example downloads 300 messages and gets messages that belong to the user - /// 53905483156684800. - /// - /// var messages = await messageChannel.GetMessagesAsync(300).FlattenAsync(); - /// var userMessages = messages.Where(x => x.Author.Id == 53905483156684800); - /// - /// /// The numbers of message to be gotten from. /// The options to be used when sending the request. /// @@ -132,29 +118,9 @@ namespace Discord.WebSocket /// Gets a collection of messages in this channel. /// /// - /// - /// The returned collection is an asynchronous enumerable object; one must call - /// to access the individual messages as a - /// collection. - /// - /// - /// Do not fetch too many messages at once! This may cause unwanted preemptive rate limit or even actual - /// rate limit, causing your bot to freeze! - /// - /// This method will attempt to fetch the number of messages specified under around - /// the message depending on the . The library will - /// attempt to split up the requests according to your and - /// . In other words, should the user request 500 messages, - /// and the constant is 100, the request will - /// be split into 5 individual requests; thus returning 5 individual asynchronous responses, hence the need - /// of flattening. + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// - /// - /// The following example gets 5 message prior to the message identifier 442012544660537354. - /// - /// var messages = await channel.GetMessagesAsync(442012544660537354, Direction.Before, 5).FlattenAsync(); - /// - /// /// The ID of the starting message to get the messages from. /// The direction of the messages to be gotten from. /// The numbers of message to be gotten from. @@ -168,29 +134,9 @@ namespace Discord.WebSocket /// Gets a collection of messages in this channel. /// /// - /// - /// The returned collection is an asynchronous enumerable object; one must call - /// to access the individual messages as a - /// collection. - /// - /// - /// Do not fetch too many messages at once! This may cause unwanted preemptive rate limit or even actual - /// rate limit, causing your bot to freeze! - /// - /// This method will attempt to fetch the number of messages specified under around - /// the message depending on the . The library will - /// attempt to split up the requests according to your and - /// . In other words, should the user request 500 messages, - /// and the constant is 100, the request will - /// be split into 5 individual requests; thus returning 5 individual asynchronous responses, hence the need - /// of flattening. + /// This method follows the same behavior as described in . + /// Please visit its documentation for more details on this method. /// - /// - /// The following example gets 5 message prior to a specific message, oldMessage. - /// - /// var messages = await channel.GetMessagesAsync(oldMessage, Direction.Before, 5).FlattenAsync(); - /// - /// /// The starting message to get the messages from. /// The direction of the messages to be gotten from. /// The numbers of message to be gotten from. diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs index 48a7d7c3b..9fff6c207 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs @@ -30,6 +30,7 @@ namespace Discord.WebSocket /// public ICategoryChannel Category => CategoryId.HasValue ? Guild.GetChannel(CategoryId.Value) as ICategoryChannel : null; + /// public Task SyncPermissionsAsync(RequestOptions options = null) => ChannelHelper.SyncPermissionsAsync(this, Discord, options); diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs index 41c463a89..4832e7311 100644 --- a/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs +++ b/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs @@ -38,6 +38,9 @@ namespace Discord.WebSocket public IActivity Activity => Presence.Activity; /// public UserStatus Status => Presence.Status; + /// + /// Gets mutual guilds shared with this user. + /// public IReadOnlyCollection MutualGuilds => Discord.Guilds.Where(g => g.Users.Any(u => u.Id == Id)).ToImmutableArray();