From 456ee4b15017a39ea964b49702b9eb027663ba75 Mon Sep 17 00:00:00 2001
From: Still Hsu <341464@gmail.com>
Date: Sun, 10 Feb 2019 03:12:48 +0800
Subject: [PATCH] Add/migrate code examples
---
Discord.Net.sln | 19 +-
.../Entities/Channels/IGuildChannel.cs | 10 +-
.../Entities/Channels/IMessageChannel.cs | 63 +++---
.../Entities/Channels/ITextChannel.cs | 2 +-
.../Entities/Guilds/IGuild.cs | 12 +-
src/Discord.Net.Core/Entities/Users/IUser.cs | 7 +-
src/Discord.Net.Core/IDiscordClient.cs | 8 +-
.../Channels/IGuildChannel.Examples.cs | 63 +++---
.../Channels/IMessageChannel.Examples.cs | 114 +++++++++++
.../Core/Entities/Guilds/IGuild.Examples.cs | 25 +++
.../Core/Entities/Users/IUser.Examples.cs | 50 +++--
.../Discord.Net.Examples.csproj | 21 ++
.../BaseSocketClient.Events.Examples.cs | 193 ++++++++++--------
.../Entities/Guilds/RestGuild.cs | 2 +-
.../BaseSocketClient.Events.cs | 20 +-
src/Discord.Net.WebSocket/BaseSocketClient.cs | 28 +--
.../DiscordSocketConfig.cs | 5 +-
.../Entities/Guilds/SocketGuild.cs | 2 +-
18 files changed, 432 insertions(+), 212 deletions(-)
create mode 100644 src/Discord.Net.Examples/Core/Entities/Channels/IMessageChannel.Examples.cs
create mode 100644 src/Discord.Net.Examples/Core/Entities/Guilds/IGuild.Examples.cs
create mode 100644 src/Discord.Net.Examples/Discord.Net.Examples.csproj
diff --git a/Discord.Net.sln b/Discord.Net.sln
index 245515c7c..75f0a4391 100644
--- a/Discord.Net.sln
+++ b/Discord.Net.sln
@@ -30,7 +30,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "01_basic_ping_bot", "sample
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "02_commands_framework", "samples\02_commands_framework\02_commands_framework.csproj", "{4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "03_sharded_client", "samples\03_sharded_client\03_sharded_client.csproj", "{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "03_sharded_client", "samples\03_sharded_client\03_sharded_client.csproj", "{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{D1F0271E-0EE2-4B66-AC3D-9871B7E1C4CF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Examples", "src\Discord.Net.Examples\Discord.Net.Examples.csproj", "{7EA96B2B-4D71-458D-9423-839362DC38BE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -174,6 +178,18 @@ Global
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|x64.Build.0 = Release|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|x86.ActiveCfg = Release|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|x86.Build.0 = Release|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|x64.Build.0 = Debug|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|x86.Build.0 = Debug|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|x64.ActiveCfg = Release|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|x64.Build.0 = Release|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|x86.ActiveCfg = Release|Any CPU
+ {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -188,6 +204,7 @@ Global
{F2FF84FB-F6AD-47E5-9EE5-18206CAE136E} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B}
{4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B}
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B}
+ {7EA96B2B-4D71-458D-9423-839362DC38BE} = {D1F0271E-0EE2-4B66-AC3D-9871B7E1C4CF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D2404771-EEC8-45F2-9D71-F3373F6C1495}
diff --git a/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs b/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
index 652507492..b964c0896 100644
--- a/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
@@ -101,9 +101,8 @@ namespace Discord
/// . Next, it checks if an overwrite had already been set via
/// ; if not, it denies the role from sending any
/// messages to the channel.
- ///
+ ///
///
/// The role to add the overwrite to.
/// The overwrite to add to the role.
@@ -121,9 +120,8 @@ namespace Discord
/// . Next, it checks if an overwrite had already been set via
/// ; if not, it denies the user from sending any
/// messages to the channel.
- ///
+ ///
///
/// The user to add the overwrite to.
/// The overwrite to add to the user.
diff --git a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
index 919b3f60b..322150e92 100644
--- a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
@@ -16,11 +16,8 @@ namespace Discord
///
/// The following example sends a message with the current system time in RFC 1123 format to the channel and
/// deletes itself after 5 seconds.
- ///
- /// var message = await channel.SendMessageAsync(DateTimeOffset.UtcNow.ToString("R"));
- /// await Task.Delay(TimeSpan.FromSeconds(5))
- /// .ContinueWith(x => message.DeleteAsync());
- ///
+ ///
///
/// The message to be sent.
/// Determines whether the message should be read aloud by Discord or not.
@@ -35,18 +32,14 @@ namespace Discord
/// Sends a file to this message channel with an optional caption.
///
///
- /// The following example uploads a local file called wumpus.txt along with the text
- /// good discord boi to the channel.
- ///
- /// await channel.SendFileAsync("wumpus.txt", "good discord boi");
- ///
- ///
- /// The following example uploads a local image called b1nzy.jpg embedded inside a rich embed to the
- /// channel.
- ///
- /// await channel.SendFileAsync("b1nzy.jpg",
- /// embed: new EmbedBuilder {ImageUrl = "attachment://b1nzy.jpg"}.Build());
- ///
+ /// The following example uploads a local file called wumpus.txt along with the text
+ /// good discord boi to the channel.
+ ///
+ /// The following example uploads a local image called b1nzy.jpg embedded inside a rich embed to the
+ /// channel.
+ ///
///
///
/// This method sends a file as if you are uploading an attachment directly from your Discord client.
@@ -72,10 +65,8 @@ namespace Discord
///
/// The following example uploads a streamed image that will be called b1nzy.jpg embedded inside a
/// rich embed to the channel.
- ///
- /// await channel.SendFileAsync(b1nzyStream, "b1nzy.jpg",
- /// embed: new EmbedBuilder {ImageUrl = "attachment://b1nzy.jpg"}.Build());
- ///
+ ///
///
///
/// This method sends a file as if you are uploading an attachment directly from your Discord client.
@@ -132,10 +123,8 @@ namespace Discord
///
/// 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 that determines whether the object should be fetched from
@@ -168,10 +157,13 @@ namespace Discord
/// of flattening.
///
///
- /// The following example gets 5 message prior to the message identifier 442012544660537354.
- ///
- /// var messages = await channel.GetMessagesAsync(442012544660537354, Direction.Before, 5).FlattenAsync();
- ///
+ /// The following example gets 5 message prior to the message identifier 442012544660537354.
+ ///
+ /// The following example attempts to retrieve messageCount number of messages from the
+ /// beginning of the channel and prints them to the console.
+ ///
///
/// The ID of the starting message to get the messages from.
/// The direction of the messages to be gotten from.
@@ -207,9 +199,8 @@ namespace Discord
///
///
/// 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.
@@ -263,12 +254,8 @@ namespace Discord
///
///
/// The following example keeps the client in the typing state until LongRunningAsync has finished.
- ///
- /// using (messageChannel.EnterTypingState())
- /// {
- /// await LongRunningAsync();
- /// }
- ///
+ ///
///
/// The options to be used when sending the request.
///
diff --git a/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs b/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
index 440349eca..29c764e3f 100644
--- a/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
@@ -40,7 +40,7 @@ namespace Discord
///
///
/// The following example gets 250 messages from the channel and deletes them.
- ///
+ ///
/// var messages = await textChannel.GetMessagesAsync(250).FlattenAsync();
/// await textChannel.DeleteMessagesAsync(messages);
///
diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
index 3b35796b9..571afef15 100644
--- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
@@ -440,16 +440,8 @@ namespace Discord
///
///
/// The following example creates a new text channel under an existing category named Wumpus with a set topic.
- ///
- /// var categories = await guild.GetCategoriesAsync();
- /// var targetCategory = categories.FirstOrDefault(x => x.Name == "wumpus");
- /// if (targetCategory == null) return;
- /// await Context.Guild.CreateTextChannelAsync(name, x =>
- /// {
- /// x.CategoryId = targetCategory.Id;
- /// x.Topic = $"This channel was created at {DateTimeOffset.UtcNow} by {user}.";
- /// });
- ///
+ ///
///
/// The new name for the text channel.
/// The delegate containing the properties to be applied to the channel upon its creation.
diff --git a/src/Discord.Net.Core/Entities/Users/IUser.cs b/src/Discord.Net.Core/Entities/Users/IUser.cs
index 66fdcf5ba..c59a75de1 100644
--- a/src/Discord.Net.Core/Entities/Users/IUser.cs
+++ b/src/Discord.Net.Core/Entities/Users/IUser.cs
@@ -23,7 +23,8 @@ namespace Discord
///
/// 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.
- ///
+ ///
///
/// The format to return.
/// The size of the image to return in. This can be any power of two between 16 and 2048.
@@ -91,8 +92,8 @@ namespace Discord
///
/// The following example attempts to send a direct message to the target user and logs the incident should
/// it fail.
- ///
+ ///
///
/// The options to be used when sending the request.
///
diff --git a/src/Discord.Net.Core/IDiscordClient.cs b/src/Discord.Net.Core/IDiscordClient.cs
index d6a863556..e1c900680 100644
--- a/src/Discord.Net.Core/IDiscordClient.cs
+++ b/src/Discord.Net.Core/IDiscordClient.cs
@@ -63,7 +63,7 @@ namespace Discord
/// Gets a generic channel.
///
///
- ///
+ ///
/// var channel = await _client.GetChannelAsync(381889909113225237);
/// if (channel != null && channel is IMessageChannel msgChannel)
/// {
@@ -194,7 +194,7 @@ namespace Discord
/// Gets a user.
///
///
- ///
+ ///
/// var user = await _client.GetUserAsync(168693960628371456);
/// if (user != null)
/// Console.WriteLine($"{user} is created at {user.CreatedAt}.";
@@ -212,7 +212,7 @@ namespace Discord
/// Gets a user.
///
///
- ///
+ ///
/// var user = await _client.GetUserAsync("Still", "2876");
/// if (user != null)
/// Console.WriteLine($"{user} is created at {user.CreatedAt}.";
@@ -232,7 +232,7 @@ namespace Discord
///
///
/// The following example gets the most optimal voice region from the collection.
- ///
+ ///
/// var regions = await client.GetVoiceRegionsAsync();
/// var optimalRegion = regions.FirstOrDefault(x => x.IsOptimal);
///
diff --git a/src/Discord.Net.Examples/Core/Entities/Channels/IGuildChannel.Examples.cs b/src/Discord.Net.Examples/Core/Entities/Channels/IGuildChannel.Examples.cs
index c059f4681..d382ddbf3 100644
--- a/src/Discord.Net.Examples/Core/Entities/Channels/IGuildChannel.Examples.cs
+++ b/src/Discord.Net.Examples/Core/Entities/Channels/IGuildChannel.Examples.cs
@@ -1,31 +1,46 @@
-#region AddPermissionOverwriteAsyncRole
-public async Task MuteRoleAsync(IRole role, IGuildChannel channel)
+using System;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
+
+namespace Discord.Net.Examples.Core.Entities.Channels
{
- if (role == null) throw new ArgumentNullException(nameof(role));
- if (channel == null) throw new ArgumentNullException(nameof(channel));
+ [PublicAPI]
+ internal class GuildChannelExamples
+ {
+ #region AddPermissionOverwriteAsyncRole
- // Fetches the previous overwrite and bail if one is found
- var previousOverwrite = channel.GetPermissionOverwrite(role);
- if (previousOverwrite.HasValue && previousOverwrite.Value.SendMessages == PermValue.Deny)
- throw new InvalidOperationException($"Role {role.Name} had already been muted in this channel.");
+ public async Task MuteRoleAsync(IRole role, IGuildChannel channel)
+ {
+ if (role == null) throw new ArgumentNullException(nameof(role));
+ if (channel == null) throw new ArgumentNullException(nameof(channel));
- // Creates a new OverwritePermissions with send message set to deny and pass it into the method
- await channel.AddPermissionOverwriteAsync(role, new OverwritePermissions(sendMessages: PermValue.Deny));
-}
-#endregion
+ // Fetches the previous overwrite and bail if one is found
+ var previousOverwrite = channel.GetPermissionOverwrite(role);
+ if (previousOverwrite.HasValue && previousOverwrite.Value.SendMessages == PermValue.Deny)
+ throw new InvalidOperationException($"Role {role.Name} had already been muted in this channel.");
-#region AddPermissionOverwriteAsyncUser
-public async Task MuteUserAsync(IGuildUser user, IGuildChannel channel)
-{
- if (role == null) throw new ArgumentNullException(nameof(user));
- if (channel == null) throw new ArgumentNullException(nameof(channel));
+ // Creates a new OverwritePermissions with send message set to deny and pass it into the method
+ await channel.AddPermissionOverwriteAsync(role, new OverwritePermissions(sendMessages: PermValue.Deny));
+ }
+
+ #endregion
+
+ #region AddPermissionOverwriteAsyncUser
+
+ public async Task MuteUserAsync(IGuildUser user, IGuildChannel channel)
+ {
+ if (user == null) throw new ArgumentNullException(nameof(user));
+ if (channel == null) throw new ArgumentNullException(nameof(channel));
+
+ // Fetches the previous overwrite and bail if one is found
+ var previousOverwrite = channel.GetPermissionOverwrite(user);
+ if (previousOverwrite.HasValue && previousOverwrite.Value.SendMessages == PermValue.Deny)
+ throw new InvalidOperationException($"User {user.Username} had already been muted in this channel.");
- // Fetches the previous overwrite and bail if one is found
- var previousOverwrite = channel.GetPermissionOverwrite(user);
- if (previousOverwrite.HasValue && previousOverwrite.Value.SendMessages == PermValue.Deny)
- throw new InvalidOperationException($"User {user.Name} had already been muted in this channel.");
+ // Creates a new OverwritePermissions with send message set to deny and pass it into the method
+ await channel.AddPermissionOverwriteAsync(user, new OverwritePermissions(sendMessages: PermValue.Deny));
+ }
- // Creates a new OverwritePermissions with send message set to deny and pass it into the method
- await channel.AddPermissionOverwriteAsync(user, new OverwritePermissions(sendMessages: PermValue.Deny));
+ #endregion
+ }
}
-#endregion
\ No newline at end of file
diff --git a/src/Discord.Net.Examples/Core/Entities/Channels/IMessageChannel.Examples.cs b/src/Discord.Net.Examples/Core/Entities/Channels/IMessageChannel.Examples.cs
new file mode 100644
index 000000000..5f9d4b5d6
--- /dev/null
+++ b/src/Discord.Net.Examples/Core/Entities/Channels/IMessageChannel.Examples.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Linq;
+using System.Net.Http;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
+
+namespace Discord.Net.Examples.Core.Entities.Channels
+{
+ [PublicAPI]
+ internal class MessageChannelExamples
+ {
+ #region GetMessagesAsync.FromId.BeginningMessages
+
+ public async Task PrintFirstMessages(IMessageChannel channel, int messageCount)
+ {
+ // Although the library does attempt to divide the messageCount by 100
+ // to comply to Discord's maximum message limit per request, sending
+ // too many could still cause the queue to clog up.
+ // The purpose of this exception is to discourage users from sending
+ // too many requests at once.
+ if (messageCount > 1000)
+ throw new InvalidOperationException("Too many messages requested.");
+
+ // Setting fromMessageId to 0 will make Discord
+ // default to the first message in channel.
+ var messages = await channel.GetMessagesAsync(
+ 0, Direction.After, messageCount)
+ .FlattenAsync();
+
+ // Print message content
+ foreach (var message in messages)
+ Console.WriteLine($"{message.Author} posted '{message.Content}' at {message.CreatedAt}.");
+ }
+
+ #endregion
+
+ public async Task GetMessagesExampleBody(IMessageChannel channel)
+ {
+#pragma warning disable IDISP001
+#pragma warning disable IDISP014
+ // We're just declaring this for the sample below.
+ // Ideally, you want to get or create your HttpClient
+ // from IHttpClientFactory.
+ // You get a bonus for reading the example source though!
+ var httpClient = new HttpClient();
+#pragma warning restore IDISP014
+#pragma warning restore IDISP001
+
+ // Another dummy method
+ Task LongRunningAsync()
+ {
+ return Task.Delay(0);
+ }
+
+ #region GetMessagesAsync.FromLimit.Standard
+
+ var messages = await channel.GetMessagesAsync(300).FlattenAsync();
+ var userMessages = messages.Where(x => x.Author.Id == 53905483156684800);
+
+ #endregion
+
+ #region GetMessagesAsync.FromMessage
+
+ var oldMessage = await channel.SendMessageAsync("boi");
+ var messagesFromMsg = await channel.GetMessagesAsync(oldMessage, Direction.Before, 5).FlattenAsync();
+
+ #endregion
+
+
+ #region GetMessagesAsync.FromId.FromMessage
+
+ await channel.GetMessagesAsync(442012544660537354, Direction.Before, 5).FlattenAsync();
+
+ #endregion
+
+ #region SendMessageAsync
+
+ var message = await channel.SendMessageAsync(DateTimeOffset.UtcNow.ToString("R"));
+ await Task.Delay(TimeSpan.FromSeconds(5))
+ .ContinueWith(x => message.DeleteAsync());
+
+ #endregion
+
+ #region SendFileAsync.FilePath
+
+ await channel.SendFileAsync("wumpus.txt", "good discord boi");
+
+ #endregion
+
+ #region SendFileAsync.FilePath.EmbeddedImage
+
+ await channel.SendFileAsync("b1nzy.jpg",
+ embed: new EmbedBuilder {ImageUrl = "attachment://b1nzy.jpg"}.Build());
+
+ #endregion
+
+
+ #region SendFileAsync.FileStream.EmbeddedImage
+
+ using (var b1nzyStream = await httpClient.GetStreamAsync("https://example.com/b1nzy"))
+ await channel.SendFileAsync(b1nzyStream, "b1nzy.jpg",
+ embed: new EmbedBuilder {ImageUrl = "attachment://b1nzy.jpg"}.Build());
+
+ #endregion
+
+ #region EnterTypingState
+
+ using (channel.EnterTypingState()) await LongRunningAsync();
+
+ #endregion
+
+ }
+ }
+}
diff --git a/src/Discord.Net.Examples/Core/Entities/Guilds/IGuild.Examples.cs b/src/Discord.Net.Examples/Core/Entities/Guilds/IGuild.Examples.cs
new file mode 100644
index 000000000..03144b232
--- /dev/null
+++ b/src/Discord.Net.Examples/Core/Entities/Guilds/IGuild.Examples.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
+
+namespace Discord.Net.Examples.Core.Entities.Guilds
+{
+ [PublicAPI]
+ internal class GuildExamples
+ {
+ #region CreateTextChannelAsync
+ public async Task CreateTextChannelUnderWumpus(IGuild guild, string name)
+ {
+ var categories = await guild.GetCategoriesAsync();
+ var targetCategory = categories.FirstOrDefault(x => x.Name == "wumpus");
+ if (targetCategory == null) return;
+ await guild.CreateTextChannelAsync(name, x =>
+ {
+ x.CategoryId = targetCategory.Id;
+ x.Topic = $"This channel was created at {DateTimeOffset.UtcNow}.";
+ });
+ }
+ #endregion
+ }
+}
diff --git a/src/Discord.Net.Examples/Core/Entities/Users/IUser.Examples.cs b/src/Discord.Net.Examples/Core/Entities/Users/IUser.Examples.cs
index 145e406ba..79a90b46d 100644
--- a/src/Discord.Net.Examples/Core/Entities/Users/IUser.Examples.cs
+++ b/src/Discord.Net.Examples/Core/Entities/Users/IUser.Examples.cs
@@ -1,22 +1,38 @@
-#region GetAvatarUrl
-public async Task GetAvatarAsync(IUser user)
-{
- var userAvatarUrl = user.GetAvatarUrl() ?? user.GetDefaultAvatarUrl();
- await textChannel.SendMessageAsync(userAvatarUrl);
-}
-#endregion
+using System;
+using System.Net;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
-#region GetOrCreateDMChannelAsync
-public async Task MessageUserAsync(IUser user)
+namespace Discord.Net.Examples.Core.Entities.Users
{
- var channel = await user.GetOrCreateDMChannelAsync();
- try
+ [PublicAPI]
+ internal class UserExamples
{
- await channel.SendMessageAsync("Awesome stuff!");
- }
- catch (Discord.Net.HttpException ex) when (ex.HttpCode == 403)
- {
- Console.WriteLine($"Boo, I cannot message {user}");
+ #region GetAvatarUrl
+
+ public async Task GetAvatarAsync(IUser user, ITextChannel textChannel)
+ {
+ var userAvatarUrl = user.GetAvatarUrl() ?? user.GetDefaultAvatarUrl();
+ await textChannel.SendMessageAsync(userAvatarUrl);
+ }
+
+ #endregion
+
+ #region GetOrCreateDMChannelAsync
+
+ public async Task MessageUserAsync(IUser user)
+ {
+ var channel = await user.GetOrCreateDMChannelAsync();
+ try
+ {
+ await channel.SendMessageAsync("Awesome stuff!");
+ }
+ catch (Discord.Net.HttpException ex) when (ex.HttpCode == HttpStatusCode.Forbidden)
+ {
+ Console.WriteLine($"Boo, I cannot message {user}.");
+ }
+ }
+
+ #endregion
}
}
-#endregion
\ No newline at end of file
diff --git a/src/Discord.Net.Examples/Discord.Net.Examples.csproj b/src/Discord.Net.Examples/Discord.Net.Examples.csproj
new file mode 100644
index 000000000..b02d2e6d8
--- /dev/null
+++ b/src/Discord.Net.Examples/Discord.Net.Examples.csproj
@@ -0,0 +1,21 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Discord.Net.Examples/WebSocket/BaseSocketClient.Events.Examples.cs b/src/Discord.Net.Examples/WebSocket/BaseSocketClient.Events.Examples.cs
index 0041929c2..387584877 100644
--- a/src/Discord.Net.Examples/WebSocket/BaseSocketClient.Events.Examples.cs
+++ b/src/Discord.Net.Examples/WebSocket/BaseSocketClient.Events.Examples.cs
@@ -1,90 +1,117 @@
-#region ReactionAdded
-public void HookReactionAdded(BaseSocketClient client)
-{
- client.ReactionAdded += HandleReactionAddedAsync;
-}
-public async Task HandleReactionAddedAsync(Cacheable cachedMessage,
- ISocketMessageChannel originChannel, SocketReaction reaction)
-{
- var message = await cachedMessage.GetOrDownloadAsync();
- if (message != null && reaction.User.IsSpecified)
- Console.WriteLine($"{message.User.Value} just added a reaction '{reaction.Emote}' " +
- $"to {message.Author}'s message ({message.Id}).");
-}
-#endregion
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Discord.WebSocket;
+using JetBrains.Annotations;
-#region ChannelCreated
-public void HookChannelCreated(BaseSocketClient client)
-{
- client.ChannelCreated += HandleChannelCreated;
-}
-public Task HandleChannelCreated(SocketChannel channel)
+namespace Discord.Net.Examples.WebSocket
{
- Console.WriteLine($"A new channel '{channel.Name}'({channel.Id}, {channel.GetType()})"
- + $"has been created at {channel.CreatedAt}.");
- return Task.CompletedTask;
-}
-#endregion
+ [PublicAPI]
+ internal class BaseSocketClientExamples
+ {
+ #region ReactionAdded
-#region ChannelDestroyed
-public void HookChannelDestroyed(BaseSocketClient client)
-{
- client.ChannelDestroyed += HandleChannelDestroyed;
-}
-public Task HandleChannelDestroyed(SocketChannel channel)
-{
- Console.WriteLine($"A new channel '{channel.Name}'({channel.Id}, {channel.GetType()}) has been deleted.");
- return Task.CompletedTask;
-}
-#endregion
+ public void HookReactionAdded(BaseSocketClient client)
+ => client.ReactionAdded += HandleReactionAddedAsync;
-#region ChannelUpdated
-public void HookChannelUpdated(BaseSocketClient client)
-{
- client.ChannelUpdated += HandleChannelRename;
-}
-public Task HandleChannelRename(SocketChannel beforeChannel, SocketChannel afterChannel)
-{
- if (beforeChannel.Name != afterChannel.Name)
- Console.WriteLine($"A channel ({beforeChannel.Id}) is renamed from {beforeChannel.Name} to {afterChannel.Name}.");
- return Task.CompletedTask;
-}
-#endregion
+ public async Task HandleReactionAddedAsync(Cacheable cachedMessage,
+ ISocketMessageChannel originChannel, SocketReaction reaction)
+ {
+ var message = await cachedMessage.GetOrDownloadAsync();
+ if (message != null && reaction.User.IsSpecified)
+ Console.WriteLine($"{reaction.User.Value} just added a reaction '{reaction.Emote}' " +
+ $"to {message.Author}'s message ({message.Id}).");
+ }
-#region MessageReceived
-private readonly ulong[] _targetUserIds = new {168693960628371456, 53905483156684800};
-public void HookMessageReceived(BaseSocketClient client)
-{
- client.MessageReceived += HandleMessageReceived;
-}
-public Task HandleMessageReceived(SocketMessage message)
-{
- // check if the message is a user message as opposed to a system message (e.g. Clyde, pins, etc.)
- if (!(message is SocketUserMessage userMessage)) return;
- // check if the message origin is a guild message channel
- if (!(userMessage.Channel is SocketTextChannel textChannel)) return;
- // check if the target user was mentioned
- var targetUsers = userMessage.MentionedUsers.Where(x => _targetUserIds.Contains(x));
- if (targetUsers == null) return;
- foreach (var targetUser in targetUsers)
- Console.WriteLine($"{targetUser} was mentioned in the message '{message.Content}' by {message.Author}.");
- return Task.CompletedTask;
-}
-#endregion
+ #endregion
-#region MessageDeleted
-public void HookMessageDeleted(BaseSocketClient client)
-{
- client.MessageDeleted += HandleMessageDelete;
-}
-public Task HandleMessageDelete(Cacheable cachedMessage, ISocketMessageChannel channel)
-{
- // check if the message exists in cache; if not, we cannot report what was removed
- if (!cachedMessage.HasValue) return;
- var message = cachedMessage.Value;
- Console.WriteLine($"A message ({message.Id}) from {message.Author} was removed from the channel {channel.Name} ({channel.Id}):"
- + Environment.NewLine
- + message.Content);
- return Task.CompletedTask;
+ #region ChannelCreated
+
+ public void HookChannelCreated(BaseSocketClient client)
+ => client.ChannelCreated += HandleChannelCreated;
+
+ public Task HandleChannelCreated(SocketChannel channel)
+ {
+ if (channel is SocketGuildChannel guildChannel)
+ Console.WriteLine($"A new channel '{guildChannel.Name}'({guildChannel.Id}, {guildChannel.GetType()})"
+ + $"has been created at {guildChannel.CreatedAt}.");
+ return Task.CompletedTask;
+ }
+
+ #endregion
+
+ #region ChannelDestroyed
+
+ public void HookChannelDestroyed(BaseSocketClient client)
+ => client.ChannelDestroyed += HandleChannelDestroyed;
+
+ public Task HandleChannelDestroyed(SocketChannel channel)
+ {
+ if (channel is SocketGuildChannel guildChannel)
+ Console.WriteLine(
+ $"A new channel '{guildChannel.Name}'({guildChannel.Id}, {guildChannel.GetType()}) has been deleted.");
+ return Task.CompletedTask;
+ }
+
+ #endregion
+
+ #region ChannelUpdated
+
+ public void HookChannelUpdated(BaseSocketClient client)
+ => client.ChannelUpdated += HandleChannelRename;
+
+ public Task HandleChannelRename(SocketChannel beforeChannel, SocketChannel afterChannel)
+ {
+ if (beforeChannel is SocketGuildChannel beforeGuildChannel &&
+ afterChannel is SocketGuildChannel afterGuildChannel)
+ if (beforeGuildChannel.Name != afterGuildChannel.Name)
+ Console.WriteLine(
+ $"A channel ({beforeChannel.Id}) is renamed from {beforeGuildChannel.Name} to {afterGuildChannel.Name}.");
+ return Task.CompletedTask;
+ }
+
+ #endregion
+
+ #region MessageReceived
+
+ private readonly ulong[] _targetUserIds = {168693960628371456, 53905483156684800};
+
+ public void HookMessageReceived(BaseSocketClient client)
+ => client.MessageReceived += HandleMessageReceived;
+
+ public Task HandleMessageReceived(SocketMessage message)
+ {
+ // check if the message is a user message as opposed to a system message (e.g. Clyde, pins, etc.)
+ if (!(message is SocketUserMessage userMessage)) return Task.CompletedTask;
+ // check if the message origin is a guild message channel
+ if (!(userMessage.Channel is SocketTextChannel textChannel)) return Task.CompletedTask;
+ // check if the target user was mentioned
+ var targetUsers = userMessage.MentionedUsers.Where(x => _targetUserIds.Contains(x.Id));
+ foreach (var targetUser in targetUsers)
+ Console.WriteLine(
+ $"{targetUser} was mentioned in the message '{message.Content}' by {message.Author} in {textChannel.Name}.");
+ return Task.CompletedTask;
+ }
+
+ #endregion
+
+ #region MessageDeleted
+
+ public void HookMessageDeleted(BaseSocketClient client)
+ => client.MessageDeleted += HandleMessageDelete;
+
+ public Task HandleMessageDelete(Cacheable cachedMessage, ISocketMessageChannel channel)
+ {
+ // check if the message exists in cache; if not, we cannot report what was removed
+ if (!cachedMessage.HasValue) return Task.CompletedTask;
+ var message = cachedMessage.Value;
+ Console.WriteLine(
+ $"A message ({message.Id}) from {message.Author} was removed from the channel {channel.Name} ({channel.Id}):"
+ + Environment.NewLine
+ + message.Content);
+ return Task.CompletedTask;
+ }
+
+ #endregion
+ }
}
-#endregion
\ No newline at end of file
diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
index a847998b5..902d2c9a8 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
@@ -405,7 +405,7 @@ namespace Discord.Rest
///
///
/// The following example creates a new text channel under an existing category named Wumpus with a set topic.
- ///
+ ///
/// var categories = await guild.GetCategoriesAsync();
/// var targetCategory = categories.FirstOrDefault(x => x.Name == "wumpus");
/// if (targetCategory == null) return;
diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs b/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
index 8d759dbcb..4f94f702d 100644
--- a/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
+++ b/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
@@ -19,7 +19,8 @@ namespace Discord.WebSocket
///
///
///
- ///
+ ///
///
public event Func ChannelCreated
{
@@ -40,7 +41,8 @@ namespace Discord.WebSocket
///
///
///
- ///
+ ///
///
public event Func ChannelDestroyed {
add { _channelDestroyedEvent.Add(value); }
@@ -61,7 +63,8 @@ namespace Discord.WebSocket
///
///
///
- ///
+ ///
///
public event Func ChannelUpdated {
add { _channelUpdatedEvent.Add(value); }
@@ -84,8 +87,9 @@ namespace Discord.WebSocket
///
///
///
- /// The example below checks if the newly received message contains the target user.
- ///
+ /// The example below checks if the newly received message contains the target user.
+ ///
///
public event Func MessageReceived {
add { _messageReceivedEvent.Add(value); }
@@ -116,7 +120,8 @@ namespace Discord.WebSocket
///
///
///
- ///
+ ///
///
public event Func, ISocketMessageChannel, Task> MessageDeleted {
add { _messageDeletedEvent.Add(value); }
@@ -176,7 +181,8 @@ namespace Discord.WebSocket
///
///
///
- ///
+ ///
///
public event Func, ISocketMessageChannel, SocketReaction, Task> ReactionAdded {
add { _reactionAddedEvent.Add(value); }
diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.cs b/src/Discord.Net.WebSocket/BaseSocketClient.cs
index a7ebf72d8..4ab149832 100644
--- a/src/Discord.Net.WebSocket/BaseSocketClient.cs
+++ b/src/Discord.Net.WebSocket/BaseSocketClient.cs
@@ -97,15 +97,15 @@ namespace Discord.WebSocket
///
/// This method gets the user present in the WebSocket cache with the given condition.
///
- /// Sometimes a user may return null due to Discord not sending offline users in large
- /// guilds (i.e. guild with 100+ members) actively. To download users on startup and to see
- /// more information about this subject, see .
+ /// Sometimes a user may return null due to Discord not sending offline users in large guilds
+ /// (i.e. guild with 100+ members) actively. To download users on startup and to see more information
+ /// about this subject, see .
///
///
/// This method does not attempt to fetch users that the logged-in user does not have access to (i.e.
- /// users who don't share mutual guild(s) with the current user). If you wish to get a user that
- /// you do not have access to, consider using the REST implementation of
- /// .
+ /// users who don't share mutual guild(s) with the current user). If you wish to get a user that you do
+ /// not have access to, consider using the REST implementation of
+ /// .
///
///
///
@@ -116,22 +116,22 @@ namespace Discord.WebSocket
///
/// Gets a user.
///
- /// The name of the user.
- /// The discriminator value of the user.
///
/// This method gets the user present in the WebSocket cache with the given condition.
///
- /// Sometimes a user may return null due to Discord not sending offline users in large
- /// guilds (i.e. guild with 100+ members) actively. To download users on startup and to see
- /// more information about this subject, see .
+ /// Sometimes a user may return null due to Discord not sending offline users in large guilds
+ /// (i.e. guild with 100+ members) actively. To download users on startup and to see more information
+ /// about this subject, see .
///
///
/// This method does not attempt to fetch users that the logged-in user does not have access to (i.e.
- /// users who don't share mutual guild(s) with the current user). If you wish to get a user that
- /// you do not have access to, consider using the REST implementation of
- /// .
+ /// users who don't share mutual guild(s) with the current user). If you wish to get a user that you do
+ /// not have access to, consider using the REST implementation of
+ /// .
///
///
+ /// The name of the user.
+ /// The discriminator value of the user.
///
/// A generic WebSocket-based user; null when the user cannot be found.
///
diff --git a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs
index 6ff83b152..8571cd5c9 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs
@@ -94,8 +94,9 @@ namespace Discord.WebSocket
/// 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
- /// or as a backup.
+ /// overriding the TypeReader and use
+ ///
+ /// or as a backup.
///
///
public bool AlwaysDownloadUsers { get; set; } = false;
diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
index 955e219af..d952b3d92 100644
--- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
+++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
@@ -535,7 +535,7 @@ namespace Discord.WebSocket
///
///
/// The following example creates a new text channel under an existing category named Wumpus with a set topic.
- ///
+ ///
/// var categories = await guild.GetCategoriesAsync();
/// var targetCategory = categories.FirstOrDefault(x => x.Name == "wumpus");
/// if (targetCategory == null) return;