diff --git a/Discord.Net.targets b/Discord.Net.targets
index 95eccd790..3f623c619 100644
--- a/Discord.Net.targets
+++ b/Discord.Net.targets
@@ -1,7 +1,7 @@
- 2.0.0-alpha
-
+ 2.0.0
+ beta
RogueException
discord;discordapp
https://github.com/RogueException/Discord.Net
diff --git a/README.md b/README.md
index 2b58d4579..bd0ef20c7 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,11 @@
[](https://www.nuget.org/packages/Discord.Net)
[](https://www.myget.org/feed/Packages/discord-net)
[](https://ci.appveyor.com/project/RogueException/discord-net/branch/dev)
-[](https://discord.gg/0SBTUU1wZTVjAMPx)
+[](https://discord.gg/jkrBmQR)
An unofficial .NET API Wrapper for the Discord client (http://discordapp.com).
-Check out the [documentation](https://discord.foxbot.me/docs/) or join the [Discord API Chat](https://discord.gg/0SBTUU1wZTVjAMPx).
+Check out the [documentation](https://discord.foxbot.me/docs/) or join the [Discord API Chat](https://discord.gg/jkrBmQR).
## Installation
### Stable (NuGet)
diff --git a/appveyor.yml b/appveyor.yml
index d94e2ad68..3bf70c09c 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -34,7 +34,7 @@ after_build:
if ($Env:APPVEYOR_REPO_TAG -eq "true") {
nuget pack src\Discord.Net\Discord.Net.nuspec -OutputDirectory "artifacts" -properties suffix=""
} else {
- nuget pack src\Discord.Net\Discord.Net.nuspec -OutputDirectory "artifacts" -properties suffix="-build-$Env:BUILD"
+ nuget pack src\Discord.Net\Discord.Net.nuspec -OutputDirectory "artifacts" -properties suffix="-$Env:BUILD"
}
- ps: Get-ChildItem artifacts\*.nupkg | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
diff --git a/docs/guides/getting_started/intro.md b/docs/guides/getting_started/intro.md
index 02f04bec4..db086df21 100644
--- a/docs/guides/getting_started/intro.md
+++ b/docs/guides/getting_started/intro.md
@@ -74,7 +74,7 @@ async main.
[!code-csharp[Async Context](samples/intro/async-context.cs)]
-As a result of this, your program will now start and immidiately
+As a result of this, your program will now start and immediately
jump into an async context. This will allow us to create a connection
to Discord later on without needing to worry about setting up the
correct async implementation.
diff --git a/docs/guides/getting_started/samples/intro/structure.cs b/docs/guides/getting_started/samples/intro/structure.cs
index 789ceff76..bdfc12b67 100644
--- a/docs/guides/getting_started/samples/intro/structure.cs
+++ b/docs/guides/getting_started/samples/intro/structure.cs
@@ -1,5 +1,6 @@
using System;
using System.Reflection;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Discord;
@@ -80,7 +81,7 @@ class Program
private async Task MainAsync()
{
- // Centralize the logic for commands into a seperate method.
+ // Centralize the logic for commands into a separate method.
await InitCommands();
// Login and connect.
@@ -88,7 +89,7 @@ class Program
await _client.StartAsync();
// Wait infinitely so your bot actually stays connected.
- await Task.Delay(-1);
+ await Task.Delay(Timeout.Infinite);
}
private IServiceProvider _services;
@@ -138,7 +139,7 @@ class Program
var context = new SocketCommandContext(_client, msg);
// Execute the command. (result does not indicate a return value,
- // rather an object stating if the command executed succesfully).
+ // rather an object stating if the command executed successfully).
var result = await _commands.ExecuteAsync(context, pos, _services);
// Uncomment the following lines if you want the bot
diff --git a/docs/guides/getting_started/samples/project.csproj b/docs/guides/getting_started/samples/project.csproj
index 8daf71877..feb0b0c40 100644
--- a/docs/guides/getting_started/samples/project.csproj
+++ b/docs/guides/getting_started/samples/project.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/docs/guides/voice/samples/audio_create_ffmpeg.cs b/docs/guides/voice/samples/audio_create_ffmpeg.cs
index e24af088b..dda560efe 100644
--- a/docs/guides/voice/samples/audio_create_ffmpeg.cs
+++ b/docs/guides/voice/samples/audio_create_ffmpeg.cs
@@ -1,11 +1,10 @@
private Process CreateStream(string path)
{
- var ffmpeg = new ProcessStartInfo
+ return Process.Start(new ProcessStartInfo
{
FileName = "ffmpeg",
- Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 pipe:1",
+ Arguments = $"-hide_banner -loglevel panic -i \"{path}\" -ac 2 -f s16le -ar 48000 pipe:1",
UseShellExecute = false,
RedirectStandardOutput = true,
- };
- return Process.Start(ffmpeg);
-}
\ No newline at end of file
+ });
+}
diff --git a/docs/guides/voice/samples/audio_ffmpeg.cs b/docs/guides/voice/samples/audio_ffmpeg.cs
index b9430ac11..d36fbbc20 100644
--- a/docs/guides/voice/samples/audio_ffmpeg.cs
+++ b/docs/guides/voice/samples/audio_ffmpeg.cs
@@ -1,9 +1,11 @@
private async Task SendAsync(IAudioClient client, string path)
{
// Create FFmpeg using the previous example
- var ffmpeg = CreateStream(path);
- var output = ffmpeg.StandardOutput.BaseStream;
- var discord = client.CreatePCMStream(AudioApplication.Mixed);
- await output.CopyToAsync(discord);
- await discord.FlushAsync();
+ using (var ffmpeg = CreateStream(path))
+ using (var output = ffmpeg.StandardOutput.BaseStream)
+ using (var discord = client.CreatePCMStream(AudioApplication.Mixed))
+ {
+ try { await output.CopyToAsync(discord); }
+ finally { await discord.FlushAsync(); }
+ }
}
diff --git a/docs/guides/voice/samples/joining_audio.cs b/docs/guides/voice/samples/joining_audio.cs
index 0cc36978a..4cec67540 100644
--- a/docs/guides/voice/samples/joining_audio.cs
+++ b/docs/guides/voice/samples/joining_audio.cs
@@ -7,4 +7,4 @@ public async Task JoinChannel(IVoiceChannel channel = null)
// For the next step with transmitting audio, you would want to pass this Audio Client in to a service.
var audioClient = await channel.ConnectAsync();
-}
\ No newline at end of file
+}
diff --git a/src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs b/src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs
index 49dae6080..209822583 100644
--- a/src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs
+++ b/src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs
@@ -7,6 +7,6 @@ namespace Discord.Commands
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
public abstract class ParameterPreconditionAttribute : Attribute
{
- public abstract Task CheckPermissions(ICommandContext context, ParameterInfo parameter, object value, IServiceProvider services);
+ public abstract Task CheckPermissionsAsync(ICommandContext context, ParameterInfo parameter, object value, IServiceProvider services);
}
}
\ No newline at end of file
diff --git a/src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs b/src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs
index 3727510d9..367adebf0 100644
--- a/src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs
+++ b/src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs
@@ -8,11 +8,11 @@ namespace Discord.Commands
{
///
/// Specify a group that this precondition belongs to. Preconditions of the same group require only one
- /// of the preconditions to pass in order to be successful (A || B). Specifying =
+ /// of the preconditions to pass in order to be successful (A || B). Specifying =
/// or not at all will require *all* preconditions to pass, just like normal (A && B).
///
public string Group { get; set; } = null;
- public abstract Task CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services);
+ public abstract Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services);
}
}
diff --git a/src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs b/src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs
index b2cd3811c..104252799 100644
--- a/src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs
+++ b/src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs
@@ -41,7 +41,7 @@ namespace Discord.Commands
GuildPermission = null;
}
- public override async Task CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services)
+ public override async Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
IGuildUser guildUser = null;
if (context.Guild != null)
@@ -57,13 +57,11 @@ namespace Discord.Commands
if (ChannelPermission.HasValue)
{
- var guildChannel = context.Channel as IGuildChannel;
-
ChannelPermissions perms;
- if (guildChannel != null)
+ if (context.Channel is IGuildChannel guildChannel)
perms = guildUser.GetPermissions(guildChannel);
else
- perms = ChannelPermissions.All(guildChannel);
+ perms = ChannelPermissions.All(context.Channel);
if (!perms.Has(ChannelPermission.Value))
return PreconditionResult.FromError($"Bot requires channel permission {ChannelPermission.Value}");
diff --git a/src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs b/src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs
index a221eb4a9..5fa0fb1b9 100644
--- a/src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs
+++ b/src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs
@@ -38,7 +38,7 @@ namespace Discord.Commands
Contexts = contexts;
}
- public override Task CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services)
+ public override Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
bool isValid = false;
diff --git a/src/Discord.Net.Commands/Attributes/Preconditions/RequireNsfwAttribute.cs b/src/Discord.Net.Commands/Attributes/Preconditions/RequireNsfwAttribute.cs
index b3cf25365..c8e3bfa82 100644
--- a/src/Discord.Net.Commands/Attributes/Preconditions/RequireNsfwAttribute.cs
+++ b/src/Discord.Net.Commands/Attributes/Preconditions/RequireNsfwAttribute.cs
@@ -9,7 +9,7 @@ namespace Discord.Commands
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequireNsfwAttribute : PreconditionAttribute
{
- public override Task CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services)
+ public override Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
if (context.Channel is ITextChannel text && text.IsNsfw)
return Task.FromResult(PreconditionResult.FromSuccess());
diff --git a/src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs b/src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs
index 2055a358e..e370aeec4 100644
--- a/src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs
+++ b/src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs
@@ -12,7 +12,7 @@ namespace Discord.Commands
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequireOwnerAttribute : PreconditionAttribute
{
- public override async Task CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services)
+ public override async Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
switch (context.Client.TokenType)
{
diff --git a/src/Discord.Net.Commands/Attributes/Preconditions/RequireUserPermissionAttribute.cs b/src/Discord.Net.Commands/Attributes/Preconditions/RequireUserPermissionAttribute.cs
index f5e3a9fc5..14121f35b 100644
--- a/src/Discord.Net.Commands/Attributes/Preconditions/RequireUserPermissionAttribute.cs
+++ b/src/Discord.Net.Commands/Attributes/Preconditions/RequireUserPermissionAttribute.cs
@@ -42,7 +42,7 @@ namespace Discord.Commands
GuildPermission = null;
}
- public override Task CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services)
+ public override Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
var guildUser = context.User as IGuildUser;
@@ -56,13 +56,11 @@ namespace Discord.Commands
if (ChannelPermission.HasValue)
{
- var guildChannel = context.Channel as IGuildChannel;
-
ChannelPermissions perms;
- if (guildChannel != null)
+ if (context.Channel is IGuildChannel guildChannel)
perms = guildUser.GetPermissions(guildChannel);
else
- perms = ChannelPermissions.All(guildChannel);
+ perms = ChannelPermissions.All(context.Channel);
if (!perms.Has(ChannelPermission.Value))
return Task.FromResult(PreconditionResult.FromError($"User requires channel permission {ChannelPermission.Value}"));
diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs
index 394f8589d..28e36d54d 100644
--- a/src/Discord.Net.Commands/CommandParser.cs
+++ b/src/Discord.Net.Commands/CommandParser.cs
@@ -14,7 +14,7 @@ namespace Discord.Commands
QuotedParameter
}
- public static async Task ParseArgs(CommandInfo command, ICommandContext context, IServiceProvider services, string input, int startPos)
+ public static async Task ParseArgsAsync(CommandInfo command, ICommandContext context, IServiceProvider services, string input, int startPos)
{
ParameterInfo curParam = null;
StringBuilder argBuilder = new StringBuilder(input.Length);
@@ -111,7 +111,7 @@ namespace Discord.Commands
if (curParam == null)
return ParseResult.FromError(CommandError.BadArgCount, "The input text has too many parameters.");
- var typeReaderResult = await curParam.Parse(context, argString, services).ConfigureAwait(false);
+ var typeReaderResult = await curParam.ParseAsync(context, argString, services).ConfigureAwait(false);
if (!typeReaderResult.IsSuccess && typeReaderResult.Error != CommandError.MultipleMatches)
return ParseResult.FromError(typeReaderResult);
@@ -134,7 +134,7 @@ namespace Discord.Commands
if (curParam != null && curParam.IsRemainder)
{
- var typeReaderResult = await curParam.Parse(context, argBuilder.ToString(), services).ConfigureAwait(false);
+ var typeReaderResult = await curParam.ParseAsync(context, argBuilder.ToString(), services).ConfigureAwait(false);
if (!typeReaderResult.IsSuccess)
return ParseResult.FromError(typeReaderResult);
argList.Add(typeReaderResult);
diff --git a/src/Discord.Net.Commands/Info/CommandInfo.cs b/src/Discord.Net.Commands/Info/CommandInfo.cs
index c94be525f..6bb621f94 100644
--- a/src/Discord.Net.Commands/Info/CommandInfo.cs
+++ b/src/Discord.Net.Commands/Info/CommandInfo.cs
@@ -78,7 +78,7 @@ namespace Discord.Commands
{
foreach (PreconditionAttribute precondition in preconditionGroup)
{
- var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false);
+ var result = await precondition.CheckPermissionsAsync(context, this, services).ConfigureAwait(false);
if (!result.IsSuccess)
return result;
}
@@ -87,7 +87,7 @@ namespace Discord.Commands
{
var results = new List();
foreach (PreconditionAttribute precondition in preconditionGroup)
- results.Add(await precondition.CheckPermissions(context, this, services).ConfigureAwait(false));
+ results.Add(await precondition.CheckPermissionsAsync(context, this, services).ConfigureAwait(false));
if (!results.Any(p => p.IsSuccess))
return PreconditionGroupResult.FromError($"{type} precondition group {preconditionGroup.Key} failed.", results);
@@ -117,7 +117,7 @@ namespace Discord.Commands
return ParseResult.FromError(preconditionResult);
string input = searchResult.Text.Substring(startIndex);
- return await CommandParser.ParseArgs(this, context, services, input, 0).ConfigureAwait(false);
+ return await CommandParser.ParseArgsAsync(this, context, services, input, 0).ConfigureAwait(false);
}
public Task ExecuteAsync(ICommandContext context, ParseResult parseResult, IServiceProvider services)
@@ -163,11 +163,11 @@ namespace Discord.Commands
switch (RunMode)
{
case RunMode.Sync: //Always sync
- return await ExecuteAsyncInternal(context, args, services).ConfigureAwait(false);
+ return await ExecuteAsyncInternalAsync(context, args, services).ConfigureAwait(false);
case RunMode.Async: //Always async
var t2 = Task.Run(async () =>
{
- await ExecuteAsyncInternal(context, args, services).ConfigureAwait(false);
+ await ExecuteAsyncInternalAsync(context, args, services).ConfigureAwait(false);
});
break;
}
@@ -179,7 +179,7 @@ namespace Discord.Commands
}
}
- private async Task ExecuteAsyncInternal(ICommandContext context, object[] args, IServiceProvider services)
+ private async Task ExecuteAsyncInternalAsync(ICommandContext context, object[] args, IServiceProvider services)
{
await Module.Service._cmdLogger.DebugAsync($"Executing {GetLogText(context)}").ConfigureAwait(false);
try
@@ -199,10 +199,13 @@ namespace Discord.Commands
return result;
}
else
+ {
await task.ConfigureAwait(false);
+ var result = ExecuteResult.FromSuccess();
+ await Module.Service._commandExecutedEvent.InvokeAsync(this, context, result).ConfigureAwait(false);
+ }
var executeResult = ExecuteResult.FromSuccess();
- await Module.Service._commandExecutedEvent.InvokeAsync(this, context, executeResult).ConfigureAwait(false);
return executeResult;
}
catch (Exception ex)
diff --git a/src/Discord.Net.Commands/Info/ParameterInfo.cs b/src/Discord.Net.Commands/Info/ParameterInfo.cs
index e417b1ab6..4a56415e5 100644
--- a/src/Discord.Net.Commands/Info/ParameterInfo.cs
+++ b/src/Discord.Net.Commands/Info/ParameterInfo.cs
@@ -48,7 +48,7 @@ namespace Discord.Commands
foreach (var precondition in Preconditions)
{
- var result = await precondition.CheckPermissions(context, this, arg, services).ConfigureAwait(false);
+ var result = await precondition.CheckPermissionsAsync(context, this, arg, services).ConfigureAwait(false);
if (!result.IsSuccess)
return result;
}
@@ -56,10 +56,10 @@ namespace Discord.Commands
return PreconditionResult.FromSuccess();
}
- public async Task Parse(ICommandContext context, string input, IServiceProvider services = null)
+ public async Task ParseAsync(ICommandContext context, string input, IServiceProvider services = null)
{
services = services ?? EmptyServiceProvider.Instance;
- return await _reader.Read(context, input, services).ConfigureAwait(false);
+ return await _reader.ReadAsync(context, input, services).ConfigureAwait(false);
}
public override string ToString() => Name;
diff --git a/src/Discord.Net.Commands/Readers/ChannelTypeReader.cs b/src/Discord.Net.Commands/Readers/ChannelTypeReader.cs
index 72c62282e..3136eb2cb 100644
--- a/src/Discord.Net.Commands/Readers/ChannelTypeReader.cs
+++ b/src/Discord.Net.Commands/Readers/ChannelTypeReader.cs
@@ -9,7 +9,7 @@ namespace Discord.Commands
internal class ChannelTypeReader : TypeReader
where T : class, IChannel
{
- public override async Task Read(ICommandContext context, string input, IServiceProvider services)
+ public override async Task ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
if (context.Guild != null)
{
diff --git a/src/Discord.Net.Commands/Readers/EnumTypeReader.cs b/src/Discord.Net.Commands/Readers/EnumTypeReader.cs
index 383b8e63c..c097e6189 100644
--- a/src/Discord.Net.Commands/Readers/EnumTypeReader.cs
+++ b/src/Discord.Net.Commands/Readers/EnumTypeReader.cs
@@ -44,7 +44,7 @@ namespace Discord.Commands
_enumsByValue = byValueBuilder.ToImmutable();
}
- public override Task Read(ICommandContext context, string input, IServiceProvider services)
+ public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
object enumValue;
diff --git a/src/Discord.Net.Commands/Readers/MessageTypeReader.cs b/src/Discord.Net.Commands/Readers/MessageTypeReader.cs
index 895713e4f..fe576c3c6 100644
--- a/src/Discord.Net.Commands/Readers/MessageTypeReader.cs
+++ b/src/Discord.Net.Commands/Readers/MessageTypeReader.cs
@@ -7,7 +7,7 @@ namespace Discord.Commands
internal class MessageTypeReader : TypeReader
where T : class, IMessage
{
- public override async Task Read(ICommandContext context, string input, IServiceProvider services)
+ public override async Task ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
ulong id;
diff --git a/src/Discord.Net.Commands/Readers/NullableTypeReader.cs b/src/Discord.Net.Commands/Readers/NullableTypeReader.cs
index 07976fb69..109689e15 100644
--- a/src/Discord.Net.Commands/Readers/NullableTypeReader.cs
+++ b/src/Discord.Net.Commands/Readers/NullableTypeReader.cs
@@ -24,11 +24,11 @@ namespace Discord.Commands
_baseTypeReader = baseTypeReader;
}
- public override async Task Read(ICommandContext context, string input, IServiceProvider services)
+ public override async Task ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
if (string.Equals(input, "null", StringComparison.OrdinalIgnoreCase) || string.Equals(input, "nothing", StringComparison.OrdinalIgnoreCase))
return TypeReaderResult.FromSuccess(new T?());
- return await _baseTypeReader.Read(context, input, services); ;
+ return await _baseTypeReader.ReadAsync(context, input, services);
}
}
}
diff --git a/src/Discord.Net.Commands/Readers/PrimitiveTypeReader.cs b/src/Discord.Net.Commands/Readers/PrimitiveTypeReader.cs
index 2656741f0..b19a6bd69 100644
--- a/src/Discord.Net.Commands/Readers/PrimitiveTypeReader.cs
+++ b/src/Discord.Net.Commands/Readers/PrimitiveTypeReader.cs
@@ -30,7 +30,7 @@ namespace Discord.Commands
_score = score;
}
- public override Task Read(ICommandContext context, string input, IServiceProvider services)
+ public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
if (_tryParse(input, out T value))
return Task.FromResult(TypeReaderResult.FromSuccess(new TypeReaderValue(value, _score)));
diff --git a/src/Discord.Net.Commands/Readers/RoleTypeReader.cs b/src/Discord.Net.Commands/Readers/RoleTypeReader.cs
index 17786e6f0..703374c05 100644
--- a/src/Discord.Net.Commands/Readers/RoleTypeReader.cs
+++ b/src/Discord.Net.Commands/Readers/RoleTypeReader.cs
@@ -9,7 +9,7 @@ namespace Discord.Commands
internal class RoleTypeReader : TypeReader
where T : class, IRole
{
- public override Task Read(ICommandContext context, string input, IServiceProvider services)
+ public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
ulong id;
diff --git a/src/Discord.Net.Commands/Readers/TypeReader.cs b/src/Discord.Net.Commands/Readers/TypeReader.cs
index 2c4644376..af45a0aac 100644
--- a/src/Discord.Net.Commands/Readers/TypeReader.cs
+++ b/src/Discord.Net.Commands/Readers/TypeReader.cs
@@ -5,6 +5,6 @@ namespace Discord.Commands
{
public abstract class TypeReader
{
- public abstract Task Read(ICommandContext context, string input, IServiceProvider services);
+ public abstract Task ReadAsync(ICommandContext context, string input, IServiceProvider services);
}
}
diff --git a/src/Discord.Net.Commands/Readers/UserTypeReader.cs b/src/Discord.Net.Commands/Readers/UserTypeReader.cs
index c71dac2d2..ca337aaf6 100644
--- a/src/Discord.Net.Commands/Readers/UserTypeReader.cs
+++ b/src/Discord.Net.Commands/Readers/UserTypeReader.cs
@@ -10,7 +10,7 @@ namespace Discord.Commands
internal class UserTypeReader : TypeReader
where T : class, IUser
{
- public override async Task Read(ICommandContext context, string input, IServiceProvider services)
+ public override async Task ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
var results = new Dictionary();
IReadOnlyCollection channelUsers = (await context.Channel.GetUsersAsync(CacheMode.CacheOnly).Flatten().ConfigureAwait(false)).ToArray(); //TODO: must be a better way?
diff --git a/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs b/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
index 3d08a8c51..c7cf0b3c2 100644
--- a/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
@@ -20,7 +20,7 @@ namespace Discord
/// The time (in seconds) until the invite expires. Set to null to never expire.
/// The max amount of times this invite may be used. Set to null to have unlimited uses.
/// If true, a user accepting this invite will be kicked from the guild after closing their client.
- Task CreateInviteAsync(int? maxAge = 1800, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null);
+ 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.
Task> GetInvitesAsync(RequestOptions options = null);
diff --git a/src/Discord.Net.Core/Entities/Emotes/EmoteProperties.cs b/src/Discord.Net.Core/Entities/Emotes/EmoteProperties.cs
new file mode 100644
index 000000000..be24d306c
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Emotes/EmoteProperties.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+
+namespace Discord
+{
+ public class EmoteProperties
+ {
+ public Optional Name { get; set; }
+ public Optional> Roles { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
index 909f480ac..0fdd92405 100644
--- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
@@ -122,5 +122,14 @@ namespace Discord
Task GetWebhookAsync(ulong id, RequestOptions options = null);
/// Gets a collection of all webhooks for this guild.
Task> GetWebhooksAsync(RequestOptions options = null);
+
+ /// Gets a specific emote from this guild.
+ Task GetEmoteAsync(ulong id, RequestOptions options = null);
+ /// Creates a new emote in this guild.
+ Task CreateEmoteAsync(string name, Image image, Optional> roles = default(Optional>), RequestOptions options = null);
+ /// Modifies an existing emote in this guild.
+ Task ModifyEmoteAsync(GuildEmote emote, Action func, RequestOptions options = null);
+ /// Deletes an existing emote from this guild.
+ Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null);
}
}
\ No newline at end of file
diff --git a/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs b/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs
index 22e85263c..4c11d0db0 100644
--- a/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs
+++ b/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs
@@ -10,7 +10,7 @@ namespace Discord
/// Gets a blank ChannelPermissions that grants no permissions.
public static readonly ChannelPermissions None = new ChannelPermissions();
/// Gets a ChannelPermissions that grants all permissions for text channels.
- public static readonly ChannelPermissions Text = new ChannelPermissions(0b00100_0000000_1111111110001_010001);
+ public static readonly ChannelPermissions Text = new ChannelPermissions(0b01100_0000000_1111111110001_010001);
/// Gets a ChannelPermissions that grants all permissions for voice channels.
public static readonly ChannelPermissions Voice = new ChannelPermissions(0b00100_1111110_0000000000000_010001);
/// Gets a ChannelPermissions that grants all permissions for direct message channels.
diff --git a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
index 030ccd587..a880e62ca 100644
--- a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
+++ b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
@@ -11,7 +11,7 @@ namespace Discord
/// Gets a GuildPermissions that grants all guild permissions for webhook users.
public static readonly GuildPermissions Webhook = new GuildPermissions(0b00000_0000000_0001101100000_000000);
/// Gets a GuildPermissions that grants all guild permissions.
- public static readonly GuildPermissions All = new GuildPermissions(0b11111_1111110_0111111110011_111111);
+ public static readonly GuildPermissions All = new GuildPermissions(0b11111_1111110_1111111110011_111111);
/// Gets a packed value representing all the permissions in this GuildPermissions.
public ulong RawValue { get; }
@@ -28,7 +28,7 @@ namespace Discord
public bool ManageChannels => Permissions.GetValue(RawValue, GuildPermission.ManageChannels);
/// If True, a user may adjust guild properties.
public bool ManageGuild => Permissions.GetValue(RawValue, GuildPermission.ManageGuild);
-
+
/// If true, a user may add reactions.
public bool AddReactions => Permissions.GetValue(RawValue, GuildPermission.AddReactions);
/// If true, a user may view the audit log.
@@ -80,13 +80,13 @@ namespace Discord
/// Creates a new GuildPermissions 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,
+ 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? 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)
{
ulong value = initialValue;
@@ -124,31 +124,36 @@ namespace Discord
}
/// Creates a new GuildPermissions with the provided permissions.
- public GuildPermissions(bool createInstantInvite = false, bool kickMembers = false,
+ 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 moveMembers = false, bool useVoiceActivation = false, bool? changeNickname = false, bool? manageNicknames = false,
bool manageRoles = false, bool manageWebhooks = false, bool manageEmojis = false)
- : this(0, createInstantInvite, manageRoles, kickMembers, banMembers, manageChannels, manageGuild, addReactions, viewAuditLog,
- readMessages, sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles, mentionEveryone, useExternalEmojis, connect,
- manageWebhooks, manageEmojis) { }
+ : 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)
+ { }
/// Creates a new GuildPermissions from this one, changing the provided non-null permissions.
- public GuildPermissions Modify(bool? createInstantInvite = null, bool? kickMembers = 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? 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? moveMembers = null, bool? useVoiceActivation = null, bool? changeNickname = null, bool? manageNicknames = null,
bool? manageRoles = null, bool? manageWebhooks = null, bool? manageEmojis = null)
- => new GuildPermissions(RawValue, createInstantInvite, manageRoles, kickMembers, banMembers, manageChannels, manageGuild, addReactions, viewAuditLog,
- readMessages, sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles, mentionEveryone, useExternalEmojis, connect,
- speak, muteMembers, deafenMembers, moveMembers, useVoiceActivation, changeNickname, manageNicknames, manageRoles,
- manageWebhooks, manageEmojis);
+ => new GuildPermissions(RawValue, createInstantInvite, kickMembers, banMembers, administrator, manageChannels, manageGuild, addReactions,
+ viewAuditLog, readMessages, sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles,
+ readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers, moveMembers,
+ useVoiceActivation, changeNickname, manageNicknames, manageRoles, manageWebhooks, manageEmojis);
public bool Has(GuildPermission permission) => Permissions.GetValue(RawValue, permission);
diff --git a/src/Discord.Net.Core/Utils/Optional.cs b/src/Discord.Net.Core/Utils/Optional.cs
index df927b7ea..eb3cbdca2 100644
--- a/src/Discord.Net.Core/Utils/Optional.cs
+++ b/src/Discord.Net.Core/Utils/Optional.cs
@@ -10,7 +10,7 @@ namespace Discord
public static Optional Unspecified => default(Optional);
private readonly T _value;
- /// Gets the value for this paramter.
+ /// Gets the value for this parameter.
public T Value
{
get
diff --git a/src/Discord.Net.Core/Utils/Preconditions.cs b/src/Discord.Net.Core/Utils/Preconditions.cs
index bec8de9dc..300f584e4 100644
--- a/src/Discord.Net.Core/Utils/Preconditions.cs
+++ b/src/Discord.Net.Core/Utils/Preconditions.cs
@@ -188,7 +188,8 @@ namespace Discord
var minimum = SnowflakeUtils.ToSnowflake(DateTimeOffset.UtcNow.Subtract(TimeSpan.FromDays(14)));
for (var i = 0; i < collection.Length; i++)
{
- if (collection[i] <= minimum)
+ if (collection[i] == 0) continue;
+ if (collection[i] <= minimum)
throw new ArgumentOutOfRangeException(name, "Messages must be younger than two weeks old.");
}
}
diff --git a/src/Discord.Net.Rest/API/Rest/CreateGuildEmoteParams.cs b/src/Discord.Net.Rest/API/Rest/CreateGuildEmoteParams.cs
new file mode 100644
index 000000000..308199820
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Rest/CreateGuildEmoteParams.cs
@@ -0,0 +1,16 @@
+#pragma warning disable CS1591
+using Newtonsoft.Json;
+
+namespace Discord.API.Rest
+{
+ [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+ internal class CreateGuildEmoteParams
+ {
+ [JsonProperty("name")]
+ public string Name { get; set; }
+ [JsonProperty("image")]
+ public Image Image { get; set; }
+ [JsonProperty("roles")]
+ public Optional RoleIds { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Rest/ModifyGuildEmoteParams.cs b/src/Discord.Net.Rest/API/Rest/ModifyGuildEmoteParams.cs
new file mode 100644
index 000000000..a2295dd5d
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Rest/ModifyGuildEmoteParams.cs
@@ -0,0 +1,14 @@
+#pragma warning disable CS1591
+using Newtonsoft.Json;
+
+namespace Discord.API.Rest
+{
+ [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+ internal class ModifyGuildEmoteParams
+ {
+ [JsonProperty("name")]
+ public Optional Name { get; set; }
+ [JsonProperty("roles")]
+ public Optional RoleIds { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index 5cf2a8901..ab47b1e98 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -1066,6 +1066,50 @@ namespace Discord.API
return await SendJsonAsync>("PATCH", () => $"guilds/{guildId}/roles", args, ids, options: options).ConfigureAwait(false);
}
+ //Guild emoji
+ public async Task GetGuildEmoteAsync(ulong guildId, ulong emoteId, RequestOptions options = null)
+ {
+ Preconditions.NotEqual(guildId, 0, nameof(guildId));
+ Preconditions.NotEqual(emoteId, 0, nameof(emoteId));
+ options = RequestOptions.CreateOrClone(options);
+
+ var ids = new BucketIds(guildId: guildId);
+ return await SendAsync("GET", () => $"guilds/{guildId}/emojis/{emoteId}", ids, options: options);
+ }
+
+ public async Task CreateGuildEmoteAsync(ulong guildId, Rest.CreateGuildEmoteParams args, RequestOptions options = null)
+ {
+ Preconditions.NotEqual(guildId, 0, nameof(guildId));
+ Preconditions.NotNull(args, nameof(args));
+ Preconditions.NotNullOrWhitespace(args.Name, nameof(args.Name));
+ Preconditions.NotNull(args.Image.Stream, nameof(args.Image));
+ options = RequestOptions.CreateOrClone(options);
+
+ var ids = new BucketIds(guildId: guildId);
+ return await SendJsonAsync("POST", () => $"guilds/{guildId}/emojis", args, ids, options: options);
+ }
+
+ public async Task ModifyGuildEmoteAsync(ulong guildId, ulong emoteId, ModifyGuildEmoteParams args, RequestOptions options = null)
+ {
+ Preconditions.NotEqual(guildId, 0, nameof(guildId));
+ Preconditions.NotEqual(emoteId, 0, nameof(emoteId));
+ Preconditions.NotNull(args, nameof(args));
+ options = RequestOptions.CreateOrClone(options);
+
+ var ids = new BucketIds(guildId: guildId);
+ return await SendJsonAsync("PATCH", () => $"guilds/{guildId}/emojis/{emoteId}", args, ids, options: options);
+ }
+
+ public async Task DeleteGuildEmoteAsync(ulong guildId, ulong emoteId, RequestOptions options = null)
+ {
+ Preconditions.NotEqual(guildId, 0, nameof(guildId));
+ Preconditions.NotEqual(emoteId, 0, nameof(emoteId));
+ options = RequestOptions.CreateOrClone(options);
+
+ var ids = new BucketIds(guildId: guildId);
+ await SendAsync("DELETE", () => $"guilds/{guildId}/emojis/{emoteId}", ids, options: options);
+ }
+
//Users
public async Task GetUserAsync(ulong userId, RequestOptions options = null)
{
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs
index 342e57717..04cc5a937 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs
@@ -48,8 +48,8 @@ namespace Discord.Rest
string IChannel.Name => null;
Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
- => Task.FromResult(null); //Overriden
+ => Task.FromResult(null); //Overridden
IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
- => AsyncEnumerable.Empty>(); //Overriden
+ => AsyncEnumerable.Empty>(); //Overridden
}
}
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
index 07832a3a9..1ce1c8368 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
@@ -119,7 +119,7 @@ namespace Discord.Rest
public async Task> GetInvitesAsync(RequestOptions options = null)
=> await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false);
- public async Task CreateInviteAsync(int? maxAge = 3600, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
+ public async Task CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false);
public override string ToString() => Name;
@@ -154,14 +154,14 @@ namespace Discord.Rest
=> await RemovePermissionOverwriteAsync(user, options).ConfigureAwait(false);
IAsyncEnumerable> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
- => AsyncEnumerable.Empty>(); //Overriden //Overriden in Text/Voice
+ => AsyncEnumerable.Empty>(); //Overridden //Overridden in Text/Voice
Task IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
- => Task.FromResult(null); //Overriden in Text/Voice
+ => Task.FromResult(null); //Overridden in Text/Voice
//IChannel
IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
- => AsyncEnumerable.Empty>(); //Overriden in Text/Voice
+ => AsyncEnumerable.Empty>(); //Overridden in Text/Voice
Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
- => Task.FromResult(null); //Overriden in Text/Voice
+ => Task.FromResult(null); //Overridden in Text/Voice
}
}
diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
index 029ac70da..7e25b53f3 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
@@ -267,5 +267,46 @@ namespace Discord.Rest
var models = await client.ApiClient.GetGuildWebhooksAsync(guild.Id, options).ConfigureAwait(false);
return models.Select(x => RestWebhook.Create(client, guild, x)).ToImmutableArray();
}
+
+ //Emotes
+ public static async Task GetEmoteAsync(IGuild guild, BaseDiscordClient client, ulong id, RequestOptions options)
+ {
+ var emote = await client.ApiClient.GetGuildEmoteAsync(guild.Id, id, options);
+ return emote.ToEntity();
+ }
+ public static async Task CreateEmoteAsync(IGuild guild, BaseDiscordClient client, string name, Image image, Optional> roles,
+ RequestOptions options)
+ {
+ var apiargs = new CreateGuildEmoteParams
+ {
+ Name = name,
+ Image = image.ToModel()
+ };
+ if (roles.IsSpecified)
+ apiargs.RoleIds = roles.Value?.Select(xr => xr.Id)?.ToArray();
+
+ var emote = await client.ApiClient.CreateGuildEmoteAsync(guild.Id, apiargs, options);
+ return emote.ToEntity();
+ }
+ public static async Task ModifyEmoteAsync(IGuild guild, BaseDiscordClient client, ulong id, Action func,
+ RequestOptions options)
+ {
+ if (func == null) throw new ArgumentNullException(nameof(func));
+
+ var props = new EmoteProperties();
+ func(props);
+
+ var apiargs = new ModifyGuildEmoteParams
+ {
+ Name = props.Name
+ };
+ if (props.Roles.IsSpecified)
+ apiargs.RoleIds = props.Roles.Value?.Select(xr => xr.Id)?.ToArray();
+
+ var emote = await client.ApiClient.ModifyGuildEmoteAsync(guild.Id, id, apiargs, options);
+ return emote.ToEntity();
+ }
+ public static Task DeleteEmoteAsync(IGuild guild, BaseDiscordClient client, ulong id, RequestOptions options)
+ => client.ApiClient.DeleteGuildEmoteAsync(guild.Id, id, options);
}
}
diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
index 32df7fb06..3b6a2bfa8 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
@@ -266,6 +266,16 @@ namespace Discord.Rest
public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} ({Id})";
+ //Emotes
+ public Task GetEmoteAsync(ulong id, RequestOptions options = null)
+ => GuildHelper.GetEmoteAsync(this, Discord, id, options);
+ public Task CreateEmoteAsync(string name, Image image, Optional> roles = default(Optional>), RequestOptions options = null)
+ => GuildHelper.CreateEmoteAsync(this, Discord, name, image, roles, options);
+ public Task ModifyEmoteAsync(GuildEmote emote, Action func, RequestOptions options = null)
+ => GuildHelper.ModifyEmoteAsync(this, Discord, emote.Id, func, options);
+ public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null)
+ => GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options);
+
//IGuild
bool IGuild.Available => Available;
IAudioClient IGuild.AudioClient => null;
diff --git a/src/Discord.Net.Rest/Extensions/EmbedBuilderExtensions.cs b/src/Discord.Net.Rest/Extensions/EmbedBuilderExtensions.cs
index cee9a136e..2eb4ed473 100644
--- a/src/Discord.Net.Rest/Extensions/EmbedBuilderExtensions.cs
+++ b/src/Discord.Net.Rest/Extensions/EmbedBuilderExtensions.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace Discord
{
public static class EmbedBuilderExtensions
@@ -19,5 +21,38 @@ namespace Discord
public static EmbedBuilder WithAuthor(this EmbedBuilder builder, IGuildUser user) =>
builder.WithAuthor($"{user.Nickname ?? user.Username}#{user.Discriminator}", user.GetAvatarUrl());
+
+ public static EmbedBuilder ToEmbedBuilder(this IEmbed embed)
+ {
+ if (embed.Type != EmbedType.Rich)
+ throw new InvalidOperationException($"Only {nameof(EmbedType.Rich)} embeds may be built.");
+
+ var builder = new EmbedBuilder
+ {
+ Author = new EmbedAuthorBuilder
+ {
+ Name = embed.Author?.Name,
+ IconUrl = embed.Author?.IconUrl,
+ Url = embed.Author?.Url
+ },
+ Color = embed.Color ?? Color.Default,
+ Description = embed.Description,
+ Footer = new EmbedFooterBuilder
+ {
+ Text = embed.Footer?.Text,
+ IconUrl = embed.Footer?.IconUrl
+ },
+ ImageUrl = embed.Image?.Url,
+ ThumbnailUrl = embed.Thumbnail?.Url,
+ Timestamp = embed.Timestamp,
+ Title = embed.Title,
+ Url = embed.Url
+ };
+
+ foreach (var field in embed.Fields)
+ builder.AddField(field.Name, field.Value, field.Inline);
+
+ return builder;
+ }
}
}
diff --git a/src/Discord.Net.Rpc/Entities/Channels/RpcGuildChannel.cs b/src/Discord.Net.Rpc/Entities/Channels/RpcGuildChannel.cs
index 48eb8ec3e..401263555 100644
--- a/src/Discord.Net.Rpc/Entities/Channels/RpcGuildChannel.cs
+++ b/src/Discord.Net.Rpc/Entities/Channels/RpcGuildChannel.cs
@@ -51,7 +51,7 @@ namespace Discord.Rpc
public async Task> GetInvitesAsync(RequestOptions options = null)
=> await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false);
- public async Task CreateInviteAsync(int? maxAge = 3600, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
+ public async Task CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false);
public override string ToString() => Name;
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs
index 1fe9a741f..8e24a5196 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs
@@ -113,7 +113,7 @@ namespace Discord.WebSocket
public async Task> GetInvitesAsync(RequestOptions options = null)
=> await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false);
- public async Task CreateInviteAsync(int? maxAge = 3600, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
+ public async Task CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false);
public new virtual SocketGuildUser GetUser(ulong id) => null;
@@ -154,8 +154,8 @@ namespace Discord.WebSocket
//IChannel
IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
- => ImmutableArray.Create>(Users).ToAsyncEnumerable(); //Overriden in Text/Voice
+ => ImmutableArray.Create>(Users).ToAsyncEnumerable(); //Overridden in Text/Voice
Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
- => Task.FromResult(GetUser(id)); //Overriden in Text/Voice
+ => Task.FromResult(GetUser(id)); //Overridden in Text/Voice
}
}
diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
index 17a9116ef..c4158c136 100644
--- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
+++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
@@ -439,6 +439,16 @@ namespace Discord.WebSocket
public Task> GetWebhooksAsync(RequestOptions options = null)
=> GuildHelper.GetWebhooksAsync(this, Discord, options);
+ //Emotes
+ public Task GetEmoteAsync(ulong id, RequestOptions options = null)
+ => GuildHelper.GetEmoteAsync(this, Discord, id, options);
+ public Task CreateEmoteAsync(string name, Image image, Optional> roles = default(Optional>), RequestOptions options = null)
+ => GuildHelper.CreateEmoteAsync(this, Discord, name, image, roles, options);
+ public Task ModifyEmoteAsync(GuildEmote emote, Action func, RequestOptions options = null)
+ => GuildHelper.ModifyEmoteAsync(this, Discord, emote.Id, func, options);
+ public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null)
+ => GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options);
+
//Voice States
internal async Task AddOrUpdateVoiceStateAsync(ClientState state, VoiceStateModel model)
{
diff --git a/src/Discord.Net/Discord.Net.nuspec b/src/Discord.Net/Discord.Net.nuspec
index 309532615..f904f4126 100644
--- a/src/Discord.Net/Discord.Net.nuspec
+++ b/src/Discord.Net/Discord.Net.nuspec
@@ -2,7 +2,7 @@
Discord.Net
- 2.0.0-alpha$suffix$
+ 2.0.0-beta$suffix$
Discord.Net
Discord.Net Contributors
RogueException
@@ -13,28 +13,28 @@
false
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/test/Discord.Net.Tests/Tests.ChannelPermissions.cs b/test/Discord.Net.Tests/Tests.ChannelPermissions.cs
new file mode 100644
index 000000000..92234e88b
--- /dev/null
+++ b/test/Discord.Net.Tests/Tests.ChannelPermissions.cs
@@ -0,0 +1,324 @@
+using System;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Discord
+{
+ public partial class Tests
+ {
+ [Fact]
+ public void TestChannelPermission()
+ {
+ var perm = new ChannelPermissions();
+
+ // check initial values
+ Assert.Equal((ulong)0, perm.RawValue);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // permissions list empty by default
+ Assert.Empty(perm.ToList());
+
+ // test modify with no parameters
+ var copy = perm.Modify();
+ Assert.Equal((ulong)0, copy.RawValue);
+
+ // test the values that are returned by ChannelPermission.All
+ Assert.Equal((ulong)0, ChannelPermissions.None.RawValue);
+
+ // for text channels
+ ulong textChannel = (ulong)( ChannelPermission.CreateInstantInvite
+ | ChannelPermission.ManageChannels
+ | ChannelPermission.AddReactions
+ | ChannelPermission.ReadMessages
+ | ChannelPermission.SendMessages
+ | ChannelPermission.SendTTSMessages
+ | ChannelPermission.ManageMessages
+ | ChannelPermission.EmbedLinks
+ | ChannelPermission.AttachFiles
+ | ChannelPermission.ReadMessageHistory
+ | ChannelPermission.MentionEveryone
+ | ChannelPermission.UseExternalEmojis
+ | ChannelPermission.ManageRoles
+ | ChannelPermission.ManageWebhooks);
+
+ Assert.Equal(textChannel, ChannelPermissions.Text.RawValue);
+
+ // voice channels
+ ulong voiceChannel = (ulong)(
+ ChannelPermission.CreateInstantInvite
+ | ChannelPermission.ManageChannels
+ | ChannelPermission.Connect
+ | ChannelPermission.Speak
+ | ChannelPermission.MuteMembers
+ | ChannelPermission.DeafenMembers
+ | ChannelPermission.MoveMembers
+ | ChannelPermission.UseVAD
+ | ChannelPermission.ManageRoles);
+
+ Assert.Equal(voiceChannel, ChannelPermissions.Voice.RawValue);
+
+ // DM Channels
+ ulong dmChannel = (ulong)(
+ ChannelPermission.ReadMessages
+ | ChannelPermission.SendMessages
+ | ChannelPermission.EmbedLinks
+ | ChannelPermission.AttachFiles
+ | ChannelPermission.ReadMessageHistory
+ | ChannelPermission.UseExternalEmojis
+ | ChannelPermission.Connect
+ | ChannelPermission.Speak
+ | ChannelPermission.UseVAD
+ );
+ Assert.Equal(dmChannel, ChannelPermissions.DM.RawValue);
+
+ // group channel
+ ulong groupChannel = (ulong)(
+ ChannelPermission.SendMessages
+ | ChannelPermission.EmbedLinks
+ | ChannelPermission.AttachFiles
+ | ChannelPermission.SendTTSMessages
+ | ChannelPermission.Connect
+ | ChannelPermission.Speak
+ | ChannelPermission.UseVAD
+ );
+ Assert.Equal(groupChannel, ChannelPermissions.Group.RawValue);
+ }
+
+ public void TestChannelPermissionModify()
+ {
+ // test channel permission modify
+
+ var perm = new ChannelPermissions();
+
+ // ensure that the permission is initially false
+ Assert.False(perm.CreateInstantInvite);
+
+ // ensure that when modified it works
+ perm = perm.Modify(createInstantInvite: true);
+ Assert.True(perm.CreateInstantInvite);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.CreateInstantInvite);
+
+ // set false again, move on to next permission
+ perm = perm.Modify(createInstantInvite: false);
+ Assert.False(perm.CreateInstantInvite);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.ManageChannel);
+
+ perm = perm.Modify(manageChannel: true);
+ Assert.True(perm.ManageChannel);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ManageChannels);
+
+ perm = perm.Modify(manageChannel: false);
+ Assert.False(perm.ManageChannel);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.AddReactions);
+
+ perm = perm.Modify(addReactions: true);
+ Assert.True(perm.AddReactions);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.AddReactions);
+
+ perm = perm.Modify(addReactions: false);
+ Assert.False(perm.AddReactions);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.ReadMessages);
+
+ perm = perm.Modify(readMessages: true);
+ Assert.True(perm.ReadMessages);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ReadMessages);
+
+ perm = perm.Modify(readMessages: false);
+ Assert.False(perm.ReadMessages);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.SendMessages);
+
+ perm = perm.Modify(sendMessages: true);
+ Assert.True(perm.SendMessages);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.SendMessages);
+
+ perm = perm.Modify(sendMessages: false);
+ Assert.False(perm.SendMessages);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.SendTTSMessages);
+
+ perm = perm.Modify(sendTTSMessages: true);
+ Assert.True(perm.SendTTSMessages);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.SendTTSMessages);
+
+ perm = perm.Modify(sendTTSMessages: false);
+ Assert.False(perm.SendTTSMessages);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.ManageMessages);
+
+ perm = perm.Modify(manageMessages: true);
+ Assert.True(perm.ManageMessages);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ManageMessages);
+
+ perm = perm.Modify(manageMessages: false);
+ Assert.False(perm.ManageMessages);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.EmbedLinks);
+
+ perm = perm.Modify(embedLinks: true);
+ Assert.True(perm.EmbedLinks);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.EmbedLinks);
+
+ perm = perm.Modify(embedLinks: false);
+ Assert.False(perm.EmbedLinks);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.AttachFiles);
+
+ perm = perm.Modify(attachFiles: true);
+ Assert.True(perm.AttachFiles);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.AttachFiles);
+
+ perm = perm.Modify(attachFiles: false);
+ Assert.False(perm.AttachFiles);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.ReadMessageHistory);
+
+ perm = perm.Modify(readMessageHistory: true);
+ Assert.True(perm.ReadMessageHistory);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ReadMessageHistory);
+
+ perm = perm.Modify(readMessageHistory: false);
+ Assert.False(perm.ReadMessageHistory);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.MentionEveryone);
+
+ perm = perm.Modify(mentionEveryone: true);
+ Assert.True(perm.MentionEveryone);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.MentionEveryone);
+
+ perm = perm.Modify(mentionEveryone: false);
+ Assert.False(perm.MentionEveryone);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.UseExternalEmojis);
+
+ perm = perm.Modify(useExternalEmojis: true);
+ Assert.True(perm.UseExternalEmojis);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.UseExternalEmojis);
+
+ perm = perm.Modify(useExternalEmojis: false);
+ Assert.False(perm.UseExternalEmojis);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.Connect);
+
+ perm = perm.Modify(connect: true);
+ Assert.True(perm.Connect);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.Connect);
+
+ perm = perm.Modify(connect: false);
+ Assert.False(perm.Connect);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.Speak);
+
+ perm = perm.Modify(speak: true);
+ Assert.True(perm.Speak);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.Speak);
+
+ perm = perm.Modify(speak: false);
+ Assert.False(perm.Speak);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.MuteMembers);
+
+ perm = perm.Modify(muteMembers: true);
+ Assert.True(perm.MuteMembers);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.MuteMembers);
+
+ perm = perm.Modify(muteMembers: false);
+ Assert.False(perm.MuteMembers);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.DeafenMembers);
+
+ perm = perm.Modify(deafenMembers: true);
+ Assert.True(perm.DeafenMembers);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.DeafenMembers);
+
+ perm = perm.Modify(deafenMembers: false);
+ Assert.False(perm.DeafenMembers);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.MoveMembers);
+
+ perm = perm.Modify(moveMembers: true);
+ Assert.True(perm.MoveMembers);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.MoveMembers);
+
+ perm = perm.Modify(moveMembers: false);
+ Assert.False(perm.MoveMembers);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.UseVAD);
+
+ perm = perm.Modify(useVoiceActivation: true);
+ Assert.True(perm.UseVAD);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.UseVAD);
+
+ perm = perm.Modify(useVoiceActivation: false);
+ Assert.False(perm.UseVAD);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.ManageRoles);
+
+ perm = perm.Modify(manageRoles: true);
+ Assert.True(perm.ManageRoles);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ManageRoles);
+
+ perm = perm.Modify(manageRoles: false);
+ Assert.False(perm.ManageRoles);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ Assert.False(perm.ManageWebhooks);
+
+ perm = perm.Modify(manageWebhooks: true);
+ Assert.True(perm.ManageWebhooks);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ManageWebhooks);
+
+ perm = perm.Modify(manageWebhooks: false);
+ Assert.False(perm.ManageWebhooks);
+ Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue);
+ }
+
+ [Fact]
+ public void TestChannelTypeResolution()
+ {
+ ITextChannel someChannel = null;
+ // null channels will throw exception
+ Assert.Throws(() => ChannelPermissions.All(someChannel));
+ }
+ }
+}
diff --git a/test/Discord.Net.Tests/Tests.GuildPermissions.cs b/test/Discord.Net.Tests/Tests.GuildPermissions.cs
new file mode 100644
index 000000000..dc51600cf
--- /dev/null
+++ b/test/Discord.Net.Tests/Tests.GuildPermissions.cs
@@ -0,0 +1,304 @@
+using System;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Discord
+{
+ public partial class Tests
+ {
+ [Fact]
+ public void TestGuildPermission()
+ {
+ // Test Guild Permission Constructors
+ var perm = new GuildPermissions();
+
+ // the default raw value is 0
+ Assert.Equal((ulong)0, perm.RawValue);
+ // also check that it is the same as none
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // permissions list is empty by default
+ Assert.Empty(perm.ToList());
+ Assert.NotNull(perm.ToList());
+
+ // Test modify with no parameters
+ var copy = perm.Modify();
+ // ensure that the raw values match
+ Assert.Equal((ulong)0, copy.RawValue);
+
+ // test GuildPermissions.All
+ ulong sumOfAllGuildPermissions = 0;
+ foreach(var v in Enum.GetValues(typeof(GuildPermission)))
+ {
+ sumOfAllGuildPermissions |= (ulong)v;
+ }
+
+ // assert that the raw values match
+ Assert.Equal(sumOfAllGuildPermissions, GuildPermissions.All.RawValue);
+ Assert.Equal((ulong)0, GuildPermissions.None.RawValue);
+
+ // assert that GuildPermissions.All contains the same number of permissions as the
+ // GuildPermissions enum
+ Assert.Equal(Enum.GetValues(typeof(GuildPermission)).Length, GuildPermissions.All.ToList().Count);
+
+ // assert that webhook has the same raw value
+ ulong webHookPermissions = (ulong)(
+ GuildPermission.SendMessages | GuildPermission.SendTTSMessages | GuildPermission.EmbedLinks |
+ GuildPermission.AttachFiles);
+ Assert.Equal(webHookPermissions, GuildPermissions.Webhook.RawValue);
+ }
+
+ [Fact]
+ public void TestGuildPermissionModify()
+ {
+ var perm = new GuildPermissions();
+
+ // tests each of the parameters of Modify one by one
+
+ // test modify with each of the parameters
+ // test initially false state
+ Assert.False(perm.CreateInstantInvite);
+
+ // ensure that when we modify it the parameter works
+ perm = perm.Modify(createInstantInvite: true);
+ Assert.True(perm.CreateInstantInvite);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.CreateInstantInvite);
+
+ // set it false again, then move on to the next permission
+ perm = perm.Modify(createInstantInvite: false);
+ Assert.False(perm.CreateInstantInvite);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(kickMembers: true);
+ Assert.True(perm.KickMembers);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.KickMembers);
+
+ perm = perm.Modify(kickMembers: false);
+ Assert.False(perm.KickMembers);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(banMembers: true);
+ Assert.True(perm.BanMembers);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.BanMembers);
+
+ perm = perm.Modify(banMembers: false);
+ Assert.False(perm.BanMembers);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(administrator: true);
+ Assert.True(perm.Administrator);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.Administrator);
+
+ perm = perm.Modify(administrator: false);
+ Assert.False(perm.Administrator);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(manageChannels: true);
+ Assert.True(perm.ManageChannels);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ManageChannels);
+
+ perm = perm.Modify(manageChannels: false);
+ Assert.False(perm.ManageChannels);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(manageGuild: true);
+ Assert.True(perm.ManageGuild);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ManageGuild);
+
+ perm = perm.Modify(manageGuild: false);
+ Assert.False(perm.ManageGuild);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+
+ // individual permission test
+ perm = perm.Modify(addReactions: true);
+ Assert.True(perm.AddReactions);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.AddReactions);
+
+ perm = perm.Modify(addReactions: false);
+ Assert.False(perm.AddReactions);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+
+ // individual permission test
+ perm = perm.Modify(viewAuditLog: true);
+ Assert.True(perm.ViewAuditLog);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ViewAuditLog);
+
+ perm = perm.Modify(viewAuditLog: false);
+ Assert.False(perm.ViewAuditLog);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+
+ // individual permission test
+ perm = perm.Modify(readMessages: true);
+ Assert.True(perm.ReadMessages);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ReadMessages);
+
+ perm = perm.Modify(readMessages: false);
+ Assert.False(perm.ReadMessages);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+
+ // individual permission test
+ perm = perm.Modify(sendMessages: true);
+ Assert.True(perm.SendMessages);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.SendMessages);
+
+ perm = perm.Modify(sendMessages: false);
+ Assert.False(perm.SendMessages);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(embedLinks: true);
+ Assert.True(perm.EmbedLinks);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.EmbedLinks);
+
+ perm = perm.Modify(embedLinks: false);
+ Assert.False(perm.EmbedLinks);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(attachFiles: true);
+ Assert.True(perm.AttachFiles);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.AttachFiles);
+
+ perm = perm.Modify(attachFiles: false);
+ Assert.False(perm.AttachFiles);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(readMessageHistory: true);
+ Assert.True(perm.ReadMessageHistory);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ReadMessageHistory);
+
+ perm = perm.Modify(readMessageHistory: false);
+ Assert.False(perm.ReadMessageHistory);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(mentionEveryone: true);
+ Assert.True(perm.MentionEveryone);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.MentionEveryone);
+
+ perm = perm.Modify(mentionEveryone: false);
+ Assert.False(perm.MentionEveryone);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(useExternalEmojis: true);
+ Assert.True(perm.UseExternalEmojis);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.UseExternalEmojis);
+
+ perm = perm.Modify(useExternalEmojis: false);
+ Assert.False(perm.UseExternalEmojis);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(connect: true);
+ Assert.True(perm.Connect);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.Connect);
+
+ perm = perm.Modify(connect: false);
+ Assert.False(perm.Connect);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(speak: true);
+ Assert.True(perm.Speak);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.Speak);
+
+ perm = perm.Modify(speak: false);
+ Assert.False(perm.Speak);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(muteMembers: true);
+ Assert.True(perm.MuteMembers);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.MuteMembers);
+
+ perm = perm.Modify(muteMembers: false);
+ Assert.False(perm.MuteMembers);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(deafenMembers: true);
+ Assert.True(perm.DeafenMembers);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.DeafenMembers);
+
+ perm = perm.Modify(deafenMembers: false);
+ Assert.False(perm.DeafenMembers);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(moveMembers: true);
+ Assert.True(perm.MoveMembers);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.MoveMembers);
+
+ perm = perm.Modify(moveMembers: false);
+ Assert.False(perm.MoveMembers);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(useVoiceActivation: true);
+ Assert.True(perm.UseVAD);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.UseVAD);
+
+ perm = perm.Modify(useVoiceActivation: false);
+ Assert.False(perm.UseVAD);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(changeNickname: true);
+ Assert.True(perm.ChangeNickname);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ChangeNickname);
+
+ perm = perm.Modify(changeNickname: false);
+ Assert.False(perm.ChangeNickname);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(manageNicknames: true);
+ Assert.True(perm.ManageNicknames);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ManageNicknames);
+
+ perm = perm.Modify(manageNicknames: false);
+ Assert.False(perm.ManageNicknames);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(manageRoles: true);
+ Assert.True(perm.ManageRoles);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ManageRoles);
+
+ perm = perm.Modify(manageRoles: false);
+ Assert.False(perm.ManageRoles);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(manageWebhooks: true);
+ Assert.True(perm.ManageWebhooks);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ManageWebhooks);
+
+ perm = perm.Modify(manageWebhooks: false);
+ Assert.False(perm.ManageWebhooks);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ // individual permission test
+ perm = perm.Modify(manageEmojis: true);
+ Assert.True(perm.ManageEmojis);
+ Assert.Equal(perm.RawValue, (ulong)GuildPermission.ManageEmojis);
+
+ perm = perm.Modify(manageEmojis: false);
+ Assert.False(perm.ManageEmojis);
+ Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue);
+
+ }
+
+ }
+}