diff --git a/Discord.Net.targets b/Discord.Net.targets
index 958b2053f5..079ec77492 100644
--- a/Discord.Net.targets
+++ b/Discord.Net.targets
@@ -16,13 +16,7 @@
$(VersionSuffix)-$(BuildNumber)
build-$(BuildNumber)
-
-
- $(DefineConstants);FILESYSTEM;DEFAULTUDPCLIENT;DEFAULTWEBSOCKET
-
-
- $(DefineConstants);FORMATSTR;UNIXTIME;MSTRYBUFFER;UDPDISPOSE
-
+
$(NoWarn);CS1573;CS1591
true
diff --git a/docs/_template/light-dark-theme/styles/light.css b/docs/_template/light-dark-theme/styles/light.css
index 18660dfe69..a602274a2a 100644
--- a/docs/_template/light-dark-theme/styles/light.css
+++ b/docs/_template/light-dark-theme/styles/light.css
@@ -10,11 +10,24 @@ body {
overflow: visible;
}
+/* links */
+
+a:active, a:hover, a:visited {
+ color: #0078d7;
+}
+
+a {
+ color: #0050c5;
+ cursor: pointer;
+ text-decoration: none;
+ word-wrap: break-word;
+}
+
/* code */
code {
- color: #222f3d;
- background-color: #f9f9f9;
+ color: #3b5269;
+ background-color: #ececec;
border-radius: 4px;
padding: 3px 7px;
}
diff --git a/docs/docfx.json b/docs/docfx.json
index cb6a363607..663a49cdaf 100644
--- a/docs/docfx.json
+++ b/docs/docfx.json
@@ -43,7 +43,7 @@
"globalMetadata": {
"_appTitle": "Discord.Net Documentation",
"_appFooter": "Discord.Net (c) 2015-2018 2.0.0-beta",
- "_enableSearch": true,
+ "_enableSearch": true
},
"noLangKeyword": false,
"xrefService": [
diff --git a/docs/guides/commands/samples/command_handler.cs b/docs/guides/commands/samples/command_handler.cs
index 470be27073..d63d550ee0 100644
--- a/docs/guides/commands/samples/command_handler.cs
+++ b/docs/guides/commands/samples/command_handler.cs
@@ -1,12 +1,14 @@
-public class CommandHandle
+public class CommandHandler
{
private readonly DiscordSocketClient _client;
private readonly CommandService _commands;
+ private readonly IServiceProvider _services;
- public CommandHandle(DiscordSocketClient client)
+ public CommandHandler(IServiceProvider services)
{
- _client = client;
- _commands = new CommandService();
+ _services = services;
+ _commands = services.GetRequiredService();
+ _client = services.GetRequiredService();
}
public async Task InstallCommandsAsync()
diff --git a/src/Discord.Net.Rpc/Entities/Channels/RpcCategoryChannel.cs b/experiment/Discord.Net.Rpc/Entities/Channels/RpcCategoryChannel.cs
similarity index 100%
rename from src/Discord.Net.Rpc/Entities/Channels/RpcCategoryChannel.cs
rename to experiment/Discord.Net.Rpc/Entities/Channels/RpcCategoryChannel.cs
diff --git a/samples/02_commands_framework/02_commands_framework.csproj b/samples/02_commands_framework/02_commands_framework.csproj
index 77fdc65e12..f479ee0b0e 100644
--- a/samples/02_commands_framework/02_commands_framework.csproj
+++ b/samples/02_commands_framework/02_commands_framework.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj b/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj
index 8ab398ff56..5da3d506d0 100644
--- a/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj
+++ b/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj
@@ -7,7 +7,7 @@
netstandard1.3
-
+
diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs
index 02011bd9f8..49df92a31c 100644
--- a/src/Discord.Net.Commands/CommandParser.cs
+++ b/src/Discord.Net.Commands/CommandParser.cs
@@ -1,4 +1,5 @@
-using System;
+using System;
+using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text;
using System.Threading.Tasks;
@@ -13,8 +14,7 @@ private enum ParserPart
Parameter,
QuotedParameter
}
-
- public static async Task ParseArgsAsync(CommandInfo command, ICommandContext context, IServiceProvider services, string input, int startPos)
+ public static async Task ParseArgsAsync(CommandInfo command, ICommandContext context, bool ignoreExtraArgs, IServiceProvider services, string input, int startPos, IReadOnlyDictionary aliasMap)
{
ParameterInfo curParam = null;
StringBuilder argBuilder = new StringBuilder(input.Length);
@@ -24,7 +24,27 @@ public static async Task ParseArgsAsync(CommandInfo command, IComma
var argList = ImmutableArray.CreateBuilder();
var paramList = ImmutableArray.CreateBuilder();
bool isEscaping = false;
- char c;
+ char c, matchQuote = '\0';
+
+ // local helper functions
+ bool IsOpenQuote(IReadOnlyDictionary dict, char ch)
+ {
+ // return if the key is contained in the dictionary if it is populated
+ if (dict.Count != 0)
+ return dict.ContainsKey(ch);
+ // or otherwise if it is the default double quote
+ return c == '\"';
+ }
+
+ char GetMatch(IReadOnlyDictionary dict, char ch)
+ {
+ // get the corresponding value for the key, if it exists
+ // and if the dictionary is populated
+ if (dict.Count != 0 && dict.TryGetValue(c, out var value))
+ return value;
+ // or get the default pair of the default double quote
+ return '\"';
+ }
for (int curPos = startPos; curPos <= endPos; curPos++)
{
@@ -74,9 +94,11 @@ public static async Task ParseArgsAsync(CommandInfo command, IComma
argBuilder.Append(c);
continue;
}
- if (c == '\"')
+
+ if (IsOpenQuote(aliasMap, c))
{
curPart = ParserPart.QuotedParameter;
+ matchQuote = GetMatch(aliasMap, c);
continue;
}
curPart = ParserPart.Parameter;
@@ -97,7 +119,7 @@ public static async Task ParseArgsAsync(CommandInfo command, IComma
}
else if (curPart == ParserPart.QuotedParameter)
{
- if (c == '\"')
+ if (c == matchQuote)
{
argString = argBuilder.ToString(); //Remove quotes
lastArgEndPos = curPos + 1;
diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs
index 24db6e9b50..0c23f79d00 100644
--- a/src/Discord.Net.Commands/CommandService.cs
+++ b/src/Discord.Net.Commands/CommandService.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
@@ -38,6 +38,7 @@ public class CommandService
internal readonly RunMode _defaultRunMode;
internal readonly Logger _cmdLogger;
internal readonly LogManager _logManager;
+ internal readonly IReadOnlyDictionary _quotationMarkAliasMap;
///
/// Represents all modules loaded within .
@@ -73,6 +74,7 @@ public CommandService(CommandServiceConfig config)
_ignoreExtraArgs = config.IgnoreExtraArgs;
_separatorChar = config.SeparatorChar;
_defaultRunMode = config.DefaultRunMode;
+ _quotationMarkAliasMap = (config.QuotationMarkAliasMap ?? new Dictionary()).ToImmutableDictionary();
if (_defaultRunMode == RunMode.Default)
throw new InvalidOperationException("The default run mode cannot be set to Default.");
@@ -93,6 +95,10 @@ public CommandService(CommandServiceConfig config)
_defaultTypeReaders[typeof(Nullable<>).MakeGenericType(type)] = NullableTypeReader.Create(type, _defaultTypeReaders[type]);
}
+ var tsreader = new TimeSpanTypeReader();
+ _defaultTypeReaders[typeof(TimeSpan)] = tsreader;
+ _defaultTypeReaders[typeof(TimeSpan?)] = NullableTypeReader.Create(typeof(TimeSpan), tsreader);
+
_defaultTypeReaders[typeof(string)] =
new PrimitiveTypeReader((string x, out string y) => { y = x; return true; }, 0);
@@ -447,7 +453,6 @@ public Task ExecuteAsync(ICommandContext context, int argPos, IServiceP
public async Task ExecuteAsync(ICommandContext context, string input, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
{
services = services ?? EmptyServiceProvider.Instance;
-
var searchResult = Search(context, input);
if (!searchResult.IsSuccess)
return searchResult;
diff --git a/src/Discord.Net.Commands/CommandServiceConfig.cs b/src/Discord.Net.Commands/CommandServiceConfig.cs
index f06289a8dd..f9c90f08e9 100644
--- a/src/Discord.Net.Commands/CommandServiceConfig.cs
+++ b/src/Discord.Net.Commands/CommandServiceConfig.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
namespace Discord.Commands
{
@@ -34,8 +35,27 @@ public class CommandServiceConfig
public bool ThrowOnError { get; set; } = true;
///
- /// Gets or sets whether extra parameters should be ignored.
+ /// Collection of aliases for matching pairs of string delimiters.
+ /// The dictionary stores the opening delimiter as a key, and the matching closing delimiter as the value.
+ /// If no value is supplied will be used, which contains
+ /// many regional equivalents.
+ /// Only values that are specified in this map will be used as string delimiters, so if " is removed then
+ /// it won't be used.
+ /// If this map is set to null or empty, the default delimiter of " will be used.
///
+ ///
+ ///
+ /// QuotationMarkAliasMap = new Dictionary<char, char%gt;()
+ /// {
+ /// {'\"', '\"' },
+ /// {'“', '”' },
+ /// {'「', '」' },
+ /// }
+ ///
+ ///
+ public Dictionary QuotationMarkAliasMap { get; set; } = QuotationAliasUtils.GetDefaultAliasMap;
+
+ /// Determines whether extra parameters should be ignored.
public bool IgnoreExtraArgs { get; set; } = false;
}
}
diff --git a/src/Discord.Net.Commands/Discord.Net.Commands.csproj b/src/Discord.Net.Commands/Discord.Net.Commands.csproj
index 9694dd5fcc..a754486ddb 100644
--- a/src/Discord.Net.Commands/Discord.Net.Commands.csproj
+++ b/src/Discord.Net.Commands/Discord.Net.Commands.csproj
@@ -1,15 +1,19 @@
-
+
Discord.Net.Commands
Discord.Commands
A Discord.Net extension adding support for bot commands.
- netstandard1.1;netstandard1.3
+ net46;netstandard1.3;netstandard2.0
+ netstandard1.3;netstandard2.0
-
+
+
+
+
\ No newline at end of file
diff --git a/src/Discord.Net.Commands/Info/CommandInfo.cs b/src/Discord.Net.Commands/Info/CommandInfo.cs
index 3f4429bad2..0f0572be76 100644
--- a/src/Discord.Net.Commands/Info/CommandInfo.cs
+++ b/src/Discord.Net.Commands/Info/CommandInfo.cs
@@ -1,4 +1,4 @@
-using Discord.Commands.Builders;
+using Discord.Commands.Builders;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
@@ -172,7 +172,8 @@ public async Task ParseAsync(ICommandContext context, int startInde
return ParseResult.FromError(preconditionResult);
string input = searchResult.Text.Substring(startIndex);
- return await CommandParser.ParseArgsAsync(this, context, services, input, 0).ConfigureAwait(false);
+
+ return await CommandParser.ParseArgsAsync(this, context, _commandService._ignoreExtraArgs, services, input, 0, _commandService._quotationMarkAliasMap).ConfigureAwait(false);
}
public Task ExecuteAsync(ICommandContext context, ParseResult parseResult, IServiceProvider services)
diff --git a/src/Discord.Net.Commands/PrimitiveParsers.cs b/src/Discord.Net.Commands/PrimitiveParsers.cs
index 6a54ba4026..bf0622c285 100644
--- a/src/Discord.Net.Commands/PrimitiveParsers.cs
+++ b/src/Discord.Net.Commands/PrimitiveParsers.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Collections.Immutable;
@@ -29,7 +29,7 @@ static IReadOnlyDictionary CreateParsers()
parserBuilder[typeof(decimal)] = (TryParseDelegate)decimal.TryParse;
parserBuilder[typeof(DateTime)] = (TryParseDelegate)DateTime.TryParse;
parserBuilder[typeof(DateTimeOffset)] = (TryParseDelegate)DateTimeOffset.TryParse;
- parserBuilder[typeof(TimeSpan)] = (TryParseDelegate)TimeSpan.TryParse;
+ //parserBuilder[typeof(TimeSpan)] = (TryParseDelegate)TimeSpan.TryParse;
parserBuilder[typeof(char)] = (TryParseDelegate)char.TryParse;
return parserBuilder.ToImmutable();
}
diff --git a/src/Discord.Net.Commands/Readers/TimeSpanTypeReader.cs b/src/Discord.Net.Commands/Readers/TimeSpanTypeReader.cs
new file mode 100644
index 0000000000..31ab9d8216
--- /dev/null
+++ b/src/Discord.Net.Commands/Readers/TimeSpanTypeReader.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Globalization;
+using System.Threading.Tasks;
+
+namespace Discord.Commands
+{
+ internal class TimeSpanTypeReader : TypeReader
+ {
+ private static readonly string[] _formats = new[]
+ {
+ "%d'd'%h'h'%m'm'%s's'", //4d3h2m1s
+ "%d'd'%h'h'%m'm'", //4d3h2m
+ "%d'd'%h'h'%s's'", //4d3h 1s
+ "%d'd'%h'h'", //4d3h
+ "%d'd'%m'm'%s's'", //4d 2m1s
+ "%d'd'%m'm'", //4d 2m
+ "%d'd'%s's'", //4d 1s
+ "%d'd'", //4d
+ "%h'h'%m'm'%s's'", // 3h2m1s
+ "%h'h'%m'm'", // 3h2m
+ "%h'h'%s's'", // 3h 1s
+ "%h'h'", // 3h
+ "%m'm'%s's'", // 2m1s
+ "%m'm'", // 2m
+ "%s's'", // 1s
+ };
+
+ public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services)
+ {
+ return (TimeSpan.TryParseExact(input.ToLowerInvariant(), _formats, CultureInfo.InvariantCulture, out var timeSpan))
+ ? Task.FromResult(TypeReaderResult.FromSuccess(timeSpan))
+ : Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Failed to parse TimeSpan"));
+ }
+ }
+}
diff --git a/src/Discord.Net.Commands/Utilities/QuotationAliasUtils.cs b/src/Discord.Net.Commands/Utilities/QuotationAliasUtils.cs
new file mode 100644
index 0000000000..dc2328c1c6
--- /dev/null
+++ b/src/Discord.Net.Commands/Utilities/QuotationAliasUtils.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Globalization;
+
+namespace Discord.Commands
+{
+ ///
+ /// Utility class which contains the default matching pairs of quotation marks for CommandServiceConfig
+ ///
+ internal static class QuotationAliasUtils
+ {
+ ///
+ /// A default map of open-close pairs of quotation marks.
+ /// Contains many regional and Unicode equivalents.
+ /// Used in the .
+ ///
+ ///
+ internal static Dictionary GetDefaultAliasMap
+ {
+ get
+ {
+ // Output of a gist provided by https://gist.github.com/ufcpp
+ // https://gist.github.com/ufcpp/5b2cf9a9bf7d0b8743714a0b88f7edc5
+ // This was not used for the implementation because of incompatibility with netstandard1.1
+ return new Dictionary {
+ {'\"', '\"' },
+ {'«', '»' },
+ {'‘', '’' },
+ {'“', '”' },
+ {'„', '‟' },
+ {'‹', '›' },
+ {'‚', '‛' },
+ {'《', '》' },
+ {'〈', '〉' },
+ {'「', '」' },
+ {'『', '』' },
+ {'〝', '〞' },
+ {'﹁', '﹂' },
+ {'﹃', '﹄' },
+ {'"', '"' },
+ {''', ''' },
+ {'「', '」' },
+ {'(', ')' },
+ {'༺', '༻' },
+ {'༼', '༽' },
+ {'᚛', '᚜' },
+ {'⁅', '⁆' },
+ {'⌈', '⌉' },
+ {'⌊', '⌋' },
+ {'❨', '❩' },
+ {'❪', '❫' },
+ {'❬', '❭' },
+ {'❮', '❯' },
+ {'❰', '❱' },
+ {'❲', '❳' },
+ {'❴', '❵' },
+ {'⟅', '⟆' },
+ {'⟦', '⟧' },
+ {'⟨', '⟩' },
+ {'⟪', '⟫' },
+ {'⟬', '⟭' },
+ {'⟮', '⟯' },
+ {'⦃', '⦄' },
+ {'⦅', '⦆' },
+ {'⦇', '⦈' },
+ {'⦉', '⦊' },
+ {'⦋', '⦌' },
+ {'⦍', '⦎' },
+ {'⦏', '⦐' },
+ {'⦑', '⦒' },
+ {'⦓', '⦔' },
+ {'⦕', '⦖' },
+ {'⦗', '⦘' },
+ {'⧘', '⧙' },
+ {'⧚', '⧛' },
+ {'⧼', '⧽' },
+ {'⸂', '⸃' },
+ {'⸄', '⸅' },
+ {'⸉', '⸊' },
+ {'⸌', '⸍' },
+ {'⸜', '⸝' },
+ {'⸠', '⸡' },
+ {'⸢', '⸣' },
+ {'⸤', '⸥' },
+ {'⸦', '⸧' },
+ {'⸨', '⸩' },
+ {'【', '】'},
+ {'〔', '〕' },
+ {'〖', '〗' },
+ {'〘', '〙' },
+ {'〚', '〛' }
+ };
+ }
+ }
+ }
+}
diff --git a/src/Discord.Net.Core/Discord.Net.Core.csproj b/src/Discord.Net.Core/Discord.Net.Core.csproj
index 7565fa1781..6a58367e67 100644
--- a/src/Discord.Net.Core/Discord.Net.Core.csproj
+++ b/src/Discord.Net.Core/Discord.Net.Core.csproj
@@ -1,15 +1,15 @@
-
+
Discord.Net.Core
Discord
The core components for the Discord.Net library.
- net45;netstandard1.1;netstandard1.3
- netstandard1.1;netstandard1.3
+ net46;netstandard1.3;netstandard2.0
+ netstandard1.3;netstandard2.0
-
-
+
+
diff --git a/src/Discord.Net.Core/DiscordConfig.cs b/src/Discord.Net.Core/DiscordConfig.cs
index 0e46f29601..d0c1c3a84b 100644
--- a/src/Discord.Net.Core/DiscordConfig.cs
+++ b/src/Discord.Net.Core/DiscordConfig.cs
@@ -11,13 +11,21 @@ public class DiscordConfig
/// Returns the API version Discord.Net uses.
///
///
- /// A 32-bit integer representing the API version that Discord.Net uses to communicate with Discord.
+ /// An representing the API version that Discord.Net uses to communicate with Discord.
/// A list of available API version can be seen on the official
/// Discord API documentation
/// .
///
public const int APIVersion = 6;
///
+ /// Returns the Voice API version Discord.Net uses.
+ ///
+ ///
+ /// An representing the API version that Discord.Net uses to communicate with Discord's
+ /// voice server.
+ ///
+ public const int VoiceAPIVersion = 3;
+ ///
/// Gets the Discord.Net version, including the build number.
///
///
@@ -93,6 +101,19 @@ public class DiscordConfig
/// The maximum number of guilds that can be gotten per-batch.
///
public const int MaxGuildsPerBatch = 100;
+ ///
+ /// Returns the max user reactions allowed to be in a request.
+ ///
+ ///
+ /// The maximum number of user reactions that can be gotten per-batch.
+ ///
+ public const int MaxUserReactionsPerBatch = 100;
+ ///
+ /// Returns the max audit log entries allowed to be in a request.
+ ///
+ ///
+ /// The maximum number of audit log entries that can be gotten per-batch.
+ ///
public const int MaxAuditLogEntriesPerBatch = 100;
///
diff --git a/src/Discord.Net.Core/Entities/Activities/GameAsset.cs b/src/Discord.Net.Core/Entities/Activities/GameAsset.cs
index 467b2885f4..7217bded3a 100644
--- a/src/Discord.Net.Core/Entities/Activities/GameAsset.cs
+++ b/src/Discord.Net.Core/Entities/Activities/GameAsset.cs
@@ -12,15 +12,26 @@ internal GameAsset() { }
///
/// Gets the description of the asset.
///
+ ///
+ /// A string containing the description of the asset.
+ ///
public string Text { get; internal set; }
///
/// Gets the image ID of the asset.
///
+ ///
+ /// A string containing the unique image identifier of the asset.
+ ///
public string ImageId { get; internal set; }
///
- /// Returns the image URL of the asset, or null when the application ID does not exist.
+ /// Returns the image URL of the asset.
///
+ /// The size of the image to return in. This can be any power of two between 16 and 2048.
+ /// The format to return.
+ ///
+ /// A string pointing to the image URL of the asset; null when the application ID does not exist.
+ ///
public string GetImageUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
=> ApplicationId.HasValue ? CDN.GetRichAssetUrl(ApplicationId.Value, ImageId, size, format) : null;
}
diff --git a/src/Discord.Net.Core/Entities/Activities/GameParty.cs b/src/Discord.Net.Core/Entities/Activities/GameParty.cs
index c3449df36b..0cfa9980d5 100644
--- a/src/Discord.Net.Core/Entities/Activities/GameParty.cs
+++ b/src/Discord.Net.Core/Entities/Activities/GameParty.cs
@@ -10,11 +10,17 @@ internal GameParty() { }
///
/// Gets the ID of the party.
///
+ ///
+ /// A string containing the unique identifier of the party.
+ ///
public string Id { get; internal set; }
public long Members { get; internal set; }
///
/// Gets the party's current and maximum size.
///
+ ///
+ /// A representing the capacity of the party.
+ ///
public long Capacity { get; internal set; }
}
}
diff --git a/src/Discord.Net.Core/Entities/Activities/IActivity.cs b/src/Discord.Net.Core/Entities/Activities/IActivity.cs
index 30d9369523..ac0c1b5d74 100644
--- a/src/Discord.Net.Core/Entities/Activities/IActivity.cs
+++ b/src/Discord.Net.Core/Entities/Activities/IActivity.cs
@@ -8,10 +8,16 @@ public interface IActivity
///
/// Gets the name of the activity.
///
+ ///
+ /// A string containing the name of the activity that the user is doing.
+ ///
string Name { get; }
///
/// Gets the type of the activity.
///
+ ///
+ /// The type of activity.
+ ///
ActivityType Type { get; }
}
}
diff --git a/src/Discord.Net.Core/Entities/AuditLogs/ActionType.cs b/src/Discord.Net.Core/Entities/AuditLogs/ActionType.cs
index e5a4ff30a5..2561a09709 100644
--- a/src/Discord.Net.Core/Entities/AuditLogs/ActionType.cs
+++ b/src/Discord.Net.Core/Entities/AuditLogs/ActionType.cs
@@ -1,50 +1,122 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
namespace Discord
{
///
- /// The action type within a
+ /// Representing a type of action within an .
///
public enum ActionType
{
+ ///
+ /// this guild was updated.
+ ///
GuildUpdated = 1,
+ ///
+ /// A channel was created.
+ ///
ChannelCreated = 10,
+ ///
+ /// A channel was updated.
+ ///
ChannelUpdated = 11,
+ ///
+ /// A channel was deleted.
+ ///
ChannelDeleted = 12,
+ ///
+ /// A permission overwrite was created for a channel.
+ ///
OverwriteCreated = 13,
+ ///
+ /// A permission overwrite was updated for a channel.
+ ///
OverwriteUpdated = 14,
+ ///
+ /// A permission overwrite was deleted for a channel.
+ ///
OverwriteDeleted = 15,
+ ///
+ /// A user was kicked from this guild.
+ ///
Kick = 20,
+ ///
+ /// A prune took place in this guild.
+ ///
Prune = 21,
+ ///
+ /// A user banned another user from this guild.
+ ///
Ban = 22,
+ ///
+ /// A user unbanned another user from this guild.
+ ///
Unban = 23,
+ ///
+ /// A guild member whose information was updated.
+ ///
MemberUpdated = 24,
+ ///
+ /// A guild member's role collection was updated.
+ ///
MemberRoleUpdated = 25,
+ ///
+ /// A role was created in this guild.
+ ///
RoleCreated = 30,
+ ///
+ /// A role was updated in this guild.
+ ///
RoleUpdated = 31,
+ ///
+ /// A role was deleted from this guild.
+ ///
RoleDeleted = 32,
+ ///
+ /// An invite was created in this guild.
+ ///
InviteCreated = 40,
+ ///
+ /// An invite was updated in this guild.
+ ///
InviteUpdated = 41,
+ ///
+ /// An invite was deleted from this guild.
+ ///
InviteDeleted = 42,
+ ///
+ /// A Webhook was created in this guild.
+ ///
WebhookCreated = 50,
+ ///
+ /// A Webhook was updated in this guild.
+ ///
WebhookUpdated = 51,
+ ///
+ /// A Webhook was deleted from this guild.
+ ///
WebhookDeleted = 52,
+ ///
+ /// An emoji was created in this guild.
+ ///
EmojiCreated = 60,
+ ///
+ /// An emoji was updated in this guild.
+ ///
EmojiUpdated = 61,
+ ///
+ /// An emoji was deleted from this guild.
+ ///
EmojiDeleted = 62,
+ ///
+ /// A message was deleted from this guild.
+ ///
MessageDeleted = 72
}
}
diff --git a/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogData.cs b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogData.cs
index 47aaffb26b..5d87c9d589 100644
--- a/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogData.cs
+++ b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogData.cs
@@ -1,13 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
namespace Discord
{
///
- /// Represents data applied to an
+ /// Represents data applied to an .
///
public interface IAuditLogData
{ }
diff --git a/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs
index b85730a1de..d8f7f1a9f3 100644
--- a/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs
+++ b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs
@@ -1,34 +1,40 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
namespace Discord
{
///
- /// Represents an entry in an audit log
+ /// Represents a generic audit log entry.
///
public interface IAuditLogEntry : IEntity
{
///
- /// The action which occured to create this entry
+ /// Gets the action which occurred to create this entry.
///
+ ///
+ /// The type of action for this audit log entry.
+ ///
ActionType Action { get; }
///
- /// The data for this entry. May be if no data was available.
+ /// Gets the data for this entry.
///
+ ///
+ /// An for this audit log entry; null if no data is available.
+ ///
IAuditLogData Data { get; }
///
- /// The user responsible for causing the changes
+ /// Gets the user responsible for causing the changes.
///
+ ///
+ /// A user object.
+ ///
IUser User { get; }
///
- /// The reason behind the change. May be if no reason was provided.
+ /// Gets the reason behind the change.
///
+ ///
+ /// A string containing the reason for the change; null if none is provided.
+ ///
string Reason { get; }
}
}
diff --git a/src/Discord.Net.Core/Entities/Channels/IChannel.cs b/src/Discord.Net.Core/Entities/Channels/IChannel.cs
index 4f14431c5d..04408989bc 100644
--- a/src/Discord.Net.Core/Entities/Channels/IChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IChannel.cs
@@ -11,16 +11,32 @@ public interface IChannel : ISnowflakeEntity
///
/// Gets the name of this channel.
///
+ ///
+ /// A string containing the name of this channel.
+ ///
string Name { get; }
-
+
///
/// Gets a collection of all users in this channel.
///
+ /// The that determines whether the object should be fetched from cache.
+ /// The options to be used when sending the request.
+ ///
+ /// A paged collection containing a collection of users that can access this channel. Flattening the
+ /// paginated response into a collection of users with
+ /// is required if you wish to access the users.
+ ///
IAsyncEnumerable> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
-
+
///
- /// Gets a user in this channel with the provided ID.
+ /// Gets a user in this channel.
///
+ /// The snowflake identifier of the user (e.g. 168693960628371456).
+ /// The that determines whether the object should be fetched from cache.
+ /// The options to be used when sending the request.
+ ///
+ /// An awaitable containing a user object that represents the user.
+ ///
Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
}
}
diff --git a/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs b/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
index 3d11e2c6f8..301737aa17 100644
--- a/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
@@ -20,29 +20,18 @@ public interface IGuildChannel : IChannel, IDeletable
///
int Position { get; }
- ///
- /// Gets the parent ID (category) of this channel in the guild's channel list.
- ///
- ///
- /// The parent category ID associated with this channel, or null if none is set.
- ///
- ulong? CategoryId { get; }
- ///
- /// Gets the parent channel (category) of this channel.
- ///
- Task GetCategoryAsync();
///
/// Gets the guild associated with this channel.
///
///
- /// The guild that this channel belongs to.
+ /// A guild that this channel belongs to.
///
IGuild Guild { get; }
///
/// Gets the guild ID associated with this channel.
///
///
- /// The guild ID that this channel belongs to.
+ /// A guild snowflake identifier for the guild that this channel belongs to.
///
ulong GuildId { get; }
///
@@ -66,16 +55,25 @@ public interface IGuildChannel : IChannel, IDeletable
/// If true, a user accepting this invite will be kicked from the guild after closing their client.
///
///
- /// If true, don't try to reuse a similar invite (useful for creating many unique one time use invites).
+ /// If true, don't try to reuse a similar invite (useful for creating many unique one time use
+ /// invites).
///
///
/// The options to be used when sending the request.
///
+ ///
+ /// An awaitable containing an invite metadata object containing information for the
+ /// created invite.
+ ///
Task CreateInviteAsync(int? maxAge = 86400, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null);
///
/// Returns a collection of all invites to this channel.
///
/// The options to be used when sending the request.
+ ///
+ /// An awaitable containing a read-only collection of invite metadata that are created
+ /// for this channel.
+ ///
Task> GetInvitesAsync(RequestOptions options = null);
///
@@ -83,29 +81,44 @@ public interface IGuildChannel : IChannel, IDeletable
///
/// The properties to modify the channel with.
/// The options to be used when sending the request.
+ ///
+ /// An awaitable .
+ ///
Task ModifyAsync(Action func, RequestOptions options = null);
///
/// Gets the permission overwrite for a specific role, or null if one does not exist.
///
/// The role to get the overwrite from.
+ ///
+ /// An overwrite object for the targeted role; null if none is set.
+ ///
OverwritePermissions? GetPermissionOverwrite(IRole role);
///
/// Gets the permission overwrite for a specific user, or null if one does not exist.
///
/// The user to get the overwrite from.
+ ///
+ /// An overwrite object for the targeted user; null if none is set.
+ ///
OverwritePermissions? GetPermissionOverwrite(IUser user);
///
/// Removes the permission overwrite for the given role, if one exists.
///
/// The role to remove the overwrite from.
/// The options to be used when sending the request.
+ ///
+ /// An awaitable .
+ ///
Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null);
///
/// Removes the permission overwrite for the given user, if one exists.
///
/// The user to remove the overwrite from.
/// The options to be used when sending the request.
+ ///
+ /// An awaitable .
+ ///
Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null);
///
@@ -114,6 +127,9 @@ public interface IGuildChannel : IChannel, IDeletable
/// The role to add the overwrite to.
/// The overwrite to add to the role.
/// The options to be used when sending the request.
+ ///
+ /// An awaitable .
+ ///
Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null);
///
/// Adds or updates the permission overwrite for the given user.
@@ -121,6 +137,9 @@ public interface IGuildChannel : IChannel, IDeletable
/// The user to add the overwrite to.
/// The overwrite to add to the user.
/// The options to be used when sending the request.
+ ///
+ /// An awaitable .
+ ///
Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null);
///
@@ -130,6 +149,11 @@ public interface IGuildChannel : IChannel, IDeletable
/// The that determines whether the object should be fetched from cache.
///
/// The options to be used when sending the request.
+ ///
+ /// A paged collection containing a collection of guild users that can access this channel. Flattening the
+ /// paginated response into a collection of users with
+ /// is required if you wish to access the users.
+ ///
new IAsyncEnumerable> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
///
/// Gets a user in this channel with the provided ID.
@@ -139,6 +163,9 @@ public interface IGuildChannel : IChannel, IDeletable
/// The that determines whether the object should be fetched from cache.
///
/// The options to be used when sending the request.
+ ///
+ /// An awaitable containing a guild user object that represents the user.
+ ///
new Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
}
}
diff --git a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
index 837e906041..803e07ff6c 100644
--- a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
@@ -20,8 +20,7 @@ public interface IMessageChannel : IChannel
///
/// An awaitable Task containing the message sent to the channel.
///
- Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null);
-#if FILESYSTEM
+ Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
///
/// Sends a file to this message channel with an optional caption.
///
@@ -39,7 +38,6 @@ public interface IMessageChannel : IChannel
/// An awaitable Task containing the message sent to the channel.
///
Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
-#endif
///
/// Sends a file to this message channel with an optional caption.
///
@@ -121,6 +119,11 @@ IAsyncEnumerable> GetMessagesAsync(IMessage fromMe
///
Task> GetPinnedMessagesAsync(RequestOptions options = null);
+ /// Deletes a message based on the message ID in this channel.
+ Task DeleteMessageAsync(ulong messageId, RequestOptions options = null);
+ /// Deletes a message based on the provided message in this channel.
+ Task DeleteMessageAsync(IMessage message, RequestOptions options = null);
+
///
/// Broadcasts the "user is typing" message to all users in this channel, lasting 10 seconds.
///
diff --git a/src/Discord.Net.Core/Entities/Channels/INestedChannel.cs b/src/Discord.Net.Core/Entities/Channels/INestedChannel.cs
new file mode 100644
index 0000000000..62984c2a01
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Channels/INestedChannel.cs
@@ -0,0 +1,28 @@
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ ///
+ /// Represents a type of guild channel that can be nested within a category.
+ ///
+ public interface INestedChannel : IGuildChannel
+ {
+ ///
+ /// Gets the parent (category) ID of this channel in the guild's channel list.
+ ///
+ ///
+ /// An representing the snowflake identifier of the parent of this channel;
+ /// null if none is set.
+ ///
+ ulong? CategoryId { get; }
+ ///
+ /// Gets the parent (category) channel of this channel.
+ ///
+ /// The that determines whether the object should be fetched from cache.
+ /// The options to be used when sending the request.
+ ///
+ /// A category channel representing the parent of this channel; null if none is set.
+ ///
+ Task GetCategoryAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs b/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
index 29c67bf6bd..a2dce09ecd 100644
--- a/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
@@ -8,7 +8,7 @@ namespace Discord
///
/// Represents a generic channel in a guild that can send and receive messages.
///
- public interface ITextChannel : IMessageChannel, IMentionable, IGuildChannel
+ public interface ITextChannel : IMessageChannel, IMentionable, INestedChannel
{
///
/// Determines whether the channel is NSFW.
@@ -80,7 +80,7 @@ public interface ITextChannel : IMessageChannel, IMentionable, IGuildChannel
///
/// The options to be used when sending the request.
///
- /// A collection of webhooks.
+ /// An awaitable containing a collection of webhooks.
///
Task> GetWebhooksAsync(RequestOptions options = null);
}
diff --git a/src/Discord.Net.Core/Entities/Channels/IVoiceChannel.cs b/src/Discord.Net.Core/Entities/Channels/IVoiceChannel.cs
index e1efb1a864..3119a5ae7b 100644
--- a/src/Discord.Net.Core/Entities/Channels/IVoiceChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IVoiceChannel.cs
@@ -4,9 +4,9 @@
namespace Discord
{
///
- /// Represents a voice channel in a guild.
+ /// Represents a generic voice channel in a guild.
///
- public interface IVoiceChannel : IGuildChannel, IAudioChannel
+ public interface IVoiceChannel : INestedChannel, IAudioChannel
{
///
/// Gets the bitrate, in bits per second, clients in this voice channel are requested to use.
diff --git a/src/Discord.Net.Core/Entities/Channels/ReorderChannelProperties.cs b/src/Discord.Net.Core/Entities/Channels/ReorderChannelProperties.cs
index 255279fa8a..f114e0ef5e 100644
--- a/src/Discord.Net.Core/Entities/Channels/ReorderChannelProperties.cs
+++ b/src/Discord.Net.Core/Entities/Channels/ReorderChannelProperties.cs
@@ -8,10 +8,16 @@ public class ReorderChannelProperties
///
/// Gets the ID of the channel to apply this position to.
///
+ ///
+ /// A representing the snowflake identififer of this channel.
+ ///
public ulong Id { get; }
///
/// Gets the new zero-based position of this channel.
///
+ ///
+ /// An representing the new position of this channel.
+ ///
public int Position { get; }
/// Creates a used to reorder a channel.
diff --git a/src/Discord.Net.Core/Entities/Guilds/IBan.cs b/src/Discord.Net.Core/Entities/Guilds/IBan.cs
index 3ce76d29b6..617f2fe046 100644
--- a/src/Discord.Net.Core/Entities/Guilds/IBan.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/IBan.cs
@@ -8,10 +8,16 @@ public interface IBan
///
/// Gets the banned user.
///
+ ///
+ /// A user that was banned.
+ ///
IUser User { get; }
///
- /// Gets the reason why the user is banned.
+ /// Gets the reason why the user is banned if specified.
///
+ ///
+ /// A string containing the reason behind the ban; null if none is specified.
+ ///
string Reason { get; }
}
}
diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
index 581ca551e2..8d6c090b53 100644
--- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
@@ -22,7 +22,8 @@ public interface IGuild : IDeletable, ISnowflakeEntity
/// automatically moved to the AFK voice channel.
///
///
- /// The amount of time in seconds for a user to be marked as inactive and moved into the AFK voice channel.
+ /// An representing the amount of time in seconds for a user to be marked as inactive
+ /// and moved into the AFK voice channel.
///
int AFKTimeout { get; }
///
@@ -94,8 +95,12 @@ public interface IGuild : IDeletable, ISnowflakeEntity
bool Available { get; }
///
- /// Gets the ID of the AFK voice channel for this guild, or null if none is set.
+ /// Gets the ID of the AFK voice channel for this guild.
///
+ ///
+ /// An representing the snowflake identifier of the AFK voice channel; null if
+ /// none is set.
+ ///
ulong? AFKChannelId { get; }
///
/// Gets the ID of the the default channel for this guild.
@@ -214,18 +219,20 @@ public interface IGuild : IDeletable, ISnowflakeEntity
/// Gets a ban object for a banned user.
///
/// The banned user.
+ /// The options to be used when sending the request.
///
/// An awaitable containing the ban object, which contains the user information and the
- /// reason for the ban; null if the ban entry cannot be found.
+ /// reason for the ban; null if the ban entry cannot be found.
///
Task GetBanAsync(IUser user, RequestOptions options = null);
///
/// Gets a ban object for a banned user.
///
/// The snowflake identifier for the banned user.
+ /// The options to be used when sending the request.
///
/// An awaitable containing the ban object, which contains the user information and the
- /// reason for the ban; null if the ban entry cannot be found.
+ /// reason for the ban; null if the ban entry cannot be found.
///
Task GetBanAsync(ulong userId, RequestOptions options = null);
///
@@ -406,24 +413,27 @@ public interface IGuild : IDeletable, ISnowflakeEntity
/// null if none is set.
///
Task GetEmbedChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
+
///
/// Creates a new text channel.
///
/// The new name for the text channel.
+ /// The delegate containing the properties to be applied to the channel upon its creation.
/// The options to be used when sending the request.
///
/// An awaitable containing the newly created text channel.
///
- Task CreateTextChannelAsync(string name, RequestOptions options = null);
+ Task CreateTextChannelAsync(string name, Action func = null, RequestOptions options = null);
///
/// Creates a new voice channel.
///
/// The new name for the voice channel.
+ /// The delegate containing the properties to be applied to the channel upon its creation.
/// The options to be used when sending the request.
///
/// An awaitable containing the newly created voice channel.
///
- Task CreateVoiceChannelAsync(string name, RequestOptions options = null);
+ Task CreateVoiceChannelAsync(string name, Action func = null, RequestOptions options = null);
///
/// Creates a new channel category.
///
@@ -537,7 +547,17 @@ public interface IGuild : IDeletable, ISnowflakeEntity
///
Task PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null);
- /// Gets the specified number of audit log entries for this guild.
+ ///
+ /// Gets the specified number of audit log entries for this guild.
+ ///
+ /// The number of audit log entries to fetch.
+ ///
+ /// The that determines whether the object should be fetched from cache.
+ ///
+ /// The options to be used when sending the request.
+ ///
+ /// An awaitable containing a collection of requested audit log entries.
+ ///
Task> GetAuditLogAsync(int limit = DiscordConfig.MaxAuditLogEntriesPerBatch,
CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
diff --git a/src/Discord.Net.Core/Entities/Image.cs b/src/Discord.Net.Core/Entities/Image.cs
index 5453027acb..5c775f9f4f 100644
--- a/src/Discord.Net.Core/Entities/Image.cs
+++ b/src/Discord.Net.Core/Entities/Image.cs
@@ -1,4 +1,3 @@
-using System;
using System.IO;
namespace Discord
{
@@ -22,7 +21,7 @@ public Image(Stream stream)
{
Stream = stream;
}
-#if FILESYSTEM
+
///
/// Create the image from a file path.
///
@@ -31,21 +30,21 @@ public Image(Stream stream)
/// .
///
/// The path to the file.
- ///
+ ///
/// is a zero-length string, contains only white space, or contains one or more invalid
/// characters as defined by .
///
- /// is null.
+ /// is null.
///
/// The specified path, file name, or both exceed the system-defined maximum length. For example, on
/// Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260
/// characters.
///
- /// is in an invalid format.
+ /// is in an invalid format.
///
/// The specified is invalid, (for example, it is on an unmapped drive).
///
- ///
+ ///
/// specified a directory.-or- The caller does not have the required permission.
///
/// The file specified in was not found.
@@ -55,6 +54,6 @@ public Image(string path)
{
Stream = File.OpenRead(path);
}
-#endif
+
}
}
diff --git a/src/Discord.Net.Core/Entities/Invites/IInvite.cs b/src/Discord.Net.Core/Entities/Invites/IInvite.cs
index 62e4a4bfcb..90dde74745 100644
--- a/src/Discord.Net.Core/Entities/Invites/IInvite.cs
+++ b/src/Discord.Net.Core/Entities/Invites/IInvite.cs
@@ -1,5 +1,3 @@
-using System.Threading.Tasks;
-
namespace Discord
{
///
@@ -10,44 +8,76 @@ public interface IInvite : IEntity, IDeletable
///
/// Gets the unique identifier for this invite.
///
+ ///
+ /// A string containing the invite code (e.g. FTqNnyS).
+ ///
string Code { get; }
///
- /// Gets the URL used to accept this invite, using Code.
+ /// Gets the URL used to accept this invite using .
///
+ ///
+ /// A string containing the full invite URL (e.g. https://discord.gg/FTqNnyS).
+ ///
string Url { get; }
///
/// Gets the channel this invite is linked to.
///
+ ///
+ /// A generic channel that the invite points to.
+ ///
IChannel Channel { get; }
///
/// Gets the ID of the channel this invite is linked to.
///
+ ///
+ /// An representing the channel snowflake identifier that the invite points to.
+ ///
ulong ChannelId { get; }
///
/// Gets the name of the channel this invite is linked to.
///
+ ///
+ /// A string containing the name of the channel that the invite points to.
+ ///
string ChannelName { get; }
///
/// Gets the guild this invite is linked to.
///
+ ///
+ /// A guild object representing the guild that the invite points to.
+ ///
IGuild Guild { get; }
///
/// Gets the ID of the guild this invite is linked to.
///
+ ///
+ /// An representing the guild snowflake identifier that the invite points to.
+ ///
ulong GuildId { get; }
///
/// Gets the name of the guild this invite is linked to.
///
+ ///
+ /// A string containing the name of the guild that the invite points to.
+ ///
string GuildName { get; }
///
/// Gets the approximated count of online members in the guild.
///
+ ///
+ /// An representing the approximated online member count of the guild that the
+ /// invite points to; null if one cannot be obtained.
+ ///
int? PresenceCount { get; }
///
/// Gets the approximated count of total members in the guild.
///
+ ///
+ /// An representing the approximated total member count of the guild that the
+ /// invite points to; null if one cannot be obtained.
+ ///
int? MemberCount { get; }
}
}
diff --git a/src/Discord.Net.Core/Entities/Invites/IInviteMetadata.cs b/src/Discord.Net.Core/Entities/Invites/IInviteMetadata.cs
index 1c6b1dd79b..20f13a74c1 100644
--- a/src/Discord.Net.Core/Entities/Invites/IInviteMetadata.cs
+++ b/src/Discord.Net.Core/Entities/Invites/IInviteMetadata.cs
@@ -2,37 +2,63 @@
namespace Discord
{
- /// Represents additional information regarding the generic invite object.
+ ///
+ /// Represents additional information regarding the generic invite object.
+ ///
public interface IInviteMetadata : IInvite
{
///
/// Gets the user that created this invite.
///
+ ///
+ /// A user that created this invite.
+ ///
IUser Inviter { get; }
///
- /// Returns true if this invite was revoked.
+ /// Determines whether the invite has been revoked.
///
+ ///
+ /// true if this invite was revoked; otherwise false.
+ ///
bool IsRevoked { get; }
///
- /// Returns true if users accepting this invite will be removed from the guild when they
- /// log off.
+ /// Determines whether the invite is a temporary one (i.e. whether the invite will be removed from the guild
+ /// when the user logs off).
///
+ ///
+ /// true if users accepting this invite will be removed from the guild when they log off; otherwise
+ /// false.
+ ///
bool IsTemporary { get; }
///
- /// Gets the time (in seconds) until the invite expires, or null if it never expires.
+ /// Gets the time (in seconds) until the invite expires.
///
+ ///
+ /// An representing the time in seconds until this invite expires; null if this
+ /// invite never expires.
+ ///
int? MaxAge { get; }
///
- /// Gets the max amount of times this invite may be used, or null if there is no limit.
+ /// Gets the max number of uses this invite may have.
///
+ ///
+ /// An representing the number of uses this invite may be accepted until it is removed
+ /// from the guild; null if none is set.
+ ///
int? MaxUses { get; }
///
- /// Gets the amount of times this invite has been used.
+ /// Gets the number of times this invite has been used.
///
+ ///
+ /// An representing the number of times this invite has been used.
+ ///
int Uses { get; }
///
/// Gets when this invite was created.
///
+ ///
+ /// A representing the time of which the invite was first created.
+ ///
DateTimeOffset CreatedAt { get; }
}
}
diff --git a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
index 18ef932660..bad4e36c7b 100644
--- a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
@@ -42,7 +42,7 @@ public interface IUserMessage : IMessage
///
/// Gets all users that reacted to a message with a given emote.
///
- Task> GetReactionUsersAsync(IEmote emoji, int limit = 100, ulong? afterUserId = null, RequestOptions options = null);
+ IAsyncEnumerable> GetReactionUsersAsync(IEmote emoji, int limit, RequestOptions options = null);
///
/// Transforms this message's text into a human-readable form by resolving its tags.
diff --git a/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs b/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs
index 758bc5758d..753be6d516 100644
--- a/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs
+++ b/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs
@@ -88,12 +88,27 @@ public static ChannelPermissions All(IChannel channel)
/// Creates a new with the provided packed value.
public ChannelPermissions(ulong rawValue) { RawValue = rawValue; }
- private ChannelPermissions(ulong initialValue, bool? createInstantInvite = null, bool? manageChannel = null,
+ private ChannelPermissions(ulong initialValue,
+ bool? createInstantInvite = null,
+ bool? manageChannel = null,
bool? addReactions = null,
- bool? viewChannel = null, bool? sendMessages = null, bool? sendTTSMessages = null, bool? manageMessages = null,
- bool? embedLinks = null, bool? attachFiles = null, bool? readMessageHistory = null, bool? mentionEveryone = null,
- bool? useExternalEmojis = null, bool? connect = null, bool? speak = null, bool? muteMembers = null, bool? deafenMembers = null,
- bool? moveMembers = null, bool? useVoiceActivation = null, bool? manageRoles = null, bool? manageWebhooks = null)
+ bool? viewChannel = null,
+ bool? sendMessages = null,
+ bool? sendTTSMessages = null,
+ bool? manageMessages = null,
+ bool? embedLinks = null,
+ bool? attachFiles = null,
+ bool? readMessageHistory = null,
+ bool? mentionEveryone = null,
+ bool? useExternalEmojis = null,
+ bool? connect = null,
+ bool? speak = null,
+ bool? muteMembers = null,
+ bool? deafenMembers = null,
+ bool? moveMembers = null,
+ bool? useVoiceActivation = null,
+ bool? manageRoles = null,
+ bool? manageWebhooks = null)
{
ulong value = initialValue;
@@ -122,27 +137,75 @@ private ChannelPermissions(ulong initialValue, bool? createInstantInvite = null,
}
/// Creates a new with the provided permissions.
- public ChannelPermissions(bool createInstantInvite = false, bool manageChannel = false,
+ public ChannelPermissions(
+ bool createInstantInvite = false,
+ bool manageChannel = false,
bool addReactions = false,
- bool viewChannel = false, bool sendMessages = false, bool sendTTSMessages = false, bool manageMessages = false,
- bool embedLinks = false, bool attachFiles = false, bool readMessageHistory = false, bool mentionEveryone = false,
- bool useExternalEmojis = false, bool connect = false, bool speak = false, bool muteMembers = false, bool deafenMembers = false,
- bool moveMembers = false, bool useVoiceActivation = false, bool manageRoles = false, bool manageWebhooks = false)
+ bool viewChannel = false,
+ bool sendMessages = false,
+ bool sendTTSMessages = false,
+ bool manageMessages = false,
+ bool embedLinks = false,
+ bool attachFiles = false,
+ bool readMessageHistory = false,
+ bool mentionEveryone = false,
+ bool useExternalEmojis = false,
+ bool connect = false,
+ bool speak = false,
+ bool muteMembers = false,
+ bool deafenMembers = false,
+ bool moveMembers = false,
+ bool useVoiceActivation = false,
+ bool manageRoles = false,
+ bool manageWebhooks = false)
: this(0, createInstantInvite, manageChannel, addReactions, viewChannel, sendMessages, sendTTSMessages, manageMessages,
embedLinks, attachFiles, readMessageHistory, mentionEveryone, useExternalEmojis, connect,
speak, muteMembers, deafenMembers, moveMembers, useVoiceActivation, manageRoles, manageWebhooks)
{ }
/// Creates a new from this one, changing the provided non-null permissions.
- public ChannelPermissions Modify(bool? createInstantInvite = null, bool? manageChannel = null,
+ public ChannelPermissions Modify(
+ bool? createInstantInvite = null,
+ bool? manageChannel = null,
bool? addReactions = null,
- bool? viewChannel = null, bool? sendMessages = null, bool? sendTTSMessages = null, bool? manageMessages = null,
- bool? embedLinks = null, bool? attachFiles = null, bool? readMessageHistory = null, bool? mentionEveryone = null,
- bool useExternalEmojis = false, bool? connect = null, bool? speak = null, bool? muteMembers = null, bool? deafenMembers = null,
- bool? moveMembers = null, bool? useVoiceActivation = null, bool? manageRoles = null, bool? manageWebhooks = null)
- => new ChannelPermissions(RawValue, createInstantInvite, manageChannel, addReactions, viewChannel, sendMessages, sendTTSMessages, manageMessages,
- embedLinks, attachFiles, readMessageHistory, mentionEveryone, useExternalEmojis, connect,
- speak, muteMembers, deafenMembers, moveMembers, useVoiceActivation, manageRoles, manageWebhooks);
+ bool? viewChannel = null,
+ bool? sendMessages = null,
+ bool? sendTTSMessages = null,
+ bool? manageMessages = null,
+ bool? embedLinks = null,
+ bool? attachFiles = null,
+ bool? readMessageHistory = null,
+ bool? mentionEveryone = null,
+ bool? useExternalEmojis = null,
+ bool? connect = null,
+ bool? speak = null,
+ bool? muteMembers = null,
+ bool? deafenMembers = null,
+ bool? moveMembers = null,
+ bool? useVoiceActivation = null,
+ bool? manageRoles = null,
+ bool? manageWebhooks = null)
+ => new ChannelPermissions(RawValue,
+ createInstantInvite,
+ manageChannel,
+ addReactions,
+ viewChannel,
+ sendMessages,
+ sendTTSMessages,
+ manageMessages,
+ embedLinks,
+ attachFiles,
+ readMessageHistory,
+ mentionEveryone,
+ useExternalEmojis,
+ connect,
+ speak,
+ muteMembers,
+ deafenMembers,
+ moveMembers,
+ useVoiceActivation,
+ manageRoles,
+ manageWebhooks);
public bool Has(ChannelPermission permission) => Permissions.GetValue(RawValue, permission);
diff --git a/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs b/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs
index 663c7fc6c8..f2724778f1 100644
--- a/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs
+++ b/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs
@@ -41,13 +41,9 @@ public enum GuildPermission : ulong
/// Allows for viewing of audit logs.
///
ViewAuditLog = 0x00_00_00_80,
- ///
- /// Allows for reading of message.
- ///
- ReadMessages = 0x00_00_04_00,
- ///
- /// Allows for sending messages in a channel.
- ///
+ [Obsolete("Use ViewChannel instead.")]
+ ReadMessages = ViewChannel,
+ ViewChannel = 0x00_00_04_00,
SendMessages = 0x00_00_08_00,
///
/// Allows for sending of text-to-speech messages.
diff --git a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
index 9a0cb2919a..9ad7d34b44 100644
--- a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
+++ b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -34,9 +35,12 @@ public struct GuildPermissions
/// If true, a user may view the audit log.
public bool ViewAuditLog => Permissions.GetValue(RawValue, GuildPermission.ViewAuditLog);
- /// If true, a user may join channels.
- public bool ReadMessages => Permissions.GetValue(RawValue, GuildPermission.ReadMessages);
- /// If true, a user may send messages.
+ /// If True, a user may join channels.
+ [Obsolete("Use ViewChannel instead.")]
+ public bool ReadMessages => ViewChannel;
+ /// If True, a user may view channels.
+ public bool ViewChannel => Permissions.GetValue(RawValue, GuildPermission.ViewChannel);
+ /// If True, a user may send messages.
public bool SendMessages => Permissions.GetValue(RawValue, GuildPermission.SendMessages);
/// If true, a user may send text-to-speech messages.
public bool SendTTSMessages => Permissions.GetValue(RawValue, GuildPermission.SendTTSMessages);
@@ -80,14 +84,35 @@ public struct GuildPermissions
/// Creates a new with the provided packed value.
public GuildPermissions(ulong rawValue) { RawValue = rawValue; }
- private GuildPermissions(ulong initialValue, bool? createInstantInvite = null, bool? kickMembers = null,
- bool? banMembers = null, bool? administrator = null, bool? manageChannels = null, bool? manageGuild = null,
- bool? addReactions = null, bool? viewAuditLog = null,
- bool? readMessages = null, bool? sendMessages = null, bool? sendTTSMessages = null, bool? manageMessages = null,
- bool? embedLinks = null, bool? attachFiles = null, bool? readMessageHistory = null, bool? mentionEveryone = null,
- bool? useExternalEmojis = null, bool? connect = null, bool? speak = null, bool? muteMembers = null, bool? deafenMembers = null,
- bool? moveMembers = null, bool? useVoiceActivation = null, bool? changeNickname = null, bool? manageNicknames = null,
- bool? manageRoles = null, bool? manageWebhooks = null, bool? manageEmojis = null)
+ private GuildPermissions(ulong initialValue,
+ bool? createInstantInvite = null,
+ bool? kickMembers = null,
+ bool? banMembers = null,
+ bool? administrator = null,
+ bool? manageChannels = null,
+ bool? manageGuild = null,
+ bool? addReactions = null,
+ bool? viewAuditLog = null,
+ bool? viewChannel = null,
+ bool? sendMessages = null,
+ bool? sendTTSMessages = null,
+ bool? manageMessages = null,
+ bool? embedLinks = null,
+ bool? attachFiles = null,
+ bool? readMessageHistory = null,
+ bool? mentionEveryone = null,
+ bool? useExternalEmojis = null,
+ bool? connect = null,
+ bool? speak = null,
+ bool? muteMembers = null,
+ bool? deafenMembers = null,
+ bool? moveMembers = null,
+ bool? useVoiceActivation = null,
+ bool? changeNickname = null,
+ bool? manageNicknames = null,
+ bool? manageRoles = null,
+ bool? manageWebhooks = null,
+ bool? manageEmojis = null)
{
ulong value = initialValue;
@@ -99,7 +124,7 @@ private GuildPermissions(ulong initialValue, bool? createInstantInvite = null, b
Permissions.SetValue(ref value, manageGuild, GuildPermission.ManageGuild);
Permissions.SetValue(ref value, addReactions, GuildPermission.AddReactions);
Permissions.SetValue(ref value, viewAuditLog, GuildPermission.ViewAuditLog);
- Permissions.SetValue(ref value, readMessages, GuildPermission.ReadMessages);
+ Permissions.SetValue(ref value, viewChannel, GuildPermission.ViewChannel);
Permissions.SetValue(ref value, sendMessages, GuildPermission.SendMessages);
Permissions.SetValue(ref value, sendTTSMessages, GuildPermission.SendTTSMessages);
Permissions.SetValue(ref value, manageMessages, GuildPermission.ManageMessages);
@@ -124,34 +149,98 @@ private GuildPermissions(ulong initialValue, bool? createInstantInvite = null, b
}
/// Creates a new with the provided permissions.
- public GuildPermissions(bool createInstantInvite = false, bool kickMembers = false,
- bool banMembers = false, bool administrator = false, bool manageChannels = false, bool manageGuild = false,
- bool addReactions = false, bool viewAuditLog = false,
- bool readMessages = false, bool sendMessages = false, bool sendTTSMessages = false, bool manageMessages = false,
- bool embedLinks = false, bool attachFiles = false, bool readMessageHistory = false, bool mentionEveryone = false,
- bool useExternalEmojis = false, bool connect = false, bool speak = false, bool muteMembers = false, bool deafenMembers = false,
- bool moveMembers = false, bool useVoiceActivation = false, bool? changeNickname = false, bool? manageNicknames = false,
- bool manageRoles = false, bool manageWebhooks = false, bool manageEmojis = false)
- : this(0, createInstantInvite: createInstantInvite, manageRoles: manageRoles, kickMembers: kickMembers, banMembers: banMembers,
- administrator: administrator, manageChannels: manageChannels, manageGuild: manageGuild, addReactions: addReactions,
- viewAuditLog: viewAuditLog, readMessages: readMessages, sendMessages: sendMessages, sendTTSMessages: sendTTSMessages,
- manageMessages: manageMessages, embedLinks: embedLinks, attachFiles: attachFiles, readMessageHistory: readMessageHistory,
- mentionEveryone: mentionEveryone, useExternalEmojis: useExternalEmojis, connect: connect, speak: speak, muteMembers: muteMembers,
- deafenMembers: deafenMembers, moveMembers: moveMembers, useVoiceActivation: useVoiceActivation, changeNickname: changeNickname,
- manageNicknames: manageNicknames, manageWebhooks: manageWebhooks, manageEmojis: manageEmojis)
+ public GuildPermissions(
+ bool createInstantInvite = false,
+ bool kickMembers = false,
+ bool banMembers = false,
+ bool administrator = false,
+ bool manageChannels = false,
+ bool manageGuild = false,
+ bool addReactions = false,
+ bool viewAuditLog = false,
+ bool viewChannel = false,
+ bool sendMessages = false,
+ bool sendTTSMessages = false,
+ bool manageMessages = false,
+ bool embedLinks = false,
+ bool attachFiles = false,
+ bool readMessageHistory = false,
+ bool mentionEveryone = false,
+ bool useExternalEmojis = false,
+ bool connect = false,
+ bool speak = false,
+ bool muteMembers = false,
+ bool deafenMembers = false,
+ bool moveMembers = false,
+ bool useVoiceActivation = false,
+ bool changeNickname = false,
+ bool manageNicknames = false,
+ bool manageRoles = false,
+ bool manageWebhooks = false,
+ bool manageEmojis = false)
+ : this(0,
+ createInstantInvite: createInstantInvite,
+ manageRoles: manageRoles,
+ kickMembers: kickMembers,
+ banMembers: banMembers,
+ administrator: administrator,
+ manageChannels: manageChannels,
+ manageGuild: manageGuild,
+ addReactions: addReactions,
+ viewAuditLog: viewAuditLog,
+ viewChannel: viewChannel,
+ sendMessages: sendMessages,
+ sendTTSMessages: sendTTSMessages,
+ manageMessages: manageMessages,
+ embedLinks: embedLinks,
+ attachFiles: attachFiles,
+ readMessageHistory: readMessageHistory,
+ mentionEveryone: mentionEveryone,
+ useExternalEmojis: useExternalEmojis,
+ connect: connect,
+ speak: speak,
+ muteMembers: muteMembers,
+ deafenMembers: deafenMembers,
+ moveMembers: moveMembers,
+ useVoiceActivation: useVoiceActivation,
+ changeNickname: changeNickname,
+ manageNicknames: manageNicknames,
+ manageWebhooks: manageWebhooks,
+ manageEmojis: manageEmojis)
{ }
/// Creates a new from this one, changing the provided non-null permissions.
- public GuildPermissions Modify(bool? createInstantInvite = null, bool? kickMembers = null,
- bool? banMembers = null, bool? administrator = null, bool? manageChannels = null, bool? manageGuild = null,
- bool? addReactions = null, bool? viewAuditLog = null,
- bool? readMessages = null, bool? sendMessages = null, bool? sendTTSMessages = null, bool? manageMessages = null,
- bool? embedLinks = null, bool? attachFiles = null, bool? readMessageHistory = null, bool? mentionEveryone = null,
- bool? useExternalEmojis = null, bool? connect = null, bool? speak = null, bool? muteMembers = null, bool? deafenMembers = null,
- bool? moveMembers = null, bool? useVoiceActivation = null, bool? changeNickname = null, bool? manageNicknames = null,
- bool? manageRoles = null, bool? manageWebhooks = null, bool? manageEmojis = null)
+ public GuildPermissions Modify(
+ bool? createInstantInvite = null,
+ bool? kickMembers = null,
+ bool? banMembers = null,
+ bool? administrator = null,
+ bool? manageChannels = null,
+ bool? manageGuild = null,
+ bool? addReactions = null,
+ bool? viewAuditLog = null,
+ bool? viewChannel = null,
+ bool? sendMessages = null,
+ bool? sendTTSMessages = null,
+ bool? manageMessages = null,
+ bool? embedLinks = null,
+ bool? attachFiles = null,
+ bool? readMessageHistory = null,
+ bool? mentionEveryone = null,
+ bool? useExternalEmojis = null,
+ bool? connect = null,
+ bool? speak = null,
+ bool? muteMembers = null,
+ bool? deafenMembers = null,
+ bool? moveMembers = null,
+ bool? useVoiceActivation = null,
+ bool? changeNickname = null,
+ bool? manageNicknames = null,
+ bool? manageRoles = null,
+ bool? manageWebhooks = null,
+ bool? manageEmojis = null)
=> new GuildPermissions(RawValue, createInstantInvite, kickMembers, banMembers, administrator, manageChannels, manageGuild, addReactions,
- viewAuditLog, readMessages, sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles,
+ viewAuditLog, viewChannel, sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles,
readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers, moveMembers,
useVoiceActivation, changeNickname, manageNicknames, manageRoles, manageWebhooks, manageEmojis);
diff --git a/src/Discord.Net.Core/Entities/Permissions/OverwritePermissions.cs b/src/Discord.Net.Core/Entities/Permissions/OverwritePermissions.cs
index bcc34b98a3..97735c42ce 100644
--- a/src/Discord.Net.Core/Entities/Permissions/OverwritePermissions.cs
+++ b/src/Discord.Net.Core/Entities/Permissions/OverwritePermissions.cs
@@ -84,12 +84,26 @@ public OverwritePermissions(ulong allowValue, ulong denyValue)
DenyValue = denyValue;
}
- private OverwritePermissions(ulong allowValue, ulong denyValue, PermValue? createInstantInvite = null, PermValue? manageChannel = null,
+ private OverwritePermissions(ulong allowValue, ulong denyValue,
+ PermValue? createInstantInvite = null,
+ PermValue? manageChannel = null,
PermValue? addReactions = null,
- PermValue? viewChannel = null, PermValue? sendMessages = null, PermValue? sendTTSMessages = null, PermValue? manageMessages = null,
- PermValue? embedLinks = null, PermValue? attachFiles = null, PermValue? readMessageHistory = null, PermValue? mentionEveryone = null,
- PermValue? useExternalEmojis = null, PermValue? connect = null, PermValue? speak = null, PermValue? muteMembers = null,
- PermValue? deafenMembers = null, PermValue? moveMembers = null, PermValue? useVoiceActivation = null, PermValue? manageRoles = null,
+ PermValue? viewChannel = null,
+ PermValue? sendMessages = null,
+ PermValue? sendTTSMessages = null,
+ PermValue? manageMessages = null,
+ PermValue? embedLinks = null,
+ PermValue? attachFiles = null,
+ PermValue? readMessageHistory = null,
+ PermValue? mentionEveryone = null,
+ PermValue? useExternalEmojis = null,
+ PermValue? connect = null,
+ PermValue? speak = null,
+ PermValue? muteMembers = null,
+ PermValue? deafenMembers = null,
+ PermValue? moveMembers = null,
+ PermValue? useVoiceActivation = null,
+ PermValue? manageRoles = null,
PermValue? manageWebhooks = null)
{
Permissions.SetValue(ref allowValue, ref denyValue, createInstantInvite, ChannelPermission.CreateInstantInvite);
@@ -120,13 +134,28 @@ private OverwritePermissions(ulong allowValue, ulong denyValue, PermValue? creat
///
/// Creates a new with the provided permissions.
///
- public OverwritePermissions(PermValue createInstantInvite = PermValue.Inherit, PermValue manageChannel = PermValue.Inherit,
+ public OverwritePermissions(
+ PermValue createInstantInvite = PermValue.Inherit,
+ PermValue manageChannel = PermValue.Inherit,
PermValue addReactions = PermValue.Inherit,
- PermValue readMessages = PermValue.Inherit, PermValue sendMessages = PermValue.Inherit, PermValue sendTTSMessages = PermValue.Inherit, PermValue manageMessages = PermValue.Inherit,
- PermValue embedLinks = PermValue.Inherit, PermValue attachFiles = PermValue.Inherit, PermValue readMessageHistory = PermValue.Inherit, PermValue mentionEveryone = PermValue.Inherit,
- PermValue useExternalEmojis = PermValue.Inherit, PermValue connect = PermValue.Inherit, PermValue speak = PermValue.Inherit, PermValue muteMembers = PermValue.Inherit, PermValue deafenMembers = PermValue.Inherit,
- PermValue moveMembers = PermValue.Inherit, PermValue useVoiceActivation = PermValue.Inherit, PermValue manageRoles = PermValue.Inherit, PermValue manageWebhooks = PermValue.Inherit)
- : this(0, 0, createInstantInvite, manageChannel, addReactions, readMessages, sendMessages, sendTTSMessages, manageMessages,
+ PermValue viewChannel = PermValue.Inherit,
+ PermValue sendMessages = PermValue.Inherit,
+ PermValue sendTTSMessages = PermValue.Inherit,
+ PermValue manageMessages = PermValue.Inherit,
+ PermValue embedLinks = PermValue.Inherit,
+ PermValue attachFiles = PermValue.Inherit,
+ PermValue readMessageHistory = PermValue.Inherit,
+ PermValue mentionEveryone = PermValue.Inherit,
+ PermValue useExternalEmojis = PermValue.Inherit,
+ PermValue connect = PermValue.Inherit,
+ PermValue speak = PermValue.Inherit,
+ PermValue muteMembers = PermValue.Inherit,
+ PermValue deafenMembers = PermValue.Inherit,
+ PermValue moveMembers = PermValue.Inherit,
+ PermValue useVoiceActivation = PermValue.Inherit,
+ PermValue manageRoles = PermValue.Inherit,
+ PermValue manageWebhooks = PermValue.Inherit)
+ : this(0, 0, createInstantInvite, manageChannel, addReactions, viewChannel, sendMessages, sendTTSMessages, manageMessages,
embedLinks, attachFiles, readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers,
moveMembers, useVoiceActivation, manageRoles, manageWebhooks) { }
@@ -134,13 +163,28 @@ public OverwritePermissions(PermValue createInstantInvite = PermValue.Inherit, P
/// Creates a new from this one, changing the provided non-null
/// permissions.
///
- public OverwritePermissions Modify(PermValue? createInstantInvite = null, PermValue? manageChannel = null,
+ public OverwritePermissions Modify(
+ PermValue? createInstantInvite = null,
+ PermValue? manageChannel = null,
PermValue? addReactions = null,
- PermValue? readMessages = null, PermValue? sendMessages = null, PermValue? sendTTSMessages = null, PermValue? manageMessages = null,
- PermValue? embedLinks = null, PermValue? attachFiles = null, PermValue? readMessageHistory = null, PermValue? mentionEveryone = null,
- PermValue? useExternalEmojis = null, PermValue? connect = null, PermValue? speak = null, PermValue? muteMembers = null, PermValue? deafenMembers = null,
- PermValue? moveMembers = null, PermValue? useVoiceActivation = null, PermValue? manageRoles = null, PermValue? manageWebhooks = null)
- => new OverwritePermissions(AllowValue, DenyValue, createInstantInvite, manageChannel, addReactions, readMessages, sendMessages, sendTTSMessages, manageMessages,
+ PermValue? viewChannel = null,
+ PermValue? sendMessages = null,
+ PermValue? sendTTSMessages = null,
+ PermValue? manageMessages = null,
+ PermValue? embedLinks = null,
+ PermValue? attachFiles = null,
+ PermValue? readMessageHistory = null,
+ PermValue? mentionEveryone = null,
+ PermValue? useExternalEmojis = null,
+ PermValue? connect = null,
+ PermValue? speak = null,
+ PermValue? muteMembers = null,
+ PermValue? deafenMembers = null,
+ PermValue? moveMembers = null,
+ PermValue? useVoiceActivation = null,
+ PermValue? manageRoles = null,
+ PermValue? manageWebhooks = null)
+ => new OverwritePermissions(AllowValue, DenyValue, createInstantInvite, manageChannel, addReactions, viewChannel, sendMessages, sendTTSMessages, manageMessages,
embedLinks, attachFiles, readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers,
moveMembers, useVoiceActivation, manageRoles, manageWebhooks);
diff --git a/src/Discord.Net.Core/Entities/Roles/Color.cs b/src/Discord.Net.Core/Entities/Roles/Color.cs
index fa7624a57d..f24ac883e0 100644
--- a/src/Discord.Net.Core/Entities/Roles/Color.cs
+++ b/src/Discord.Net.Core/Entities/Roles/Color.cs
@@ -1,5 +1,8 @@
using System;
using System.Diagnostics;
+#if NETSTANDARD2_0 || NET45
+using StandardColor = System.Drawing.Color;
+#endif
namespace Discord
{
@@ -125,6 +128,13 @@ public Color(float r, float g, float b)
(uint)(b * 255.0f);
}
+#if NETSTANDARD2_0 || NET45
+ public static implicit operator StandardColor(Color color) =>
+ StandardColor.FromArgb((int)color.RawValue);
+ public static explicit operator Color(StandardColor color) =>
+ new Color((uint)color.ToArgb() << 8 >> 8);
+#endif
+
///
/// Gets the hexadecimal representation of the color (e.g. #000ccc).
///
diff --git a/src/Discord.Net.Core/Extensions/UserExtensions.cs b/src/Discord.Net.Core/Extensions/UserExtensions.cs
index 41e84c3cb1..7759c8ea30 100644
--- a/src/Discord.Net.Core/Extensions/UserExtensions.cs
+++ b/src/Discord.Net.Core/Extensions/UserExtensions.cs
@@ -18,7 +18,7 @@ public static class UserExtensions
/// An awaitable Task containing the message sent to the channel.
///
public static async Task SendMessageAsync(this IUser user,
- string text,
+ string text = null,
bool isTTS = false,
Embed embed = null,
RequestOptions options = null)
@@ -55,7 +55,6 @@ public static async Task SendFileAsync(this IUser user,
return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
}
-#if FILESYSTEM
///
/// Sends a file via DM with an optional caption.
///
@@ -81,7 +80,7 @@ public static async Task SendFileAsync(this IUser user,
{
return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
}
-#endif
+
///
/// Bans the provided user from the guild and optionally prunes their recent messages.
///
diff --git a/src/Discord.Net.Core/Logging/LogManager.cs b/src/Discord.Net.Core/Logging/LogManager.cs
index 35727c33d3..a99c45b39d 100644
--- a/src/Discord.Net.Core/Logging/LogManager.cs
+++ b/src/Discord.Net.Core/Logging/LogManager.cs
@@ -41,7 +41,7 @@ public async Task LogAsync(LogSeverity severity, string source, string message,
// ignored
}
}
-#if FORMATSTR
+
public async Task LogAsync(LogSeverity severity, string source, FormattableString message, Exception ex = null)
{
try
@@ -51,52 +51,49 @@ public async Task LogAsync(LogSeverity severity, string source, FormattableStrin
}
catch { }
}
-#endif
+
public Task ErrorAsync(string source, Exception ex)
=> LogAsync(LogSeverity.Error, source, ex);
public Task ErrorAsync(string source, string message, Exception ex = null)
=> LogAsync(LogSeverity.Error, source, message, ex);
-#if FORMATSTR
+
public Task ErrorAsync(string source, FormattableString message, Exception ex = null)
=> LogAsync(LogSeverity.Error, source, message, ex);
-#endif
+
public Task WarningAsync(string source, Exception ex)
=> LogAsync(LogSeverity.Warning, source, ex);
public Task WarningAsync(string source, string message, Exception ex = null)
=> LogAsync(LogSeverity.Warning, source, message, ex);
-#if FORMATSTR
+
public Task WarningAsync(string source, FormattableString message, Exception ex = null)
=> LogAsync(LogSeverity.Warning, source, message, ex);
-#endif
+
public Task InfoAsync(string source, Exception ex)
=> LogAsync(LogSeverity.Info, source, ex);
public Task InfoAsync(string source, string message, Exception ex = null)
=> LogAsync(LogSeverity.Info, source, message, ex);
-#if FORMATSTR
public Task InfoAsync(string source, FormattableString message, Exception ex = null)
=> LogAsync(LogSeverity.Info, source, message, ex);
-#endif
+
public Task VerboseAsync(string source, Exception ex)
=> LogAsync(LogSeverity.Verbose, source, ex);
public Task VerboseAsync(string source, string message, Exception ex = null)
=> LogAsync(LogSeverity.Verbose, source, message, ex);
-#if FORMATSTR
public Task VerboseAsync(string source, FormattableString message, Exception ex = null)
=> LogAsync(LogSeverity.Verbose, source, message, ex);
-#endif
+
public Task DebugAsync(string source, Exception ex)
=> LogAsync(LogSeverity.Debug, source, ex);
public Task DebugAsync(string source, string message, Exception ex = null)
=> LogAsync(LogSeverity.Debug, source, message, ex);
-#if FORMATSTR
public Task DebugAsync(string source, FormattableString message, Exception ex = null)
=> LogAsync(LogSeverity.Debug, source, message, ex);
-#endif
+
public Logger CreateLogger(string name) => new Logger(this, name);
diff --git a/src/Discord.Net.Core/Logging/Logger.cs b/src/Discord.Net.Core/Logging/Logger.cs
index a8d88b2b43..e71c569921 100644
--- a/src/Discord.Net.Core/Logging/Logger.cs
+++ b/src/Discord.Net.Core/Logging/Logger.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Threading.Tasks;
namespace Discord.Logging
@@ -20,54 +20,53 @@ public Task LogAsync(LogSeverity severity, Exception exception = null)
=> _manager.LogAsync(severity, Name, exception);
public Task LogAsync(LogSeverity severity, string message, Exception exception = null)
=> _manager.LogAsync(severity, Name, message, exception);
-#if FORMATSTR
public Task LogAsync(LogSeverity severity, FormattableString message, Exception exception = null)
=> _manager.LogAsync(severity, Name, message, exception);
-#endif
+
public Task ErrorAsync(Exception exception)
=> _manager.ErrorAsync(Name, exception);
public Task ErrorAsync(string message, Exception exception = null)
=> _manager.ErrorAsync(Name, message, exception);
-#if FORMATSTR
+
public Task ErrorAsync(FormattableString message, Exception exception = null)
=> _manager.ErrorAsync(Name, message, exception);
-#endif
+
public Task WarningAsync(Exception exception)
=> _manager.WarningAsync(Name, exception);
public Task WarningAsync(string message, Exception exception = null)
=> _manager.WarningAsync(Name, message, exception);
-#if FORMATSTR
+
public Task WarningAsync(FormattableString message, Exception exception = null)
=> _manager.WarningAsync(Name, message, exception);
-#endif
+
public Task InfoAsync(Exception exception)
=> _manager.InfoAsync(Name, exception);
public Task InfoAsync(string message, Exception exception = null)
=> _manager.InfoAsync(Name, message, exception);
-#if FORMATSTR
+
public Task InfoAsync(FormattableString message, Exception exception = null)
=> _manager.InfoAsync(Name, message, exception);
-#endif
+
public Task VerboseAsync(Exception exception)
=> _manager.VerboseAsync(Name, exception);
public Task VerboseAsync(string message, Exception exception = null)
=> _manager.VerboseAsync(Name, message, exception);
-#if FORMATSTR
+
public Task VerboseAsync(FormattableString message, Exception exception = null)
=> _manager.VerboseAsync(Name, message, exception);
-#endif
+
public Task DebugAsync(Exception exception)
=> _manager.DebugAsync(Name, exception);
public Task DebugAsync(string message, Exception exception = null)
=> _manager.DebugAsync(Name, message, exception);
-#if FORMATSTR
+
public Task DebugAsync(FormattableString message, Exception exception = null)
=> _manager.DebugAsync(Name, message, exception);
-#endif
+
}
}
diff --git a/src/Discord.Net.Core/RequestOptions.cs b/src/Discord.Net.Core/RequestOptions.cs
index c2d1f65494..785b518f3e 100644
--- a/src/Discord.Net.Core/RequestOptions.cs
+++ b/src/Discord.Net.Core/RequestOptions.cs
@@ -25,9 +25,12 @@ public class RequestOptions
public RetryMode? RetryMode { get; set; }
public bool HeaderOnly { get; internal set; }
///
- /// Gets or sets the reason for this action in the guild's audit log. Note that this property may not apply
- /// to every action.
+ /// Gets or sets the reason for this action in the guild's audit log.
///
+ ///
+ /// Gets or sets the reason that will be written to the guild's audit log if applicable. This may not apply
+ /// to all actions.
+ ///
public string AuditLogReason { get; set; }
internal bool IgnoreState { get; set; }
diff --git a/src/Discord.Net.Core/Utils/DateTimeUtils.cs b/src/Discord.Net.Core/Utils/DateTimeUtils.cs
index af21268535..e2a8faa755 100644
--- a/src/Discord.Net.Core/Utils/DateTimeUtils.cs
+++ b/src/Discord.Net.Core/Utils/DateTimeUtils.cs
@@ -1,57 +1,14 @@
-using System;
+using System;
namespace Discord
{
//Source: https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/DateTimeOffset.cs
internal static class DateTimeUtils
{
-#if !UNIXTIME
- private const long UnixEpochTicks = 621_355_968_000_000_000;
- private const long UnixEpochSeconds = 62_135_596_800;
- private const long UnixEpochMilliseconds = 62_135_596_800_000;
-#endif
-
public static DateTimeOffset FromTicks(long ticks)
=> new DateTimeOffset(ticks, TimeSpan.Zero);
public static DateTimeOffset? FromTicks(long? ticks)
=> ticks != null ? new DateTimeOffset(ticks.Value, TimeSpan.Zero) : (DateTimeOffset?)null;
-
- public static DateTimeOffset FromUnixSeconds(long seconds)
- {
-#if UNIXTIME
- return DateTimeOffset.FromUnixTimeSeconds(seconds);
-#else
- long ticks = seconds * TimeSpan.TicksPerSecond + UnixEpochTicks;
- return new DateTimeOffset(ticks, TimeSpan.Zero);
-#endif
- }
- public static DateTimeOffset FromUnixMilliseconds(long milliseconds)
- {
-#if UNIXTIME
- return DateTimeOffset.FromUnixTimeMilliseconds(milliseconds);
-#else
- long ticks = milliseconds * TimeSpan.TicksPerMillisecond + UnixEpochTicks;
- return new DateTimeOffset(ticks, TimeSpan.Zero);
-#endif
- }
-
- public static long ToUnixSeconds(DateTimeOffset dto)
- {
-#if UNIXTIME
- return dto.ToUnixTimeSeconds();
-#else
- long seconds = dto.UtcDateTime.Ticks / TimeSpan.TicksPerSecond;
- return seconds - UnixEpochSeconds;
-#endif
- }
- public static long ToUnixMilliseconds(DateTimeOffset dto)
- {
-#if UNIXTIME
- return dto.ToUnixTimeMilliseconds();
-#else
- long milliseconds = dto.UtcDateTime.Ticks / TimeSpan.TicksPerMillisecond;
- return milliseconds - UnixEpochMilliseconds;
-#endif
- }
+
}
}
diff --git a/src/Discord.Net.Core/Utils/SnowflakeUtils.cs b/src/Discord.Net.Core/Utils/SnowflakeUtils.cs
index c9d0d130be..eecebfb244 100644
--- a/src/Discord.Net.Core/Utils/SnowflakeUtils.cs
+++ b/src/Discord.Net.Core/Utils/SnowflakeUtils.cs
@@ -5,8 +5,8 @@ namespace Discord
public static class SnowflakeUtils
{
public static DateTimeOffset FromSnowflake(ulong value)
- => DateTimeUtils.FromUnixMilliseconds((long)((value >> 22) + 1420070400000UL));
+ => DateTimeOffset.FromUnixTimeMilliseconds((long)((value >> 22) + 1420070400000UL));
public static ulong ToSnowflake(DateTimeOffset value)
- => ((ulong)DateTimeUtils.ToUnixMilliseconds(value) - 1420070400000UL) << 22;
+ => ((ulong)value.ToUnixTimeMilliseconds() - 1420070400000UL) << 22;
}
}
diff --git a/src/Discord.Net.Rest/API/Common/Message.cs b/src/Discord.Net.Rest/API/Common/Message.cs
index 9a7629b963..229249ccf1 100644
--- a/src/Discord.Net.Rest/API/Common/Message.cs
+++ b/src/Discord.Net.Rest/API/Common/Message.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
using System;
@@ -12,10 +12,16 @@ internal class Message
public MessageType Type { get; set; }
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
+ // ALWAYS sent on WebSocket messages
+ [JsonProperty("guild_id")]
+ public Optional GuildId { get; set; }
[JsonProperty("webhook_id")]
public Optional WebhookId { get; set; }
[JsonProperty("author")]
public Optional Author { get; set; }
+ // ALWAYS sent on WebSocket messages
+ [JsonProperty("member")]
+ public Optional Member { get; set; }
[JsonProperty("content")]
public Optional Content { get; set; }
[JsonProperty("timestamp")]
diff --git a/src/Discord.Net.Rest/API/Common/VoiceState.cs b/src/Discord.Net.Rest/API/Common/VoiceState.cs
index 563a5f95b0..b1f937b09a 100644
--- a/src/Discord.Net.Rest/API/Common/VoiceState.cs
+++ b/src/Discord.Net.Rest/API/Common/VoiceState.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API
@@ -11,6 +11,9 @@ internal class VoiceState
public ulong? ChannelId { get; set; }
[JsonProperty("user_id")]
public ulong UserId { get; set; }
+ // ALWAYS sent over WebSocket, never on REST
+ [JsonProperty("member")]
+ public Optional Member { get; set; }
[JsonProperty("session_id")]
public string SessionId { get; set; }
[JsonProperty("deaf")]
diff --git a/src/Discord.Net.Rest/API/Rest/CreateGuildChannelParams.cs b/src/Discord.Net.Rest/API/Rest/CreateGuildChannelParams.cs
index bae677148b..05cdf4b8af 100644
--- a/src/Discord.Net.Rest/API/Rest/CreateGuildChannelParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/CreateGuildChannelParams.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Rest
@@ -10,9 +10,20 @@ internal class CreateGuildChannelParams
public string Name { get; }
[JsonProperty("type")]
public ChannelType Type { get; }
+ [JsonProperty("parent_id")]
+ public Optional CategoryId { get; set; }
+ //Text channels
+ [JsonProperty("topic")]
+ public Optional Topic { get; set; }
+ [JsonProperty("nsfw")]
+ public Optional IsNsfw { get; set; }
+
+ //Voice channels
[JsonProperty("bitrate")]
public Optional Bitrate { get; set; }
+ [JsonProperty("user_limit")]
+ public Optional UserLimit { get; set; }
public CreateGuildChannelParams(string name, ChannelType type)
{
diff --git a/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs b/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs
index d70da5632b..a0967bb75d 100644
--- a/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs
@@ -1,4 +1,4 @@
-namespace Discord.API.Rest
+namespace Discord.API.Rest
{
internal class GetReactionUsersParams
{
diff --git a/src/Discord.Net.Rest/Discord.Net.Rest.csproj b/src/Discord.Net.Rest/Discord.Net.Rest.csproj
index 0eb07a4b2f..75b69bd043 100644
--- a/src/Discord.Net.Rest/Discord.Net.Rest.csproj
+++ b/src/Discord.Net.Rest/Discord.Net.Rest.csproj
@@ -1,20 +1,19 @@
-
+
Discord.Net.Rest
Discord.Rest
A core Discord.Net library containing the REST client and models.
- net45;netstandard1.1;netstandard1.3
- netstandard1.1;netstandard1.3
+ net46;netstandard1.3;netstandard2.0
+ netstandard1.3;netstandard2.0
-
-
-
+
+
-
+
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index f235471064..70a2acd154 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -630,11 +630,11 @@ public async Task> GetReactionUsersAsync(ulong channel
Preconditions.NotNullOrWhitespace(emoji, nameof(emoji));
Preconditions.NotNull(args, nameof(args));
Preconditions.GreaterThan(args.Limit, 0, nameof(args.Limit));
- Preconditions.AtMost(args.Limit, DiscordConfig.MaxUsersPerBatch, nameof(args.Limit));
+ Preconditions.AtMost(args.Limit, DiscordConfig.MaxUserReactionsPerBatch, nameof(args.Limit));
Preconditions.GreaterThan(args.AfterUserId, 0, nameof(args.AfterUserId));
options = RequestOptions.CreateOrClone(options);
- int limit = args.Limit.GetValueOrDefault(int.MaxValue);
+ int limit = args.Limit.GetValueOrDefault(DiscordConfig.MaxUserReactionsPerBatch);
ulong afterUserId = args.AfterUserId.GetValueOrDefault(0);
var ids = new BucketIds(channelId: channelId);
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BanAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BanAuditLogData.cs
index 4b9d5875f2..2e5331d59a 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BanAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BanAuditLogData.cs
@@ -1,10 +1,13 @@
-using System.Linq;
+using System.Linq;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
namespace Discord.Rest
{
+ ///
+ /// Represents a piece of audit log data related to a ban.
+ ///
public class BanAuditLogData : IAuditLogData
{
private BanAuditLogData(IUser user)
@@ -18,6 +21,12 @@ internal static BanAuditLogData Create(BaseDiscordClient discord, Model log, Ent
return new BanAuditLogData(RestUser.Create(discord, userInfo));
}
+ ///
+ /// Gets the user that was banned.
+ ///
+ ///
+ /// A user object representing the banned user.
+ ///
public IUser Target { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelCreateAuditLogData.cs
index ef4787295a..451aac3734 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelCreateAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelCreateAuditLogData.cs
@@ -1,4 +1,3 @@
-using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;
@@ -7,6 +6,9 @@
namespace Discord.Rest
{
+ ///
+ /// Represents a piece of audit log data related to a channel creation.
+ ///
public class ChannelCreateAuditLogData : IAuditLogData
{
private ChannelCreateAuditLogData(ulong id, string name, ChannelType type, IReadOnlyCollection overwrites)
@@ -44,9 +46,33 @@ internal static ChannelCreateAuditLogData Create(BaseDiscordClient discord, Mode
return new ChannelCreateAuditLogData(entry.TargetId.Value, name, type, overwrites.ToReadOnlyCollection());
}
+ ///
+ /// Gets the snowflake ID of the created channel.
+ ///
+ ///
+ /// An representing the snowflake identifier for the created channel.
+ ///
public ulong ChannelId { get; }
+ ///
+ /// Gets the name of the created channel.
+ ///
+ ///
+ /// A string containing the name of the created channel.
+ ///
public string ChannelName { get; }
+ ///
+ /// Gets the type of the created channel.
+ ///
+ ///
+ /// The type of channel that was created.
+ ///
public ChannelType ChannelType { get; }
+ ///
+ /// Gets a collection of permission overwrites that was assigned to the created channel.
+ ///
+ ///
+ /// A collection of permission .
+ ///
public IReadOnlyCollection Overwrites { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelDeleteAuditLogData.cs
index 4816ce770f..7278b7b753 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelDeleteAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelDeleteAuditLogData.cs
@@ -1,14 +1,14 @@
-using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
namespace Discord.Rest
{
+ ///
+ /// Represents a piece of audit log data related to a channel deletion.
+ ///
public class ChannelDeleteAuditLogData : IAuditLogData
{
private ChannelDeleteAuditLogData(ulong id, string name, ChannelType type, IReadOnlyCollection overwrites)
@@ -37,9 +37,33 @@ internal static ChannelDeleteAuditLogData Create(BaseDiscordClient discord, Mode
return new ChannelDeleteAuditLogData(id, name, type, overwrites.ToReadOnlyCollection());
}
+ ///
+ /// Gets the snowflake ID of the deleted channel.
+ ///
+ ///
+ /// An representing the snowflake identifier for the deleted channel.
+ ///
public ulong ChannelId { get; }
+ ///
+ /// Gets the name of the deleted channel.
+ ///
+ ///
+ /// A string containing the name of the deleted channel.
+ ///
public string ChannelName { get; }
+ ///
+ /// Gets the type of the deleted channel.
+ ///
+ ///
+ /// The type of channel that was deleted.
+ ///
public ChannelType ChannelType { get; }
+ ///
+ /// Gets a collection of permission overwrites that was assigned to the deleted channel.
+ ///
+ ///
+ /// A collection of permission .
+ ///
public IReadOnlyCollection Overwrites { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelInfo.cs
index e2d6064a9a..82b1296563 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelInfo.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelInfo.cs
@@ -1,5 +1,8 @@
namespace Discord.Rest
{
+ ///
+ /// Represents information for a channel.
+ ///
public struct ChannelInfo
{
internal ChannelInfo(string name, string topic, int? bitrate, int? limit)
@@ -10,9 +13,35 @@ internal ChannelInfo(string name, string topic, int? bitrate, int? limit)
UserLimit = limit;
}
+ ///
+ /// Gets the name of this channel.
+ ///
+ ///
+ /// A string containing the name of this channel.
+ ///
public string Name { get; }
+ ///
+ /// Gets the topic of this channel.
+ ///
+ ///
+ /// A string containing the topic of this channel, if any.
+ ///
public string Topic { get; }
+ ///
+ /// Gets the bitrate of this channel if applicable.
+ ///
+ ///
+ /// An representing the bitrate set for the voice channel; null if not
+ /// applicable.
+ ///
public int? Bitrate { get; }
+ ///
+ /// Gets the number of users allowed to be in this channel if applicable.
+ ///
+ ///
+ /// An representing the number of users allowed to be in this voice channel;
+ /// null if not applicable.
+ ///
public int? UserLimit { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelUpdateAuditLogData.cs
index f3403138da..7cad9eff7d 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelUpdateAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelUpdateAuditLogData.cs
@@ -1,10 +1,13 @@
-using System.Linq;
+using System.Linq;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
namespace Discord.Rest
{
+ ///
+ /// Represents a piece of audit log data related to a channel update.
+ ///
public class ChannelUpdateAuditLogData : IAuditLogData
{
private ChannelUpdateAuditLogData(ulong id, ChannelInfo before, ChannelInfo after)
@@ -38,8 +41,14 @@ internal static ChannelUpdateAuditLogData Create(BaseDiscordClient discord, Mode
return new ChannelUpdateAuditLogData(entry.TargetId.Value, before, after);
}
+ ///
+ /// Gets the snowflake ID of the updated channel.
+ ///
+ ///
+ /// An representing the snowflake identifier for the updated channel.
+ ///
public ulong ChannelId { get; }
- public ChannelInfo Before { get; set; }
- public ChannelInfo After { get; set; }
+ public ChannelInfo Before { get; }
+ public ChannelInfo After { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteCreateAuditLogData.cs
index 5d1ef8463d..a114548ccb 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteCreateAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteCreateAuditLogData.cs
@@ -1,14 +1,13 @@
-using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
namespace Discord.Rest
{
+ ///
+ /// Represents a piece of audit log data related to an emoji creation.
+ ///
public class EmoteCreateAuditLogData : IAuditLogData
{
private EmoteCreateAuditLogData(ulong id, string name)
@@ -25,7 +24,19 @@ internal static EmoteCreateAuditLogData Create(BaseDiscordClient discord, Model
return new EmoteCreateAuditLogData(entry.TargetId.Value, emoteName);
}
+ ///
+ /// Gets the snowflake ID of the created emoji.
+ ///
+ ///
+ /// An representing the snowflake identifier for the created emoji.
+ ///
public ulong EmoteId { get; }
+ ///
+ /// Gets the name of the created emoji.
+ ///
+ ///
+ /// A string containing the name of the created emoji.
+ ///
public string Name { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteDeleteAuditLogData.cs
index d0a11191f4..e522b0ee27 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteDeleteAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteDeleteAuditLogData.cs
@@ -1,10 +1,13 @@
-using System.Linq;
+using System.Linq;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
namespace Discord.Rest
{
+ ///
+ /// Represents a piece of audit log data related to an emoji deletion.
+ ///
public class EmoteDeleteAuditLogData : IAuditLogData
{
private EmoteDeleteAuditLogData(ulong id, string name)
@@ -22,7 +25,19 @@ internal static EmoteDeleteAuditLogData Create(BaseDiscordClient discord, Model
return new EmoteDeleteAuditLogData(entry.TargetId.Value, emoteName);
}
+ ///
+ /// Gets the snowflake ID of the deleted emoji.
+ ///
+ ///
+ /// An representing the snowflake identifier for the deleted emoji.
+ ///
public ulong EmoteId { get; }
+ ///
+ /// Gets the name of the deleted emoji.
+ ///
+ ///
+ /// A string containing the name of the deleted emoji.
+ ///
public string Name { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteUpdateAuditLogData.cs
index 60020bcaa4..e8cd765138 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteUpdateAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteUpdateAuditLogData.cs
@@ -1,10 +1,13 @@
-using System.Linq;
+using System.Linq;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
namespace Discord.Rest
{
+ ///
+ /// Represents a piece of audit log data related to an emoji update.
+ ///
public class EmoteUpdateAuditLogData : IAuditLogData
{
private EmoteUpdateAuditLogData(ulong id, string oldName, string newName)
@@ -24,8 +27,26 @@ internal static EmoteUpdateAuditLogData Create(BaseDiscordClient discord, Model
return new EmoteUpdateAuditLogData(entry.TargetId.Value, oldName, newName);
}
+ ///
+ /// Gets the snowflake ID of the updated emoji.
+ ///
+ ///
+ /// An representing the snowflake identifier of the updated emoji.
+ ///
public ulong EmoteId { get; }
+ ///
+ /// Gets the new name of the updated emoji.
+ ///
+ ///
+ /// A string containing the new name of the updated emoji.
+ ///
public string NewName { get; }
+ ///
+ /// Gets the old name of the updated emoji.
+ ///
+ ///
+ /// A string containing the old name of the updated emoji.
+ ///
public string OldName { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildInfo.cs
index 90865ef722..494aac1338 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildInfo.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildInfo.cs
@@ -1,5 +1,8 @@
namespace Discord.Rest
{
+ ///
+ /// Represents information for a guild.
+ ///
public struct GuildInfo
{
internal GuildInfo(int? afkTimeout, DefaultMessageNotifications? defaultNotifs,
@@ -18,14 +21,66 @@ internal GuildInfo(int? afkTimeout, DefaultMessageNotifications? defaultNotifs,
ContentFilterLevel = filter;
}
+ ///
+ /// Gets the amount of time (in seconds) a user must be inactive in a voice channel for until they are
+ /// automatically moved to the AFK voice channel.
+ ///
+ ///
+ /// An representing the amount of time in seconds for a user to be marked as inactive
+ /// and moved into the AFK voice channel.
+ ///
public int? AfkTimeout { get; }
+ ///
+ /// Gets the default message notifications for users who haven't explicitly set their notification settings.
+ ///
public DefaultMessageNotifications? DefaultMessageNotifications { get; }
+ ///
+ /// Gets the ID of the AFK voice channel for this guild.
+ ///
+ ///
+ /// An representing the snowflake identifier of the AFK voice channel; null if
+ /// none is set.
+ ///
public ulong? AfkChannelId { get; }
+ ///
+ /// Gets the name of this guild.
+ ///
+ ///
+ /// A string containing the name of this guild.
+ ///
public string Name { get; }
+ ///
+ /// Gets the ID of the region hosting this guild's voice channels.
+ ///
public string RegionId { get; }
+ ///
+ /// Gets the ID of this guild's icon.
+ ///
+ ///
+ /// A string containing the identifier for the splash image; null if none is set.
+ ///
public string IconHash { get; }
+ ///
+ /// Gets the level of requirements a user must fulfill before being allowed to post messages in this guild.
+ ///
+ ///
+ /// The level of requirements.
+ ///
public VerificationLevel? VerificationLevel { get; }
+ ///
+ /// Gets the owner of this guild.
+ ///
+ ///
+ /// A user object representing the owner of this guild.
+ ///
public IUser Owner { get; }
+ ///
+ /// Gets the level of Multi-Factor Authentication requirements a user must fulfill before being allowed to
+ /// perform administrative actions in this guild.
+ ///
+ ///
+ /// The level of MFA requirement.
+ ///
public MfaLevel? MfaLevel { get; }
public int? ContentFilterLevel { get; }
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildUpdateAuditLogData.cs
index 08550ed7a3..b4ffd3bf1e 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildUpdateAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildUpdateAuditLogData.cs
@@ -1,10 +1,13 @@
-using System.Linq;
+using System.Linq;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
namespace Discord.Rest
{
+ ///
+ /// Represents a piece of audit log data related to a guild update.
+ ///
public class GuildUpdateAuditLogData : IAuditLogData
{
private GuildUpdateAuditLogData(GuildInfo before, GuildInfo after)
@@ -73,7 +76,19 @@ internal static GuildUpdateAuditLogData Create(BaseDiscordClient discord, Model
return new GuildUpdateAuditLogData(before, after);
}
+ ///
+ /// Gets the guild information before the changes.
+ ///
+ ///
+ /// An information object containing the original guild information before the changes were made.
+ ///
public GuildInfo Before { get; }
+ ///
+ /// Gets the guild information after the changes.
+ ///
+ ///
+ /// An information object containing the guild information after the changes were made.
+ ///
public GuildInfo After { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteCreateAuditLogData.cs
index 292715420b..df95d13b64 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteCreateAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteCreateAuditLogData.cs
@@ -1,10 +1,13 @@
-using System.Linq;
+using System.Linq;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
namespace Discord.Rest
{
+ ///
+ /// Represents a piece of audit log data related to an invite creation.
+ ///
public class InviteCreateAuditLogData : IAuditLogData
{
private InviteCreateAuditLogData(int maxAge, string code, bool temporary, IUser inviter, ulong channelId, int uses, int maxUses)
@@ -44,12 +47,57 @@ internal static InviteCreateAuditLogData Create(BaseDiscordClient discord, Model
return new InviteCreateAuditLogData(maxAge, code, temporary, inviter, channelId, uses, maxUses);
}
+ ///
+ /// Gets the time (in seconds) until the invite expires.
+ ///
+ ///
+ /// An representing the time in seconds until this invite expires.
+ ///
public int MaxAge { get; }
+ ///
+ /// Gets the unique identifier for this invite.
+ ///
+ ///
+ /// A string containing the invite code (e.g. FTqNnyS).
+ ///
public string Code { get; }
+ ///
+ /// Determines whether the invite is a temporary one (i.e. whether the invite will be removed from the guild
+ /// when the user logs off).
+ ///
+ ///
+ /// true if users accepting this invite will be removed from the guild when they log off; otherwise
+ /// false.
+ ///
public bool Temporary { get; }
+ ///
+ /// Gets the user that created this invite.
+ ///
+ ///
+ /// A user that created this invite.
+ ///
public IUser Creator { get; }
+ ///
+ /// Gets the ID of the channel this invite is linked to.
+ ///
+ ///
+ /// An representing the channel snowflake identifier that the invite points to.
+ ///
public ulong ChannelId { get; }
+ ///
+ /// Gets the number of times this invite has been used.
+ ///
+ ///
+ /// An representing the number of times this invite has been used.
+ ///
public int Uses { get; }
+ ///
+ /// Gets the max number of uses this invite may have.
+ ///
+ ///
+ /// An representing the number of uses this invite may be accepted until it is removed
+ /// from the guild; null if none is set.
+ ///
public int MaxUses { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteDeleteAuditLogData.cs
index 1dc6d518b8..472f227c07 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteDeleteAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteDeleteAuditLogData.cs
@@ -1,10 +1,13 @@
-using System.Linq;
+using System.Linq;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
namespace Discord.Rest
{
+ ///
+ /// Represents a piece of audit log data related to an invite removal.
+ ///
public class InviteDeleteAuditLogData : IAuditLogData
{
private InviteDeleteAuditLogData(int maxAge, string code, bool temporary, IUser inviter, ulong channelId, int uses, int maxUses)
@@ -44,12 +47,57 @@ internal static InviteDeleteAuditLogData Create(BaseDiscordClient discord, Model
return new InviteDeleteAuditLogData(maxAge, code, temporary, inviter, channelId, uses, maxUses);
}
+ ///
+ /// Gets the time (in seconds) until the invite expires.
+ ///
+ ///
+ /// An representing the time in seconds until this invite expires.
+ ///
public int MaxAge { get; }
+ ///
+ /// Gets the unique identifier for this invite.
+ ///
+ ///
+ /// A string containing the invite code (e.g. FTqNnyS).
+ ///
public string Code { get; }
+ ///
+ /// Determines whether the invite is a temporary one (i.e. whether the invite will be removed from the guild
+ /// when the user logs off).
+ ///
+ ///
+ /// true if users accepting this invite will be removed from the guild when they log off; otherwise
+ /// false.
+ ///
public bool Temporary { get; }
+ ///
+ /// Gets the user that created this invite.
+ ///
+ ///
+ /// A user that created this invite.
+ ///
public IUser Creator { get; }
+ ///
+ /// Gets the ID of the channel this invite is linked to.
+ ///
+ ///
+ /// An representing the channel snowflake identifier that the invite points to.
+ ///
public ulong ChannelId { get; }
+ ///
+ /// Gets the number of times this invite has been used.
+ ///
+ ///
+ /// An representing the number of times this invite has been used.
+ ///
public int Uses { get; }
+ ///
+ /// Gets the max number of uses this invite may have.
+ ///
+ ///
+ /// An representing the number of uses this invite may be accepted until it is removed
+ /// from the guild; null if none is set.
+ ///
public int MaxUses { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteInfo.cs
index c9840f6cc3..54026dbf38 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteInfo.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteInfo.cs
@@ -1,5 +1,8 @@
namespace Discord.Rest
{
+ ///
+ /// Represents information for an invite.
+ ///
public struct InviteInfo
{
internal InviteInfo(int? maxAge, string code, bool? temporary, ulong? channelId, int? maxUses)
@@ -11,10 +14,45 @@ internal InviteInfo(int? maxAge, string code, bool? temporary, ulong? channelId,
MaxUses = maxUses;
}
+ ///
+ /// Gets the time (in seconds) until the invite expires.
+ ///
+ ///
+ /// An representing the time in seconds until this invite expires; null if this
+ /// invite never expires or not specified.
+ ///
public int? MaxAge { get; }
+ ///
+ /// Gets the unique identifier for this invite.
+ ///
+ ///
+ /// A string containing the invite code (e.g. FTqNnyS).
+ ///
public string Code { get; }
+ ///
+ /// Determines whether the invite is a temporary one (i.e. whether the invite will be removed from the guild
+ /// when the user logs off).
+ ///
+ ///
+ /// true if users accepting this invite will be removed from the guild when they log off,
+ /// false if not; null if not specified.
+ ///
public bool? Temporary { get; }
+ ///
+ /// Gets the ID of the channel this invite is linked to.
+ ///
+ ///
+ /// An representing the channel snowflake identifier that the invite points to;
+ /// null if not specified.
+ ///
public ulong? ChannelId { get; }
+ ///
+ /// Gets the max number of uses this invite may have.
+ ///
+ ///
+ /// An representing the number of uses this invite may be accepted until it is removed
+ /// from the guild; null if none is specified.
+ ///
public int? MaxUses { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleAuditLogData.cs
index b0f0a1fe1b..0d9a2a708f 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleAuditLogData.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,7 +8,7 @@ namespace Discord.Rest
{
public class MemberRoleAuditLogData : IAuditLogData
{
- private MemberRoleAuditLogData(IReadOnlyCollection roles, IUser target)
+ private MemberRoleAuditLogData(IReadOnlyCollection roles, IUser target)
{
Roles = roles;
Target = target;
@@ -21,7 +20,7 @@ internal static MemberRoleAuditLogData Create(BaseDiscordClient discord, Model l
var roleInfos = changes.SelectMany(x => x.NewValue.ToObject(),
(model, role) => new { model.ChangedProperty, Role = role })
- .Select(x => new RoleInfo(x.Role.Name, x.Role.Id, x.ChangedProperty == "$add"))
+ .Select(x => new MemberRoleEditInfo(x.Role.Name, x.Role.Id, x.ChangedProperty == "$add"))
.ToList();
var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId);
@@ -30,21 +29,7 @@ internal static MemberRoleAuditLogData Create(BaseDiscordClient discord, Model l
return new MemberRoleAuditLogData(roleInfos.ToReadOnlyCollection(), user);
}
- public IReadOnlyCollection Roles { get; }
+ public IReadOnlyCollection Roles { get; }
public IUser Target { get; }
-
- public struct RoleInfo
- {
- internal RoleInfo(string name, ulong roleId, bool added)
- {
- Name = name;
- RoleId = roleId;
- Added = added;
- }
-
- public string Name { get; }
- public ulong RoleId { get; }
- public bool Added { get; }
- }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleEditInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleEditInfo.cs
new file mode 100644
index 0000000000..4838b75c90
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleEditInfo.cs
@@ -0,0 +1,16 @@
+namespace Discord.Rest
+{
+ public struct MemberRoleEditInfo
+ {
+ internal MemberRoleEditInfo(string name, ulong roleId, bool added)
+ {
+ Name = name;
+ RoleId = roleId;
+ Added = added;
+ }
+
+ public string Name { get; }
+ public ulong RoleId { get; }
+ public bool Added { get; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs
index 38f078848f..7d3d3dba08 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs
@@ -1,8 +1,7 @@
-using System.Linq;
+using System.Linq;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
-using ChangeModel = Discord.API.AuditLogChange;
namespace Discord.Rest
{
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteDeleteAuditLogData.cs
index 445c2e3022..dc2f4a6f02 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteDeleteAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteDeleteAuditLogData.cs
@@ -1,13 +1,7 @@
-using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
-using ChangeModel = Discord.API.AuditLogChange;
-using OptionModel = Discord.API.AuditLogOptions;
namespace Discord.Rest
{
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleCreateAuditLogData.cs
index aa951d6e7b..dcc1c6ab65 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleCreateAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleCreateAuditLogData.cs
@@ -7,7 +7,7 @@ namespace Discord.Rest
{
public class RoleCreateAuditLogData : IAuditLogData
{
- private RoleCreateAuditLogData(ulong id, RoleInfo props)
+ private RoleCreateAuditLogData(ulong id, RoleEditInfo props)
{
RoleId = id;
Properties = props;
@@ -38,10 +38,10 @@ internal static RoleCreateAuditLogData Create(BaseDiscordClient discord, Model l
permissions = new GuildPermissions(permissionsRaw.Value);
return new RoleCreateAuditLogData(entry.TargetId.Value,
- new RoleInfo(color, mentionable, hoist, name, permissions));
+ new RoleEditInfo(color, mentionable, hoist, name, permissions));
}
public ulong RoleId { get; }
- public RoleInfo Properties { get; }
+ public RoleEditInfo Properties { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleDeleteAuditLogData.cs
index e90d70d4d2..263909daf4 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleDeleteAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleDeleteAuditLogData.cs
@@ -7,7 +7,7 @@ namespace Discord.Rest
{
public class RoleDeleteAuditLogData : IAuditLogData
{
- private RoleDeleteAuditLogData(ulong id, RoleInfo props)
+ private RoleDeleteAuditLogData(ulong id, RoleEditInfo props)
{
RoleId = id;
Properties = props;
@@ -38,10 +38,10 @@ internal static RoleDeleteAuditLogData Create(BaseDiscordClient discord, Model l
permissions = new GuildPermissions(permissionsRaw.Value);
return new RoleDeleteAuditLogData(entry.TargetId.Value,
- new RoleInfo(color, mentionable, hoist, name, permissions));
+ new RoleEditInfo(color, mentionable, hoist, name, permissions));
}
public ulong RoleId { get; }
- public RoleInfo Properties { get; }
+ public RoleEditInfo Properties { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleEditInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleEditInfo.cs
new file mode 100644
index 0000000000..186ea8d110
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleEditInfo.cs
@@ -0,0 +1,21 @@
+namespace Discord.Rest
+{
+ public struct RoleEditInfo
+ {
+ internal RoleEditInfo(Color? color, bool? mentionable, bool? hoist, string name,
+ GuildPermissions? permissions)
+ {
+ Color = color;
+ Mentionable = mentionable;
+ Hoist = hoist;
+ Name = name;
+ Permissions = permissions;
+ }
+
+ public Color? Color { get; }
+ public bool? Mentionable { get; }
+ public bool? Hoist { get; }
+ public string Name { get; }
+ public GuildPermissions? Permissions { get; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleInfo.cs
deleted file mode 100644
index 2208990e6e..0000000000
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleInfo.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace Discord.Rest
-{
- public struct RoleInfo
- {
- internal RoleInfo(Color? color, bool? mentionable, bool? hoist, string name,
- GuildPermissions? permissions)
- {
- Color = color;
- Mentionable = mentionable;
- Hoist = hoist;
- Name = name;
- Permissions = permissions;
- }
-
- public Color? Color { get; }
- public bool? Mentionable { get; }
- public bool? Hoist { get; }
- public string Name { get; }
- public GuildPermissions? Permissions { get; }
- }
-}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleUpdateAuditLogData.cs
index be484e2d50..b645ef7ae0 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleUpdateAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleUpdateAuditLogData.cs
@@ -7,7 +7,7 @@ namespace Discord.Rest
{
public class RoleUpdateAuditLogData : IAuditLogData
{
- private RoleUpdateAuditLogData(ulong id, RoleInfo oldProps, RoleInfo newProps)
+ private RoleUpdateAuditLogData(ulong id, RoleEditInfo oldProps, RoleEditInfo newProps)
{
RoleId = id;
Before = oldProps;
@@ -49,14 +49,14 @@ internal static RoleUpdateAuditLogData Create(BaseDiscordClient discord, Model l
if (newPermissionsRaw.HasValue)
newPermissions = new GuildPermissions(newPermissionsRaw.Value);
- var oldProps = new RoleInfo(oldColor, oldMentionable, oldHoist, oldName, oldPermissions);
- var newProps = new RoleInfo(newColor, newMentionable, newHoist, newName, newPermissions);
+ var oldProps = new RoleEditInfo(oldColor, oldMentionable, oldHoist, oldName, oldPermissions);
+ var newProps = new RoleEditInfo(newColor, newMentionable, newHoist, newName, newPermissions);
return new RoleUpdateAuditLogData(entry.TargetId.Value, oldProps, newProps);
}
public ulong RoleId { get; }
- public RoleInfo Before { get; }
- public RoleInfo After { get; }
+ public RoleEditInfo Before { get; }
+ public RoleEditInfo After { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookDeleteAuditLogData.cs
index 4133d5dff9..2d536d8681 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookDeleteAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookDeleteAuditLogData.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookUpdateAuditLogData.cs
index 54da42a8b0..7db7aee36d 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookUpdateAuditLogData.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookUpdateAuditLogData.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs b/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs
index 9e30a5014e..0cf616973d 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs
@@ -1,10 +1,13 @@
-using System.Linq;
+using System.Linq;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
namespace Discord.Rest
{
+ ///
+ /// Represents a REST-based audit log entry.
+ ///
public class RestAuditLogEntry : RestEntity, IAuditLogEntry
{
private RestAuditLogEntry(BaseDiscordClient discord, Model fullLog, EntryModel model, IUser user)
diff --git a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
index 6a3521bff1..0362fa600e 100644
--- a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
@@ -162,7 +162,6 @@ public static async Task SendMessageAsync(IMessageChannel chann
return RestUserMessage.Create(client, channel, client.CurrentUser, model);
}
-#if FILESYSTEM
///
/// is a zero-length string, contains only white space, or contains one or more
/// invalid characters as defined by .
@@ -194,7 +193,7 @@ public static async Task SendFileAsync(IMessageChannel channel,
using (var file = File.OpenRead(filePath))
return await SendFileAsync(channel, client, file, filename, text, isTTS, embed, options).ConfigureAwait(false);
}
-#endif
+
/// Message content is too long, length must be less or equal to .
public static async Task SendFileAsync(IMessageChannel channel, BaseDiscordClient client,
Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
@@ -204,6 +203,10 @@ public static async Task SendFileAsync(IMessageChannel channel,
return RestUserMessage.Create(client, channel, client.CurrentUser, model);
}
+ public static Task DeleteMessageAsync(IMessageChannel channel, ulong messageId, BaseDiscordClient client,
+ RequestOptions options)
+ => MessageHelper.DeleteAsync(channel.Id, messageId, client, options);
+
public static async Task DeleteMessagesAsync(ITextChannel channel, BaseDiscordClient client,
IEnumerable messageIds, RequestOptions options)
{
@@ -334,6 +337,16 @@ public static async Task> GetWebhooksAsync(ITex
return models.Select(x => RestWebhook.Create(client, channel, x))
.ToImmutableArray();
}
+ // Categories
+ public static async Task GetCategoryAsync(INestedChannel channel, BaseDiscordClient client, RequestOptions options)
+ {
+ // if no category id specified, return null
+ if (!channel.CategoryId.HasValue)
+ return null;
+ // CategoryId will contain a value here
+ var model = await client.ApiClient.GetChannelAsync(channel.CategoryId.Value, options).ConfigureAwait(false);
+ return RestCategoryChannel.Create(client, model) as ICategoryChannel;
+ }
//Helpers
private static IUser GetAuthor(BaseDiscordClient client, IGuild guild, UserModel model, ulong? webhookId)
@@ -345,10 +358,5 @@ private static IUser GetAuthor(BaseDiscordClient client, IGuild guild, UserModel
author = RestUser.Create(client, guild, model, webhookId);
return author;
}
-
- public static bool IsNsfw(IChannel channel)
- => IsNsfw(channel.Name);
- public static bool IsNsfw(string channelName) =>
- channelName == "nsfw" || channelName.StartsWith("nsfw-");
}
}
diff --git a/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs b/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs
index b0eed8b255..ac2f27bbdb 100644
--- a/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs
@@ -19,8 +19,7 @@ public interface IRestMessageChannel : IMessageChannel
///
/// An awaitable Task containing the message sent to the channel.
///
- new Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null);
-#if FILESYSTEM
+ new Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
///
/// Sends a file to this message channel, with an optional caption.
///
@@ -38,7 +37,6 @@ public interface IRestMessageChannel : IMessageChannel
/// An awaitable Task containing the message sent to the channel.
///
new Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
-#endif
///
/// Sends a file to this message channel, with an optional caption.
///
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestCategoryChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestCategoryChannel.cs
index eb3fdd94b5..9d69d6bdcd 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestCategoryChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestCategoryChannel.cs
@@ -28,14 +28,6 @@ internal RestCategoryChannel(BaseDiscordClient discord, IGuild guild, ulong id)
// IGuildChannel
///
/// This method is not supported with category channels.
- IAsyncEnumerable> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
- => throw new NotSupportedException();
- ///
- /// This method is not supported with category channels.
- Task IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
- => throw new NotSupportedException();
- ///
- /// This method is not supported with category channels.
Task IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, bool isUnique, RequestOptions options)
=> throw new NotSupportedException();
///
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs
index c6d765787a..dd190199f6 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs
@@ -6,6 +6,9 @@
namespace Discord.Rest
{
+ ///
+ /// Represents a generic REST-based channel.
+ ///
public class RestChannel : RestEntity, IChannel, IUpdateable
{
///
@@ -26,6 +29,8 @@ internal static RestChannel Create(BaseDiscordClient discord, Model model)
case ChannelType.DM:
case ChannelType.Group:
return CreatePrivate(discord, model) as RestChannel;
+ case ChannelType.Category:
+ return RestCategoryChannel.Create(discord, new RestGuild(discord, model.GuildId.Value), model);
default:
return new RestChannel(discord, model.Id);
}
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs
index a3161c72cf..eb6fe91053 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs
@@ -10,7 +10,7 @@
namespace Discord.Rest
{
///
- /// Represents a REST-based DM channel.
+ /// Represents a REST-based direct-message channel.
///
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestDMChannel : RestChannel, IDMChannel, IRestPrivateChannel, IRestMessageChannel
@@ -74,17 +74,49 @@ public Task> GetPinnedMessagesAsync(RequestOpti
=> ChannelHelper.GetPinnedMessagesAsync(this, Discord, options);
///
- public Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
+ /// Message content is too long, length must be less or equal to .
+ public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options);
-#if FILESYSTEM
+
///
+ ///
+ /// is a zero-length string, contains only white space, or contains one or more
+ /// invalid characters as defined by .
+ ///
+ ///
+ /// is null.
+ ///
+ ///
+ /// The specified path, file name, or both exceed the system-defined maximum length. For example, on
+ /// Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260
+ /// characters.
+ ///
+ ///
+ /// The specified path is invalid, (for example, it is on an unmapped drive).
+ ///
+ ///
+ /// specified a directory.-or- The caller does not have the required permission.
+ ///
+ ///
+ /// The file specified in was not found.
+ ///
+ /// is in an invalid format.
+ /// An I/O error occurred while opening the file.
+ /// Message content is too long, length must be less or equal to .
public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options);
-#endif
///
+ /// Message content is too long, length must be less or equal to .
public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options);
+ ///
+ public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
+ => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options);
+ ///
+ public Task DeleteMessageAsync(IMessage message, RequestOptions options = null)
+ => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options);
+
///
public Task TriggerTypingAsync(RequestOptions options = null)
=> ChannelHelper.TriggerTypingAsync(this, Discord, options);
@@ -143,12 +175,9 @@ IAsyncEnumerable> IMessageChannel.GetMessagesAsync
async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);
-#if FILESYSTEM
- ///
async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
-#endif
- ///
+
async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
///
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs
index 4b4ccb0578..2f14dc94ff 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs
@@ -83,11 +83,18 @@ public IAsyncEnumerable> GetMessagesAsync(IMess
public Task> GetPinnedMessagesAsync(RequestOptions options = null)
=> ChannelHelper.GetPinnedMessagesAsync(this, Discord, options);
+ ///
+ public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
+ => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options);
+ ///
+ public Task DeleteMessageAsync(IMessage message, RequestOptions options = null)
+ => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options);
+
///
/// Message content is too long, length must be less or equal to .
- public Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
+ public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options);
-#if FILESYSTEM
+
///
///
/// is a zero-length string, contains only white space, or contains one or more
@@ -115,7 +122,6 @@ public Task SendMessageAsync(string text, bool isTTS = false, E
/// Message content is too long, length must be less or equal to .
public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options);
-#endif
///
/// Message content is too long, length must be less or equal to .
public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
@@ -168,10 +174,9 @@ IAsyncEnumerable> IMessageChannel.GetMessagesAsync
async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);
-#if FILESYSTEM
async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
-#endif
+
async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
async Task IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
index 7c3cc53c9b..cc52a9864e 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
@@ -8,7 +8,7 @@
namespace Discord.Rest
{
///
- /// Represents a private REST group channel.
+ /// Represents a private REST-based group channel.
///
public class RestGuildChannel : RestChannel, IGuildChannel
{
@@ -23,8 +23,6 @@ public class RestGuildChannel : RestChannel, IGuildChannel
///
public int Position { get; private set; }
///
- public ulong? CategoryId { get; private set; }
- ///
public ulong GuildId => Guild.Id;
internal RestGuildChannel(BaseDiscordClient discord, IGuild guild, ulong id)
@@ -43,7 +41,6 @@ internal static RestGuildChannel Create(BaseDiscordClient discord, IGuild guild,
case ChannelType.Category:
return RestCategoryChannel.Create(discord, guild, model);
default:
- // TODO: Channel categories
return new RestGuildChannel(discord, guild, model.Id);
}
}
@@ -75,14 +72,6 @@ public async Task ModifyAsync(Action func, RequestOption
public Task DeleteAsync(RequestOptions options = null)
=> ChannelHelper.DeleteAsync(this, Discord, options);
- ///
- public async Task GetCategoryAsync()
- {
- if (CategoryId.HasValue)
- return (await Guild.GetChannelAsync(CategoryId.Value).ConfigureAwait(false)) as ICategoryChannel;
- return null;
- }
-
public OverwritePermissions? GetPermissionOverwrite(IUser user)
{
for (int i = 0; i < _overwrites.Length; i++)
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
index 9752697d60..1cef7ab4c2 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
@@ -8,15 +8,22 @@
namespace Discord.Rest
{
+ ///
+ /// Represents a REST-based channel in a guild that can send and receive messages.
+ ///
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestTextChannel : RestGuildChannel, IRestMessageChannel, ITextChannel
{
+ ///
public string Topic { get; private set; }
+ public ulong? CategoryId { get; private set; }
+ ///
public string Mention => MentionUtils.MentionChannel(Id);
private bool _nsfw;
- public bool IsNsfw => _nsfw || ChannelHelper.IsNsfw(this);
+ ///
+ public bool IsNsfw => _nsfw;
internal RestTextChannel(BaseDiscordClient discord, IGuild guild, ulong id)
: base(discord, guild, id)
@@ -31,11 +38,12 @@ internal RestTextChannel(BaseDiscordClient discord, IGuild guild, ulong id)
internal override void Update(Model model)
{
base.Update(model);
-
+ CategoryId = model.CategoryId;
Topic = model.Topic.Value;
_nsfw = model.Nsfw.GetValueOrDefault();
}
+ ///
public async Task ModifyAsync(Action func, RequestOptions options = null)
{
var model = await ChannelHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false);
@@ -47,36 +55,80 @@ public Task GetUserAsync(ulong id, RequestOptions options = null)
public IAsyncEnumerable> GetUsersAsync(RequestOptions options = null)
=> ChannelHelper.GetUsersAsync(this, Guild, Discord, null, null, options);
+ ///
public Task GetMessageAsync(ulong id, RequestOptions options = null)
=> ChannelHelper.GetMessageAsync(this, Discord, id, options);
+ ///
public IAsyncEnumerable> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, null, Direction.Before, limit, options);
+ ///
public IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, fromMessageId, dir, limit, options);
+ ///
public IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, fromMessage.Id, dir, limit, options);
+ ///
public Task> GetPinnedMessagesAsync(RequestOptions options = null)
=> ChannelHelper.GetPinnedMessagesAsync(this, Discord, options);
- public Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
+ ///
+ /// Message content is too long, length must be less or equal to .
+ public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options);
-#if FILESYSTEM
+
+ ///
+ ///
+ /// is a zero-length string, contains only white space, or contains one or more
+ /// invalid characters as defined by .
+ ///
+ ///
+ /// is null.
+ ///
+ ///
+ /// The specified path, file name, or both exceed the system-defined maximum length. For example, on
+ /// Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260
+ /// characters.
+ ///
+ ///
+ /// The specified path is invalid, (for example, it is on an unmapped drive).
+ ///
+ ///
+ /// specified a directory.-or- The caller does not have the required permission.
+ ///
+ ///
+ /// The file specified in was not found.
+ ///
+ /// is in an invalid format.
+ /// An I/O error occurred while opening the file.
+ /// Message content is too long, length must be less or equal to .
public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options);
-#endif
+
+ ///
+ /// Message content is too long, length must be less or equal to .
public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options);
+ ///
+ public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
+ => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options);
+ ///
+ public Task DeleteMessageAsync(IMessage message, RequestOptions options = null)
+ => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options);
+
+ ///
public Task DeleteMessagesAsync(IEnumerable messages, RequestOptions options = null)
=> ChannelHelper.DeleteMessagesAsync(this, Discord, messages.Select(x => x.Id), options);
+ ///
public Task DeleteMessagesAsync(IEnumerable messageIds, RequestOptions options = null)
=> ChannelHelper.DeleteMessagesAsync(this, Discord, messageIds, options);
+ ///
public Task TriggerTypingAsync(RequestOptions options = null)
=> ChannelHelper.TriggerTypingAsync(this, Discord, options);
public IDisposable EnterTypingState(RequestOptions options = null)
=> ChannelHelper.EnterTypingState(this, Discord, options);
-
+
public Task CreateWebhookAsync(string name, Stream avatar = null, RequestOptions options = null)
=> ChannelHelper.CreateWebhookAsync(this, Discord, name, avatar, options);
public Task GetWebhookAsync(ulong id, RequestOptions options = null)
@@ -84,17 +136,24 @@ public Task GetWebhookAsync(ulong id, RequestOptions options = null
public Task> GetWebhooksAsync(RequestOptions options = null)
=> ChannelHelper.GetWebhooksAsync(this, Discord, options);
+ public Task GetCategoryAsync(RequestOptions options = null)
+ => ChannelHelper.GetCategoryAsync(this, Discord, options);
+
private string DebuggerDisplay => $"{Name} ({Id}, Text)";
//ITextChannel
+ ///
async Task ITextChannel.CreateWebhookAsync(string name, Stream avatar, RequestOptions options)
=> await CreateWebhookAsync(name, avatar, options).ConfigureAwait(false);
+ ///
async Task ITextChannel.GetWebhookAsync(ulong id, RequestOptions options)
=> await GetWebhookAsync(id, options).ConfigureAwait(false);
+ ///
async Task> ITextChannel.GetWebhooksAsync(RequestOptions options)
=> await GetWebhooksAsync(options).ConfigureAwait(false);
//IMessageChannel
+ ///
async Task IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
@@ -102,6 +161,7 @@ async Task IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, R
else
return null;
}
+ ///
IAsyncEnumerable> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
@@ -109,6 +169,8 @@ IAsyncEnumerable> IMessageChannel.GetMessagesAsync
else
return AsyncEnumerable.Empty>();
}
+
+ ///
IAsyncEnumerable> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
@@ -116,6 +178,7 @@ IAsyncEnumerable> IMessageChannel.GetMessagesAsync
else
return AsyncEnumerable.Empty>();
}
+ ///
IAsyncEnumerable> IMessageChannel.GetMessagesAsync(IMessage fromMessage, Direction dir, int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
@@ -123,21 +186,26 @@ IAsyncEnumerable> IMessageChannel.GetMessagesAsync
else
return AsyncEnumerable.Empty>();
}
+ ///
async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);
-#if FILESYSTEM
+ ///
async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
-#endif
+
+ ///
async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
+ ///
async Task IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendMessageAsync(text, isTTS, embed, options).ConfigureAwait(false);
+ ///
IDisposable IMessageChannel.EnterTypingState(RequestOptions options)
=> EnterTypingState(options);
//IGuildChannel
+ ///
async Task IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
@@ -145,6 +213,7 @@ async Task IGuildChannel.GetUserAsync(ulong id, CacheMode mode, Requ
else
return null;
}
+ ///
IAsyncEnumerable> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
@@ -154,6 +223,7 @@ IAsyncEnumerable> IGuildChannel.GetUsersAsync(Ca
}
//IChannel
+ ///
async Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
@@ -161,6 +231,7 @@ async Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions
else
return null;
}
+ ///
IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
@@ -168,5 +239,13 @@ IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mo
else
return AsyncEnumerable.Empty>();
}
+
+ // INestedChannel
+ async Task INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options)
+ {
+ if (CategoryId.HasValue && mode == CacheMode.AllowDownload)
+ return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel;
+ return null;
+ }
}
}
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs
index 5b44136e0b..07da22235e 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs
@@ -8,11 +8,17 @@
namespace Discord.Rest
{
+ ///
+ /// Represents a REST-based voice channel in a guild.
+ ///
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestVoiceChannel : RestGuildChannel, IVoiceChannel, IRestAudioChannel
{
+ ///
public int Bitrate { get; private set; }
+ ///
public int? UserLimit { get; private set; }
+ public ulong? CategoryId { get; private set; }
internal RestVoiceChannel(BaseDiscordClient discord, IGuild guild, ulong id)
: base(discord, guild, id)
@@ -24,20 +30,25 @@ internal RestVoiceChannel(BaseDiscordClient discord, IGuild guild, ulong id)
entity.Update(model);
return entity;
}
+ ///
internal override void Update(Model model)
{
base.Update(model);
-
+ CategoryId = model.CategoryId;
Bitrate = model.Bitrate.Value;
UserLimit = model.UserLimit.Value != 0 ? model.UserLimit.Value : (int?)null;
}
+ ///
public async Task ModifyAsync(Action func, RequestOptions options = null)
{
var model = await ChannelHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false);
Update(model);
}
+ public Task GetCategoryAsync(RequestOptions options = null)
+ => ChannelHelper.GetCategoryAsync(this, Discord, options);
+
private string DebuggerDisplay => $"{Name} ({Id}, Voice)";
//IAudioChannel
@@ -46,9 +57,19 @@ public async Task ModifyAsync(Action func, RequestOption
Task IAudioChannel.ConnectAsync(Action configAction) => throw new NotSupportedException();
//IGuildChannel
+ ///
Task IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult(null);
+ ///
IAsyncEnumerable> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> AsyncEnumerable.Empty>();
+
+ // INestedChannel
+ async Task INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options)
+ {
+ if (CategoryId.HasValue && mode == CacheMode.AllowDownload)
+ return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel;
+ return null;
+ }
}
}
diff --git a/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs
index 049f86c089..0643ecf6c1 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs
@@ -33,15 +33,19 @@ public IAsyncEnumerable> GetMessagesAsync(IMess
public Task> GetPinnedMessagesAsync(RequestOptions options = null)
=> ChannelHelper.GetPinnedMessagesAsync(this, Discord, options);
- public Task SendMessageAsync(string text, bool isTTS, Embed embed = null, RequestOptions options = null)
+ public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options);
-#if FILESYSTEM
- public Task SendFileAsync(string filePath, string text, bool isTTS, Embed embed = null, RequestOptions options = null)
+ public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options);
-#endif
- public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed = null, RequestOptions options = null)
+ public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
+
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options);
+ public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
+ => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options);
+ public Task DeleteMessageAsync(IMessage message, RequestOptions options = null)
+ => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options);
+
public Task TriggerTypingAsync(RequestOptions options = null)
=> ChannelHelper.TriggerTypingAsync(this, Discord, options);
public IDisposable EnterTypingState(RequestOptions options = null)
@@ -81,10 +85,9 @@ IAsyncEnumerable> IMessageChannel.GetMessagesAsync
async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);
-#if FILESYSTEM
async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
- => await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
-#endif
+ => await SendFileAsync(filePath, text, isTTS, embed, options);
+
async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
async Task IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
index 64f195a0dd..195e6f3c0a 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
@@ -147,21 +147,37 @@ public static async Task> GetChannelsAsync
}
/// is null.
public static async Task CreateTextChannelAsync(IGuild guild, BaseDiscordClient client,
- string name, RequestOptions options)
+ string name, RequestOptions options, Action func = null)
{
if (name == null) throw new ArgumentNullException(nameof(name));
- var args = new CreateGuildChannelParams(name, ChannelType.Text);
+ var props = new TextChannelProperties();
+ func?.Invoke(props);
+
+ var args = new CreateGuildChannelParams(name, ChannelType.Text)
+ {
+ CategoryId = props.CategoryId,
+ Topic = props.Topic,
+ IsNsfw = props.IsNsfw
+ };
var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false);
return RestTextChannel.Create(client, guild, model);
}
/// is null.
public static async Task CreateVoiceChannelAsync(IGuild guild, BaseDiscordClient client,
- string name, RequestOptions options)
+ string name, RequestOptions options, Action func = null)
{
if (name == null) throw new ArgumentNullException(nameof(name));
- var args = new CreateGuildChannelParams(name, ChannelType.Voice);
+ var props = new VoiceChannelProperties();
+ func?.Invoke(props);
+
+ var args = new CreateGuildChannelParams(name, ChannelType.Voice)
+ {
+ CategoryId = props.CategoryId,
+ Bitrate = props.Bitrate,
+ UserLimit = props.UserLimit
+ };
var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false);
return RestVoiceChannel.Create(client, guild, model);
}
diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestBan.cs b/src/Discord.Net.Rest/Entities/Guilds/RestBan.cs
index 2c65c8b599..ec8f60ae52 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/RestBan.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/RestBan.cs
@@ -3,9 +3,18 @@
namespace Discord.Rest
{
+ ///
+ /// Represents a REST-based ban object.
+ ///
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestBan : IBan
{
+ ///
+ /// Gets the banned user.
+ ///
+ ///
+ /// A generic object that was banned.
+ ///
public RestUser User { get; }
///
public string Reason { get; }
@@ -20,6 +29,12 @@ internal static RestBan Create(BaseDiscordClient client, Model model)
return new RestBan(RestUser.Create(client, model.User), model.Reason);
}
+ ///
+ /// Gets the name of the banned user.
+ ///
+ ///
+ /// A string containing the name of the user that was banned.
+ ///
public override string ToString() => User.ToString();
private string DebuggerDisplay => $"{User}: {Reason}";
diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
index e301db892d..e003e21308 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
@@ -258,10 +258,10 @@ public async Task GetSystemChannelAsync(RequestOptions options
}
return null;
}
- public Task CreateTextChannelAsync(string name, RequestOptions options = null)
- => GuildHelper.CreateTextChannelAsync(this, Discord, name, options);
- public Task CreateVoiceChannelAsync(string name, RequestOptions options = null)
- => GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options);
+ public Task CreateTextChannelAsync(string name, Action func = null, RequestOptions options = null)
+ => GuildHelper.CreateTextChannelAsync(this, Discord, name, options, func);
+ public Task CreateVoiceChannelAsync(string name, Action func = null, RequestOptions options = null)
+ => GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options, func);
public Task CreateCategoryChannelAsync(string name, RequestOptions options = null)
=> GuildHelper.CreateCategoryChannelAsync(this, Discord, name, options);
@@ -448,11 +448,11 @@ async Task IGuild.GetSystemChannelAsync(CacheMode mode, RequestOpt
return null;
}
///
- async Task IGuild.CreateTextChannelAsync(string name, RequestOptions options)
- => await CreateTextChannelAsync(name, options).ConfigureAwait(false);
+ async Task IGuild.CreateTextChannelAsync(string name, Action func, RequestOptions options)
+ => await CreateTextChannelAsync(name, func, options).ConfigureAwait(false);
///
- async Task IGuild.CreateVoiceChannelAsync(string name, RequestOptions options)
- => await CreateVoiceChannelAsync(name, options).ConfigureAwait(false);
+ async Task IGuild.CreateVoiceChannelAsync(string name, Action func, RequestOptions options)
+ => await CreateVoiceChannelAsync(name, func, options).ConfigureAwait(false);
///
async Task IGuild.CreateCategoryAsync(string name, RequestOptions options)
=> await CreateCategoryChannelAsync(name, options).ConfigureAwait(false);
diff --git a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
index 34e64cd5a4..ac1eacc3a7 100644
--- a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
@@ -27,10 +27,12 @@ public static async Task ModifyAsync(IMessage msg, BaseDiscordClient clie
};
return await client.ApiClient.ModifyMessageAsync(msg.Channel.Id, msg.Id, apiArgs, options).ConfigureAwait(false);
}
- public static async Task DeleteAsync(IMessage msg, BaseDiscordClient client,
+ public static Task DeleteAsync(IMessage msg, BaseDiscordClient client, RequestOptions options)
+ => DeleteAsync(msg.Channel.Id, msg.Id, client, options);
+ public static async Task DeleteAsync(ulong channelId, ulong msgId, BaseDiscordClient client,
RequestOptions options)
{
- await client.ApiClient.DeleteMessageAsync(msg.Channel.Id, msg.Id, options).ConfigureAwait(false);
+ await client.ApiClient.DeleteMessageAsync(channelId, msgId, options).ConfigureAwait(false);
}
public static async Task AddReactionAsync(IMessage msg, IEmote emote, BaseDiscordClient client, RequestOptions options)
@@ -48,13 +50,38 @@ public static async Task RemoveAllReactionsAsync(IMessage msg, BaseDiscordClient
await client.ApiClient.RemoveAllReactionsAsync(msg.Channel.Id, msg.Id, options).ConfigureAwait(false);
}
- public static async Task> GetReactionUsersAsync(IMessage msg, IEmote emote,
- Action func, BaseDiscordClient client, RequestOptions options)
+ public static IAsyncEnumerable> GetReactionUsersAsync(IMessage msg, IEmote emote,
+ int? limit, BaseDiscordClient client, RequestOptions options)
{
- var args = new GetReactionUsersParams();
- func(args);
- string emoji = (emote is Emote e ? $"{e.Name}:{e.Id}" : emote.Name);
- return (await client.ApiClient.GetReactionUsersAsync(msg.Channel.Id, msg.Id, emoji, args, options).ConfigureAwait(false)).Select(u => RestUser.Create(client, u)).ToImmutableArray();
+ Preconditions.NotNull(emote, nameof(emote));
+ var emoji = (emote is Emote e ? $"{e.Name}:{e.Id}" : emote.Name);
+
+ return new PagedAsyncEnumerable(
+ DiscordConfig.MaxUserReactionsPerBatch,
+ async (info, ct) =>
+ {
+ var args = new GetReactionUsersParams
+ {
+ Limit = info.PageSize
+ };
+
+ if (info.Position != null)
+ args.AfterUserId = info.Position.Value;
+
+ var models = await client.ApiClient.GetReactionUsersAsync(msg.Channel.Id, msg.Id, emoji, args, options).ConfigureAwait(false);
+ return models.Select(x => RestUser.Create(client, x)).ToImmutableArray();
+ },
+ nextPage: (info, lastPage) =>
+ {
+ if (lastPage.Count != DiscordConfig.MaxUsersPerBatch)
+ return false;
+
+ info.Position = lastPage.Max(x => x.Id);
+ return true;
+ },
+ count: limit
+ );
+
}
public static async Task PinAsync(IMessage msg, BaseDiscordClient client,
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
index de295af94e..7e000fd5f9 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
@@ -151,9 +151,9 @@ public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options
public Task RemoveAllReactionsAsync(RequestOptions options = null)
=> MessageHelper.RemoveAllReactionsAsync(this, Discord, options);
///
- public Task> GetReactionUsersAsync(IEmote emote, int limit = 100, ulong? afterUserId = null, RequestOptions options = null)
- => MessageHelper.GetReactionUsersAsync(this, emote, x => { x.Limit = limit; x.AfterUserId = afterUserId ?? Optional.Create(); }, Discord, options);
-
+ public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null)
+ => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options);
+
///
public Task PinAsync(RequestOptions options = null)
=> MessageHelper.PinAsync(this, Discord, options);
diff --git a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs
index 9213c5d750..8a3c1037bb 100644
--- a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs
+++ b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs
@@ -1,4 +1,4 @@
-using Discord.API;
+using Discord.API;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
@@ -25,7 +25,6 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ
if (converter != null)
{
property.Converter = converter;
- property.MemberConverter = converter;
}
}
else
diff --git a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs
index 5894aa7684..a4f87a3e9b 100644
--- a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs
+++ b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs
@@ -230,7 +230,7 @@ private void UpdateRateLimit(int id, RestRequest request, RateLimitInfo info, bo
#endif
}
- var now = DateTimeUtils.ToUnixSeconds(DateTimeOffset.UtcNow);
+ var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
DateTimeOffset? resetTick = null;
//Using X-RateLimit-Remaining causes a race condition
diff --git a/src/Discord.Net.Rest/Net/RateLimitInfo.cs b/src/Discord.Net.Rest/Net/RateLimitInfo.cs
index e9a5fde9ed..d31cc5cddf 100644
--- a/src/Discord.Net.Rest/Net/RateLimitInfo.cs
+++ b/src/Discord.Net.Rest/Net/RateLimitInfo.cs
@@ -21,7 +21,7 @@ internal RateLimitInfo(Dictionary headers)
Remaining = headers.TryGetValue("X-RateLimit-Remaining", out temp) &&
int.TryParse(temp, out var remaining) ? remaining : (int?)null;
Reset = headers.TryGetValue("X-RateLimit-Reset", out temp) &&
- int.TryParse(temp, out var reset) ? DateTimeUtils.FromUnixSeconds(reset) : (DateTimeOffset?)null;
+ int.TryParse(temp, out var reset) ? DateTimeOffset.FromUnixTimeSeconds(reset) : (DateTimeOffset?)null;
RetryAfter = headers.TryGetValue("Retry-After", out temp) &&
int.TryParse(temp, out var retryAfter) ? retryAfter : (int?)null;
Lag = headers.TryGetValue("Date", out temp) &&
diff --git a/src/Discord.Net.WebSocket/API/Gateway/TypingStartEvent.cs b/src/Discord.Net.WebSocket/API/Gateway/TypingStartEvent.cs
index 3cce512bdb..5ceae4b7aa 100644
--- a/src/Discord.Net.WebSocket/API/Gateway/TypingStartEvent.cs
+++ b/src/Discord.Net.WebSocket/API/Gateway/TypingStartEvent.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
@@ -9,6 +9,10 @@ internal class TypingStartEvent
public ulong UserId { get; set; }
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
+ [JsonProperty("guild_id")]
+ public ulong GuildId { get; set; }
+ [JsonProperty("member")]
+ public GuildMember Member { get; set; }
[JsonProperty("timestamp")]
public int Timestamp { get; set; }
}
diff --git a/src/Discord.Net.WebSocket/API/Voice/HelloEvent.cs b/src/Discord.Net.WebSocket/API/Voice/HelloEvent.cs
new file mode 100644
index 0000000000..8fdb0808fe
--- /dev/null
+++ b/src/Discord.Net.WebSocket/API/Voice/HelloEvent.cs
@@ -0,0 +1,10 @@
+using Newtonsoft.Json;
+
+namespace Discord.API.Voice
+{
+ internal class HelloEvent
+ {
+ [JsonProperty("heartbeat_interval")]
+ public int HeartbeatInterval { get; set; }
+ }
+}
diff --git a/src/Discord.Net.WebSocket/API/Voice/ReadyEvent.cs b/src/Discord.Net.WebSocket/API/Voice/ReadyEvent.cs
index 2a134ced18..7188cd8f7c 100644
--- a/src/Discord.Net.WebSocket/API/Voice/ReadyEvent.cs
+++ b/src/Discord.Net.WebSocket/API/Voice/ReadyEvent.cs
@@ -1,5 +1,6 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
+using System;
namespace Discord.API.Voice
{
@@ -14,6 +15,7 @@ internal class ReadyEvent
[JsonProperty("modes")]
public string[] Modes { get; set; }
[JsonProperty("heartbeat_interval")]
+ [Obsolete("This field is errorneous and should not be used", true)]
public int HeartbeatInterval { get; set; }
}
}
diff --git a/src/Discord.Net.WebSocket/API/Voice/VoiceOpCode.cs b/src/Discord.Net.WebSocket/API/Voice/VoiceOpCode.cs
index ae11a4c8f7..67afe6173b 100644
--- a/src/Discord.Net.WebSocket/API/Voice/VoiceOpCode.cs
+++ b/src/Discord.Net.WebSocket/API/Voice/VoiceOpCode.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
namespace Discord.API.Voice
{
internal enum VoiceOpCode : byte
@@ -11,11 +11,19 @@ internal enum VoiceOpCode : byte
Ready = 2,
/// C→S - Used to keep the connection alive and measure latency.
Heartbeat = 3,
- /// C←S - Used to reply to a client's heartbeat.
- HeartbeatAck = 3,
/// C←S - Used to provide an encryption key to the client.
SessionDescription = 4,
/// C↔S - Used to inform that a certain user is speaking.
- Speaking = 5
+ Speaking = 5,
+ /// C←S - Used to reply to a client's heartbeat.
+ HeartbeatAck = 6,
+ /// C→S - Used to resume a connection.
+ Resume = 7,
+ /// C←S - Used to inform the client the heartbeat interval.
+ Hello = 8,
+ /// C←S - Used to acknowledge a resumed connection.
+ Resumed = 9,
+ /// C←S - Used to notify that a client has disconnected.
+ ClientDisconnect = 13,
}
}
diff --git a/src/Discord.Net.WebSocket/Audio/AudioClient.cs b/src/Discord.Net.WebSocket/Audio/AudioClient.cs
index c3960fa673..e6cf203123 100644
--- a/src/Discord.Net.WebSocket/Audio/AudioClient.cs
+++ b/src/Discord.Net.WebSocket/Audio/AudioClient.cs
@@ -107,7 +107,7 @@ public async Task StopAsync()
private async Task OnConnectingAsync()
{
await _audioLogger.DebugAsync("Connecting ApiClient").ConfigureAwait(false);
- await ApiClient.ConnectAsync("wss://" + _url).ConfigureAwait(false);
+ await ApiClient.ConnectAsync("wss://" + _url + "?v=" + DiscordConfig.VoiceAPIVersion).ConfigureAwait(false);
await _audioLogger.DebugAsync("Listening on port " + ApiClient.UdpPort).ConfigureAwait(false);
await _audioLogger.DebugAsync("Sending Identity").ConfigureAwait(false);
await ApiClient.SendIdentityAsync(_userId, _sessionId, _token).ConfigureAwait(false);
@@ -216,6 +216,14 @@ private async Task ProcessMessageAsync(VoiceOpCode opCode, object payload)
{
switch (opCode)
{
+ case VoiceOpCode.Hello:
+ {
+ await _audioLogger.DebugAsync("Received Hello").ConfigureAwait(false);
+ var data = (payload as JToken).ToObject(_serializer);
+
+ _heartbeatTask = RunHeartbeatAsync(data.HeartbeatInterval, _connection.CancelToken);
+ }
+ break;
case VoiceOpCode.Ready:
{
await _audioLogger.DebugAsync("Received Ready").ConfigureAwait(false);
@@ -225,8 +233,6 @@ private async Task ProcessMessageAsync(VoiceOpCode opCode, object payload)
if (!data.Modes.Contains(DiscordVoiceAPIClient.Mode))
throw new InvalidOperationException($"Discord does not support {DiscordVoiceAPIClient.Mode}");
-
- _heartbeatTask = RunHeartbeatAsync(data.HeartbeatInterval, _connection.CancelToken);
ApiClient.SetUdpEndpoint(data.Ip, data.Port);
await ApiClient.SendDiscoveryAsync(_ssrc).ConfigureAwait(false);
diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs b/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
index c236b10458..db4eb9c94d 100644
--- a/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
+++ b/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
@@ -7,6 +7,17 @@ public partial class BaseSocketClient
{
//Channels
/// Fired when a channel is created.
+ ///
+ ///
+ /// This event is fired when a generic channel has been created. The event handler must return a
+ /// and accept a as its parameter.
+ ///
+ ///
+ /// The newly created channel is passed into the event handler parameter. The given channel type may
+ /// include, but not limited to, Private Channels (DM, Group), Guild Channels (Text, Voice, Category);
+ /// see the derived classes of for more details.
+ ///
+ ///
public event Func ChannelCreated
{
add { _channelCreatedEvent.Add(value); }
@@ -14,12 +25,35 @@ public event Func ChannelCreated
}
internal readonly AsyncEvent> _channelCreatedEvent = new AsyncEvent>();
/// Fired when a channel is destroyed.
+ ///
+ ///
+ /// This event is fired when a generic channel has been destroyed. The event handler must return a
+ /// and accept a as its parameter.
+ ///
+ ///
+ /// The destroyed channel is passed into the event handler parameter. The given channel type may
+ /// include, but not limited to, Private Channels (DM, Group), Guild Channels (Text, Voice, Category);
+ /// see the derived classes of for more details.
+ ///
+ ///
public event Func ChannelDestroyed {
add { _channelDestroyedEvent.Add(value); }
remove { _channelDestroyedEvent.Remove(value); }
}
internal readonly AsyncEvent> _channelDestroyedEvent = new AsyncEvent>();
/// Fired when a channel is updated.
+ ///
+ ///
+ /// This event is fired when a generic channel has been destroyed. The event handler must return a
+ /// and accept 2 as its parameters.
+ ///
+ ///
+ /// The original (prior to update) channel is passed into the first , while
+ /// the updated channel is passed into the second. The given channel type may include, but not limited
+ /// to, Private Channels (DM, Group), Guild Channels (Text, Voice, Category); see the derived classes of
+ /// for more details.
+ ///
+ ///
public event Func ChannelUpdated {
add { _channelUpdatedEvent.Add(value); }
remove { _channelUpdatedEvent.Remove(value); }
@@ -28,18 +62,72 @@ public event Func ChannelUpdated {
//Messages
/// Fired when a message is received.
+ ///
+ ///
+ /// This event is fired when a message is received. The event handler must return a
+ /// and accept a as its parameter.
+ ///
+ ///
+ /// The message that is sent to the client is passed into the event handler parameter as
+ /// . This message may be a system message (i.e.
+ /// ) or a user message (i.e. . See the
+ /// derived clsases of for more details.
+ ///
+ ///
public event Func MessageReceived {
add { _messageReceivedEvent.Add(value); }
remove { _messageReceivedEvent.Remove(value); }
}
internal readonly AsyncEvent> _messageReceivedEvent = new AsyncEvent>();
/// Fired when a message is deleted.
+ ///
+ ///
+ /// This event is fired when a message is deleted. The event handler must return a
+ /// and accept a and
+ /// as its parameters.
+ ///
+ ///
+ ///
+ /// It is not possible to retrieve the message via
+ /// ; the message cannot be retrieved by Discord
+ /// after the message has been deleted.
+ ///
+ /// If caching is enabled via , the
+ /// entity will contain the deleted message; otherwise, in event
+ /// that the message cannot be retrieved, the snowflake ID of the message is preserved in the
+ /// .
+ ///
+ ///
+ /// The source channel of the removed message will be passed into the
+ /// parameter.
+ ///
+ ///
public event Func, ISocketMessageChannel, Task> MessageDeleted {
add { _messageDeletedEvent.Add(value); }
remove { _messageDeletedEvent.Remove(value); }
}
internal readonly AsyncEvent, ISocketMessageChannel, Task>> _messageDeletedEvent = new AsyncEvent, ISocketMessageChannel, Task>>();
/// Fired when a message is updated.
+ ///
+ ///
+ /// This event is fired when a message is updated. The event handler must return a
+ /// and accept a , ,
+ /// and as its parameters.
+ ///
+ ///
+ /// If caching is enabled via , the
+ /// entity will contain the original message; otherwise, in event
+ /// that the message cannot be retrieved, the snowflake ID of the message is preserved in the
+ /// .
+ ///
+ ///
+ /// The updated message will be passed into the parameter.
+ ///
+ ///
+ /// The source channel of the updated message will be passed into the
+ /// parameter.
+ ///
+ ///
public event Func, SocketMessage, ISocketMessageChannel, Task> MessageUpdated {
add { _messageUpdatedEvent.Add(value); }
remove { _messageUpdatedEvent.Remove(value); }
diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.cs b/src/Discord.Net.WebSocket/BaseSocketClient.cs
index 858fec7fed..e9d30a30dc 100644
--- a/src/Discord.Net.WebSocket/BaseSocketClient.cs
+++ b/src/Discord.Net.WebSocket/BaseSocketClient.cs
@@ -76,7 +76,7 @@ private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config
///
///
///
- /// A WebSocket-based generic user; null when the user cannot be found.
+ /// A generic WebSocket-based user; null when the user cannot be found.
///
public abstract SocketUser GetUser(ulong id);
@@ -98,7 +98,7 @@ private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config
///
///
///
- /// A WebSocket-based generic user; null when the user cannot be found.
+ /// A generic WebSocket-based user; null when the user cannot be found.
///
public abstract SocketUser GetUser(string username, string discriminator);
///
diff --git a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj
index 251cdb18ba..ddd3b7954c 100644
--- a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj
+++ b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj
@@ -1,11 +1,11 @@
-
+
Discord.Net.WebSocket
Discord.WebSocket
A core Discord.Net library containing the WebSocket client and models.
- net45;netstandard1.1;netstandard1.3
- netstandard1.1;netstandard1.3
+ net46;netstandard1.3;netstandard2.0
+ netstandard1.3;netstandard2.0
true
@@ -13,6 +13,6 @@
-
+
diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
index dc4e720208..d147f365be 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
@@ -378,7 +378,7 @@ private async Task SendStatusAsync()
await ApiClient.SendStatusUpdateAsync(
status,
status == UserStatus.AFK,
- statusSince != null ? DateTimeUtils.ToUnixMilliseconds(_statusSince.Value) : (long?)null,
+ statusSince != null ? _statusSince.Value.ToUnixTimeMilliseconds() : (long?)null,
gameModel).ConfigureAwait(false);
}
@@ -1104,7 +1104,7 @@ private async Task ProcessMessageAsync(GatewayOpCode opCode, int? seq, string ty
if (author == null)
{
if (guild != null)
- author = guild.AddOrUpdateUser(data.Author.Value); //User has no guild-specific data
+ author = guild.AddOrUpdateUser(data.Member.Value); //per g250k, we can create an entire member now
else if (channel is SocketGroupChannel)
author = (channel as SocketGroupChannel).GetOrAddUser(data.Author.Value);
else
@@ -1374,6 +1374,11 @@ private async Task ProcessMessageAsync(GatewayOpCode opCode, int? seq, string ty
}
var user = (channel as SocketChannel).GetUser(data.UserId);
+ if (user == null)
+ {
+ if (guild != null)
+ user = guild.AddOrUpdateUser(data.Member);
+ }
if (user != null)
await TimedInvokeAsync(_userIsTypingEvent, nameof(UserIsTyping), user, channel).ConfigureAwait(false);
}
@@ -1437,7 +1442,9 @@ private async Task ProcessMessageAsync(GatewayOpCode opCode, int? seq, string ty
after = SocketVoiceState.Create(null, data);
}
- user = guild.GetUser(data.UserId);
+ // per g250k, this should always be sent, but apparently not always
+ user = guild.GetUser(data.UserId)
+ ?? (data.Member.IsSpecified ? guild.AddOrUpdateUser(data.Member.Value) : null);
if (user == null)
{
await UnknownGuildUserAsync(type, data.UserId, guild.Id).ConfigureAwait(false);
diff --git a/src/Discord.Net.WebSocket/DiscordVoiceApiClient.cs b/src/Discord.Net.WebSocket/DiscordVoiceApiClient.cs
index 25dc2cf7b0..0eb92caed7 100644
--- a/src/Discord.Net.WebSocket/DiscordVoiceApiClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordVoiceApiClient.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Discord.API;
using Discord.API.Voice;
using Discord.Net.Converters;
@@ -129,7 +129,7 @@ public async Task SendAsync(byte[] data, int offset, int bytes)
//WebSocket
public async Task SendHeartbeatAsync(RequestOptions options = null)
{
- await SendAsync(VoiceOpCode.Heartbeat, DateTimeUtils.ToUnixMilliseconds(DateTimeOffset.UtcNow), options: options).ConfigureAwait(false);
+ await SendAsync(VoiceOpCode.Heartbeat, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), options: options).ConfigureAwait(false);
}
public async Task SendIdentityAsync(ulong userId, string sessionId, string token)
{
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs
index c37311a41a..73fc3c34c1 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs
@@ -28,8 +28,7 @@ public interface ISocketMessageChannel : IMessageChannel
///
/// An awaitable Task containing the message sent to the channel.
///
- new Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null);
-#if FILESYSTEM
+ new Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
///
/// Sends a file to this message channel, with an optional caption.
///
@@ -47,7 +46,6 @@ public interface ISocketMessageChannel : IMessageChannel
/// An awaitable Task containing the message sent to the channel.
///
new Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
-#endif
///
/// Sends a file to this message channel, with an optional caption.
///
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketCategoryChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketCategoryChannel.cs
index 37e6afef10..4c224e09ac 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketCategoryChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketCategoryChannel.cs
@@ -21,7 +21,7 @@ public override IReadOnlyCollection Users
ChannelPermission.ViewChannel)).ToImmutableArray();
public IReadOnlyCollection Channels
- => Guild.Channels.Where(x => x.CategoryId == Id).ToImmutableArray();
+ => Guild.Channels.Where(x => x is INestedChannel nestedChannel && nestedChannel.CategoryId == Id).ToImmutableArray();
internal SocketCategoryChannel(DiscordSocketClient discord, ulong id, SocketGuild guild)
: base(discord, id, guild)
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs
index 763296590e..af8854f213 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs
@@ -79,18 +79,22 @@ public Task> GetPinnedMessagesAsync(RequestOpti
///
/// Message content is too long, length must be less or equal to .
- public Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
+ public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options);
-#if FILESYSTEM
+
///
public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options);
-#endif
///
/// Message content is too long, length must be less or equal to .
public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options);
+ public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
+ => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options);
+ public Task DeleteMessageAsync(IMessage message, RequestOptions options = null)
+ => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options);
+
///
public Task TriggerTypingAsync(RequestOptions options = null)
=> ChannelHelper.TriggerTypingAsync(this, Discord, options);
@@ -160,12 +164,8 @@ IAsyncEnumerable> IMessageChannel.GetMessagesAsync
///
async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);
-#if FILESYSTEM
- ///
async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
-#endif
- ///
async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
///
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs
index 57fcc51a28..5eb2a6e122 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs
@@ -109,17 +109,21 @@ public Task> GetPinnedMessagesAsync(RequestOpti
///